From 182a721755efcfe143e2d9158f18777611340d30 Mon Sep 17 00:00:00 2001 From: Andrew Min Date: Fri, 29 May 2026 15:43:02 -0400 Subject: [PATCH 1/2] add prettier tooling --- .prettierignore | 9 +++++++++ Makefile | 10 +++++++++- README.md | 15 +++++++++++++++ package-lock.json | 27 ++++++++++++++++++++++++++- 4 files changed, 59 insertions(+), 2 deletions(-) diff --git a/.prettierignore b/.prettierignore index 14af5911..da5e8e11 100644 --- a/.prettierignore +++ b/.prettierignore @@ -132,3 +132,12 @@ test-results/ playwright-report/ playwright/.cache/ +# Generated API artifacts (regenerated via `make gen`) +public_api.swagger.json +proxy_api.swagger.json +scripts/openapi-gen/openapi.json +scripts/openapi-gen/proxy_api_openapi.json + +# Synced from the SDK repo via `make sync-sdk-gen-docs` (don't reformat in place) +generated-docs/ + diff --git a/Makefile b/Makefile index 58ca7e26..0d520269 100644 --- a/Makefile +++ b/Makefile @@ -1,12 +1,20 @@ ROOT := $(shell git rev-parse --show-toplevel) JS_SDK_ROOT := $(ROOT)/../sdk -.PHONY: openapi-gen gen tags mintlify-check +.PHONY: openapi-gen gen tags mintlify-check format format-check # Convenience method to start dev server dev: mintlify dev +# Format all hand-written content with Prettier (mdx, md, css, json, ts, js, ...) +format: + npm run format + +# Check formatting without writing changes (use in CI) +format-check: + npm run format:check + # Install deps for OpenAPI install: cd scripts/openapi-gen && npm install diff --git a/README.md b/README.md index 53f93fcf..3e9bad53 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,21 @@ mintlify dev This will start a local development server where you can preview your changes in real-time. +### Formatting + +This repo uses [Prettier](https://prettier.io) to format all hand-written content (`.mdx`, `.md`, `.css`, `.json`, `.ts`, `.js`, ...). Generated artifacts (swagger files, `generated-docs/`) are excluded via `.prettierignore`. + +```sh +# Install dev dependencies (one time) +npm install + +# Format everything in place +npm run format # or: make format + +# Check formatting without writing (useful in CI) +npm run format:check # or: make format-check +``` + If you encounter any issues with the development server: - Run `mintlify install` to reinstall dependencies diff --git a/package-lock.json b/package-lock.json index 6ab68257..f8d2e670 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,31 @@ { "name": "docs", + "version": "1.0.0", "lockfileVersion": 3, "requires": true, - "packages": {} + "packages": { + "": { + "name": "docs", + "version": "1.0.0", + "devDependencies": { + "prettier": "^3.4.2" + } + }, + "node_modules/prettier": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.3.tgz", + "integrity": "sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + } + } } From 921d933be1c13b0a33814fd00cf1ff93ea545077 Mon Sep 17 00:00:00 2001 From: Andrew Min Date: Fri, 29 May 2026 15:44:55 -0400 Subject: [PATCH 2/2] prettify --- DESIGN-WORKFLOW.md | 14 +- README.md | 8 +- api-reference/activities/approve-activity.mdx | 67 +- .../activities/broadcast-evm-transaction.mdx | 59 +- .../activities/broadcast-svm-transaction.mdx | 59 +- .../activities/claim-spark-transfer.mdx | 215 +- .../create-a-fiat-on-ramp-credential.mdx | 59 +- api-reference/activities/create-a-tvc-app.mdx | 322 ++- .../activities/create-a-tvc-deployment.mdx | 218 +- .../create-an-oauth-20-credential.mdx | 59 +- api-reference/activities/create-api-keys.mdx | 73 +- .../activities/create-authenticators.mdx | 77 +- .../activities/create-invitations.mdx | 68 +- .../activities/create-oauth-providers.mdx | 63 +- api-reference/activities/create-policies.mdx | 63 +- api-reference/activities/create-policy.mdx | 59 +- .../activities/create-private-key-tag.mdx | 67 +- .../activities/create-private-keys.mdx | 68 +- .../activities/create-read-only-session.mdx | 70 +- .../activities/create-read-write-session.mdx | 59 +- .../create-smart-contract-interface.mdx | 59 +- .../activities/create-sub-organization.mdx | 97 +- .../create-tvc-manifest-approvals.mdx | 106 +- api-reference/activities/create-user-tag.mdx | 67 +- api-reference/activities/create-users.mdx | 74 +- .../activities/create-wallet-accounts.mdx | 75 +- api-reference/activities/create-wallet.mdx | 74 +- .../activities/create-webhook-endpoint.mdx | 59 +- .../delete-a-fiat-on-ramp-credential.mdx | 59 +- ...e-a-tvc-app-and-all-of-its-deployments.mdx | 59 +- .../activities/delete-a-tvc-deployment.mdx | 59 +- .../delete-an-oauth-20-credential.mdx | 59 +- api-reference/activities/delete-api-keys.mdx | 67 +- .../activities/delete-authenticators.mdx | 67 +- .../activities/delete-invitation.mdx | 59 +- .../activities/delete-oauth-providers.mdx | 67 +- api-reference/activities/delete-policies.mdx | 67 +- api-reference/activities/delete-policy.mdx | 59 +- .../activities/delete-private-key-tags.mdx | 72 +- .../activities/delete-private-keys.mdx | 78 +- .../delete-smart-contract-interface.mdx | 59 +- .../activities/delete-sub-organization.mdx | 59 +- api-reference/activities/delete-user-tags.mdx | 72 +- api-reference/activities/delete-users.mdx | 67 +- .../activities/delete-wallet-accounts.mdx | 78 +- api-reference/activities/delete-wallets.mdx | 78 +- .../activities/delete-webhook-endpoint.mdx | 59 +- .../activities/export-private-key.mdx | 59 +- .../activities/export-wallet-account.mdx | 59 +- api-reference/activities/export-wallet.mdx | 59 +- .../activities/import-private-key.mdx | 63 +- api-reference/activities/import-wallet.mdx | 63 +- .../activities/init-email-recovery.mdx | 88 +- .../activities/init-fiat-on-ramp.mdx | 59 +- api-reference/activities/init-generic-otp.mdx | 120 +- .../activities/init-import-private-key.mdx | 59 +- .../activities/init-import-wallet.mdx | 59 +- api-reference/activities/init-otp-auth.mdx | 120 +- .../activities/login-with-a-stamp.mdx | 59 +- api-reference/activities/login-with-oauth.mdx | 59 +- api-reference/activities/login-with-otp.mdx | 79 +- .../activities/oauth-20-authentication.mdx | 59 +- api-reference/activities/oauth.mdx | 59 +- api-reference/activities/otp-auth.mdx | 59 +- .../activities/perform-email-auth.mdx | 97 +- .../activities/prepare-spark-transfer.mdx | 442 +++- api-reference/activities/recover-a-user.mdx | 77 +- api-reference/activities/reject-activity.mdx | 67 +- .../activities/remove-ip-allowlist.mdx | 59 +- .../remove-organization-feature.mdx | 59 +- .../activities/restore-a-tvc-deployment.mdx | 59 +- api-reference/activities/set-ip-allowlist.mdx | 70 +- .../activities/set-organization-feature.mdx | 59 +- api-reference/activities/sign-frost-spark.mdx | 277 +- api-reference/activities/sign-raw-payload.mdx | 59 +- .../activities/sign-raw-payloads.mdx | 64 +- api-reference/activities/sign-transaction.mdx | 59 +- .../spark-prepare-lightning-receive.mdx | 138 +- .../update-a-fiat-on-ramp-credential.mdx | 59 +- .../update-an-oauth-20-credential.mdx | 59 +- .../activities/update-organization-name.mdx | 59 +- api-reference/activities/update-policy.mdx | 59 +- .../activities/update-private-key-tag.mdx | 68 +- .../activities/update-root-quorum.mdx | 63 +- api-reference/activities/update-user-tag.mdx | 68 +- api-reference/activities/update-user.mdx | 73 +- .../activities/update-users-email.mdx | 59 +- .../activities/update-users-name.mdx | 59 +- .../activities/update-users-phone-number.mdx | 59 +- api-reference/activities/update-wallet.mdx | 59 +- .../activities/update-webhook-endpoint.mdx | 59 +- .../activities/verify-generic-otp.mdx | 59 +- api-reference/auth-proxy/account.mdx | 24 +- api-reference/auth-proxy/oauth-login.mdx | 25 +- .../auth-proxy/oauth2-authenticate.mdx | 26 +- api-reference/auth-proxy/otp-init.mdx | 44 +- api-reference/auth-proxy/otp-login.mdx | 25 +- api-reference/auth-proxy/otp-verify.mdx | 24 +- api-reference/auth-proxy/signup.mdx | 411 ++- .../auth-proxy/wallet-kit-config.mdx | 20 +- api-reference/overview/errors.mdx | 173 +- api-reference/overview/intro.mdx | 10 +- api-reference/overview/stamps.mdx | 70 +- .../queries/get-a-specific-boot-proof.mdx | 17 +- api-reference/queries/get-activity.mdx | 1544 ++++++++--- api-reference/queries/get-api-key.mdx | 19 +- api-reference/queries/get-api-keys.mdx | 19 +- api-reference/queries/get-authenticator.mdx | 14 +- api-reference/queries/get-authenticators.mdx | 14 +- api-reference/queries/get-balances.mdx | 18 +- api-reference/queries/get-configs.mdx | 11 +- api-reference/queries/get-gas-usage.mdx | 21 +- api-reference/queries/get-ip-allowlist.mdx | 39 +- api-reference/queries/get-nonces.mdx | 18 +- .../queries/get-oauth-20-credential.mdx | 8 +- api-reference/queries/get-oauth-providers.mdx | 8 +- .../get-on-ramp-transaction-status.mdx | 12 +- .../queries/get-policy-evaluations.mdx | 8 +- api-reference/queries/get-policy.mdx | 29 +- api-reference/queries/get-private-key.mdx | 33 +- .../queries/get-send-transaction-status.mdx | 36 +- .../queries/get-smart-contract-interface.mdx | 8 +- .../queries/get-sub-organizations.mdx | 55 +- .../get-the-latest-boot-proof-for-an-app.mdx | 17 +- api-reference/queries/get-tvc-app-status.mdx | 17 +- api-reference/queries/get-tvc-app.mdx | 39 +- api-reference/queries/get-tvc-deployment.mdx | 38 +- api-reference/queries/get-user.mdx | 36 +- .../get-verified-sub-organizations.mdx | 55 +- api-reference/queries/get-wallet-account.mdx | 33 +- api-reference/queries/get-wallet.mdx | 27 +- api-reference/queries/list-activities.mdx | 1781 +++++++++---- .../list-app-proofs-for-an-activity.mdx | 7 +- .../queries/list-fiat-on-ramp-credentials.mdx | 7 +- .../queries/list-oauth-20-credentials.mdx | 7 +- api-reference/queries/list-policies.mdx | 35 +- .../queries/list-private-key-tags.mdx | 7 +- api-reference/queries/list-private-keys.mdx | 32 +- .../list-smart-contract-interfaces.mdx | 7 +- .../queries/list-supported-assets.mdx | 7 +- api-reference/queries/list-tvc-apps.mdx | 38 +- .../queries/list-tvc-deployments.mdx | 38 +- api-reference/queries/list-user-tags.mdx | 7 +- api-reference/queries/list-users.mdx | 35 +- .../queries/list-wallets-accounts.mdx | 73 +- api-reference/queries/list-wallets.mdx | 26 +- .../queries/list-webhook-endpoints.mdx | 6 +- api-reference/queries/overview.mdx | 2 - .../validate-container-image-for-tvc.mdx | 12 +- api-reference/queries/who-am-i.mdx | 24 +- changelogs/api-key-stamper/readme.mdx | 2 +- changelogs/core/readme.mdx | 2 +- changelogs/cosmjs/readme.mdx | 2 +- changelogs/crypto/readme.mdx | 2 +- changelogs/eip-1193-provider/readme.mdx | 2 +- changelogs/encoding/readme.mdx | 2 +- changelogs/ethers/readme.mdx | 2 +- changelogs/http/readme.mdx | 2 +- changelogs/iframe-stamper/readme.mdx | 2 +- .../react-native-passkey-stamper/readme.mdx | 2 +- changelogs/react-wallet-kit/readme.mdx | 2 +- changelogs/sdk-browser/readme.mdx | 2 +- changelogs/sdk-react-native/readme.mdx | 2 +- changelogs/sdk-react/readme.mdx | 2 +- changelogs/sdk-server/readme.mdx | 2 +- changelogs/solana/readme.mdx | 2 +- .../telegram-cloud-storage-stamper/readme.mdx | 2 +- changelogs/viem/readme.mdx | 2 +- changelogs/wallet-stamper/readme.mdx | 2 +- changelogs/webauthn-stamper/readme.mdx | 2 +- docs.json | 32 +- features/authentication/auth-proxy.mdx | 43 +- features/authentication/backend-setup.mdx | 142 +- .../authentication/bring-your-own-auth.mdx | 84 +- features/authentication/email.mdx | 80 +- features/authentication/overview.mdx | 45 +- .../discoverable-vs-non-discoverable.mdx | 22 +- .../authentication/passkeys/integration.mdx | 24 +- .../authentication/passkeys/introduction.mdx | 16 +- features/authentication/passkeys/native.mdx | 18 +- features/authentication/passkeys/options.mdx | 51 +- .../proxying-signed-requests.mdx | 9 +- features/authentication/sessions.mdx | 21 +- features/authentication/sms.mdx | 4 +- features/authentication/social-logins.mdx | 20 +- features/networks/aptos.mdx | 26 +- features/networks/bitcoin.mdx | 57 +- features/networks/cosmos.mdx | 6 +- features/networks/doge.mdx | 4 +- features/networks/ethereum.mdx | 4 +- features/networks/hyperliquid.mdx | 2 +- features/networks/iota.mdx | 56 +- features/networks/overview.mdx | 12 +- features/networks/sei.mdx | 4 +- features/networks/solana-rent-refunds.mdx | 6 +- features/networks/solana.mdx | 4 +- features/networks/spark.mdx | 21 +- features/networks/stacks.mdx | 2 +- features/networks/sui.mdx | 58 +- features/networks/tempo.mdx | 2 + features/networks/tron.mdx | 2 +- features/organizations.mdx | 6 +- .../delegated-access/agentic-wallets.mdx | 77 +- .../policies/delegated-access/backend.mdx | 14 +- .../policies/delegated-access/frontend.mdx | 150 +- .../policies/delegated-access/overview.mdx | 123 +- features/policies/examples/bitcoin.mdx | 3 +- .../examples/co-signing-transactions.mdx | 12 +- features/policies/examples/ethereum.mdx | 7 +- features/policies/examples/solana.mdx | 4 +- features/policies/language.mdx | 62 +- features/policies/quickstart.mdx | 29 +- .../policies/smart-contract-interfaces.mdx | 193 +- features/transaction-management.mdx | 2 +- .../transaction-management/broadcasting.mdx | 2 +- .../sending-sponsored-solana-transactions.mdx | 14 +- features/users/best-practices.mdx | 6 +- features/users/credentials.mdx | 29 +- features/users/introduction.mdx | 12 +- features/users/root-quorum.mdx | 18 +- features/verifiable-cloud/onboarding.mdx | 23 +- features/verifiable-cloud/overview.mdx | 84 +- features/verifiable-cloud/quickstart.mdx | 57 +- features/wallets/aa-wallets.mdx | 5 +- features/wallets/claim-links.mdx | 2 +- features/webhooks/overview.mdx | 122 +- ga.js | 16 +- get-started/about-turnkey.mdx | 5 +- get-started/ai-skills.mdx | 83 +- get-started/backup-recovery.mdx | 2 +- get-started/examples.mdx | 44 +- get-started/production-checklist.mdx | 5 +- get-started/quickstart.mdx | 63 +- hero-animation.js | 51 +- reference/faq.mdx | 17 +- reference/migration-guide.mdx | 25 +- reference/resource-limits.mdx | 26 +- scripts/openapi-gen/README.md | 3 +- scripts/openapi-gen/openapi-gen-plan.md | 4 +- scripts/openapi-gen/openapi-gen.ts | 80 +- .../openapi-gen/openapi-to-api-endpoints.md | 2 - scripts/openapi-gen/output.json | 2 +- scripts/openapi-gen/swagger-to-openapi.ts | 30 +- scripts/openapi-gen/test-endpoints.json | 2 +- scripts/openapi-gen/types.ts | 2 +- scripts/openapi-gen/utils/cli.ts | 23 +- .../utils/endpoint-parser/formatter.ts | 4 +- .../utils/endpoint-parser/parser.ts | 86 +- .../utils/endpoint-parser/types.ts | 2 +- .../mdx-generator/auth-proxy-generator.ts | 23 +- .../utils/mdx-generator/generator.ts | 94 +- .../openapi-gen/utils/mdx-generator/index.ts | 4 +- scripts/openapi-gen/utils/parser.ts | 4 +- sdks/advanced/api-key-stamper.mdx | 5 + sdks/advanced/client-side-signing.mdx | 26 +- sdks/advanced/iframe-stamper.mdx | 8 + sdks/advanced/overview.mdx | 59 +- sdks/advanced/turnkey-client.mdx | 10 +- sdks/advanced/wallet-stamper.mdx | 6 + sdks/advanced/webauthn-stamper.mdx | 7 + sdks/foundry.mdx | 2 - sdks/introduction.mdx | 49 +- sdks/swift/proxy-middleware.mdx | 6 +- sdks/web3/gas-station.mdx | 5 +- sdks/web3/overview.mdx | 59 +- sdks/web3/viem.mdx | 2 +- sdks/web3/wagmi.mdx | 15 +- security/overview.mdx | 94 +- security/reporting-a-vulnerability.mdx | 2 +- security/shared-responsibility-model.mdx | 26 +- security/turnkey-verified.mdx | 45 +- snippets/api/authorizations.mdx | 3 +- snippets/data/endpoint-tags.mdx | 2282 ++++++++--------- snippets/divider.mdx | 8 +- snippets/logo.mdx | 255 +- snippets/shared/balance-concepts.mdx | 63 +- snippets/shared/export-wallets.mdx | 7 +- snippets/shared/import-wallets.mdx | 12 +- snippets/shared/networks-links.mdx | 41 +- snippets/shared/policy-engine.mdx | 3 +- .../shared/send-solana-tx-sdk-overview.mdx | 6 +- snippets/shared/send-tx-concepts.mdx | 41 +- snippets/shared/send-tx-core.mdx | 15 +- snippets/shared/send-tx-gas-usage.mdx | 7 +- snippets/shared/send-tx-react.mdx | 1 + snippets/sms-price-data.mdx | 4 +- snippets/solution-card.mdx | 2 +- solutions/company-wallets/agentic-wallets.mdx | 120 +- .../integration-guide/golang.mdx | 1 - .../integration-guide/javascript-server.mdx | 12 +- .../integration-guide/overview.mdx | 48 +- .../integration-guide/rust.mdx | 2 - solutions/company-wallets/overview.mdx | 10 +- .../company-wallets/payment-orchestration.mdx | 95 +- solutions/company-wallets/quickstart.mdx | 75 +- .../smart-contract-management.mdx | 74 +- solutions/cookbooks/0x.mdx | 20 +- solutions/cookbooks/aave.mdx | 231 +- solutions/cookbooks/base-builder-codes.mdx | 2 +- solutions/cookbooks/brale.mdx | 7 +- solutions/cookbooks/breeze.mdx | 28 +- solutions/cookbooks/jupiter.mdx | 29 +- solutions/cookbooks/landing.mdx | 10 +- solutions/cookbooks/lifi.mdx | 73 +- solutions/cookbooks/morpho.mdx | 158 +- solutions/cookbooks/polymarket-builders.mdx | 31 +- solutions/cookbooks/relay.mdx | 44 +- .../wallet-connect-pay-integration.mdx | 35 +- solutions/cookbooks/yieldxyz.mdx | 94 +- .../embedded-business-wallets.mdx | 73 +- .../embedded-consumer-wallet.mdx | 50 +- solutions/embedded-wallets/embedded-waas.mdx | 44 +- .../flutter/advanced-api-requests.mdx | 7 +- .../flutter/authentication/email-sms.mdx | 11 +- .../flutter/authentication/overview.mdx | 40 +- .../flutter/authentication/passkey.mdx | 18 +- .../flutter/authentication/social-logins.mdx | 67 +- .../flutter/getting-started.mdx | 16 +- .../integration-guide/flutter/index.mdx | 47 +- .../integration-guide/flutter/signing.mdx | 2 - .../sub-organization-customization.mdx | 1 - .../flutter/using-embedded-wallets.mdx | 3 - .../kotlin/advanced-api-requests.mdx | 12 +- .../kotlin/authentication/email-sms.mdx | 2 +- .../kotlin/authentication/overview.mdx | 40 +- .../kotlin/authentication/passkey.mdx | 2 +- .../kotlin/authentication/rp-id-setup.mdx | 1 + .../kotlin/authentication/social-logins.mdx | 2 +- .../kotlin/getting-started.mdx | 6 +- .../integration-guide/kotlin/overview.mdx | 47 +- .../integration-guide/kotlin/signing.mdx | 2 +- .../kotlin/sub-organization-customization.mdx | 31 +- .../kotlin/using-embedded-wallets.mdx | 13 +- .../integration-guide/overview.mdx | 84 +- .../react-native/advanced-api-requests.mdx | 2 +- .../react-native/authentication/email-sms.mdx | 2 +- .../react-native/authentication/overview.mdx | 31 +- .../react-native/getting-started.mdx | 2 +- .../react-native/overview.mdx | 45 +- .../react/advanced-api-requests.mdx | 2 +- .../react/advanced-backend-authentication.mdx | 4 +- .../integration-guide/react/auth.mdx | 10 +- .../react/getting-started.mdx | 23 +- .../integration-guide/react/index.mdx | 80 +- .../react/migrating-sdk-react.mdx | 18 +- .../integration-guide/react/signing.mdx | 4 +- .../react/troubleshooting.mdx | 40 +- .../react/using-embedded-wallets.mdx | 2 +- .../using-external-wallets/authentication.mdx | 58 +- .../using-external-wallets/connecting.mdx | 128 +- .../react/using-external-wallets/overview.mdx | 37 +- .../swift/authentication/email-sms.mdx | 9 +- .../swift/authentication/overview.mdx | 32 +- .../swift/authentication/passkey.mdx | 9 +- .../swift/authentication/social-logins.mdx | 9 +- .../integration-guide/swift/overview.mdx | 8 +- .../typescript/advanced-api-requests.mdx | 2 +- .../integration-guide/typescript/auth.mdx | 15 +- .../typescript/getting-started.mdx | 41 +- .../integration-guide/typescript/index.mdx | 38 +- .../integration-guide/typescript/legacy.mdx | 31 +- solutions/embedded-wallets/overview.mdx | 15 +- solutions/embedded-wallets/quickstart.mdx | 78 +- .../key-management/encryption-key-storage.mdx | 75 +- .../enterprise-disaster-recovery.mdx | 72 +- solutions/key-management/overview.mdx | 10 +- solutions/overview.mdx | 26 +- styles.css | 210 +- welcome.mdx | 100 +- 369 files changed, 14573 insertions(+), 6794 deletions(-) diff --git a/DESIGN-WORKFLOW.md b/DESIGN-WORKFLOW.md index d9294359..3dd77c48 100644 --- a/DESIGN-WORKFLOW.md +++ b/DESIGN-WORKFLOW.md @@ -17,13 +17,13 @@ Production deploys from **`main`** (see README). ## Files to edit -| Change | Files | -|--------|--------| -| Welcome / landing layout | `welcome.mdx` | -| Welcome / shared UI styles | `styles.css` (`.tk-*` classes) | -| Site-wide color, nav, fonts | `docs.json` | -| Illustrations, icons | `images/` (use `/images/...` paths) | -| Logos / favicon | `logo/`, `favicon.svg` | +| Change | Files | +| --------------------------- | ----------------------------------- | +| Welcome / landing layout | `welcome.mdx` | +| Welcome / shared UI styles | `styles.css` (`.tk-*` classes) | +| Site-wide color, nav, fonts | `docs.json` | +| Illustrations, icons | `images/` (use `/images/...` paths) | +| Logos / favicon | `logo/`, `favicon.svg` | Avoid unless intentional: diff --git a/README.md b/README.md index 3e9bad53..1b45b86b 100644 --- a/README.md +++ b/README.md @@ -84,10 +84,10 @@ The docs in this repository utilize shared MDX snippets to ensure consistency an **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` | +| 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/company-wallets/features/export-wallets.mdx` | `/snippets/shared/export-wallets.mdx` | | `products/company-wallets/features/import-wallets.mdx` | `/snippets/shared/import-wallets.mdx` | diff --git a/api-reference/activities/approve-activity.mdx b/api-reference/activities/approve-activity.mdx index 3f190c1d..c1a5f493 100644 --- a/api-reference/activities/approve-activity.mdx +++ b/api-reference/activities/approve-activity.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_APPROVE_ACTIVITY` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -40,11 +43,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -76,26 +79,58 @@ An artifact verifying a User's action. - -The result of the activity + + + The result of the activity -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/broadcast-evm-transaction.mdx b/api-reference/activities/broadcast-evm-transaction.mdx index 1fa2f632..5f7f2428 100644 --- a/api-reference/activities/broadcast-evm-transaction.mdx +++ b/api-reference/activities/broadcast-evm-transaction.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_ETH_SEND_TRANSACTION` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -84,11 +87,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -156,6 +159,7 @@ The gas station delegate contract nonce. Only used when sponsor=true. Include th + The result of the activity @@ -171,23 +175,50 @@ The send_transaction_status ID associated with the transaction submission + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/broadcast-svm-transaction.mdx b/api-reference/activities/broadcast-svm-transaction.mdx index 20ec8ce7..062042e1 100644 --- a/api-reference/activities/broadcast-svm-transaction.mdx +++ b/api-reference/activities/broadcast-svm-transaction.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_SOL_SEND_TRANSACTION` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -56,11 +59,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -107,6 +110,7 @@ user-provided blockhash for replay protection / deadline control. If omitted and + The result of the activity @@ -122,23 +126,50 @@ The send_transaction_status ID associated with the transaction submission + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/claim-spark-transfer.mdx b/api-reference/activities/claim-spark-transfer.mdx index 1f0931ca..9a6cc25c 100644 --- a/api-reference/activities/claim-spark-transfer.mdx +++ b/api-reference/activities/claim-spark-transfer.mdx @@ -17,74 +17,156 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_SPARK_CLAIM_TRANSFER` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + -

The parameters object containing the specific intent data for this activity.

+

+ The parameters object containing the specific intent data for this activity. +

- - A Spark wallet account address identifying the wallet. + + A Spark wallet account address identifying the wallet. - - + +

claim field

- +

Leaves being claimed.

- - Leaf identifier (UUID). + + Leaf identifier (UUID). - - - ECIES ciphertext (hex-encoded) containing the inbound transfer secret. Decrypted inside the enclave using the wallet's Identity key. + + + ECIES ciphertext (hex-encoded) containing the inbound transfer + secret. Decrypted inside the enclave using the wallet's Identity + key. - - - Hex-encoded 64-byte compact ECDSA signature binding (leaf_id, transfer_id, ciphertext) to the sender's identity key. Verified inside the enclave before decryption. + + + Hex-encoded 64-byte compact ECDSA signature binding (leaf_id, + transfer_id, ciphertext) to the sender's identity key. Verified + inside the enclave before decryption.
- - Shamir threshold for reconstructing the per-leaf claim secret. + + Shamir threshold for reconstructing the per-leaf claim secret. - - + +

Operators that will receive Shamir shares.

- - Spark operator identifier (UUID). + + Spark operator identifier (UUID). - - - Operator's ECIES encryption pubkey (hex-encoded compressed secp256k1 point). + + + Operator's ECIES encryption pubkey (hex-encoded compressed + secp256k1 point).
- - Spark transfer identifier (UUID). Used together with each leaf's sender_signature to verify the sender bound this ciphertext to this transfer. + + Spark transfer identifier (UUID). Used together with each leaf's + sender_signature to verify the sender bound this ciphertext to this + transfer. - - - Sender's compressed secp256k1 identity public key (hex-encoded, 33 bytes). Used to verify the per-leaf sender_signature fields. + + + Sender's compressed secp256k1 identity public key (hex-encoded, 33 + bytes). Used to verify the per-leaf sender_signature fields.
- -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -128,6 +210,7 @@ Hex-encoded 64-byte compact ECDSA signature binding (leaf_id, transfer_id, ciphe
+ Shamir threshold for reconstructing the per-leaf claim secret. @@ -143,11 +226,24 @@ Operator's ECIES encryption pubkey (hex-encoded compressed secp256k1 point).
- -Spark transfer identifier (UUID). Used together with each leaf's sender_signature to verify the sender bound this ciphertext to this transfer. + + + Spark transfer identifier (UUID). Used together with each leaf's + sender_signature to verify the sender bound this ciphertext to this transfer. - -Sender's compressed secp256k1 identity public key (hex-encoded, 33 bytes). Used to verify the per-leaf sender_signature fields. + + Sender's compressed secp256k1 identity public key (hex-encoded, 33 bytes). + Used to verify the per-leaf sender_signature fields. @@ -158,6 +254,7 @@ Sender's compressed secp256k1 identity public key (hex-encoded, 33 bytes). Used + The result of the activity @@ -176,6 +273,7 @@ ECIES ciphertext (hex-encoded) opaque to Turnkey after emission. + Newly-derived SigningLeaf public keys, one per leaf, in input order. @@ -194,23 +292,50 @@ Hex-encoded compressed secp256k1 point (33 bytes) for the SigningLeaf derivation + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/create-a-fiat-on-ramp-credential.mdx b/api-reference/activities/create-a-fiat-on-ramp-credential.mdx index 5d5b7e92..b37c0442 100644 --- a/api-reference/activities/create-a-fiat-on-ramp-credential.mdx +++ b/api-reference/activities/create-a-fiat-on-ramp-credential.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_CREATE_FIAT_ON_RAMP_CREDENTIAL` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -60,11 +63,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -114,6 +117,7 @@ If the on-ramp credential is a sandbox credential + The result of the activity @@ -129,23 +133,50 @@ Unique identifier of the Fiat On-Ramp credential that was created + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/create-a-tvc-app.mdx b/api-reference/activities/create-a-tvc-app.mdx index e39e7df5..0a684979 100644 --- a/api-reference/activities/create-a-tvc-app.mdx +++ b/api-reference/activities/create-a-tvc-app.mdx @@ -17,107 +17,230 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_CREATE_TVC_APP` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + -

The parameters object containing the specific intent data for this activity.

+

+ The parameters object containing the specific intent data for this activity. +

- - The name of the new TVC application + + The name of the new TVC application - - - Quorum public key to use for this application + + + Quorum public key to use for this application - - - Unique identifier for an existing TVC operator set to use as the Manifest Set for this TVC application. If left empty, a new Manifest Set configuration is required + + + Unique identifier for an existing TVC operator set to use as the Manifest + Set for this TVC application. If left empty, a new Manifest Set + configuration is required - - + +

manifestSetParams field

- - Short description for this new operator set + + Short description for this new operator set - - + +

Operators to create as part of this new operator set

- - The name for this new operator + + The name for this new operator - - - Public key for this operator + + + Public key for this operator
- +

Existing operators to use as part of this new operator set

-

Array item type: string

-

item field

+

+ Array item type: string +

+

item field

- - The threshold of operators needed to reach consensus in this new Operator Set + + The threshold of operators needed to reach consensus in this new + Operator Set
- - Unique identifier for an existing TVC operator set to use as the Share Set for this TVC application. If left empty, a new Share Set configuration is required + + Unique identifier for an existing TVC operator set to use as the Share Set + for this TVC application. If left empty, a new Share Set configuration is + required - - + +

shareSetParams field

- - Short description for this new operator set + + Short description for this new operator set - - + +

Operators to create as part of this new operator set

- - The name for this new operator + + The name for this new operator - - - Public key for this operator + + + Public key for this operator
- +

Existing operators to use as part of this new operator set

-

Array item type: string

-

item field

+

+ Array item type: string +

+

item field

- - The threshold of operators needed to reach consensus in this new Operator Set + + The threshold of operators needed to reach consensus in this new + Operator Set
- - Enables network egress for this TVC app. Default if not provided: false. + + Enables network egress for this TVC app. Default if not provided: false.
- -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -167,6 +290,7 @@ Public key for this operator
+ Existing operators to use as part of this new operator set @@ -176,12 +300,19 @@ item field - -The threshold of operators needed to reach consensus in this new Operator Set + + + The threshold of operators needed to reach consensus in this new Operator Set + Unique identifier for an existing TVC operator set to use as the Share Set for this TVC application. If left empty, a new Share Set configuration is required @@ -203,6 +334,7 @@ Public key for this operator
+ Existing operators to use as part of this new operator set @@ -212,14 +344,26 @@ item field - -The threshold of operators needed to reach consensus in this new Operator Set + + + The threshold of operators needed to reach consensus in this new Operator Set - -Enables network egress for this TVC app. Default if not provided: false. + + + Enables network egress for this TVC app. Default if not provided: false. @@ -227,6 +371,7 @@ Enables network egress for this TVC app. Default if not provided: false. + The result of the activity @@ -248,8 +393,14 @@ item field - -The required number of approvals for the manifest set + + + The required number of approvals for the manifest set @@ -257,23 +408,50 @@ The required number of approvals for the manifest set + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. @@ -395,9 +573,7 @@ const response = await turnkeyClient.apiClient().createTvcApp({ "publicKey": "" } ], - "existingOperatorIds": [ - "" - ], + "existingOperatorIds": [""], "threshold": "" }, "shareSetId": "", @@ -409,9 +585,7 @@ const response = await turnkeyClient.apiClient().createTvcApp({ "publicKey": "" } ], - "existingOperatorIds": [ - "" - ], + "existingOperatorIds": [""], "threshold": "" }, "enableEgress": "" @@ -421,9 +595,7 @@ const response = await turnkeyClient.apiClient().createTvcApp({ "createTvcAppResult": { "appId": "", "manifestSetId": "", - "manifestSetOperatorIds": [ - "" - ], + "manifestSetOperatorIds": [""], "manifestSetThreshold": "" } }, diff --git a/api-reference/activities/create-a-tvc-deployment.mdx b/api-reference/activities/create-a-tvc-deployment.mdx index 666d27cf..60c4a731 100644 --- a/api-reference/activities/create-a-tvc-deployment.mdx +++ b/api-reference/activities/create-a-tvc-deployment.mdx @@ -17,76 +17,161 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_CREATE_TVC_DEPLOYMENT` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + -

The parameters object containing the specific intent data for this activity.

+

+ The parameters object containing the specific intent data for this activity. +

- - The unique identifier of the to-be-deployed TVC application + + The unique identifier of the to-be-deployed TVC application - - - The QuorumOS version to use to deploy this application + + + The QuorumOS version to use to deploy this application - - - URL of the container containing the pivot binary + + + URL of the container containing the pivot binary - - - Location of the binary in the pivot container + + + Location of the binary in the pivot container - - -

Arguments to pass to the pivot binary at startup. Encoded as a list of strings, for example ["--foo", "bar"]

+ + +

+ Arguments to pass to the pivot binary at startup. Encoded as a list of + strings, for example ["--foo", "bar"] +

-

Array item type: string

-

item field

+

+ Array item type: string +

+

item field

- - Digest of the pivot binary in the pivot container. This value will be inserted in the QOS manifest to ensure application integrity. + + Digest of the pivot binary in the pivot container. This value will be + inserted in the QOS manifest to ensure application integrity. - - - Optional nonce to ensure uniqueness of the deployment manifest. If not provided, it defaults to the current Unix timestamp in seconds. + + + Optional nonce to ensure uniqueness of the deployment manifest. If not + provided, it defaults to the current Unix timestamp in seconds. - - - Optional encrypted pull secret to authorize Turnkey to pull the pivot container image. If your image is public, leave this empty. + + + Optional encrypted pull secret to authorize Turnkey to pull the pivot + container image. If your image is public, leave this empty. - - - Optional flag to indicate whether to deploy the TVC app in debug mode, which includes additional logging and debugging tools. Default is false. + + + Optional flag to indicate whether to deploy the TVC app in debug mode, + which includes additional logging and debugging tools. Default is false. - - - Enum options: `TVC_HEALTH_CHECK_TYPE_HTTP`, `TVC_HEALTH_CHECK_TYPE_GRPC` + + + Enum options: `TVC_HEALTH_CHECK_TYPE_HTTP`, `TVC_HEALTH_CHECK_TYPE_GRPC` - - - Port to use for health checks. + + + Port to use for health checks. - - - Port to use for public ingress. + + + Port to use for public ingress.
- -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -130,6 +215,7 @@ item field
+ Digest of the pivot binary in the pivot container. This value will be inserted in the QOS manifest to ensure application integrity. @@ -160,6 +246,7 @@ Port to use for public ingress.
+ The result of the activity @@ -178,23 +265,50 @@ The unique identifier for the TVC manifest + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. @@ -281,9 +395,7 @@ const response = await turnkeyClient.apiClient().createTvcDeployment({ "qosVersion": "", "pivotContainerImageUrl": "", "pivotPath": "", - "pivotArgs": [ - "" - ], + "pivotArgs": [""], "expectedPivotDigest": "", "nonce": "", "pivotContainerEncryptedPullSecret": "", diff --git a/api-reference/activities/create-an-oauth-20-credential.mdx b/api-reference/activities/create-an-oauth-20-credential.mdx index b1fa385d..1fff47c1 100644 --- a/api-reference/activities/create-an-oauth-20-credential.mdx +++ b/api-reference/activities/create-an-oauth-20-credential.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_CREATE_OAUTH2_CREDENTIAL` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -48,11 +51,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -93,6 +96,7 @@ The client secret issued by the OAuth 2.0 provider encrypted to the TLS Fetcher + The result of the activity @@ -108,23 +112,50 @@ Unique identifier of the OAuth 2.0 credential that was created + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/create-api-keys.mdx b/api-reference/activities/create-api-keys.mdx index afe84d6c..2583e5b7 100644 --- a/api-reference/activities/create-api-keys.mdx +++ b/api-reference/activities/create-api-keys.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_CREATE_API_KEYS_V2` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -60,11 +63,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -108,8 +111,14 @@ Optional window (in seconds) indicating how long the API Key should last. - -Unique identifier for a given User. + + + Unique identifier for a given User. @@ -117,6 +126,7 @@ Unique identifier for a given User. + The result of the activity @@ -138,23 +148,50 @@ item field + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. @@ -240,9 +277,7 @@ const response = await turnkeyClient.apiClient().createApiKeys({ }, "result": { "createApiKeysResult": { - "apiKeyIds": [ - "" - ] + "apiKeyIds": [""] } }, "votes": "", diff --git a/api-reference/activities/create-authenticators.mdx b/api-reference/activities/create-authenticators.mdx index 82100f2e..9183965f 100644 --- a/api-reference/activities/create-authenticators.mdx +++ b/api-reference/activities/create-authenticators.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_CREATE_AUTHENTICATORS_V2` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -73,11 +76,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -139,8 +142,14 @@ Enum options: `AUTHENTICATOR_TRANSPORT_BLE`, `AUTHENTICATOR_TRANSPORT_INTERNAL`, - -Unique identifier for a given User. + + + Unique identifier for a given User. @@ -148,6 +157,7 @@ Unique identifier for a given User. + The result of the activity @@ -169,23 +179,50 @@ item field + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. @@ -276,9 +313,7 @@ const response = await turnkeyClient.apiClient().createAuthenticators({ "credentialId": "", "clientDataJson": "", "attestationObject": "", - "transports": [ - "" - ] + "transports": [""] } } ], @@ -287,9 +322,7 @@ const response = await turnkeyClient.apiClient().createAuthenticators({ }, "result": { "createAuthenticatorsResult": { - "authenticatorIds": [ - "" - ] + "authenticatorIds": [""] } }, "votes": "", diff --git a/api-reference/activities/create-invitations.mdx b/api-reference/activities/create-invitations.mdx index ef82fef2..44d08e3a 100644 --- a/api-reference/activities/create-invitations.mdx +++ b/api-reference/activities/create-invitations.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_CREATE_INVITATIONS` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -64,11 +67,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -109,6 +112,7 @@ item field + accessType field @@ -127,6 +131,7 @@ Unique identifier for the Sender of an Invitation. + The result of the activity @@ -148,23 +153,50 @@ item field + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. @@ -243,9 +275,7 @@ const response = await turnkeyClient.apiClient().createInvitations({ { "receiverUserName": "", "receiverUserEmail": "", - "receiverUserTags": [ - "" - ], + "receiverUserTags": [""], "accessType": "", "senderUserId": "" } @@ -254,9 +284,7 @@ const response = await turnkeyClient.apiClient().createInvitations({ }, "result": { "createInvitationsResult": { - "invitationIds": [ - "" - ] + "invitationIds": [""] } }, "votes": "", diff --git a/api-reference/activities/create-oauth-providers.mdx b/api-reference/activities/create-oauth-providers.mdx index 233d5004..b977ad4b 100644 --- a/api-reference/activities/create-oauth-providers.mdx +++ b/api-reference/activities/create-oauth-providers.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_CREATE_OAUTH_PROVIDERS_V2` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -70,11 +73,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -133,6 +136,7 @@ The audience from the OIDC token (aud claim) + The result of the activity @@ -154,23 +158,50 @@ item field + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. @@ -265,9 +296,7 @@ const response = await turnkeyClient.apiClient().createOauthProviders({ }, "result": { "createOauthProvidersResultV2": { - "providerIds": [ - "" - ] + "providerIds": [""] } }, "votes": "", diff --git a/api-reference/activities/create-policies.mdx b/api-reference/activities/create-policies.mdx index 987867bd..5a454487 100644 --- a/api-reference/activities/create-policies.mdx +++ b/api-reference/activities/create-policies.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_CREATE_POLICIES` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -61,11 +64,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -118,6 +121,7 @@ Notes for a Policy. + The result of the activity @@ -139,23 +143,50 @@ item field + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. @@ -241,9 +272,7 @@ const response = await turnkeyClient.apiClient().createPolicies({ }, "result": { "createPoliciesResult": { - "policyIds": [ - "" - ] + "policyIds": [""] } }, "votes": "", diff --git a/api-reference/activities/create-policy.mdx b/api-reference/activities/create-policy.mdx index 9433feca..b5be587c 100644 --- a/api-reference/activities/create-policy.mdx +++ b/api-reference/activities/create-policy.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_CREATE_POLICY_V3` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -56,11 +59,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -107,6 +110,7 @@ Notes for a Policy. + The result of the activity @@ -122,23 +126,50 @@ Unique identifier for a given Policy. + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/create-private-key-tag.mdx b/api-reference/activities/create-private-key-tag.mdx index 6528e146..064f6492 100644 --- a/api-reference/activities/create-private-key-tag.mdx +++ b/api-reference/activities/create-private-key-tag.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_CREATE_PRIVATE_KEY_TAG` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -48,11 +51,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -93,6 +96,7 @@ item field + The result of the activity @@ -117,23 +121,50 @@ item field + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. @@ -197,17 +228,13 @@ const response = await turnkeyClient.apiClient().createPrivateKeyTag({ "intent": { "createPrivateKeyTagIntent": { "privateKeyTagName": "", - "privateKeyIds": [ - "" - ] + "privateKeyIds": [""] } }, "result": { "createPrivateKeyTagResult": { "privateKeyTagId": "", - "privateKeyIds": [ - "" - ] + "privateKeyIds": [""] } }, "votes": "", diff --git a/api-reference/activities/create-private-keys.mdx b/api-reference/activities/create-private-keys.mdx index 15b9598e..e90a3ec0 100644 --- a/api-reference/activities/create-private-keys.mdx +++ b/api-reference/activities/create-private-keys.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_CREATE_PRIVATE_KEYS_V2` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -60,11 +63,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -108,6 +111,7 @@ item field + Cryptocurrency-specific formats for a derived address (e.g., Ethereum). @@ -129,6 +133,7 @@ Enum options: `ADDRESS_FORMAT_UNCOMPRESSED`, `ADDRESS_FORMAT_COMPRESSED`, `ADDRE + The result of the activity @@ -165,23 +170,50 @@ address field + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. @@ -260,12 +292,8 @@ const response = await turnkeyClient.apiClient().createPrivateKeys({ { "privateKeyName": "", "curve": "", - "privateKeyTags": [ - "" - ], - "addressFormats": [ - "" - ] + "privateKeyTags": [""], + "addressFormats": [""] } ] } diff --git a/api-reference/activities/create-read-only-session.mdx b/api-reference/activities/create-read-only-session.mdx index 707318ec..ea82b1db 100644 --- a/api-reference/activities/create-read-only-session.mdx +++ b/api-reference/activities/create-read-only-session.mdx @@ -17,31 +17,35 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_CREATE_READ_ONLY_SESSION` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + The parameters object containing the specific intent data for this activity. + Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -67,6 +71,7 @@ The createReadOnlySessionIntent object + The result of the activity @@ -97,23 +102,50 @@ UTC timestamp in seconds representing the expiry time for the read only session. + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. - - -An artifact verifying a User's action. - - -Whether the activity can be approved. - - -Whether the activity can be rejected. - - -The creation timestamp. - - -The last update timestamp. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. + + + An artifact verifying a User's action. + + + Whether the activity can be approved. + + + Whether the activity can be rejected. + + + The creation timestamp. + + + The last update timestamp. diff --git a/api-reference/activities/create-read-write-session.mdx b/api-reference/activities/create-read-write-session.mdx index 0edb2556..ef1da579 100644 --- a/api-reference/activities/create-read-write-session.mdx +++ b/api-reference/activities/create-read-write-session.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_CREATE_READ_WRITE_SESSION_V2` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -56,11 +59,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -104,6 +107,7 @@ Invalidate all other previously generated ReadWriteSession API keys + The result of the activity @@ -134,23 +138,50 @@ HPKE encrypted credential bundle + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/create-smart-contract-interface.mdx b/api-reference/activities/create-smart-contract-interface.mdx index 711e68d7..94454cdf 100644 --- a/api-reference/activities/create-smart-contract-interface.mdx +++ b/api-reference/activities/create-smart-contract-interface.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_CREATE_SMART_CONTRACT_INTERFACE` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -56,11 +59,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -107,6 +110,7 @@ Notes for a Smart Contract Interface. + The result of the activity @@ -122,23 +126,50 @@ The ID of the created Smart Contract Interface. + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/create-sub-organization.mdx b/api-reference/activities/create-sub-organization.mdx index 8d31ed3f..2f879555 100644 --- a/api-reference/activities/create-sub-organization.mdx +++ b/api-reference/activities/create-sub-organization.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_CREATE_SUB_ORGANIZATION_V8` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -216,11 +219,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -279,6 +282,7 @@ Optional window (in seconds) indicating how long the API Key should last. + A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. @@ -318,6 +322,7 @@ Enum options: `AUTHENTICATOR_TRANSPORT_BLE`, `AUTHENTICATOR_TRANSPORT_INTERNAL`, + A list of Oauth providers. This field, if not needed, should be an empty array in your request body. @@ -348,6 +353,7 @@ The audience from the OIDC token (aud claim) + The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users @@ -384,12 +390,20 @@ Enum options: `ADDRESS_FORMAT_UNCOMPRESSED`, `ADDRESS_FORMAT_COMPRESSED`, `ADDRE - -Length of mnemonic to generate the Wallet seed. Defaults to 12. Accepted values: 12, 15, 18, 21, 24. + + + Length of mnemonic to generate the Wallet seed. Defaults to 12. Accepted + values: 12, 15, 18, 21, 24. + Disable email recovery for the sub-organization @@ -432,6 +446,7 @@ The cryptographic signature over the message. + The result of the activity @@ -459,6 +474,7 @@ item field + rootUserIds field @@ -474,23 +490,50 @@ item field + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. - - -An artifact verifying a User's action. - - -Whether the activity can be approved. - - -Whether the activity can be rejected. - - -The creation timestamp. - - -The last update timestamp. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. + + + An artifact verifying a User's action. + + + Whether the activity can be approved. + + + Whether the activity can be rejected. + + + The creation timestamp. + + + The last update timestamp. @@ -687,9 +730,7 @@ const response = await turnkeyClient.apiClient().createSubOrganization({ "credentialId": "", "clientDataJson": "", "attestationObject": "", - "transports": [ - "" - ] + "transports": [""] } } ], @@ -737,13 +778,9 @@ const response = await turnkeyClient.apiClient().createSubOrganization({ "subOrganizationId": "", "wallet": { "walletId": "", - "addresses": [ - "" - ] + "addresses": [""] }, - "rootUserIds": [ - "" - ] + "rootUserIds": [""] } }, "votes": "", diff --git a/api-reference/activities/create-tvc-manifest-approvals.mdx b/api-reference/activities/create-tvc-manifest-approvals.mdx index 74104dcc..cadf3ecb 100644 --- a/api-reference/activities/create-tvc-manifest-approvals.mdx +++ b/api-reference/activities/create-tvc-manifest-approvals.mdx @@ -17,42 +17,70 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_CREATE_TVC_MANIFEST_APPROVALS` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + -

The parameters object containing the specific intent data for this activity.

+

+ The parameters object containing the specific intent data for this activity. +

- - Unique identifier of the TVC deployment to approve + + Unique identifier of the TVC deployment to approve - - + +

List of manifest approvals

- - Unique identifier of the operator providing this approval + + Unique identifier of the operator providing this approval - - - Signature from the operator approving the manifest + + + Signature from the operator approving the manifest
- -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -96,6 +124,7 @@ Signature from the operator approving the manifest
+ The result of the activity @@ -117,23 +146,50 @@ item field + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. @@ -213,9 +269,7 @@ const response = await turnkeyClient.apiClient().createTvcManifestApprovals({ }, "result": { "createTvcManifestApprovalsResult": { - "approvalIds": [ - "" - ] + "approvalIds": [""] } }, "votes": "", diff --git a/api-reference/activities/create-user-tag.mdx b/api-reference/activities/create-user-tag.mdx index a3421e3c..dd6210f9 100644 --- a/api-reference/activities/create-user-tag.mdx +++ b/api-reference/activities/create-user-tag.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_CREATE_USER_TAG` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -48,11 +51,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -93,6 +96,7 @@ item field + The result of the activity @@ -117,23 +121,50 @@ item field + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. @@ -197,17 +228,13 @@ const response = await turnkeyClient.apiClient().createUserTag({ "intent": { "createUserTagIntent": { "userTagName": "", - "userIds": [ - "" - ] + "userIds": [""] } }, "result": { "createUserTagResult": { "userTagId": "", - "userIds": [ - "" - ] + "userIds": [""] } }, "votes": "", diff --git a/api-reference/activities/create-users.mdx b/api-reference/activities/create-users.mdx index 88b10bb4..b1b2d36d 100644 --- a/api-reference/activities/create-users.mdx +++ b/api-reference/activities/create-users.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_CREATE_USERS_V4` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -143,11 +146,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -203,6 +206,7 @@ Optional window (in seconds) indicating how long the API Key should last. + A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. @@ -242,6 +246,7 @@ Enum options: `AUTHENTICATOR_TRANSPORT_BLE`, `AUTHENTICATOR_TRANSPORT_INTERNAL`, + A list of Oauth providers. This field, if not needed, should be an empty array in your request body. @@ -269,6 +274,7 @@ The audience from the OIDC token (aud claim) + A list of User Tag IDs. This field, if not needed, should be an empty array in your request body. @@ -287,6 +293,7 @@ item field + The result of the activity @@ -308,23 +315,50 @@ item field + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. @@ -476,9 +510,7 @@ const response = await turnkeyClient.apiClient().createUsers({ "credentialId": "", "clientDataJson": "", "attestationObject": "", - "transports": [ - "" - ] + "transports": [""] } } ], @@ -493,18 +525,14 @@ const response = await turnkeyClient.apiClient().createUsers({ } } ], - "userTags": [ - "" - ] + "userTags": [""] } ] } }, "result": { "createUsersResult": { - "userIds": [ - "" - ] + "userIds": [""] } }, "votes": "", diff --git a/api-reference/activities/create-wallet-accounts.mdx b/api-reference/activities/create-wallet-accounts.mdx index 32d88df8..3d5ec6da 100644 --- a/api-reference/activities/create-wallet-accounts.mdx +++ b/api-reference/activities/create-wallet-accounts.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_CREATE_WALLET_ACCOUNTS` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -64,11 +67,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -121,8 +124,16 @@ Enum options: `ADDRESS_FORMAT_UNCOMPRESSED`, `ADDRESS_FORMAT_COMPRESSED`, `ADDRE - -Indicates if the wallet accounts should be persisted. This is helpful if you'd like to see the addresses of different derivation paths without actually creating the accounts. Defaults to true. + + + Indicates if the wallet accounts should be persisted. This is helpful if you'd + like to see the addresses of different derivation paths without actually + creating the accounts. Defaults to true. @@ -130,6 +141,7 @@ Indicates if the wallet accounts should be persisted. This is helpful if you'd l + The result of the activity @@ -151,23 +163,50 @@ item field + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. @@ -256,9 +295,7 @@ const response = await turnkeyClient.apiClient().createWalletAccounts({ }, "result": { "createWalletAccountsResult": { - "addresses": [ - "" - ] + "addresses": [""] } }, "votes": "", diff --git a/api-reference/activities/create-wallet.mdx b/api-reference/activities/create-wallet.mdx index d0674865..b9015876 100644 --- a/api-reference/activities/create-wallet.mdx +++ b/api-reference/activities/create-wallet.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_CREATE_WALLET` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -64,11 +67,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -121,8 +124,15 @@ Enum options: `ADDRESS_FORMAT_UNCOMPRESSED`, `ADDRESS_FORMAT_COMPRESSED`, `ADDRE - -Length of mnemonic to generate the Wallet seed. Defaults to 12. Accepted values: 12, 15, 18, 21, 24. + + + Length of mnemonic to generate the Wallet seed. Defaults to 12. Accepted + values: 12, 15, 18, 21, 24. @@ -130,6 +140,7 @@ Length of mnemonic to generate the Wallet seed. Defaults to 12. Accepted values: + The result of the activity @@ -154,23 +165,50 @@ item field + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. @@ -260,9 +298,7 @@ const response = await turnkeyClient.apiClient().createWallet({ "result": { "createWalletResult": { "walletId": "", - "addresses": [ - "" - ] + "addresses": [""] } }, "votes": "", diff --git a/api-reference/activities/create-webhook-endpoint.mdx b/api-reference/activities/create-webhook-endpoint.mdx index 9628153d..dd349cf9 100644 --- a/api-reference/activities/create-webhook-endpoint.mdx +++ b/api-reference/activities/create-webhook-endpoint.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_CREATE_WEBHOOK_ENDPOINT` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -61,11 +64,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -115,6 +118,7 @@ Whether this subscription is active. + The result of the activity @@ -166,23 +170,50 @@ Whether this subscription is active. + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/delete-a-fiat-on-ramp-credential.mdx b/api-reference/activities/delete-a-fiat-on-ramp-credential.mdx index 2c3cbaef..3fb544a7 100644 --- a/api-reference/activities/delete-a-fiat-on-ramp-credential.mdx +++ b/api-reference/activities/delete-a-fiat-on-ramp-credential.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_DELETE_FIAT_ON_RAMP_CREDENTIAL` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -40,11 +43,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -76,6 +79,7 @@ The ID of the fiat on-ramp credential to delete + The result of the activity @@ -91,23 +95,50 @@ Unique identifier of the Fiat On-Ramp credential that was deleted + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/delete-a-tvc-app-and-all-of-its-deployments.mdx b/api-reference/activities/delete-a-tvc-app-and-all-of-its-deployments.mdx index cb360d70..45cae407 100644 --- a/api-reference/activities/delete-a-tvc-app-and-all-of-its-deployments.mdx +++ b/api-reference/activities/delete-a-tvc-app-and-all-of-its-deployments.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_DELETE_TVC_APP_AND_DEPLOYMENTS` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -40,11 +43,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -76,6 +79,7 @@ The unique identifier of the TVC app to delete. The app and all associated deplo + The result of the activity @@ -91,23 +95,50 @@ The unique identifier of the deleted TVC app. + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/delete-a-tvc-deployment.mdx b/api-reference/activities/delete-a-tvc-deployment.mdx index ded812ff..9e0b8d86 100644 --- a/api-reference/activities/delete-a-tvc-deployment.mdx +++ b/api-reference/activities/delete-a-tvc-deployment.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_DELETE_TVC_DEPLOYMENT` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -40,11 +43,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -76,6 +79,7 @@ The unique identifier of the TVC deployment to delete. + The result of the activity @@ -91,23 +95,50 @@ The unique identifier of the deleted TVC deployment. + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/delete-an-oauth-20-credential.mdx b/api-reference/activities/delete-an-oauth-20-credential.mdx index 0d4b4254..a246bcad 100644 --- a/api-reference/activities/delete-an-oauth-20-credential.mdx +++ b/api-reference/activities/delete-an-oauth-20-credential.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_DELETE_OAUTH2_CREDENTIAL` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -40,11 +43,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -76,6 +79,7 @@ The ID of the OAuth 2.0 credential to delete + The result of the activity @@ -91,23 +95,50 @@ Unique identifier of the OAuth 2.0 credential that was deleted + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/delete-api-keys.mdx b/api-reference/activities/delete-api-keys.mdx index c7d11506..c0233b5b 100644 --- a/api-reference/activities/delete-api-keys.mdx +++ b/api-reference/activities/delete-api-keys.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_DELETE_API_KEYS` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -48,11 +51,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -93,6 +96,7 @@ item field + The result of the activity @@ -114,23 +118,50 @@ item field + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. @@ -194,16 +225,12 @@ const response = await turnkeyClient.apiClient().deleteApiKeys({ "intent": { "deleteApiKeysIntent": { "userId": "", - "apiKeyIds": [ - "" - ] + "apiKeyIds": [""] } }, "result": { "deleteApiKeysResult": { - "apiKeyIds": [ - "" - ] + "apiKeyIds": [""] } }, "votes": "", diff --git a/api-reference/activities/delete-authenticators.mdx b/api-reference/activities/delete-authenticators.mdx index bda7a56b..cb6d8378 100644 --- a/api-reference/activities/delete-authenticators.mdx +++ b/api-reference/activities/delete-authenticators.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_DELETE_AUTHENTICATORS` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -48,11 +51,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -93,6 +96,7 @@ item field + The result of the activity @@ -114,23 +118,50 @@ item field + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. @@ -194,16 +225,12 @@ const response = await turnkeyClient.apiClient().deleteAuthenticators({ "intent": { "deleteAuthenticatorsIntent": { "userId": "", - "authenticatorIds": [ - "" - ] + "authenticatorIds": [""] } }, "result": { "deleteAuthenticatorsResult": { - "authenticatorIds": [ - "" - ] + "authenticatorIds": [""] } }, "votes": "", diff --git a/api-reference/activities/delete-invitation.mdx b/api-reference/activities/delete-invitation.mdx index aedc7cea..428f8fbe 100644 --- a/api-reference/activities/delete-invitation.mdx +++ b/api-reference/activities/delete-invitation.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_DELETE_INVITATION` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -40,11 +43,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -76,6 +79,7 @@ Unique identifier for a given Invitation object. + The result of the activity @@ -91,23 +95,50 @@ Unique identifier for a given Invitation. + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/delete-oauth-providers.mdx b/api-reference/activities/delete-oauth-providers.mdx index 4a9a47ea..bfb9b600 100644 --- a/api-reference/activities/delete-oauth-providers.mdx +++ b/api-reference/activities/delete-oauth-providers.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_DELETE_OAUTH_PROVIDERS` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -48,11 +51,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -93,6 +96,7 @@ item field + The result of the activity @@ -114,23 +118,50 @@ item field + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. @@ -194,16 +225,12 @@ const response = await turnkeyClient.apiClient().deleteOauthProviders({ "intent": { "deleteOauthProvidersIntent": { "userId": "", - "providerIds": [ - "" - ] + "providerIds": [""] } }, "result": { "deleteOauthProvidersResult": { - "providerIds": [ - "" - ] + "providerIds": [""] } }, "votes": "", diff --git a/api-reference/activities/delete-policies.mdx b/api-reference/activities/delete-policies.mdx index a3921bfb..818dbe6b 100644 --- a/api-reference/activities/delete-policies.mdx +++ b/api-reference/activities/delete-policies.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_DELETE_POLICIES` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -44,11 +47,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -86,6 +89,7 @@ item field + The result of the activity @@ -107,23 +111,50 @@ item field + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. @@ -184,16 +215,12 @@ const response = await turnkeyClient.apiClient().deletePolicies({ "type": "", "intent": { "deletePoliciesIntent": { - "policyIds": [ - "" - ] + "policyIds": [""] } }, "result": { "deletePoliciesResult": { - "policyIds": [ - "" - ] + "policyIds": [""] } }, "votes": "", diff --git a/api-reference/activities/delete-policy.mdx b/api-reference/activities/delete-policy.mdx index 008423c1..920b6012 100644 --- a/api-reference/activities/delete-policy.mdx +++ b/api-reference/activities/delete-policy.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_DELETE_POLICY` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -40,11 +43,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -76,6 +79,7 @@ Unique identifier for a given Policy. + The result of the activity @@ -91,23 +95,50 @@ Unique identifier for a given Policy. + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/delete-private-key-tags.mdx b/api-reference/activities/delete-private-key-tags.mdx index e1be285d..dd9e216c 100644 --- a/api-reference/activities/delete-private-key-tags.mdx +++ b/api-reference/activities/delete-private-key-tags.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_DELETE_PRIVATE_KEY_TAGS` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -44,11 +47,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -86,6 +89,7 @@ item field + The result of the activity @@ -101,6 +105,7 @@ item field + A list of Private Key IDs. @@ -116,23 +121,50 @@ item field + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. @@ -193,19 +225,13 @@ const response = await turnkeyClient.apiClient().deletePrivateKeyTags({ "type": "", "intent": { "deletePrivateKeyTagsIntent": { - "privateKeyTagIds": [ - "" - ] + "privateKeyTagIds": [""] } }, "result": { "deletePrivateKeyTagsResult": { - "privateKeyTagIds": [ - "" - ], - "privateKeyIds": [ - "" - ] + "privateKeyTagIds": [""], + "privateKeyIds": [""] } }, "votes": "", diff --git a/api-reference/activities/delete-private-keys.mdx b/api-reference/activities/delete-private-keys.mdx index db522ebd..4b887a7d 100644 --- a/api-reference/activities/delete-private-keys.mdx +++ b/api-reference/activities/delete-private-keys.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_DELETE_PRIVATE_KEYS` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -47,11 +50,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -83,8 +86,15 @@ item field - -Optional parameter for deleting the private keys, even if any have not been previously exported. If they have been exported, this field is ignored. + + + Optional parameter for deleting the private keys, even if any have not been + previously exported. If they have been exported, this field is ignored. @@ -92,6 +102,7 @@ Optional parameter for deleting the private keys, even if any have not been prev + The result of the activity @@ -113,23 +124,50 @@ item field + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. @@ -192,17 +230,13 @@ const response = await turnkeyClient.apiClient().deletePrivateKeys({ "type": "", "intent": { "deletePrivateKeysIntent": { - "privateKeyIds": [ - "" - ], + "privateKeyIds": [""], "deleteWithoutExport": "" } }, "result": { "deletePrivateKeysResult": { - "privateKeyIds": [ - "" - ] + "privateKeyIds": [""] } }, "votes": "", diff --git a/api-reference/activities/delete-smart-contract-interface.mdx b/api-reference/activities/delete-smart-contract-interface.mdx index 00ba7dbd..cd84b5eb 100644 --- a/api-reference/activities/delete-smart-contract-interface.mdx +++ b/api-reference/activities/delete-smart-contract-interface.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_DELETE_SMART_CONTRACT_INTERFACE` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -40,11 +43,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -76,6 +79,7 @@ The ID of a Smart Contract Interface intended for deletion. + The result of the activity @@ -91,23 +95,50 @@ The ID of the deleted Smart Contract Interface. + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/delete-sub-organization.mdx b/api-reference/activities/delete-sub-organization.mdx index 209f78ba..62741c42 100644 --- a/api-reference/activities/delete-sub-organization.mdx +++ b/api-reference/activities/delete-sub-organization.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_DELETE_SUB_ORGANIZATION` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -40,11 +43,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -76,6 +79,7 @@ Sub-organization deletion, by default, requires associated wallets and private k + The result of the activity @@ -91,23 +95,50 @@ Unique identifier of the sub organization that was removed + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/delete-user-tags.mdx b/api-reference/activities/delete-user-tags.mdx index e08e46c9..69650a1b 100644 --- a/api-reference/activities/delete-user-tags.mdx +++ b/api-reference/activities/delete-user-tags.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_DELETE_USER_TAGS` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -44,11 +47,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -86,6 +89,7 @@ item field + The result of the activity @@ -101,6 +105,7 @@ item field + A list of User IDs. @@ -116,23 +121,50 @@ item field + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. @@ -193,19 +225,13 @@ const response = await turnkeyClient.apiClient().deleteUserTags({ "type": "", "intent": { "deleteUserTagsIntent": { - "userTagIds": [ - "" - ] + "userTagIds": [""] } }, "result": { "deleteUserTagsResult": { - "userTagIds": [ - "" - ], - "userIds": [ - "" - ] + "userTagIds": [""], + "userIds": [""] } }, "votes": "", diff --git a/api-reference/activities/delete-users.mdx b/api-reference/activities/delete-users.mdx index 2e2bbc03..cfcea836 100644 --- a/api-reference/activities/delete-users.mdx +++ b/api-reference/activities/delete-users.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_DELETE_USERS` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -44,11 +47,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -86,6 +89,7 @@ item field + The result of the activity @@ -107,23 +111,50 @@ item field + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. @@ -184,16 +215,12 @@ const response = await turnkeyClient.apiClient().deleteUsers({ "type": "", "intent": { "deleteUsersIntent": { - "userIds": [ - "" - ] + "userIds": [""] } }, "result": { "deleteUsersResult": { - "userIds": [ - "" - ] + "userIds": [""] } }, "votes": "", diff --git a/api-reference/activities/delete-wallet-accounts.mdx b/api-reference/activities/delete-wallet-accounts.mdx index 29378001..ed9123d8 100644 --- a/api-reference/activities/delete-wallet-accounts.mdx +++ b/api-reference/activities/delete-wallet-accounts.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_DELETE_WALLET_ACCOUNTS` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -47,11 +50,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -83,8 +86,15 @@ item field - -Optional parameter for deleting the wallet accounts, even if any have not been previously exported. If they have been exported, this field is ignored. + + + Optional parameter for deleting the wallet accounts, even if any have not been + previously exported. If they have been exported, this field is ignored. @@ -92,6 +102,7 @@ Optional parameter for deleting the wallet accounts, even if any have not been p + The result of the activity @@ -113,23 +124,50 @@ item field + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. @@ -192,17 +230,13 @@ const response = await turnkeyClient.apiClient().deleteWalletAccounts({ "type": "", "intent": { "deleteWalletAccountsIntent": { - "walletAccountIds": [ - "" - ], + "walletAccountIds": [""], "deleteWithoutExport": "" } }, "result": { "deleteWalletAccountsResult": { - "walletAccountIds": [ - "" - ] + "walletAccountIds": [""] } }, "votes": "", diff --git a/api-reference/activities/delete-wallets.mdx b/api-reference/activities/delete-wallets.mdx index 8ec92f15..1e87010a 100644 --- a/api-reference/activities/delete-wallets.mdx +++ b/api-reference/activities/delete-wallets.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_DELETE_WALLETS` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -47,11 +50,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -83,8 +86,15 @@ item field - -Optional parameter for deleting the wallets, even if any have not been previously exported. If they have been exported, this field is ignored. + + + Optional parameter for deleting the wallets, even if any have not been + previously exported. If they have been exported, this field is ignored. @@ -92,6 +102,7 @@ Optional parameter for deleting the wallets, even if any have not been previousl + The result of the activity @@ -113,23 +124,50 @@ item field + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. @@ -192,17 +230,13 @@ const response = await turnkeyClient.apiClient().deleteWallets({ "type": "", "intent": { "deleteWalletsIntent": { - "walletIds": [ - "" - ], + "walletIds": [""], "deleteWithoutExport": "" } }, "result": { "deleteWalletsResult": { - "walletIds": [ - "" - ] + "walletIds": [""] } }, "votes": "", diff --git a/api-reference/activities/delete-webhook-endpoint.mdx b/api-reference/activities/delete-webhook-endpoint.mdx index d70e1a07..ae9043ed 100644 --- a/api-reference/activities/delete-webhook-endpoint.mdx +++ b/api-reference/activities/delete-webhook-endpoint.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_DELETE_WEBHOOK_ENDPOINT` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -40,11 +43,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -76,6 +79,7 @@ Unique identifier of the webhook endpoint to delete. + The result of the activity @@ -91,23 +95,50 @@ Unique identifier of the deleted webhook endpoint. + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/export-private-key.mdx b/api-reference/activities/export-private-key.mdx index 47f1e79d..d3fb9d23 100644 --- a/api-reference/activities/export-private-key.mdx +++ b/api-reference/activities/export-private-key.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_EXPORT_PRIVATE_KEY` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -44,11 +47,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -83,6 +86,7 @@ Client-side public key generated by the user, to which the export bundle will be + The result of the activity @@ -101,23 +105,50 @@ Export bundle containing a private key encrypted to the client's target public k + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/export-wallet-account.mdx b/api-reference/activities/export-wallet-account.mdx index b4389c50..d2441c00 100644 --- a/api-reference/activities/export-wallet-account.mdx +++ b/api-reference/activities/export-wallet-account.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_EXPORT_WALLET_ACCOUNT` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -44,11 +47,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -83,6 +86,7 @@ Client-side public key generated by the user, to which the export bundle will be + The result of the activity @@ -101,23 +105,50 @@ Export bundle containing a private key encrypted by the client's target public k + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/export-wallet.mdx b/api-reference/activities/export-wallet.mdx index 91b118d1..0daaea64 100644 --- a/api-reference/activities/export-wallet.mdx +++ b/api-reference/activities/export-wallet.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_EXPORT_WALLET` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -48,11 +51,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -93,6 +96,7 @@ Enum options: `MNEMONIC_LANGUAGE_ENGLISH`, `MNEMONIC_LANGUAGE_SIMPLIFIED_CHINESE + The result of the activity @@ -111,23 +115,50 @@ Export bundle containing a wallet mnemonic + optional newline passphrase encrypt + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/import-private-key.mdx b/api-reference/activities/import-private-key.mdx index d141b006..44a114ff 100644 --- a/api-reference/activities/import-private-key.mdx +++ b/api-reference/activities/import-private-key.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_IMPORT_PRIVATE_KEY` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -56,11 +59,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -116,6 +119,7 @@ Enum options: `ADDRESS_FORMAT_UNCOMPRESSED`, `ADDRESS_FORMAT_COMPRESSED`, `ADDRE + The result of the activity @@ -146,23 +150,50 @@ address field + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. @@ -235,9 +266,7 @@ const response = await turnkeyClient.apiClient().importPrivateKey({ "privateKeyName": "", "encryptedBundle": "", "curve": "", - "addressFormats": [ - "" - ] + "addressFormats": [""] } }, "result": { diff --git a/api-reference/activities/import-wallet.mdx b/api-reference/activities/import-wallet.mdx index 8a2f1e7d..0b67aeda 100644 --- a/api-reference/activities/import-wallet.mdx +++ b/api-reference/activities/import-wallet.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_IMPORT_WALLET` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -69,11 +72,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -138,6 +141,7 @@ Enum options: `ADDRESS_FORMAT_UNCOMPRESSED`, `ADDRESS_FORMAT_COMPRESSED`, `ADDRE + The result of the activity @@ -162,23 +166,50 @@ item field + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. @@ -271,9 +302,7 @@ const response = await turnkeyClient.apiClient().importWallet({ "result": { "importWalletResult": { "walletId": "", - "addresses": [ - "" - ] + "addresses": [""] } }, "votes": "", diff --git a/api-reference/activities/init-email-recovery.mdx b/api-reference/activities/init-email-recovery.mdx index 71081969..35dcd416 100644 --- a/api-reference/activities/init-email-recovery.mdx +++ b/api-reference/activities/init-email-recovery.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_INIT_USER_EMAIL_RECOVERY_V2` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -84,11 +87,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -141,14 +144,31 @@ Unique identifier for a given Email Template. If not specified, the default is t - -Optional custom email address from which to send the OTP email + + + Optional custom email address from which to send the OTP email - -Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications' + + Optional custom sender name for use with sendFromEmailAddress; if left empty, + will default to 'Notifications' - -Optional custom email address to use as reply-to + + Optional custom email address to use as reply-to @@ -156,6 +176,7 @@ Optional custom email address to use as reply-to + The result of the activity @@ -171,23 +192,50 @@ Unique identifier for the user being recovered. + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/init-fiat-on-ramp.mdx b/api-reference/activities/init-fiat-on-ramp.mdx index 24cc9b27..614ed263 100644 --- a/api-reference/activities/init-fiat-on-ramp.mdx +++ b/api-reference/activities/init-fiat-on-ramp.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_INIT_FIAT_ON_RAMP` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -80,11 +83,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -161,6 +164,7 @@ Optional MoonPay Widget URL to sign when using MoonPay client SDKs with URL Sign + The result of the activity @@ -182,23 +186,50 @@ Optional signature of the MoonPay Widget URL. The signature is generated if the + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/init-generic-otp.mdx b/api-reference/activities/init-generic-otp.mdx index b7810a78..36c579da 100644 --- a/api-reference/activities/init-generic-otp.mdx +++ b/api-reference/activities/init-generic-otp.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_INIT_OTP_V3` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -104,11 +107,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -161,6 +164,7 @@ Unique identifier for a given Email Template. If not specified, the default is t + smsCustomization field @@ -170,23 +174,59 @@ Template containing references to .OtpCode i.e Your OTP is \{\{.OtpCode\}\} - -Optional client-generated user identifier to enable per-user rate limiting for SMS auth. We recommend using a hash of the client-side IP address. + + + Optional client-generated user identifier to enable per-user rate limiting for + SMS auth. We recommend using a hash of the client-side IP address. - -Optional custom email address from which to send the OTP email + + Optional custom email address from which to send the OTP email - -Optional flag to specify if the OTP code should be alphanumeric (Crockford’s Base32). If set to false, OTP code will only be numeric. Default = true + + Optional flag to specify if the OTP code should be alphanumeric (Crockford’s + Base32). If set to false, OTP code will only be numeric. Default = true - -Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications' + + Optional custom sender name for use with sendFromEmailAddress; if left empty, + will default to 'Notifications' - -Expiration window (in seconds) indicating how long the OTP is valid for. If not provided, a default of 5 minutes will be used. Maximum value is 600 seconds (10 minutes) + + Expiration window (in seconds) indicating how long the OTP is valid for. If + not provided, a default of 5 minutes will be used. Maximum value is 600 + seconds (10 minutes) - -Optional custom email address to use as reply-to + + Optional custom email address to use as reply-to @@ -194,6 +234,7 @@ Optional custom email address to use as reply-to + The result of the activity @@ -212,23 +253,50 @@ Signed bundle containing a target encryption key to use when submitting OTP code + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/init-import-private-key.mdx b/api-reference/activities/init-import-private-key.mdx index 204fca0f..25515e7a 100644 --- a/api-reference/activities/init-import-private-key.mdx +++ b/api-reference/activities/init-import-private-key.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_INIT_IMPORT_PRIVATE_KEY` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -40,11 +43,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -76,6 +79,7 @@ The ID of the User importing a Private Key. + The result of the activity @@ -91,23 +95,50 @@ Import bundle containing a public key and signature to use for importing client + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/init-import-wallet.mdx b/api-reference/activities/init-import-wallet.mdx index 5e02fb53..ed2f072a 100644 --- a/api-reference/activities/init-import-wallet.mdx +++ b/api-reference/activities/init-import-wallet.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_INIT_IMPORT_WALLET` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -40,11 +43,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -76,6 +79,7 @@ The ID of the User importing a Wallet. + The result of the activity @@ -91,23 +95,50 @@ Import bundle containing a public key and signature to use for importing client + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/init-otp-auth.mdx b/api-reference/activities/init-otp-auth.mdx index 6e4c43dc..5d0712b1 100644 --- a/api-reference/activities/init-otp-auth.mdx +++ b/api-reference/activities/init-otp-auth.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_INIT_OTP_AUTH_V3` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -104,11 +107,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -161,6 +164,7 @@ Unique identifier for a given Email Template. If not specified, the default is t + smsCustomization field @@ -170,23 +174,59 @@ Template containing references to .OtpCode i.e Your OTP is \{\{.OtpCode\}\} - -Optional client-generated user identifier to enable per-user rate limiting for SMS auth. We recommend using a hash of the client-side IP address. + + + Optional client-generated user identifier to enable per-user rate limiting for + SMS auth. We recommend using a hash of the client-side IP address. - -Optional custom email address from which to send the OTP email + + Optional custom email address from which to send the OTP email - -Optional flag to specify if the OTP code should be alphanumeric (Crockford’s Base32). Default = true + + Optional flag to specify if the OTP code should be alphanumeric (Crockford’s + Base32). Default = true - -Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications' + + Optional custom sender name for use with sendFromEmailAddress; if left empty, + will default to 'Notifications' - -Expiration window (in seconds) indicating how long the OTP is valid for. If not provided, a default of 5 minutes will be used. Maximum value is 600 seconds (10 minutes) + + Expiration window (in seconds) indicating how long the OTP is valid for. If + not provided, a default of 5 minutes will be used. Maximum value is 600 + seconds (10 minutes) - -Optional custom email address to use as reply-to + + Optional custom email address to use as reply-to @@ -194,6 +234,7 @@ Optional custom email address to use as reply-to + The result of the activity @@ -209,23 +250,50 @@ Unique identifier for an OTP authentication + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/login-with-a-stamp.mdx b/api-reference/activities/login-with-a-stamp.mdx index aa839991..9610b799 100644 --- a/api-reference/activities/login-with-a-stamp.mdx +++ b/api-reference/activities/login-with-a-stamp.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_STAMP_LOGIN` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -48,11 +51,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -90,6 +93,7 @@ Invalidate all other previously generated Login API keys + The result of the activity @@ -105,23 +109,50 @@ Signed JWT containing an expiry, public key, session type, user id, and organiza + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/login-with-oauth.mdx b/api-reference/activities/login-with-oauth.mdx index c7607ded..e21ff0a6 100644 --- a/api-reference/activities/login-with-oauth.mdx +++ b/api-reference/activities/login-with-oauth.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_OAUTH_LOGIN` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -52,11 +55,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -97,6 +100,7 @@ Invalidate all other previously generated Login API keys + The result of the activity @@ -112,23 +116,50 @@ Signed JWT containing an expiry, public key, session type, user id, and organiza + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/login-with-otp.mdx b/api-reference/activities/login-with-otp.mdx index 50dfa3ab..b3ad62ca 100644 --- a/api-reference/activities/login-with-otp.mdx +++ b/api-reference/activities/login-with-otp.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_OTP_LOGIN_V2` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -72,11 +75,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -126,11 +129,23 @@ The cryptographic signature over the message. - -Expiration window (in seconds) indicating how long the Session is valid for. If not provided, a default of 15 minutes will be used. + + + Expiration window (in seconds) indicating how long the Session is valid for. + If not provided, a default of 15 minutes will be used. - -Invalidate all other previously generated Login sessions + + Invalidate all other previously generated Login sessions @@ -138,6 +153,7 @@ Invalidate all other previously generated Login sessions + The result of the activity @@ -153,23 +169,50 @@ Signed JWT containing an expiry, public key, session type, user id, and organiza + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/oauth-20-authentication.mdx b/api-reference/activities/oauth-20-authentication.mdx index d6c13264..e47cbdd0 100644 --- a/api-reference/activities/oauth-20-authentication.mdx +++ b/api-reference/activities/oauth-20-authentication.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_OAUTH2_AUTHENTICATE` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -60,11 +63,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -111,6 +114,7 @@ An optional P256 public key to which, if provided, the bearer token will be encr + The result of the activity @@ -126,23 +130,50 @@ Base64 encoded OIDC token issued by Turnkey to be used with the LoginWithOAuth a + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/oauth.mdx b/api-reference/activities/oauth.mdx index 57b46daa..82c27323 100644 --- a/api-reference/activities/oauth.mdx +++ b/api-reference/activities/oauth.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_OAUTH` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -56,11 +59,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -104,6 +107,7 @@ Invalidate all other previously generated Oauth API keys + The result of the activity @@ -125,23 +129,50 @@ HPKE encrypted credential bundle + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/otp-auth.mdx b/api-reference/activities/otp-auth.mdx index 66c431e4..a5653115 100644 --- a/api-reference/activities/otp-auth.mdx +++ b/api-reference/activities/otp-auth.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_OTP_AUTH` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -60,11 +63,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -111,6 +114,7 @@ Invalidate all other previously generated OTP Auth API keys + The result of the activity @@ -132,23 +136,50 @@ HPKE encrypted credential bundle + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/perform-email-auth.mdx b/api-reference/activities/perform-email-auth.mdx index 5334110e..d6acbeab 100644 --- a/api-reference/activities/perform-email-auth.mdx +++ b/api-reference/activities/perform-email-auth.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_EMAIL_AUTH_V3` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -92,11 +95,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -152,17 +155,39 @@ Unique identifier for a given Email Template. If not specified, the default is t - -Invalidate all other previously generated Email Auth API keys + + + Invalidate all other previously generated Email Auth API keys - -Optional custom email address from which to send the email + + Optional custom email address from which to send the email - -Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications' + + Optional custom sender name for use with sendFromEmailAddress; if left empty, + will default to 'Notifications' - -Optional custom email address to use as reply-to + + Optional custom email address to use as reply-to @@ -170,6 +195,7 @@ Optional custom email address to use as reply-to + The result of the activity @@ -188,23 +214,50 @@ Unique identifier for the created API key. + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/prepare-spark-transfer.mdx b/api-reference/activities/prepare-spark-transfer.mdx index 3225baf0..f582a095 100644 --- a/api-reference/activities/prepare-spark-transfer.mdx +++ b/api-reference/activities/prepare-spark-transfer.mdx @@ -17,142 +17,323 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_SPARK_PREPARE_TRANSFER` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + -

The parameters object containing the specific intent data for this activity.

+

+ The parameters object containing the specific intent data for this activity. +

- - A Spark wallet account address identifying the wallet. + + A Spark wallet account address identifying the wallet. - - + +

transfer field

- - Spark transfer identifier (UUID). + + Spark transfer identifier (UUID). - - + +

Leaves being transferred.

- - Leaf identifier (UUID). + + Leaf identifier (UUID). - - + +

oldLeafDerivation field

- - identity field + + identity field - - + +

signingLeaf field

- - Unique identifier for the Spark signing leaf. + + Unique identifier for the Spark signing leaf.
- - deposit field + + deposit field - - + +

staticDeposit field

- - Index used to derive the static deposit key. + + Index used to derive the static deposit key.
- - htlcPreimage field + + htlcPreimage field
- +

newLeafDerivation field

- - identity field + + identity field - - + +

signingLeaf field

- - Unique identifier for the Spark signing leaf. + + Unique identifier for the Spark signing leaf.
- - deposit field + + deposit field - - + +

staticDeposit field

- - Index used to derive the static deposit key. + + Index used to derive the static deposit key.
- - htlcPreimage field + + htlcPreimage field
- - Client-produced CPFP refund signature (hex-encoded), passed through verbatim into the per-operator SendLeafKeyTweak. Empty omits the field from the operator package. + + Client-produced CPFP refund signature (hex-encoded), passed + through verbatim into the per-operator SendLeafKeyTweak. Empty + omits the field from the operator package. - - - Client-produced direct refund signature (hex-encoded). Passed through verbatim. + + + Client-produced direct refund signature (hex-encoded). Passed + through verbatim. - - - Client-produced direct-from-CPFP refund signature (hex-encoded). Passed through verbatim. + + + Client-produced direct-from-CPFP refund signature (hex-encoded). + Passed through verbatim.
- - Feldman VSS threshold for reconstructing the per-leaf tweak scalar. + + Feldman VSS threshold for reconstructing the per-leaf tweak scalar. - - -

Operators that will receive Feldman shares of the per-leaf tweak. Order must match the operators' numeric IDs in the Spark operator config - share index is the 1-based position in this list.

+ + +

+ Operators that will receive Feldman shares of the per-leaf tweak. + Order must match the operators' numeric IDs in the Spark operator + config - share index is the 1-based position in this list. +

- - Spark operator identifier (UUID). + + Spark operator identifier (UUID). - - - Operator's ECIES encryption pubkey (hex-encoded compressed secp256k1 point). + + + Operator's ECIES encryption pubkey (hex-encoded compressed + secp256k1 point).
- - Recipient's identity pubkey (hex-encoded compressed secp256k1 point). Each leaf's new_priv is ECIES-encrypted to this key and embedded in the per-operator package for claim-time delivery. + + Recipient's identity pubkey (hex-encoded compressed secp256k1 point). + Each leaf's new_priv is ECIES-encrypted to this key and embedded in + the per-operator package for claim-time delivery.
- -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -205,6 +386,7 @@ Unique identifier for the Spark signing leaf.
+ deposit field @@ -217,12 +399,19 @@ Index used to derive the static deposit key.
- -htlcPreimage field + + + htlcPreimage field + newLeafDerivation field @@ -238,6 +427,7 @@ Unique identifier for the Spark signing leaf. + deposit field @@ -250,24 +440,51 @@ Index used to derive the static deposit key.
- -htlcPreimage field + + + htlcPreimage field - -Client-produced CPFP refund signature (hex-encoded), passed through verbatim into the per-operator SendLeafKeyTweak. Empty omits the field from the operator package. - - -Client-produced direct refund signature (hex-encoded). Passed through verbatim. - - -Client-produced direct-from-CPFP refund signature (hex-encoded). Passed through verbatim. + + + Client-produced CPFP refund signature (hex-encoded), passed through verbatim + into the per-operator SendLeafKeyTweak. Empty omits the field from the + operator package. + + + Client-produced direct refund signature (hex-encoded). Passed through + verbatim. + + + Client-produced direct-from-CPFP refund signature (hex-encoded). Passed + through verbatim. + Feldman VSS threshold for reconstructing the per-leaf tweak scalar. @@ -283,8 +500,16 @@ Operator's ECIES encryption pubkey (hex-encoded compressed secp256k1 point).
- -Recipient's identity pubkey (hex-encoded compressed secp256k1 point). Each leaf's new_priv is ECIES-encrypted to this key and embedded in the per-operator package for claim-time delivery. + + + Recipient's identity pubkey (hex-encoded compressed secp256k1 point). Each + leaf's new_priv is ECIES-encrypted to this key and embedded in the + per-operator package for claim-time delivery. @@ -295,6 +520,7 @@ Recipient's identity pubkey (hex-encoded compressed secp256k1 point). Each leaf' + The result of the activity @@ -313,6 +539,7 @@ ECIES ciphertext (hex-encoded) opaque to Turnkey after emission. + Hex-encoded ECDSA-DER signature of the TransferPackage signing payload, signed with the wallet's IDENTITY key. @@ -334,23 +561,50 @@ Hex-encoded compressed secp256k1 point (33 bytes) for the SigningLeaf derivation
+ -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. - - -An artifact verifying a User's action. - - -Whether the activity can be approved. - - -Whether the activity can be rejected. - - -The creation timestamp. - - -The last update timestamp. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. + + + An artifact verifying a User's action. + + + Whether the activity can be approved. + + + Whether the activity can be rejected. + + + The creation timestamp. + + + The last update timestamp. diff --git a/api-reference/activities/recover-a-user.mdx b/api-reference/activities/recover-a-user.mdx index 87bbf0b1..f58a7b74 100644 --- a/api-reference/activities/recover-a-user.mdx +++ b/api-reference/activities/recover-a-user.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_RECOVER_USER` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -73,11 +76,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -139,8 +142,14 @@ Enum options: `AUTHENTICATOR_TRANSPORT_BLE`, `AUTHENTICATOR_TRANSPORT_INTERNAL`,
- -Unique identifier for the user performing recovery. + + + Unique identifier for the user performing recovery. @@ -148,6 +157,7 @@ Unique identifier for the user performing recovery. + The result of the activity @@ -169,23 +179,50 @@ item field + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. @@ -273,9 +310,7 @@ const response = await turnkeyClient.apiClient().recoverUser({ "credentialId": "", "clientDataJson": "", "attestationObject": "", - "transports": [ - "" - ] + "transports": [""] } }, "userId": "" @@ -283,9 +318,7 @@ const response = await turnkeyClient.apiClient().recoverUser({ }, "result": { "recoverUserResult": { - "authenticatorId": [ - "" - ] + "authenticatorId": [""] } }, "votes": "", diff --git a/api-reference/activities/reject-activity.mdx b/api-reference/activities/reject-activity.mdx index 16d54272..163ac18d 100644 --- a/api-reference/activities/reject-activity.mdx +++ b/api-reference/activities/reject-activity.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_REJECT_ACTIVITY` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -40,11 +43,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -76,26 +79,58 @@ An artifact verifying a User's action. - -The result of the activity + + + The result of the activity -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/remove-ip-allowlist.mdx b/api-reference/activities/remove-ip-allowlist.mdx index f191db62..02c48b04 100644 --- a/api-reference/activities/remove-ip-allowlist.mdx +++ b/api-reference/activities/remove-ip-allowlist.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_REMOVE_IP_ALLOWLIST` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -40,11 +43,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -76,6 +79,7 @@ The public component of an API key. If null, removes the organization-level IP a + The result of the activity @@ -85,23 +89,50 @@ The removeIpAllowlistResult object + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/remove-organization-feature.mdx b/api-reference/activities/remove-organization-feature.mdx index 4a7a000d..0b573b74 100644 --- a/api-reference/activities/remove-organization-feature.mdx +++ b/api-reference/activities/remove-organization-feature.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_REMOVE_ORGANIZATION_FEATURE` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -40,11 +43,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -79,6 +82,7 @@ Enum options: `FEATURE_NAME_ROOT_USER_EMAIL_RECOVERY`, `FEATURE_NAME_WEBAUTHN_OR + The result of the activity @@ -106,23 +110,50 @@ value field + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/restore-a-tvc-deployment.mdx b/api-reference/activities/restore-a-tvc-deployment.mdx index 50f4a0cc..1c4ce18a 100644 --- a/api-reference/activities/restore-a-tvc-deployment.mdx +++ b/api-reference/activities/restore-a-tvc-deployment.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_RESTORE_TVC_DEPLOYMENT` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -40,11 +43,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -76,6 +79,7 @@ The unique identifier of the TVC deployment to restore. + The result of the activity @@ -91,23 +95,50 @@ The unique identifier of the restored TVC deployment. + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/set-ip-allowlist.mdx b/api-reference/activities/set-ip-allowlist.mdx index 0aafdcc4..a699db76 100644 --- a/api-reference/activities/set-ip-allowlist.mdx +++ b/api-reference/activities/set-ip-allowlist.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_SET_IP_ALLOWLIST` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -60,11 +63,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -105,8 +108,15 @@ Optional human-readable label for this rule (e.g., 'Office VPN'). - -Behavior when an error occurs during IP allowlist evaluation. Valid values: ALLOW, DENY. Defaults to DENY. + + + Behavior when an error occurs during IP allowlist evaluation. Valid values: + ALLOW, DENY. Defaults to DENY. @@ -114,6 +124,7 @@ Behavior when an error occurs during IP allowlist evaluation. Valid values: ALLO + The result of the activity @@ -123,23 +134,50 @@ The setIpAllowlistResult object + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/set-organization-feature.mdx b/api-reference/activities/set-organization-feature.mdx index dd880f54..a601cd7c 100644 --- a/api-reference/activities/set-organization-feature.mdx +++ b/api-reference/activities/set-organization-feature.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_SET_ORGANIZATION_FEATURE` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -44,11 +47,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -86,6 +89,7 @@ Optional value for the feature. Will override existing values if feature is alre + The result of the activity @@ -113,23 +117,50 @@ value field + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/sign-frost-spark.mdx b/api-reference/activities/sign-frost-spark.mdx index 4660f02f..8926b561 100644 --- a/api-reference/activities/sign-frost-spark.mdx +++ b/api-reference/activities/sign-frost-spark.mdx @@ -17,94 +17,210 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_SPARK_SIGN_FROST` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + -

The parameters object containing the specific intent data for this activity.

+

+ The parameters object containing the specific intent data for this activity. +

- - A Spark wallet account address identifying the wallet to sign with. + + A Spark wallet account address identifying the wallet to sign with. - - -

Batched sign requests. Each produces a partial signature plus Turnkey's public commitments.

+ + +

+ Batched sign requests. Each produces a partial signature plus Turnkey's + public commitments. +

- +

derivation field

- - identity field + + identity field - - + +

signingLeaf field

- - Unique identifier for the Spark signing leaf. + + Unique identifier for the Spark signing leaf.
- - deposit field + + deposit field - - + +

staticDeposit field

- - Index used to derive the static deposit key. + + Index used to derive the static deposit key.
- - htlcPreimage field + + htlcPreimage field
- - Hex-encoded 32-byte sighash to sign. + + Hex-encoded 32-byte sighash to sign. - - - Aggregate group verifying key (hex-encoded compressed secp256k1 point), computed as P_ops + P_user. Bound into the nonce HMAC. + + + Aggregate group verifying key (hex-encoded compressed secp256k1 + point), computed as P_ops + P_user. Bound into the nonce HMAC. - - -

Commitments for every non-Turnkey participant. MUST NOT include an entry under Turnkey's identifier. Bound into the nonce HMAC.

+ + +

+ Commitments for every non-Turnkey participant. MUST NOT include an + entry under Turnkey's identifier. Bound into the nonce HMAC. +

- - FROST participant identifier, hex-encoded (32-byte scalar). + + FROST participant identifier, hex-encoded (32-byte scalar). - - - Hiding commitment D, hex-encoded compressed secp256k1 point. + + + Hiding commitment D, hex-encoded compressed secp256k1 point. - - - Binding commitment E, hex-encoded compressed secp256k1 point. + + + Binding commitment E, hex-encoded compressed secp256k1 point.
- - Optional adaptor point T (hex-encoded 33-byte compressed secp256k1 pubkey). When set, Turnkey produces a Schnorr adaptor pre-signature with the FROST challenge bound to `R+T` (where `R` is the aggregate group nonce commitment from FROST). The party holding the discrete log `t` completes the pre-sig to a valid BIP-340 signature by adding `t` (or `-t`, for parity) to the signature scalar `s`. This is primarily used by Spark leaves-swap and other adaptor-bound flows; absent or empty leads to plain FROST signing (the typical case). + + Optional adaptor point T (hex-encoded 33-byte compressed secp256k1 + pubkey). When set, Turnkey produces a Schnorr adaptor pre-signature + with the FROST challenge bound to `R+T` (where `R` is the aggregate + group nonce commitment from FROST). The party holding the discrete log + `t` completes the pre-sig to a valid BIP-340 signature by adding `t` + (or `-t`, for parity) to the signature scalar `s`. This is primarily + used by Spark leaves-swap and other adaptor-bound flows; absent or + empty leads to plain FROST signing (the typical case).
- -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -148,6 +264,7 @@ Unique identifier for the Spark signing leaf.
+ deposit field @@ -160,12 +277,19 @@ Index used to derive the static deposit key.
- -htlcPreimage field + + + htlcPreimage field + Hex-encoded 32-byte sighash to sign. @@ -187,8 +311,21 @@ Binding commitment E, hex-encoded compressed secp256k1 point.
- -Optional adaptor point T (hex-encoded 33-byte compressed secp256k1 pubkey). When set, Turnkey produces a Schnorr adaptor pre-signature with the FROST challenge bound to `R+T` (where `R` is the aggregate group nonce commitment from FROST). The party holding the discrete log `t` completes the pre-sig to a valid BIP-340 signature by adding `t` (or `-t`, for parity) to the signature scalar `s`. This is primarily used by Spark leaves-swap and other adaptor-bound flows; absent or empty leads to plain FROST signing (the typical case). + + + Optional adaptor point T (hex-encoded 33-byte compressed secp256k1 pubkey). + When set, Turnkey produces a Schnorr adaptor pre-signature with the FROST + challenge bound to `R+T` (where `R` is the aggregate group nonce commitment + from FROST). The party holding the discrete log `t` completes the pre-sig to a + valid BIP-340 signature by adding `t` (or `-t`, for parity) to the signature + scalar `s`. This is primarily used by Spark leaves-swap and other + adaptor-bound flows; absent or empty leads to plain FROST signing (the typical + case). @@ -199,6 +336,7 @@ Optional adaptor point T (hex-encoded 33-byte compressed secp256k1 pubkey). When + The result of the activity @@ -226,23 +364,50 @@ Turnkey's binding commitment E (hex-encoded compressed secp256k1 point). Forward + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/sign-raw-payload.mdx b/api-reference/activities/sign-raw-payload.mdx index e6b2d6ae..b853074f 100644 --- a/api-reference/activities/sign-raw-payload.mdx +++ b/api-reference/activities/sign-raw-payload.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_SIGN_RAW_PAYLOAD_V2` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -52,11 +55,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -103,6 +106,7 @@ Enum options: `HASH_FUNCTION_NO_OP`, `HASH_FUNCTION_SHA256`, `HASH_FUNCTION_KECC + The result of the activity @@ -124,23 +128,50 @@ Component of an ECSDA signature. + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/sign-raw-payloads.mdx b/api-reference/activities/sign-raw-payloads.mdx index 33989a6a..a3903157 100644 --- a/api-reference/activities/sign-raw-payloads.mdx +++ b/api-reference/activities/sign-raw-payloads.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_SIGN_RAW_PAYLOADS` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -55,11 +58,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -94,6 +97,7 @@ item field + encoding field @@ -112,6 +116,7 @@ Enum options: `HASH_FUNCTION_NO_OP`, `HASH_FUNCTION_SHA256`, `HASH_FUNCTION_KECC + The result of the activity @@ -139,23 +144,50 @@ Component of an ECSDA signature. + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. @@ -223,9 +255,7 @@ const response = await turnkeyClient.apiClient().signRawPayloads({ "intent": { "signRawPayloadsIntent": { "signWith": "", - "payloads": [ - "" - ], + "payloads": [""], "encoding": "", "hashFunction": "" } diff --git a/api-reference/activities/sign-transaction.mdx b/api-reference/activities/sign-transaction.mdx index f5559f7e..d395948b 100644 --- a/api-reference/activities/sign-transaction.mdx +++ b/api-reference/activities/sign-transaction.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_SIGN_TRANSACTION_V2` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -48,11 +51,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -93,6 +96,7 @@ Enum options: `TRANSACTION_TYPE_ETHEREUM`, `TRANSACTION_TYPE_SOLANA`, `TRANSACTI + The result of the activity @@ -108,23 +112,50 @@ signedTransaction field + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/spark-prepare-lightning-receive.mdx b/api-reference/activities/spark-prepare-lightning-receive.mdx index 669d7d12..f29ec2cc 100644 --- a/api-reference/activities/spark-prepare-lightning-receive.mdx +++ b/api-reference/activities/spark-prepare-lightning-receive.mdx @@ -17,41 +17,85 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_SPARK_PREPARE_LIGHTNING_RECEIVE` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + -

The parameters object containing the specific intent data for this activity.

+

+ The parameters object containing the specific intent data for this activity. +

- - A Spark wallet account address identifying the wallet. + + A Spark wallet account address identifying the wallet. - - + +

lightningReceive field

- - Feldman VSS threshold for reconstructing the preimage. + + Feldman VSS threshold for reconstructing the preimage. - - -

Operators that will receive Feldman shares of the preimage. Order must match the operators' numeric IDs in the Spark operator config - share index is the 1-based position in this list.

+ + +

+ Operators that will receive Feldman shares of the preimage. Order + must match the operators' numeric IDs in the Spark operator config - + share index is the 1-based position in this list. +

- - Spark operator identifier (UUID). + + Spark operator identifier (UUID). - - - Operator's ECIES encryption pubkey (hex-encoded compressed secp256k1 point). + + + Operator's ECIES encryption pubkey (hex-encoded compressed + secp256k1 point).
@@ -60,8 +104,8 @@ Unique identifier for a given Organization.
- -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -114,6 +158,7 @@ Operator's ECIES encryption pubkey (hex-encoded compressed secp256k1 point).
+ The result of the activity @@ -132,8 +177,14 @@ ECIES ciphertext (hex-encoded) opaque to Turnkey after emission. - -Hex-encoded SHA256(preimage). Forward to the Lightning node. + + + Hex-encoded SHA256(preimage). Forward to the Lightning node. @@ -141,23 +192,50 @@ Hex-encoded SHA256(preimage). Forward to the Lightning node. + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/update-a-fiat-on-ramp-credential.mdx b/api-reference/activities/update-a-fiat-on-ramp-credential.mdx index aaaf2775..1db4a7a1 100644 --- a/api-reference/activities/update-a-fiat-on-ramp-credential.mdx +++ b/api-reference/activities/update-a-fiat-on-ramp-credential.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_UPDATE_FIAT_ON_RAMP_CREDENTIAL` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -60,11 +63,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -114,6 +117,7 @@ Private API key for the on-ramp provider encrypted to our on-ramp encryption pub + The result of the activity @@ -129,23 +133,50 @@ Unique identifier of the Fiat On-Ramp credential that was updated + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/update-an-oauth-20-credential.mdx b/api-reference/activities/update-an-oauth-20-credential.mdx index 71222876..cdfacce6 100644 --- a/api-reference/activities/update-an-oauth-20-credential.mdx +++ b/api-reference/activities/update-an-oauth-20-credential.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_UPDATE_OAUTH2_CREDENTIAL` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -52,11 +55,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -100,6 +103,7 @@ The client secret issued by the OAuth 2.0 provider encrypted to the TLS Fetcher + The result of the activity @@ -115,23 +119,50 @@ Unique identifier of the OAuth 2.0 credential that was updated + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/update-organization-name.mdx b/api-reference/activities/update-organization-name.mdx index 3542e9f2..fb79e74e 100644 --- a/api-reference/activities/update-organization-name.mdx +++ b/api-reference/activities/update-organization-name.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_UPDATE_ORGANIZATION_NAME` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -40,11 +43,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -76,6 +79,7 @@ New name for the Organization. + The result of the activity @@ -94,23 +98,50 @@ The updated organization name. + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/update-policy.mdx b/api-reference/activities/update-policy.mdx index 0af2d4fe..8e305c46 100644 --- a/api-reference/activities/update-policy.mdx +++ b/api-reference/activities/update-policy.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_UPDATE_POLICY_V2` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -60,11 +63,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -114,6 +117,7 @@ Accompanying notes for a Policy (optional). + The result of the activity @@ -129,23 +133,50 @@ Unique identifier for a given Policy. + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/update-private-key-tag.mdx b/api-reference/activities/update-private-key-tag.mdx index 99481720..57259ee4 100644 --- a/api-reference/activities/update-private-key-tag.mdx +++ b/api-reference/activities/update-private-key-tag.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_UPDATE_PRIVATE_KEY_TAG` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -59,11 +62,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -101,6 +104,7 @@ item field + A list of Private Key IDs to remove this tag from. @@ -116,6 +120,7 @@ item field + The result of the activity @@ -131,23 +136,50 @@ Unique identifier for a given Private Key Tag. + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. @@ -218,12 +250,8 @@ const response = await turnkeyClient.apiClient().updatePrivateKeyTag({ "updatePrivateKeyTagIntent": { "privateKeyTagId": "", "newPrivateKeyTagName": "", - "addPrivateKeyIds": [ - "" - ], - "removePrivateKeyIds": [ - "" - ] + "addPrivateKeyIds": [""], + "removePrivateKeyIds": [""] } }, "result": { diff --git a/api-reference/activities/update-root-quorum.mdx b/api-reference/activities/update-root-quorum.mdx index 4563514d..b38890d7 100644 --- a/api-reference/activities/update-root-quorum.mdx +++ b/api-reference/activities/update-root-quorum.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_UPDATE_ROOT_QUORUM` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -48,11 +51,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -93,6 +96,7 @@ item field + The result of the activity @@ -102,23 +106,50 @@ The updateRootQuorumResult object + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. @@ -182,9 +213,7 @@ const response = await turnkeyClient.apiClient().updateRootQuorum({ "intent": { "updateRootQuorumIntent": { "threshold": "", - "userIds": [ - "" - ] + "userIds": [""] } }, "result": { diff --git a/api-reference/activities/update-user-tag.mdx b/api-reference/activities/update-user-tag.mdx index f19d7227..70b70f09 100644 --- a/api-reference/activities/update-user-tag.mdx +++ b/api-reference/activities/update-user-tag.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_UPDATE_USER_TAG` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -59,11 +62,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -101,6 +104,7 @@ item field + A list of User IDs to remove this tag from. @@ -116,6 +120,7 @@ item field + The result of the activity @@ -131,23 +136,50 @@ Unique identifier for a given User Tag. + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. @@ -218,12 +250,8 @@ const response = await turnkeyClient.apiClient().updateUserTag({ "updateUserTagIntent": { "userTagId": "", "newUserTagName": "", - "addUserIds": [ - "" - ], - "removeUserIds": [ - "" - ] + "addUserIds": [""], + "removeUserIds": [""] } }, "result": { diff --git a/api-reference/activities/update-user.mdx b/api-reference/activities/update-user.mdx index c3caff8f..98eac21e 100644 --- a/api-reference/activities/update-user.mdx +++ b/api-reference/activities/update-user.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_UPDATE_USER` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -59,11 +62,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -104,8 +107,14 @@ item field - -The user's phone number in E.164 format e.g. +13214567890 + + + The user's phone number in E.164 format e.g. +13214567890 @@ -113,6 +122,7 @@ The user's phone number in E.164 format e.g. +13214567890 + The result of the activity @@ -128,23 +138,50 @@ A User ID. + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. @@ -216,9 +253,7 @@ const response = await turnkeyClient.apiClient().updateUser({ "userId": "", "userName": "", "userEmail": "", - "userTagIds": [ - "" - ], + "userTagIds": [""], "userPhoneNumber": "" } }, diff --git a/api-reference/activities/update-users-email.mdx b/api-reference/activities/update-users-email.mdx index 2d8defd3..ee3423dc 100644 --- a/api-reference/activities/update-users-email.mdx +++ b/api-reference/activities/update-users-email.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_UPDATE_USER_EMAIL` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -48,11 +51,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -90,6 +93,7 @@ Signed JWT containing a unique id, expiry, verification type, contact + The result of the activity @@ -105,23 +109,50 @@ Unique identifier of the User whose email was updated. + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/update-users-name.mdx b/api-reference/activities/update-users-name.mdx index 940c1b0c..3ae493e8 100644 --- a/api-reference/activities/update-users-name.mdx +++ b/api-reference/activities/update-users-name.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_UPDATE_USER_NAME` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -44,11 +47,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -83,6 +86,7 @@ Human-readable name for a User. + The result of the activity @@ -98,23 +102,50 @@ Unique identifier of the User whose name was updated. + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/update-users-phone-number.mdx b/api-reference/activities/update-users-phone-number.mdx index 8da28814..02670586 100644 --- a/api-reference/activities/update-users-phone-number.mdx +++ b/api-reference/activities/update-users-phone-number.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_UPDATE_USER_PHONE_NUMBER` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -48,11 +51,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -90,6 +93,7 @@ Signed JWT containing a unique id, expiry, verification type, contact + The result of the activity @@ -105,23 +109,50 @@ Unique identifier of the User whose phone number was updated. + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/update-wallet.mdx b/api-reference/activities/update-wallet.mdx index 3bc3bded..11c26e43 100644 --- a/api-reference/activities/update-wallet.mdx +++ b/api-reference/activities/update-wallet.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_UPDATE_WALLET` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -44,11 +47,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -83,6 +86,7 @@ Human-readable name for a Wallet. + The result of the activity @@ -98,23 +102,50 @@ A Wallet ID. + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/update-webhook-endpoint.mdx b/api-reference/activities/update-webhook-endpoint.mdx index 490986c6..bb86ae39 100644 --- a/api-reference/activities/update-webhook-endpoint.mdx +++ b/api-reference/activities/update-webhook-endpoint.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_UPDATE_WEBHOOK_ENDPOINT` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -52,11 +55,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -97,6 +100,7 @@ Whether this webhook endpoint is active. + The result of the activity @@ -148,23 +152,50 @@ Whether this subscription is active. + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/activities/verify-generic-otp.mdx b/api-reference/activities/verify-generic-otp.mdx index bddf22e4..147d962c 100644 --- a/api-reference/activities/verify-generic-otp.mdx +++ b/api-reference/activities/verify-generic-otp.mdx @@ -17,16 +17,19 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Enum options: `ACTIVITY_TYPE_VERIFY_OTP_V2` + Timestamp (in milliseconds) of the request, used to verify liveness of user requests. + Unique identifier for a given Organization. + @@ -48,11 +51,11 @@ Unique identifier for a given Organization. Enable to have your activity generate and return App Proofs, enabling verifiability. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The activity object containing type, intent, and result @@ -90,6 +93,7 @@ Expiration window (in seconds) indicating how long the verification token is val + The result of the activity @@ -105,23 +109,50 @@ Signed JWT containing a unique id, expiry, verification type, contact. Verificat + -A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. + A list of objects representing a particular User's approval or rejection of a + Consensus request, including all relevant metadata. - -An artifact verifying a User's action. + + An artifact verifying a User's action. - -Whether the activity can be approved. + + Whether the activity can be approved. - -Whether the activity can be rejected. + + Whether the activity can be rejected. - -The creation timestamp. + + The creation timestamp. - -The last update timestamp. + + The last update timestamp. diff --git a/api-reference/auth-proxy/account.mdx b/api-reference/auth-proxy/account.mdx index 57ccb30c..9cd66cbe 100644 --- a/api-reference/auth-proxy/account.mdx +++ b/api-reference/auth-proxy/account.mdx @@ -9,8 +9,12 @@ import { NestedParam } from "/snippets/nested-param.mdx";
-
POST
-
https://authproxy.turnkey.com/v1/account
+
+ POST +
+
+ https://authproxy.turnkey.com/v1/account +
@@ -18,7 +22,8 @@ import { NestedParam } from "/snippets/nested-param.mdx"; - Your Auth Proxy config ID, found in **Dashboard → AUTH**. See [Auth Proxy reference](/reference/auth-proxy) for setup. + Your Auth Proxy config ID, found in **Dashboard → AUTH**. See [Auth Proxy + reference](/reference/auth-proxy) for setup. @@ -26,28 +31,33 @@ import { NestedParam } from "/snippets/nested-param.mdx"; Specifies the type of filter to apply, i.e 'CREDENTIAL_ID', 'NAME', 'USERNAME', 'EMAIL', 'PHONE_NUMBER', 'OIDC_TOKEN' or 'PUBLIC_KEY' + The value of the filter to apply for the specified type. For example, a specific email or name string. + Signed JWT containing a unique id, expiry, verification type, contact. Used to verify access to PII (email/phone number) when filter_type is 'EMAIL' or 'PHONE_NUMBER'. + OIDC token to verify access to PII (email/phone number) when filter_type is 'EMAIL' or 'PHONE_NUMBER'. Needed for social linking when verification_token is not available. - + - -A successful response returns the following fields: +A successful response returns the following +fields: -organizationId field + + organizationId field + diff --git a/api-reference/auth-proxy/oauth-login.mdx b/api-reference/auth-proxy/oauth-login.mdx index ac9d0160..a741713c 100644 --- a/api-reference/auth-proxy/oauth-login.mdx +++ b/api-reference/auth-proxy/oauth-login.mdx @@ -9,8 +9,12 @@ import { NestedParam } from "/snippets/nested-param.mdx";
-
POST
-
https://authproxy.turnkey.com/v1/oauth_login
+
+ POST +
+
+ https://authproxy.turnkey.com/v1/oauth_login +
@@ -18,7 +22,8 @@ import { NestedParam } from "/snippets/nested-param.mdx"; - Your Auth Proxy config ID, found in **Dashboard → AUTH**. See [Auth Proxy reference](/reference/auth-proxy) for setup. + Your Auth Proxy config ID, found in **Dashboard → AUTH**. See [Auth Proxy + reference](/reference/auth-proxy) for setup. @@ -26,28 +31,34 @@ import { NestedParam } from "/snippets/nested-param.mdx"; Base64 encoded OIDC token + Client-side public key generated by the user, which will be conditionally added to org data based on the validity of the oidc token associated with this request + Invalidate all other previously generated Login API keys + Unique identifier for a given Organization. If provided, this organization id will be used directly. If omitted, uses the OIDC token to look up the associated organization id. - + - -A successful response returns the following fields: +A successful response returns the following +fields: -Signed JWT containing an expiry, public key, session type, user id, and organization id + + Signed JWT containing an expiry, public key, session type, user id, and + organization id + diff --git a/api-reference/auth-proxy/oauth2-authenticate.mdx b/api-reference/auth-proxy/oauth2-authenticate.mdx index b3fce185..10745e28 100644 --- a/api-reference/auth-proxy/oauth2-authenticate.mdx +++ b/api-reference/auth-proxy/oauth2-authenticate.mdx @@ -9,8 +9,12 @@ import { NestedParam } from "/snippets/nested-param.mdx";
-
POST
-
https://authproxy.turnkey.com/v1/oauth2_authenticate
+
+ POST +
+
+ https://authproxy.turnkey.com/v1/oauth2_authenticate +
@@ -18,7 +22,8 @@ import { NestedParam } from "/snippets/nested-param.mdx"; - Your Auth Proxy config ID, found in **Dashboard → AUTH**. See [Auth Proxy reference](/reference/auth-proxy) for setup. + Your Auth Proxy config ID, found in **Dashboard → AUTH**. See [Auth Proxy + reference](/reference/auth-proxy) for setup. @@ -26,38 +31,45 @@ import { NestedParam } from "/snippets/nested-param.mdx"; Enum options: `OAUTH2_PROVIDER_X`, `OAUTH2_PROVIDER_DISCORD` + The auth_code provided by the OAuth 2.0 to the end user to be exchanged for a Bearer token in the OAuth 2.0 flow + The URI the user is redirected to after they have authenticated with the OAuth 2.0 provider + The code verifier used by OAuth 2.0 PKCE providers + A nonce value set to sha256(publicKey), used to bind the OIDC token to a specific public key + The client ID registered with the OAuth 2.0 provider - + - -A successful response returns the following fields: +A successful response returns the following +fields: -A Turnkey issued OIDC token to be used with the LoginWithOAuth activity + + A Turnkey issued OIDC token to be used with the LoginWithOAuth activity + diff --git a/api-reference/auth-proxy/otp-init.mdx b/api-reference/auth-proxy/otp-init.mdx index 24cee15d..c5ecbf53 100644 --- a/api-reference/auth-proxy/otp-init.mdx +++ b/api-reference/auth-proxy/otp-init.mdx @@ -9,8 +9,12 @@ import { NestedParam } from "/snippets/nested-param.mdx";
-
POST
-
https://authproxy.turnkey.com/v1/otp_init_v2
+
+ POST +
+
+ https://authproxy.turnkey.com/v1/otp_init_v2 +
@@ -18,7 +22,8 @@ import { NestedParam } from "/snippets/nested-param.mdx"; - Your Auth Proxy config ID, found in **Dashboard → AUTH**. See [Auth Proxy reference](/reference/auth-proxy) for setup. + Your Auth Proxy config ID, found in **Dashboard → AUTH**. See [Auth Proxy + reference](/reference/auth-proxy) for setup. @@ -26,27 +31,46 @@ import { NestedParam } from "/snippets/nested-param.mdx"; Enum to specify whether to send OTP code via SMS or email + Email or phone number to send the OTP code to + - +

emailCustomization field

- - Unique identifier for a given Email Template. If not specified, the default is the most recent Email Template. + + Unique identifier for a given Email Template. If not specified, the + default is the most recent Email Template.
- -A successful response returns the following fields: +A successful response returns the following +fields: -Unique identifier for an OTP flow. -Signed bundle containing a target encryption key to use when submitting OTP codes. + + Unique identifier for an OTP flow. + + + Signed bundle containing a target encryption key to use when submitting OTP + codes. + diff --git a/api-reference/auth-proxy/otp-login.mdx b/api-reference/auth-proxy/otp-login.mdx index 2c603d9a..68627a65 100644 --- a/api-reference/auth-proxy/otp-login.mdx +++ b/api-reference/auth-proxy/otp-login.mdx @@ -9,8 +9,12 @@ import { NestedParam } from "/snippets/nested-param.mdx";
-
POST
-
https://authproxy.turnkey.com/v1/otp_login_v2
+
+ POST +
+
+ https://authproxy.turnkey.com/v1/otp_login_v2 +
@@ -18,7 +22,8 @@ import { NestedParam } from "/snippets/nested-param.mdx"; - Your Auth Proxy config ID, found in **Dashboard → AUTH**. See [Auth Proxy reference](/reference/auth-proxy) for setup. + Your Auth Proxy config ID, found in **Dashboard → AUTH**. See [Auth Proxy + reference](/reference/auth-proxy) for setup. @@ -26,11 +31,13 @@ import { NestedParam } from "/snippets/nested-param.mdx"; Session containing a unique id, expiry, verification type, contact. Verification status of a user is updated when the token is consumed (in OTP_LOGIN requests) + Client-side public key generated by the user, used as the session public key upon successful login. + @@ -56,18 +63,22 @@ Client-side public key generated by the user, used as the session public key upo Invalidate all other previously generated Login sessions + Unique identifier for a given Organization. If provided, this organization id will be used directly. If omitted, uses the verification token to look up the verified sub-organization based on the contact and verification type. - + - -A successful response returns the following fields: +A successful response returns the following +fields: -Session containing an expiry, public key, session type, user id, and organization id + + Session containing an expiry, public key, session type, user id, and + organization id + diff --git a/api-reference/auth-proxy/otp-verify.mdx b/api-reference/auth-proxy/otp-verify.mdx index a4386a2e..82e4f8eb 100644 --- a/api-reference/auth-proxy/otp-verify.mdx +++ b/api-reference/auth-proxy/otp-verify.mdx @@ -9,8 +9,12 @@ import { NestedParam } from "/snippets/nested-param.mdx";
-
POST
-
https://authproxy.turnkey.com/v1/otp_verify_v2
+
+ POST +
+
+ https://authproxy.turnkey.com/v1/otp_verify_v2 +
@@ -18,7 +22,8 @@ import { NestedParam } from "/snippets/nested-param.mdx"; - Your Auth Proxy config ID, found in **Dashboard → AUTH**. See [Auth Proxy reference](/reference/auth-proxy) for setup. + Your Auth Proxy config ID, found in **Dashboard → AUTH**. See [Auth Proxy + reference](/reference/auth-proxy) for setup. @@ -26,18 +31,23 @@ import { NestedParam } from "/snippets/nested-param.mdx"; ID representing the result of an init OTP activity. + Encrypted bundle containing the OTP code and a client-generated public key. Turnkey's secure enclaves will decrypt this bundle, verify the OTP code, and issue a new Verification Token. Encrypted using the target encryption key provided in the INIT_OTP activity result. - +
- -A successful response returns the following fields: +A successful response returns the following +fields: -Verification Token containing a unique id, expiry, verification type, contact signed by Turnkey's enclaves. Verification status of a user is updated when the token is consumed (in OTP_LOGIN requests) + + Verification Token containing a unique id, expiry, verification type, contact + signed by Turnkey's enclaves. Verification status of a user is updated when + the token is consumed (in OTP_LOGIN requests) + diff --git a/api-reference/auth-proxy/signup.mdx b/api-reference/auth-proxy/signup.mdx index 58d6228b..ff8eca0b 100644 --- a/api-reference/auth-proxy/signup.mdx +++ b/api-reference/auth-proxy/signup.mdx @@ -9,8 +9,12 @@ import { NestedParam } from "/snippets/nested-param.mdx";
-
POST
-
https://authproxy.turnkey.com/v1/signup_v2
+
+ POST +
+
+ https://authproxy.turnkey.com/v1/signup_v2 +
@@ -18,7 +22,8 @@ import { NestedParam } from "/snippets/nested-param.mdx"; - Your Auth Proxy config ID, found in **Dashboard → AUTH**. See [Auth Proxy reference](/reference/auth-proxy) for setup. + Your Auth Proxy config ID, found in **Dashboard → AUTH**. See [Auth Proxy + reference](/reference/auth-proxy) for setup. @@ -26,110 +31,241 @@ import { NestedParam } from "/snippets/nested-param.mdx"; userEmail field + userPhoneNumber field + userTag field + userName field + organizationName field + verificationToken field + -

A list of API Key parameters. This field, if not needed, should be an empty array in your request body.

+

+ A list of API Key parameters. This field, if not needed, should be an empty + array in your request body. +

- - Human-readable name for an API Key. + + Human-readable name for an API Key. - - - The public component of a cryptographic key pair used to sign messages and transactions. + + + The public component of a cryptographic key pair used to sign messages and + transactions. - - - Enum options: `API_KEY_CURVE_P256`, `API_KEY_CURVE_SECP256K1`, `API_KEY_CURVE_ED25519` + + + Enum options: `API_KEY_CURVE_P256`, `API_KEY_CURVE_SECP256K1`, + `API_KEY_CURVE_ED25519` - - - Optional window (in seconds) indicating how long the API Key should last. + + + Optional window (in seconds) indicating how long the API Key should last.
- -

A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body.

+ +

+ A list of Authenticator parameters. This field, if not needed, should be an + empty array in your request body. +

- - Human-readable name for an Authenticator. + + Human-readable name for an Authenticator. - - - Challenge presented for authentication purposes. + + + Challenge presented for authentication purposes. - - + +

attestation field

- - The cbor encoded then base64 url encoded id of the credential. + + The cbor encoded then base64 url encoded id of the credential. - - - A base64 url encoded payload containing metadata about the signing context and the challenge. + + + A base64 url encoded payload containing metadata about the signing + context and the challenge. - - - A base64 url encoded payload containing authenticator data and any attestation the webauthn provider chooses. + + + A base64 url encoded payload containing authenticator data and any + attestation the webauthn provider chooses. - - - Enum options: `AUTHENTICATOR_TRANSPORT_BLE`, `AUTHENTICATOR_TRANSPORT_INTERNAL`, `AUTHENTICATOR_TRANSPORT_NFC`, `AUTHENTICATOR_TRANSPORT_USB`, `AUTHENTICATOR_TRANSPORT_HYBRID` + + + Enum options: `AUTHENTICATOR_TRANSPORT_BLE`, + `AUTHENTICATOR_TRANSPORT_INTERNAL`, `AUTHENTICATOR_TRANSPORT_NFC`, + `AUTHENTICATOR_TRANSPORT_USB`, `AUTHENTICATOR_TRANSPORT_HYBRID`
- -

A list of Oauth providers. This field, if not needed, should be an empty array in your request body.

+ +

+ A list of Oauth providers. This field, if not needed, should be an empty + array in your request body. +

- - Human-readable name to identify a Provider. + + Human-readable name to identify a Provider. - - - Base64 encoded OIDC token + + + Base64 encoded OIDC token - - + +

oidcClaims field

- - The issuer identifier from the OIDC token (iss claim) + + The issuer identifier from the OIDC token (iss claim) - - - The subject identifier from the OIDC token (sub claim) + + + The subject identifier from the OIDC token (sub claim) - - - The audience from the OIDC token (aud claim) + + + The audience from the OIDC token (aud claim)
@@ -138,58 +274,161 @@ verificationToken field

wallet field

- - Human-readable name for a Wallet. + + Human-readable name for a Wallet. - - -

A list of wallet Accounts. This field, if not needed, should be an empty array in your request body.

+ + +

+ A list of wallet Accounts. This field, if not needed, should be an empty + array in your request body. +

- - Enum options: `CURVE_SECP256K1`, `CURVE_ED25519`, `CURVE_P256` + + Enum options: `CURVE_SECP256K1`, `CURVE_ED25519`, `CURVE_P256` - - - Enum options: `PATH_FORMAT_BIP32` + + + Enum options: `PATH_FORMAT_BIP32` - - - Path used to generate a wallet Account. + + + Path used to generate a wallet Account. - - - Enum options: `ADDRESS_FORMAT_UNCOMPRESSED`, `ADDRESS_FORMAT_COMPRESSED`, `ADDRESS_FORMAT_ETHEREUM`, `ADDRESS_FORMAT_SOLANA`, `ADDRESS_FORMAT_COSMOS`, `ADDRESS_FORMAT_TRON`, `ADDRESS_FORMAT_SUI`, `ADDRESS_FORMAT_APTOS`, `ADDRESS_FORMAT_BITCOIN_MAINNET_P2PKH`, `ADDRESS_FORMAT_BITCOIN_MAINNET_P2SH`, `ADDRESS_FORMAT_BITCOIN_MAINNET_P2WPKH`, `ADDRESS_FORMAT_BITCOIN_MAINNET_P2WSH`, `ADDRESS_FORMAT_BITCOIN_MAINNET_P2TR`, `ADDRESS_FORMAT_BITCOIN_TESTNET_P2PKH`, `ADDRESS_FORMAT_BITCOIN_TESTNET_P2SH`, `ADDRESS_FORMAT_BITCOIN_TESTNET_P2WPKH`, `ADDRESS_FORMAT_BITCOIN_TESTNET_P2WSH`, `ADDRESS_FORMAT_BITCOIN_TESTNET_P2TR`, `ADDRESS_FORMAT_BITCOIN_SIGNET_P2PKH`, `ADDRESS_FORMAT_BITCOIN_SIGNET_P2SH`, `ADDRESS_FORMAT_BITCOIN_SIGNET_P2WPKH`, `ADDRESS_FORMAT_BITCOIN_SIGNET_P2WSH`, `ADDRESS_FORMAT_BITCOIN_SIGNET_P2TR`, `ADDRESS_FORMAT_BITCOIN_REGTEST_P2PKH`, `ADDRESS_FORMAT_BITCOIN_REGTEST_P2SH`, `ADDRESS_FORMAT_BITCOIN_REGTEST_P2WPKH`, `ADDRESS_FORMAT_BITCOIN_REGTEST_P2WSH`, `ADDRESS_FORMAT_BITCOIN_REGTEST_P2TR`, `ADDRESS_FORMAT_SEI`, `ADDRESS_FORMAT_XLM`, `ADDRESS_FORMAT_DOGE_MAINNET`, `ADDRESS_FORMAT_DOGE_TESTNET`, `ADDRESS_FORMAT_TON_V3R2`, `ADDRESS_FORMAT_TON_V4R2`, `ADDRESS_FORMAT_TON_V5R1`, `ADDRESS_FORMAT_XRP`, `ADDRESS_FORMAT_SPARK_MAINNET`, `ADDRESS_FORMAT_SPARK_REGTEST` + + + Enum options: `ADDRESS_FORMAT_UNCOMPRESSED`, + `ADDRESS_FORMAT_COMPRESSED`, `ADDRESS_FORMAT_ETHEREUM`, + `ADDRESS_FORMAT_SOLANA`, `ADDRESS_FORMAT_COSMOS`, + `ADDRESS_FORMAT_TRON`, `ADDRESS_FORMAT_SUI`, `ADDRESS_FORMAT_APTOS`, + `ADDRESS_FORMAT_BITCOIN_MAINNET_P2PKH`, + `ADDRESS_FORMAT_BITCOIN_MAINNET_P2SH`, + `ADDRESS_FORMAT_BITCOIN_MAINNET_P2WPKH`, + `ADDRESS_FORMAT_BITCOIN_MAINNET_P2WSH`, + `ADDRESS_FORMAT_BITCOIN_MAINNET_P2TR`, + `ADDRESS_FORMAT_BITCOIN_TESTNET_P2PKH`, + `ADDRESS_FORMAT_BITCOIN_TESTNET_P2SH`, + `ADDRESS_FORMAT_BITCOIN_TESTNET_P2WPKH`, + `ADDRESS_FORMAT_BITCOIN_TESTNET_P2WSH`, + `ADDRESS_FORMAT_BITCOIN_TESTNET_P2TR`, + `ADDRESS_FORMAT_BITCOIN_SIGNET_P2PKH`, + `ADDRESS_FORMAT_BITCOIN_SIGNET_P2SH`, + `ADDRESS_FORMAT_BITCOIN_SIGNET_P2WPKH`, + `ADDRESS_FORMAT_BITCOIN_SIGNET_P2WSH`, + `ADDRESS_FORMAT_BITCOIN_SIGNET_P2TR`, + `ADDRESS_FORMAT_BITCOIN_REGTEST_P2PKH`, + `ADDRESS_FORMAT_BITCOIN_REGTEST_P2SH`, + `ADDRESS_FORMAT_BITCOIN_REGTEST_P2WPKH`, + `ADDRESS_FORMAT_BITCOIN_REGTEST_P2WSH`, + `ADDRESS_FORMAT_BITCOIN_REGTEST_P2TR`, `ADDRESS_FORMAT_SEI`, + `ADDRESS_FORMAT_XLM`, `ADDRESS_FORMAT_DOGE_MAINNET`, + `ADDRESS_FORMAT_DOGE_TESTNET`, `ADDRESS_FORMAT_TON_V3R2`, + `ADDRESS_FORMAT_TON_V4R2`, `ADDRESS_FORMAT_TON_V5R1`, + `ADDRESS_FORMAT_XRP`, `ADDRESS_FORMAT_SPARK_MAINNET`, + `ADDRESS_FORMAT_SPARK_REGTEST`
- - Length of mnemonic to generate the Wallet seed. Defaults to 12. Accepted values: 12, 15, 18, 21, 24. + + Length of mnemonic to generate the Wallet seed. Defaults to 12. Accepted + values: 12, 15, 18, 21, 24.
- +

clientSignature field

- - The public component of a cryptographic key pair used to create the signature. + + The public component of a cryptographic key pair used to create the + signature. - - - Enum options: `CLIENT_SIGNATURE_SCHEME_API_P256` + + + Enum options: `CLIENT_SIGNATURE_SCHEME_API_P256` - - - The message that was signed. + + + The message that was signed. - - - The cryptographic signature over the message. + + + The cryptographic signature over the message.
- -A successful response returns the following fields: +A successful response returns the following +fields: organizationId field @@ -311,9 +550,7 @@ curl --request POST \ "organizationId": "", "wallet": { "walletId": "", - "addresses": [ - "" - ] + "addresses": [""] }, "userId": "", "appProofs": [ diff --git a/api-reference/auth-proxy/wallet-kit-config.mdx b/api-reference/auth-proxy/wallet-kit-config.mdx index cea380c6..46e220f9 100644 --- a/api-reference/auth-proxy/wallet-kit-config.mdx +++ b/api-reference/auth-proxy/wallet-kit-config.mdx @@ -9,8 +9,12 @@ import { NestedParam } from "/snippets/nested-param.mdx";
-
POST
-
https://authproxy.turnkey.com/v1/wallet_kit_config
+
+ POST +
+
+ https://authproxy.turnkey.com/v1/wallet_kit_config +
@@ -18,12 +22,12 @@ import { NestedParam } from "/snippets/nested-param.mdx"; - Your Auth Proxy config ID, found in **Dashboard → AUTH**. See [Auth Proxy reference](/reference/auth-proxy) for setup. + Your Auth Proxy config ID, found in **Dashboard → AUTH**. See [Auth Proxy + reference](/reference/auth-proxy) for setup. - - -A successful response returns the following fields: +A successful response returns the following +fields: List of enabled authentication providers (e.g., 'facebook', 'google', 'apple', 'email', 'sms', 'passkey', 'wallet') @@ -58,9 +62,7 @@ curl --request POST \ ```json 200 { - "enabledProviders": [ - "" - ], + "enabledProviders": [""], "sessionExpirationSeconds": "", "organizationId": "", "oauthClientIds": "", diff --git a/api-reference/overview/errors.mdx b/api-reference/overview/errors.mdx index 03bb160b..22af86f0 100644 --- a/api-reference/overview/errors.mdx +++ b/api-reference/overview/errors.mdx @@ -33,48 +33,52 @@ What matters most for error handling is the **Turnkey Error**: the human-readabl **Understanding TurnkeyErrorCodes:** These codes represent **categories** of errors, not specific messages. For example, `SIGNATURE_INVALID` may appear with messages like "could not verify WebAuthn signature" or "could not verify api key signature". Use the `turnkeyErrorCode` to identify the error category programmatically, and use the human-readable message for specific details. - - ### Available TurnkeyErrorCodes The following error codes may be returned in error details: -| Code | Description | -| :------------------------------- | :----------------------------------------------------------------------------------------------------------------------------- | -| `UNSPECIFIED` | Error code not specified | -| `INTERNAL` | Internal server error | -| `ORGANIZATION_NOT_FOUND` | The specified organization could not be found | -| `API_OPERATIONS_DISABLED` | Global API access is temporarily disabled | -| `SIGNING_QUOTA_EXCEEDED` | Organization has exceeded its signing quota and cannot execute activities | -| `REQUEST_NOT_AUTHORIZED` | Request is not authorized - may occur when accessing resources outside permissions or beyond session restrictions | -| `PUBLIC_KEY_NOT_FOUND` | Public key could not be found in the organization or its parent | -| `RATE_LIMIT_EXCEEDED` | Organization has been rate limited and cannot execute activities | -| `SIGNATURE_MISSING` | Required authentication signature is missing from the request | -| `SIGNATURE_INVALID` | Could not verify API key or WebAuthn signature | -| `CREDENTIAL_NOT_FOUND` | Credential or WebAuthn authenticator not found in organization or its parent | -| `CREDENTIAL_CONFLICT` | Multiple sub-organizations are associated with this credential, creating ambiguous authentication | -| `API_KEY_EXPIRED` | The API key has expired and can no longer be used | -| `REQUEST_INVALID` | Request contains invalid or missing required parameters | -| `FORBIDDEN` | User does not have permission to view or access this organization | -| `UNAUTHENTICATED` | Authentication failed - request lacks valid authentication credentials | -| `UNSUPPORTED_TRANSACTION_TYPE` | Transaction type is not supported (supported: Ethereum, Solana, Tron, Bitcoin, Tempo) | -| `INVALID_TRANSACTION` | Transaction structure is invalid (e.g., too many addresses in Solana transaction) | -| `INVALID_OIDC_TOKEN` | OIDC token is invalid or missing required claims (aud, sub, iss) | -| `INVALID_ORGANIZATION_ID` | Organization ID is invalid or malformed (must be a valid UUID) | -| `OAUTH2_CREDENTIAL_NOT_FOUND` | The specified OAuth 2.0 credential could not be found | -| `OAUTH2_PROVIDER_NOT_FOUND` | The specified OAuth 2.0 provider could not be found | -| `INVALID_OAUTH2_PROVIDER` | OAuth 2.0 provider configuration is invalid or misconfigured | -| `OAUTH2_PROVIDER_NOT_CONFIGURED` | OAuth 2.0 provider has not been configured for this organization | -| `INVALID_ACTIVITY_CALLER` | This activity cannot be called by sub-organizations | -| `WALLET_ACCOUNT_NOT_EXPORTED` | Wallet account has not been exported and cannot be deleted without export | -| `INVALID_TIME` | Time range is invalid or results in excessive intervals | -| `RPC_CALL_ERROR` | RPC provider communication error | -| `INVALID_EMAIL` | Email address is invalid - check format, domain, and TLD (Top-Level Domain) | -| `INVALID_FQDN` | Email domain could not be reached or verified | -| `OAUTH_PROVIDER_ALREADY_EXISTS` | OAuth provider with same audience, subject, and issuer already exists | -| `EMAIL_SENDING_DISABLED` | Email sending functionality is currently disabled | - - Not all errors currently include a `turnkeyErrorCode`, though we aim to include one in all customer-facing errors. If you encounter an error where you would expect a `turnkeyErrorCode` but don't see one, please contact Turnkey support. +| Code | Description | +| :------------------------------- | :---------------------------------------------------------------------------------------------------------------- | +| `UNSPECIFIED` | Error code not specified | +| `INTERNAL` | Internal server error | +| `ORGANIZATION_NOT_FOUND` | The specified organization could not be found | +| `API_OPERATIONS_DISABLED` | Global API access is temporarily disabled | +| `SIGNING_QUOTA_EXCEEDED` | Organization has exceeded its signing quota and cannot execute activities | +| `REQUEST_NOT_AUTHORIZED` | Request is not authorized - may occur when accessing resources outside permissions or beyond session restrictions | +| `PUBLIC_KEY_NOT_FOUND` | Public key could not be found in the organization or its parent | +| `RATE_LIMIT_EXCEEDED` | Organization has been rate limited and cannot execute activities | +| `SIGNATURE_MISSING` | Required authentication signature is missing from the request | +| `SIGNATURE_INVALID` | Could not verify API key or WebAuthn signature | +| `CREDENTIAL_NOT_FOUND` | Credential or WebAuthn authenticator not found in organization or its parent | +| `CREDENTIAL_CONFLICT` | Multiple sub-organizations are associated with this credential, creating ambiguous authentication | +| `API_KEY_EXPIRED` | The API key has expired and can no longer be used | +| `REQUEST_INVALID` | Request contains invalid or missing required parameters | +| `FORBIDDEN` | User does not have permission to view or access this organization | +| `UNAUTHENTICATED` | Authentication failed - request lacks valid authentication credentials | +| `UNSUPPORTED_TRANSACTION_TYPE` | Transaction type is not supported (supported: Ethereum, Solana, Tron, Bitcoin, Tempo) | +| `INVALID_TRANSACTION` | Transaction structure is invalid (e.g., too many addresses in Solana transaction) | +| `INVALID_OIDC_TOKEN` | OIDC token is invalid or missing required claims (aud, sub, iss) | +| `INVALID_ORGANIZATION_ID` | Organization ID is invalid or malformed (must be a valid UUID) | +| `OAUTH2_CREDENTIAL_NOT_FOUND` | The specified OAuth 2.0 credential could not be found | +| `OAUTH2_PROVIDER_NOT_FOUND` | The specified OAuth 2.0 provider could not be found | +| `INVALID_OAUTH2_PROVIDER` | OAuth 2.0 provider configuration is invalid or misconfigured | +| `OAUTH2_PROVIDER_NOT_CONFIGURED` | OAuth 2.0 provider has not been configured for this organization | +| `INVALID_ACTIVITY_CALLER` | This activity cannot be called by sub-organizations | +| `WALLET_ACCOUNT_NOT_EXPORTED` | Wallet account has not been exported and cannot be deleted without export | +| `INVALID_TIME` | Time range is invalid or results in excessive intervals | +| `RPC_CALL_ERROR` | RPC provider communication error | +| `INVALID_EMAIL` | Email address is invalid - check format, domain, and TLD (Top-Level Domain) | +| `INVALID_FQDN` | Email domain could not be reached or verified | +| `OAUTH_PROVIDER_ALREADY_EXISTS` | OAuth provider with same audience, subject, and issuer already exists | +| `EMAIL_SENDING_DISABLED` | Email sending functionality is currently disabled | + + + {" "} + Not all errors currently include a `turnkeyErrorCode`, though we aim to + include one in all customer-facing errors. If you encounter an error where you + would expect a `turnkeyErrorCode` but don't see one, please contact Turnkey + support. + ## Detailed error messages @@ -146,7 +150,7 @@ The below table enumerates common errors across different actions that can be ta | ResourceExhausted | 429 | [this sub-organization cannot execute activities because its parent is over its allotted quota. Please reach out to the Turnkey team (help@turnkey.com) for more information.](#this-sub-organization-cannot-execute-activities-because-its-parent-is-over-its-allotted-quota-please-reach-out-to-the-turnkey-team-helpturnkeycom-for-more-information) | | ResourceExhausted | 429 | [this organization cannot execute activities because it has been rate limited. Please reach out to the Turnkey team (help@turnkey.com) for more information.](#this-organization-cannot-execute-activities-because-it-has-been-rate-limited-please-reach-out-to-the-turnkey-team-helpturnkeycom-for-more-information) | | ResourceExhausted | 429 | [this sub-organization cannot execute activities because its parent has been rate limited. Please reach out to the Turnkey team (help@turnkey.com) for more information.](#this-sub-organization-cannot-execute-activities-because-its-parent-has-been-rate-limited-please-reach-out-to-the-turnkey-team-helpturnkeycom-for-more-information) | -| Internal | 500 | [internal server error](#internal-server-error) +| Internal | 500 | [internal server error](#internal-server-error) | ## GRPC error codes @@ -772,7 +776,7 @@ Troubleshooting tips: - Try to decode the payload independently and see if it returns the expected result. - We've noticed that for EIP1559 transaction types, the go-ethereum [MarshalBinary()](https://pkg.go.dev/github.com/ethereum/go-ethereum/core/types#Transaction.MarshalBinary) function will include the R, S, V values which should not be present within the serialized payload. Try to reconstruct the RLP payload manually without the R, S, V values, see the example below: - + ```go package main @@ -782,62 +786,64 @@ import ( "log" "math/big" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rlp" + ) func main() { - to := common.HexToAddress("0x...") +to := common.HexToAddress("0x...") - txData := &types.DynamicFeeTx{ - ChainID: big.NewInt(1), - Nonce: 0, - GasTipCap: big.NewInt(12344), - GasFeeCap: big.NewInt(10010000000), - Gas: 100000, - To: &to, - Value: big.NewInt(1), - Data: hexDecode(""), - AccessList: types.AccessList{}, // Optional - } + txData := &types.DynamicFeeTx{ + ChainID: big.NewInt(1), + Nonce: 0, + GasTipCap: big.NewInt(12344), + GasFeeCap: big.NewInt(10010000000), + Gas: 100000, + To: &to, + Value: big.NewInt(1), + Data: hexDecode(""), + AccessList: types.AccessList{}, // Optional + } - // RLP-encode only the fields included in the unsigned tx - unsignedRLP := encodeUnsignedDynamicFeeTx(txData) + // RLP-encode only the fields included in the unsigned tx + unsignedRLP := encodeUnsignedDynamicFeeTx(txData) - // Prepend EIP-1559 type byte (0x02) - serializedUnsigned := append([]byte{types.DynamicFeeTxType}, unsignedRLP...) + // Prepend EIP-1559 type byte (0x02) + serializedUnsigned := append([]byte{types.DynamicFeeTxType}, unsignedRLP...) - fmt.Printf("Unsigned serialized tx: 0x%x\n", serializedUnsigned) + fmt.Printf("Unsigned serialized tx: 0x%x\n", serializedUnsigned) } -func encodeUnsignedDynamicFeeTx(tx *types.DynamicFeeTx) []byte { - rlpInput := []interface{}{ - tx.ChainID, - tx.Nonce, - tx.GasTipCap, - tx.GasFeeCap, - tx.Gas, - tx.To, - tx.Value, - tx.Data, - tx.AccessList, - } - out, err := rlp.EncodeToBytes(rlpInput) - if err != nil { - log.Fatalf("failed to encode RLP: %v", err) - } - return out +func encodeUnsignedDynamicFeeTx(tx \*types.DynamicFeeTx) []byte { +rlpInput := []interface{}{ +tx.ChainID, +tx.Nonce, +tx.GasTipCap, +tx.GasFeeCap, +tx.Gas, +tx.To, +tx.Value, +tx.Data, +tx.AccessList, +} +out, err := rlp.EncodeToBytes(rlpInput) +if err != nil { +log.Fatalf("failed to encode RLP: %v", err) +} +return out } func hexDecode(input string) []byte { - b, err := hex.DecodeString(input) - if err != nil { - log.Fatal(err) - } - return b +b, err := hex.DecodeString(input) +if err != nil { +log.Fatal(err) +} +return b } + ``` @@ -960,4 +966,5 @@ Troubleshooting tips: - Verify the email domain is a valid, active domain - Check that the email provider's MX records are properly configured - Try using an email address from a well-known provider (Gmail, Outlook, etc.) to test -- If you believe this is in error, please contact Turnkey \ No newline at end of file +- If you believe this is in error, please contact Turnkey +``` diff --git a/api-reference/overview/intro.mdx b/api-reference/overview/intro.mdx index b3794264..415ca650 100644 --- a/api-reference/overview/intro.mdx +++ b/api-reference/overview/intro.mdx @@ -19,11 +19,11 @@ Requests must be stamped by registered user credentials and verified by Turnkey' Turnkey's API is divided into 2 broad categories: queries and submissions. -* Queries are read requests (e.g. `get_users`, `list_users`) -* Submissions are requests to execute a workload (e.g. `create_policy`, `sign_transaction`, `delete_user`) +- Queries are read requests (e.g. `get_users`, `list_users`) +- Submissions are requests to execute a workload (e.g. `create_policy`, `sign_transaction`, `delete_user`) ## Dive deeper -* Creating your first [Stamp](/api-reference/overview/stamps) -* Fetching data with [Queries](/api-reference/queries/overview) -* Executing workloads with [Submissions](/api-reference/activities/overview) +- Creating your first [Stamp](/api-reference/overview/stamps) +- Fetching data with [Queries](/api-reference/queries/overview) +- Executing workloads with [Submissions](/api-reference/activities/overview) diff --git a/api-reference/overview/stamps.mdx b/api-reference/overview/stamps.mdx index 2611c543..3432c5a5 100644 --- a/api-reference/overview/stamps.mdx +++ b/api-reference/overview/stamps.mdx @@ -6,6 +6,7 @@ description: "Every request made to Turnkey must include a signature over the PO ### API keys To create a valid, API key stamped request follow these steps: + Sign the JSON-encoded POST body with your API key to produce a `signature` (DER-encoded) @@ -20,6 +21,7 @@ To create a valid, API key stamped request follow these steps: * `publicKey`: the public key of API key, note that only P-256 keys (API_KEY_CURVE_P256) are currently supported * `signature`: the signature produced by the API key * `scheme`: `SIGNATURE_SCHEME_TK_API_P256` + Base64URL encode the stamp @@ -35,6 +37,7 @@ To create a valid, API key stamped request follow these steps: ### WebAuthn To create a valid, Webauthn authenticator stamped request follow these steps: + Compute the webauthn challenge by hashing the POST body bytes (JSON encoded) with SHA256. For example, if the POST body is `{"organization_id": "1234", "type": "ACTIVITY_TYPE_CREATE_API_KEYS", "params": {"for": "example"}`, the webauthn challenge is the string `7e8b4653fc7e51dc119cea031942f4693b4742ceca4dda269b925802b38b2147` @@ -42,7 +45,6 @@ To create a valid, Webauthn authenticator stamped request follow these steps: Include the challenge amongst WebAuthn signing options. Refer to the existing stamper implementations in the [following section](#stampers)) for examples - * Note that if you need to pass the challenge as bytes, you'll need to utf8-encode the challenge string (in JS, the challenge bytes will be `TextEncoder().encode("7e8b4653fc7e51dc119cea031942f4693b4742ceca4dda269b925802b38b2147")`) * Additional note for React Native contexts: the resulting string should then additionally be base64-encoded. See [implementation](https://github.com/tkhq/sdk/blob/b52db566e79a65eec8d8e7066053d6a3ac5f3943/packages/react-native-passkey-stamper/src/util.ts#L5-L10) @@ -55,6 +57,7 @@ To create a valid, Webauthn authenticator stamped request follow these steps: * `authenticatorData`: the authenticator data produced by Webauthn assertion * `clientDataJson`: the client data produced by the Webauthn assertion * `signature`: the signature produced by the Webauthn assertion + @@ -63,6 +66,7 @@ To create a valid, Webauthn authenticator stamped request follow these steps: * Header names are case-insensitive (so `X-Stamp-Webauthn` and `X-Stamp-WebAuthn` are considered equivalent) * Unlike API key stamps, the format is just JSON; no base64URL encoding necessary! For example: `X-Stamp-Webauthn: {"authenticatorData":"UaQZ...","clientDataJson":"eyJ0...","credentialId":"Grf...","signature":"MEQ..."}` + @@ -75,14 +79,62 @@ To create a valid, Webauthn authenticator stamped request follow these steps: Our [JS SDK](https://github.com/tkhq/sdk) and [CLI](https://github.com/tkhq/tkcli) abstract request stamping for you. If you choose to use an independent client, you will need to implement this yourself. For reference, check out our implementations: - - - - - - - - + + + + + + + + Our CLI has a `--no-post` option to generate stamps without sending anything over the network. This is a useful tool should you have trouble with debugging stamping-related logic. A sample command might look something like: diff --git a/api-reference/queries/get-a-specific-boot-proof.mdx b/api-reference/queries/get-a-specific-boot-proof.mdx index 8e67da06..7c128088 100644 --- a/api-reference/queries/get-a-specific-boot-proof.mdx +++ b/api-reference/queries/get-a-specific-boot-proof.mdx @@ -17,16 +17,17 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Unique identifier for a given Organization. + Hex encoded ephemeral public key. - + - -A successful response returns the following fields: +A successful response returns the following +fields: bootProof field @@ -64,8 +65,14 @@ nanos field - -QOS manifest schema version. + + + QOS manifest schema version. diff --git a/api-reference/queries/get-activity.mdx b/api-reference/queries/get-activity.mdx index e093c5e6..f722bae5 100644 --- a/api-reference/queries/get-activity.mdx +++ b/api-reference/queries/get-activity.mdx @@ -17,16 +17,17 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Unique identifier for a given organization. + Unique identifier for a given activity object. - + - -A successful response returns the following fields: +A successful response returns the following +fields: activity field @@ -112,6 +113,7 @@ Enum options: `AUTHENTICATOR_TRANSPORT_BLE`, `AUTHENTICATOR_TRANSPORT_INTERNAL`, + authenticatorAttachment field @@ -121,6 +123,7 @@ Enum options: `cross-platform`, `platform` + clientExtensionResults field @@ -145,18 +148,31 @@ rk field - -Challenge presented for authentication purposes. + + + Challenge presented for authentication purposes. - -Unique identifier for the root user object. + + + Unique identifier for the root user object. + createAuthenticatorsIntent field @@ -211,6 +227,7 @@ Enum options: `AUTHENTICATOR_TRANSPORT_BLE`, `AUTHENTICATOR_TRANSPORT_INTERNAL`, + authenticatorAttachment field @@ -220,6 +237,7 @@ Enum options: `cross-platform`, `platform` + clientExtensionResults field @@ -244,18 +262,31 @@ rk field - -Challenge presented for authentication purposes. + + + Challenge presented for authentication purposes. - -Unique identifier for a given User. + + + Unique identifier for a given User. + createUsersIntent field @@ -289,6 +320,7 @@ Optional window (in seconds) indicating how long the API Key should last. + A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. @@ -340,6 +372,7 @@ Enum options: `AUTHENTICATOR_TRANSPORT_BLE`, `AUTHENTICATOR_TRANSPORT_INTERNAL`, + authenticatorAttachment field @@ -349,6 +382,7 @@ Enum options: `cross-platform`, `platform` + clientExtensionResults field @@ -373,12 +407,19 @@ rk field - -Challenge presented for authentication purposes. + + + Challenge presented for authentication purposes. + A list of User Tag IDs. This field, if not needed, should be an empty array in your request body. @@ -394,6 +435,7 @@ item field + createPrivateKeysIntent field @@ -418,6 +460,7 @@ item field + Cryptocurrency-specific formats for a derived address (e.g., Ethereum). @@ -436,6 +479,7 @@ Enum options: `ADDRESS_FORMAT_UNCOMPRESSED`, `ADDRESS_FORMAT_COMPRESSED`, `ADDRE + signRawPayloadIntent field @@ -460,6 +504,7 @@ Enum options: `HASH_FUNCTION_NO_OP`, `HASH_FUNCTION_SHA256`, `HASH_FUNCTION_KECC + createInvitationsIntent field @@ -481,6 +526,7 @@ item field + accessType field @@ -496,6 +542,7 @@ Unique identifier for the Sender of an Invitation. + acceptInvitationIntent field @@ -556,6 +603,7 @@ Enum options: `AUTHENTICATOR_TRANSPORT_BLE`, `AUTHENTICATOR_TRANSPORT_INTERNAL`, + authenticatorAttachment field @@ -565,6 +613,7 @@ Enum options: `cross-platform`, `platform` + clientExtensionResults field @@ -589,8 +638,14 @@ rk field - -Challenge presented for authentication purposes. + + + Challenge presented for authentication purposes. @@ -598,6 +653,7 @@ Challenge presented for authentication purposes. + createPolicyIntent field @@ -622,6 +678,7 @@ target field + effect field @@ -634,6 +691,7 @@ notes field + disablePrivateKeyIntent field @@ -643,6 +701,7 @@ Unique identifier for a given Private Key. + deleteUsersIntent field @@ -658,6 +717,7 @@ item field + deleteAuthenticatorsIntent field @@ -676,6 +736,7 @@ item field + deleteInvitationIntent field @@ -685,6 +746,7 @@ Unique identifier for a given Invitation object. + deleteOrganizationIntent field @@ -694,6 +756,7 @@ Unique identifier for a given Organization. + deletePolicyIntent field @@ -703,6 +766,7 @@ Unique identifier for a given Policy. + createUserTagIntent field @@ -721,6 +785,7 @@ item field + deleteUserTagsIntent field @@ -736,6 +801,7 @@ item field + signTransactionIntent field @@ -754,6 +820,7 @@ Enum options: `TRANSACTION_TYPE_ETHEREUM`, `TRANSACTION_TYPE_SOLANA`, `TRANSACTI + createApiKeysIntent field @@ -772,12 +839,19 @@ Optional window (in seconds) indicating how long the API Key should last. - -Unique identifier for a given User. + + + Unique identifier for a given User. + deleteApiKeysIntent field @@ -796,6 +870,7 @@ item field + approveActivityIntent field @@ -805,6 +880,7 @@ An artifact verifying a User's action. + rejectActivityIntent field @@ -814,6 +890,7 @@ An artifact verifying a User's action. + createPrivateKeyTagIntent field @@ -832,6 +909,7 @@ item field + deletePrivateKeyTagsIntent field @@ -847,6 +925,7 @@ item field + createPolicyIntentV2 field @@ -877,6 +956,7 @@ item field + effect field @@ -889,6 +969,7 @@ notes field + setPaymentMethodIntent field @@ -913,6 +994,7 @@ The name associated with the credit card. + activateBillingTierIntent field @@ -925,6 +1007,7 @@ orbPlanId field + deletePaymentMethodIntent field @@ -934,6 +1017,7 @@ The payment method that the customer wants to remove. + createPolicyIntentV3 field @@ -958,6 +1042,7 @@ Notes for a Policy. + createApiOnlyUsersIntent field @@ -979,6 +1064,7 @@ item field + A list of API Key parameters. This field, if not needed, should be an empty array in your request body. @@ -1000,6 +1086,7 @@ Optional window (in seconds) indicating how long the API Key should last. + updateRootQuorumIntent field @@ -1018,6 +1105,7 @@ item field + updateUserTagIntent field @@ -1036,6 +1124,7 @@ item field + A list of User IDs to remove this tag from. @@ -1048,6 +1137,7 @@ item field + updatePrivateKeyTagIntent field @@ -1066,6 +1156,7 @@ item field + A list of Private Key IDs to remove this tag from. @@ -1078,6 +1169,7 @@ item field + createAuthenticatorsIntentV2 field @@ -1120,12 +1212,19 @@ Enum options: `AUTHENTICATOR_TRANSPORT_BLE`, `AUTHENTICATOR_TRANSPORT_INTERNAL`, - -Unique identifier for a given User. + + + Unique identifier for a given User. + acceptInvitationIntentV2 field @@ -1177,6 +1276,7 @@ Enum options: `AUTHENTICATOR_TRANSPORT_BLE`, `AUTHENTICATOR_TRANSPORT_INTERNAL`, + createOrganizationIntentV2 field @@ -1225,12 +1325,19 @@ Enum options: `AUTHENTICATOR_TRANSPORT_BLE`, `AUTHENTICATOR_TRANSPORT_INTERNAL`, - -Unique identifier for the root user object. + + + Unique identifier for the root user object. + createUsersIntentV2 field @@ -1258,6 +1365,7 @@ Optional window (in seconds) indicating how long the API Key should last. + A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. @@ -1297,6 +1405,7 @@ Enum options: `AUTHENTICATOR_TRANSPORT_BLE`, `AUTHENTICATOR_TRANSPORT_INTERNAL`, + A list of User Tag IDs. This field, if not needed, should be an empty array in your request body. @@ -1312,6 +1421,7 @@ item field + createSubOrganizationIntent field @@ -1360,6 +1470,7 @@ Enum options: `AUTHENTICATOR_TRANSPORT_BLE`, `AUTHENTICATOR_TRANSPORT_INTERNAL`, + createSubOrganizationIntentV2 field @@ -1390,6 +1501,7 @@ Optional window (in seconds) indicating how long the API Key should last. + A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. @@ -1432,12 +1544,20 @@ Enum options: `AUTHENTICATOR_TRANSPORT_BLE`, `AUTHENTICATOR_TRANSPORT_INTERNAL`, - -The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users + + + The threshold of unique approvals to reach root quorum. This value must be + less than or equal to the number of root users + updateAllowedOriginsIntent field @@ -1453,6 +1573,7 @@ item field + createPrivateKeysIntentV2 field @@ -1477,6 +1598,7 @@ item field + Cryptocurrency-specific formats for a derived address (e.g., Ethereum). @@ -1495,6 +1617,7 @@ Enum options: `ADDRESS_FORMAT_UNCOMPRESSED`, `ADDRESS_FORMAT_COMPRESSED`, `ADDRE + updateUserIntent field @@ -1516,12 +1639,19 @@ item field - -The user's phone number in E.164 format e.g. +13214567890 + + + The user's phone number in E.164 format e.g. +13214567890 + updatePolicyIntent field @@ -1549,6 +1679,7 @@ Accompanying notes for a Policy (optional). + setPaymentMethodIntentV2 field @@ -1564,6 +1695,7 @@ The name associated with the credit card. + createSubOrganizationIntentV3 field @@ -1594,6 +1726,7 @@ Optional window (in seconds) indicating how long the API Key should last. + A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. @@ -1636,6 +1769,7 @@ Enum options: `AUTHENTICATOR_TRANSPORT_BLE`, `AUTHENTICATOR_TRANSPORT_INTERNAL`, + The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users @@ -1660,6 +1794,7 @@ item field + Cryptocurrency-specific formats for a derived address (e.g., Ethereum). @@ -1678,6 +1813,7 @@ Enum options: `ADDRESS_FORMAT_UNCOMPRESSED`, `ADDRESS_FORMAT_COMPRESSED`, `ADDRE + createWalletIntent field @@ -1711,12 +1847,20 @@ Enum options: `ADDRESS_FORMAT_UNCOMPRESSED`, `ADDRESS_FORMAT_COMPRESSED`, `ADDRE - -Length of mnemonic to generate the Wallet seed. Defaults to 12. Accepted values: 12, 15, 18, 21, 24. + + + Length of mnemonic to generate the Wallet seed. Defaults to 12. Accepted + values: 12, 15, 18, 21, 24. + createWalletAccountsIntent field @@ -1750,12 +1894,21 @@ Enum options: `ADDRESS_FORMAT_UNCOMPRESSED`, `ADDRESS_FORMAT_COMPRESSED`, `ADDRE - -Indicates if the wallet accounts should be persisted. This is helpful if you'd like to see the addresses of different derivation paths without actually creating the accounts. Defaults to true. + + + Indicates if the wallet accounts should be persisted. This is helpful if you'd + like to see the addresses of different derivation paths without actually + creating the accounts. Defaults to true. + initUserEmailRecoveryIntent field @@ -1789,18 +1942,36 @@ Unique identifier for a given Email Template. If not specified, the default is t - -Optional custom email address from which to send the OTP email + + + Optional custom email address from which to send the OTP email - -Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications' + + Optional custom sender name for use with sendFromEmailAddress; if left empty, + will default to 'Notifications' - -Optional custom email address to use as reply-to + + Optional custom email address to use as reply-to + recoverUserIntent field @@ -1843,12 +2014,19 @@ Enum options: `AUTHENTICATOR_TRANSPORT_BLE`, `AUTHENTICATOR_TRANSPORT_INTERNAL`, - -Unique identifier for the user performing recovery. + + + Unique identifier for the user performing recovery. + setOrganizationFeatureIntent field @@ -1864,6 +2042,7 @@ Optional value for the feature. Will override existing values if feature is alre + removeOrganizationFeatureIntent field @@ -1876,6 +2055,7 @@ Enum options: `FEATURE_NAME_ROOT_USER_EMAIL_RECOVERY`, `FEATURE_NAME_WEBAUTHN_OR + signRawPayloadIntentV2 field @@ -1900,6 +2080,7 @@ Enum options: `HASH_FUNCTION_NO_OP`, `HASH_FUNCTION_SHA256`, `HASH_FUNCTION_KECC + signTransactionIntentV2 field @@ -1918,6 +2099,7 @@ Enum options: `TRANSACTION_TYPE_ETHEREUM`, `TRANSACTION_TYPE_SOLANA`, `TRANSACTI + exportPrivateKeyIntent field @@ -1930,6 +2112,7 @@ Client-side public key generated by the user, to which the export bundle will be + exportWalletIntent field @@ -1948,6 +2131,7 @@ Enum options: `MNEMONIC_LANGUAGE_ENGLISH`, `MNEMONIC_LANGUAGE_SIMPLIFIED_CHINESE + createSubOrganizationIntentV4 field @@ -1978,6 +2162,7 @@ Optional window (in seconds) indicating how long the API Key should last. + A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. @@ -2020,6 +2205,7 @@ Enum options: `AUTHENTICATOR_TRANSPORT_BLE`, `AUTHENTICATOR_TRANSPORT_INTERNAL`, + The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users @@ -2056,21 +2242,40 @@ Enum options: `ADDRESS_FORMAT_UNCOMPRESSED`, `ADDRESS_FORMAT_COMPRESSED`, `ADDRE - -Length of mnemonic to generate the Wallet seed. Defaults to 12. Accepted values: 12, 15, 18, 21, 24. + + + Length of mnemonic to generate the Wallet seed. Defaults to 12. Accepted + values: 12, 15, 18, 21, 24. - -Disable email recovery for the sub-organization + + + Disable email recovery for the sub-organization - -Disable email auth for the sub-organization + + Disable email auth for the sub-organization + emailAuthIntent field @@ -2107,21 +2312,44 @@ Unique identifier for a given Email Template. If not specified, the default is t - -Invalidate all other previously generated Email Auth API keys + + + Invalidate all other previously generated Email Auth API keys - -Optional custom email address from which to send the email + + Optional custom email address from which to send the email - -Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications' + + Optional custom sender name for use with sendFromEmailAddress; if left empty, + will default to 'Notifications' - -Optional custom email address to use as reply-to + + Optional custom email address to use as reply-to + exportWalletAccountIntent field @@ -2134,6 +2362,7 @@ Client-side public key generated by the user, to which the export bundle will be + initImportWalletIntent field @@ -2143,6 +2372,7 @@ The ID of the User importing a Wallet. + importWalletIntent field @@ -2185,6 +2415,7 @@ Enum options: `ADDRESS_FORMAT_UNCOMPRESSED`, `ADDRESS_FORMAT_COMPRESSED`, `ADDRE + initImportPrivateKeyIntent field @@ -2194,6 +2425,7 @@ The ID of the User importing a Private Key. + importPrivateKeyIntent field @@ -2227,6 +2459,7 @@ Enum options: `ADDRESS_FORMAT_UNCOMPRESSED`, `ADDRESS_FORMAT_COMPRESSED`, `ADDRE + createPoliciesIntent field @@ -2257,6 +2490,7 @@ Notes for a Policy. + signRawPayloadsIntent field @@ -2272,6 +2506,7 @@ item field + encoding field @@ -2287,6 +2522,7 @@ Enum options: `HASH_FUNCTION_NO_OP`, `HASH_FUNCTION_SHA256`, `HASH_FUNCTION_KECC + createReadOnlySessionIntent field @@ -2311,6 +2547,7 @@ Base64 encoded OIDC token + deleteOauthProvidersIntent field @@ -2329,6 +2566,7 @@ item field + createSubOrganizationIntentV5 field @@ -2359,6 +2597,7 @@ Optional window (in seconds) indicating how long the API Key should last. + A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. @@ -2398,6 +2637,7 @@ Enum options: `AUTHENTICATOR_TRANSPORT_BLE`, `AUTHENTICATOR_TRANSPORT_INTERNAL`, + A list of Oauth providers. This field, if not needed, should be an empty array in your request body. @@ -2413,6 +2653,7 @@ Base64 encoded OIDC token + The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users @@ -2449,21 +2690,40 @@ Enum options: `ADDRESS_FORMAT_UNCOMPRESSED`, `ADDRESS_FORMAT_COMPRESSED`, `ADDRE - -Length of mnemonic to generate the Wallet seed. Defaults to 12. Accepted values: 12, 15, 18, 21, 24. + + + Length of mnemonic to generate the Wallet seed. Defaults to 12. Accepted + values: 12, 15, 18, 21, 24. - -Disable email recovery for the sub-organization + + + Disable email recovery for the sub-organization - -Disable email auth for the sub-organization + + Disable email auth for the sub-organization + oauthIntent field @@ -2485,6 +2745,7 @@ Invalidate all other previously generated Oauth API keys + createApiKeysIntentV2 field @@ -2509,12 +2770,19 @@ Optional window (in seconds) indicating how long the API Key should last. - -Unique identifier for a given User. + + + Unique identifier for a given User. + createReadWriteSessionIntent field @@ -2533,6 +2801,7 @@ Expiration window (in seconds) indicating how long the API key is valid for. If + emailAuthIntentV2 field @@ -2569,21 +2838,44 @@ Unique identifier for a given Email Template. If not specified, the default is t - -Invalidate all other previously generated Email Auth API keys + + + Invalidate all other previously generated Email Auth API keys - -Optional custom email address from which to send the email + + Optional custom email address from which to send the email - -Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications' + + Optional custom sender name for use with sendFromEmailAddress; if left empty, + will default to 'Notifications' - -Optional custom email address to use as reply-to + + Optional custom email address to use as reply-to + createSubOrganizationIntentV6 field @@ -2620,6 +2912,7 @@ Optional window (in seconds) indicating how long the API Key should last. + A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. @@ -2659,6 +2952,7 @@ Enum options: `AUTHENTICATOR_TRANSPORT_BLE`, `AUTHENTICATOR_TRANSPORT_INTERNAL`, + A list of Oauth providers. This field, if not needed, should be an empty array in your request body. @@ -2674,6 +2968,7 @@ Base64 encoded OIDC token + The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users @@ -2710,21 +3005,40 @@ Enum options: `ADDRESS_FORMAT_UNCOMPRESSED`, `ADDRESS_FORMAT_COMPRESSED`, `ADDRE - -Length of mnemonic to generate the Wallet seed. Defaults to 12. Accepted values: 12, 15, 18, 21, 24. + + + Length of mnemonic to generate the Wallet seed. Defaults to 12. Accepted + values: 12, 15, 18, 21, 24. - -Disable email recovery for the sub-organization + + + Disable email recovery for the sub-organization - -Disable email auth for the sub-organization + + Disable email auth for the sub-organization + deletePrivateKeysIntent field @@ -2737,12 +3051,20 @@ item field - -Optional parameter for deleting the private keys, even if any have not been previously exported. If they have been exported, this field is ignored. + + + Optional parameter for deleting the private keys, even if any have not been + previously exported. If they have been exported, this field is ignored. + deleteWalletsIntent field @@ -2755,12 +3077,20 @@ item field - -Optional parameter for deleting the wallets, even if any have not been previously exported. If they have been exported, this field is ignored. + + + Optional parameter for deleting the wallets, even if any have not been + previously exported. If they have been exported, this field is ignored. + createReadWriteSessionIntentV2 field @@ -2782,6 +3112,7 @@ Invalidate all other previously generated ReadWriteSession API keys + deleteSubOrganizationIntent field @@ -2791,6 +3122,7 @@ Sub-organization deletion, by default, requires associated wallets and private k + initOtpAuthIntent field @@ -2821,6 +3153,7 @@ Unique identifier for a given Email Template. If not specified, the default is t + smsCustomization field @@ -2830,21 +3163,45 @@ Template containing references to .OtpCode i.e Your OTP is \{\{.OtpCode\}\} - -Optional client-generated user identifier to enable per-user rate limiting for SMS auth. We recommend using a hash of the client-side IP address. + + + Optional client-generated user identifier to enable per-user rate limiting for + SMS auth. We recommend using a hash of the client-side IP address. - -Optional custom email address from which to send the OTP email + + Optional custom email address from which to send the OTP email - -Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications' + + Optional custom sender name for use with sendFromEmailAddress; if left empty, + will default to 'Notifications' - -Optional custom email address to use as reply-to + + Optional custom email address to use as reply-to + otpAuthIntent field @@ -2869,6 +3226,7 @@ Invalidate all other previously generated OTP Auth API keys + createSubOrganizationIntentV7 field @@ -2908,6 +3266,7 @@ Optional window (in seconds) indicating how long the API Key should last. + A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. @@ -2947,6 +3306,7 @@ Enum options: `AUTHENTICATOR_TRANSPORT_BLE`, `AUTHENTICATOR_TRANSPORT_INTERNAL`, + A list of Oauth providers. This field, if not needed, should be an empty array in your request body. @@ -2962,6 +3322,7 @@ Base64 encoded OIDC token + The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users @@ -2998,12 +3359,20 @@ Enum options: `ADDRESS_FORMAT_UNCOMPRESSED`, `ADDRESS_FORMAT_COMPRESSED`, `ADDRE - -Length of mnemonic to generate the Wallet seed. Defaults to 12. Accepted values: 12, 15, 18, 21, 24. + + + Length of mnemonic to generate the Wallet seed. Defaults to 12. Accepted + values: 12, 15, 18, 21, 24. + Disable email recovery for the sub-organization @@ -3043,6 +3412,7 @@ The cryptographic signature over the message. + updateWalletIntent field @@ -3055,6 +3425,7 @@ Human-readable name for a Wallet. + updatePolicyIntentV2 field @@ -3082,6 +3453,7 @@ Accompanying notes for a Policy (optional). + createUsersIntentV3 field @@ -3118,6 +3490,7 @@ Optional window (in seconds) indicating how long the API Key should last. + A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. @@ -3157,6 +3530,7 @@ Enum options: `AUTHENTICATOR_TRANSPORT_BLE`, `AUTHENTICATOR_TRANSPORT_INTERNAL`, + A list of Oauth providers. This field, if not needed, should be an empty array in your request body. @@ -3169,6 +3543,7 @@ Base64 encoded OIDC token + A list of User Tag IDs. This field, if not needed, should be an empty array in your request body. @@ -3184,6 +3559,7 @@ item field + initOtpAuthIntentV2 field @@ -3217,6 +3593,7 @@ Unique identifier for a given Email Template. If not specified, the default is t + smsCustomization field @@ -3226,24 +3603,54 @@ Template containing references to .OtpCode i.e Your OTP is \{\{.OtpCode\}\} - -Optional client-generated user identifier to enable per-user rate limiting for SMS auth. We recommend using a hash of the client-side IP address. + + + Optional client-generated user identifier to enable per-user rate limiting for + SMS auth. We recommend using a hash of the client-side IP address. - -Optional custom email address from which to send the OTP email + + Optional custom email address from which to send the OTP email - -Optional flag to specify if the OTP code should be alphanumeric (Crockford’s Base32). Default = true + + Optional flag to specify if the OTP code should be alphanumeric (Crockford’s + Base32). Default = true - -Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications' + + Optional custom sender name for use with sendFromEmailAddress; if left empty, + will default to 'Notifications' - -Optional custom email address to use as reply-to + + Optional custom email address to use as reply-to + initOtpIntent field @@ -3277,6 +3684,7 @@ Unique identifier for a given Email Template. If not specified, the default is t + smsCustomization field @@ -3286,27 +3694,64 @@ Template containing references to .OtpCode i.e Your OTP is \{\{.OtpCode\}\} - -Optional client-generated user identifier to enable per-user rate limiting for SMS auth. We recommend using a hash of the client-side IP address. + + + Optional client-generated user identifier to enable per-user rate limiting for + SMS auth. We recommend using a hash of the client-side IP address. - -Optional custom email address from which to send the OTP email + + Optional custom email address from which to send the OTP email - -Optional flag to specify if the OTP code should be alphanumeric (Crockford’s Base32). Default = true + + Optional flag to specify if the OTP code should be alphanumeric (Crockford’s + Base32). Default = true - -Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications' + + Optional custom sender name for use with sendFromEmailAddress; if left empty, + will default to 'Notifications' - -Expiration window (in seconds) indicating how long the OTP is valid for. If not provided, a default of 5 minutes will be used. Maximum value is 600 seconds (10 minutes) + + Expiration window (in seconds) indicating how long the OTP is valid for. If + not provided, a default of 5 minutes will be used. Maximum value is 600 + seconds (10 minutes) - -Optional custom email address to use as reply-to + + Optional custom email address to use as reply-to + verifyOtpIntent field @@ -3325,6 +3770,7 @@ Client-side public key generated by the user, which will be added to the JWT res + otpLoginIntent field @@ -3364,6 +3810,7 @@ The cryptographic signature over the message. + stampLoginIntent field @@ -3379,6 +3826,7 @@ Invalidate all other previously generated Login API keys + oauthLoginIntent field @@ -3397,6 +3845,7 @@ Invalidate all other previously generated Login API keys + updateUserNameIntent field @@ -3409,6 +3858,7 @@ Human-readable name for a User. + updateUserEmailIntent field @@ -3424,6 +3874,7 @@ Signed JWT containing a unique id, expiry, verification type, contact + updateUserPhoneNumberIntent field @@ -3439,6 +3890,7 @@ Signed JWT containing a unique id, expiry, verification type, contact + initFiatOnRampIntent field @@ -3493,6 +3945,7 @@ Optional MoonPay Widget URL to sign when using MoonPay client SDKs with URL Sign + createSmartContractInterfaceIntent field @@ -3517,6 +3970,7 @@ Notes for a Smart Contract Interface. + deleteSmartContractInterfaceIntent field @@ -3526,6 +3980,7 @@ The ID of a Smart Contract Interface intended for deletion. + enableAuthProxyIntent field @@ -3544,6 +3999,7 @@ item field + Updated list of allowed proxy authentication methods. @@ -3553,6 +4009,7 @@ item field + Custom 'from' address for auth-related emails. @@ -3586,6 +4043,7 @@ Unique identifier for a given Email Template. If not specified, the default is t + smsCustomizationParams field @@ -3595,6 +4053,7 @@ Template containing references to .OtpCode i.e Your OTP is \{\{.OtpCode\}\} + walletKitSettings field @@ -3607,15 +4066,27 @@ item field - -Mapping of social login providers to their Oauth client IDs. + + + Mapping of social login providers to their Oauth client IDs. - -Oauth redirect URL to be used for social login flows. + + Oauth redirect URL to be used for social login flows. + OTP code lifetime in seconds. @@ -3649,6 +4120,7 @@ item field + createOauth2CredentialIntent field @@ -3667,6 +4139,7 @@ The client secret issued by the OAuth 2.0 provider encrypted to the TLS Fetcher + updateOauth2CredentialIntent field @@ -3688,6 +4161,7 @@ The client secret issued by the OAuth 2.0 provider encrypted to the TLS Fetcher + deleteOauth2CredentialIntent field @@ -3697,6 +4171,7 @@ The ID of the OAuth 2.0 credential to delete + oauth2AuthenticateIntent field @@ -3721,6 +4196,7 @@ An optional P256 public key to which, if provided, the bearer token will be encr + deleteWalletAccountsIntent field @@ -3733,12 +4209,20 @@ item field - -Optional parameter for deleting the wallet accounts, even if any have not been previously exported. If they have been exported, this field is ignored. + + + Optional parameter for deleting the wallet accounts, even if any have not been + previously exported. If they have been exported, this field is ignored. + deletePoliciesIntent field @@ -3754,6 +4238,7 @@ item field + ethSendRawTransactionIntent field @@ -3769,6 +4254,7 @@ Enum options: `eip155:1`, `eip155:11155111`, `eip155:8453`, `eip155:84532`, `eip + ethSendTransactionIntent field @@ -3814,6 +4300,7 @@ The gas station delegate contract nonce. Only used when sponsor=true. Include th + createFiatOnRampCredentialIntent field @@ -3841,6 +4328,7 @@ If the on-ramp credential is a sandbox credential + updateFiatOnRampCredentialIntent field @@ -3868,6 +4356,7 @@ Private API key for the on-ramp provider encrypted to our on-ramp encryption pub + deleteFiatOnRampCredentialIntent field @@ -3877,6 +4366,7 @@ The ID of the fiat on-ramp credential to delete + emailAuthIntentV3 field @@ -3913,21 +4403,44 @@ Unique identifier for a given Email Template. If not specified, the default is t - -Invalidate all other previously generated Email Auth API keys + + + Invalidate all other previously generated Email Auth API keys - -Optional custom email address from which to send the email + + Optional custom email address from which to send the email - -Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications' + + Optional custom sender name for use with sendFromEmailAddress; if left empty, + will default to 'Notifications' - -Optional custom email address to use as reply-to + + Optional custom email address to use as reply-to + initUserEmailRecoveryIntentV2 field @@ -3961,18 +4474,36 @@ Unique identifier for a given Email Template. If not specified, the default is t - -Optional custom email address from which to send the OTP email + + + Optional custom email address from which to send the OTP email - -Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications' + + Optional custom sender name for use with sendFromEmailAddress; if left empty, + will default to 'Notifications' - -Optional custom email address to use as reply-to + + Optional custom email address to use as reply-to + initOtpIntentV2 field @@ -4006,6 +4537,7 @@ Unique identifier for a given Email Template. If not specified, the default is t + smsCustomization field @@ -4015,27 +4547,64 @@ Template containing references to .OtpCode i.e Your OTP is \{\{.OtpCode\}\} - -Optional client-generated user identifier to enable per-user rate limiting for SMS auth. We recommend using a hash of the client-side IP address. + + + Optional client-generated user identifier to enable per-user rate limiting for + SMS auth. We recommend using a hash of the client-side IP address. - -Optional custom email address from which to send the OTP email + + Optional custom email address from which to send the OTP email - -Optional flag to specify if the OTP code should be alphanumeric (Crockford’s Base32). Default = true + + Optional flag to specify if the OTP code should be alphanumeric (Crockford’s + Base32). Default = true - -Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications' + + Optional custom sender name for use with sendFromEmailAddress; if left empty, + will default to 'Notifications' - -Expiration window (in seconds) indicating how long the OTP is valid for. If not provided, a default of 5 minutes will be used. Maximum value is 600 seconds (10 minutes) + + Expiration window (in seconds) indicating how long the OTP is valid for. If + not provided, a default of 5 minutes will be used. Maximum value is 600 + seconds (10 minutes) - -Optional custom email address to use as reply-to + + Optional custom email address to use as reply-to + initOtpAuthIntentV3 field @@ -4069,6 +4638,7 @@ Unique identifier for a given Email Template. If not specified, the default is t + smsCustomization field @@ -4078,27 +4648,64 @@ Template containing references to .OtpCode i.e Your OTP is \{\{.OtpCode\}\} - -Optional client-generated user identifier to enable per-user rate limiting for SMS auth. We recommend using a hash of the client-side IP address. + + + Optional client-generated user identifier to enable per-user rate limiting for + SMS auth. We recommend using a hash of the client-side IP address. - -Optional custom email address from which to send the OTP email + + Optional custom email address from which to send the OTP email - -Optional flag to specify if the OTP code should be alphanumeric (Crockford’s Base32). Default = true + + Optional flag to specify if the OTP code should be alphanumeric (Crockford’s + Base32). Default = true - -Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications' + + Optional custom sender name for use with sendFromEmailAddress; if left empty, + will default to 'Notifications' - -Expiration window (in seconds) indicating how long the OTP is valid for. If not provided, a default of 5 minutes will be used. Maximum value is 600 seconds (10 minutes) + + Expiration window (in seconds) indicating how long the OTP is valid for. If + not provided, a default of 5 minutes will be used. Maximum value is 600 + seconds (10 minutes) - -Optional custom email address to use as reply-to + + Optional custom email address to use as reply-to + upsertGasUsageConfigIntent field @@ -4126,6 +4733,7 @@ Whether Solana rent prefunding is enabled for the organization. When omitted, th + createTvcAppIntent field @@ -4156,6 +4764,7 @@ Public key for this operator + Existing operators to use as part of this new operator set @@ -4165,12 +4774,19 @@ item field - -The threshold of operators needed to reach consensus in this new Operator Set + + + The threshold of operators needed to reach consensus in this new Operator Set + Unique identifier for an existing TVC operator set to use as the Share Set for this TVC application. If left empty, a new Share Set configuration is required @@ -4192,6 +4808,7 @@ Public key for this operator + Existing operators to use as part of this new operator set @@ -4201,18 +4818,31 @@ item field - -The threshold of operators needed to reach consensus in this new Operator Set + + + The threshold of operators needed to reach consensus in this new Operator Set - -Enables network egress for this TVC app. Default if not provided: false. + + + Enables network egress for this TVC app. Default if not provided: false. + createTvcDeploymentIntent field @@ -4237,6 +4867,7 @@ item field + Digest of the pivot binary in the pivot container. This value will be inserted in the QOS manifest to ensure application integrity. @@ -4264,6 +4895,7 @@ Port to use for public ingress. + createTvcManifestApprovalsIntent field @@ -4285,6 +4917,7 @@ Signature from the operator approving the manifest + solSendTransactionIntent field @@ -4309,6 +4942,7 @@ user-provided blockhash for replay protection / deadline control. If omitted and + initOtpIntentV3 field @@ -4342,6 +4976,7 @@ Unique identifier for a given Email Template. If not specified, the default is t + smsCustomization field @@ -4351,27 +4986,64 @@ Template containing references to .OtpCode i.e Your OTP is \{\{.OtpCode\}\} - -Optional client-generated user identifier to enable per-user rate limiting for SMS auth. We recommend using a hash of the client-side IP address. + + + Optional client-generated user identifier to enable per-user rate limiting for + SMS auth. We recommend using a hash of the client-side IP address. - -Optional custom email address from which to send the OTP email + + Optional custom email address from which to send the OTP email - -Optional flag to specify if the OTP code should be alphanumeric (Crockford’s Base32). If set to false, OTP code will only be numeric. Default = true + + Optional flag to specify if the OTP code should be alphanumeric (Crockford’s + Base32). If set to false, OTP code will only be numeric. Default = true - -Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications' + + Optional custom sender name for use with sendFromEmailAddress; if left empty, + will default to 'Notifications' - -Expiration window (in seconds) indicating how long the OTP is valid for. If not provided, a default of 5 minutes will be used. Maximum value is 600 seconds (10 minutes) + + Expiration window (in seconds) indicating how long the OTP is valid for. If + not provided, a default of 5 minutes will be used. Maximum value is 600 + seconds (10 minutes) - -Optional custom email address to use as reply-to + + Optional custom email address to use as reply-to + verifyOtpIntentV2 field @@ -4387,6 +5059,7 @@ Expiration window (in seconds) indicating how long the verification token is val + otpLoginIntentV2 field @@ -4417,15 +5090,28 @@ The cryptographic signature over the message. - -Expiration window (in seconds) indicating how long the Session is valid for. If not provided, a default of 15 minutes will be used. + + + Expiration window (in seconds) indicating how long the Session is valid for. + If not provided, a default of 15 minutes will be used. - -Invalidate all other previously generated Login sessions + + Invalidate all other previously generated Login sessions + updateOrganizationNameIntent field @@ -4435,6 +5121,7 @@ New name for the Organization. + createSubOrganizationIntentV8 field @@ -4474,6 +5161,7 @@ Optional window (in seconds) indicating how long the API Key should last. + A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. @@ -4513,6 +5201,7 @@ Enum options: `AUTHENTICATOR_TRANSPORT_BLE`, `AUTHENTICATOR_TRANSPORT_INTERNAL`, + A list of Oauth providers. This field, if not needed, should be an empty array in your request body. @@ -4543,6 +5232,7 @@ The audience from the OIDC token (aud claim) + The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users @@ -4579,12 +5269,20 @@ Enum options: `ADDRESS_FORMAT_UNCOMPRESSED`, `ADDRESS_FORMAT_COMPRESSED`, `ADDRE - -Length of mnemonic to generate the Wallet seed. Defaults to 12. Accepted values: 12, 15, 18, 21, 24. + + + Length of mnemonic to generate the Wallet seed. Defaults to 12. Accepted + values: 12, 15, 18, 21, 24. + Disable email recovery for the sub-organization @@ -4624,6 +5322,7 @@ The cryptographic signature over the message. + createOauthProvidersIntentV2 field @@ -4660,6 +5359,7 @@ The audience from the OIDC token (aud claim) + createUsersIntentV4 field @@ -4696,6 +5396,7 @@ Optional window (in seconds) indicating how long the API Key should last. + A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. @@ -4735,6 +5436,7 @@ Enum options: `AUTHENTICATOR_TRANSPORT_BLE`, `AUTHENTICATOR_TRANSPORT_INTERNAL`, + A list of Oauth providers. This field, if not needed, should be an empty array in your request body. @@ -4762,6 +5464,7 @@ The audience from the OIDC token (aud claim) + A list of User Tag IDs. This field, if not needed, should be an empty array in your request body. @@ -4777,6 +5480,7 @@ item field + createWebhookEndpointIntent field @@ -4804,6 +5508,7 @@ Whether this subscription is active. + updateWebhookEndpointIntent field @@ -4822,6 +5527,7 @@ Whether this webhook endpoint is active. + deleteWebhookEndpointIntent field @@ -4831,6 +5537,7 @@ Unique identifier of the webhook endpoint to delete. + setIpAllowlistIntent field @@ -4852,12 +5559,20 @@ Optional human-readable label for this rule (e.g., 'Office VPN'). - -Behavior when an error occurs during IP allowlist evaluation. Valid values: ALLOW, DENY. Defaults to DENY. + + + Behavior when an error occurs during IP allowlist evaluation. Valid values: + ALLOW, DENY. Defaults to DENY. + removeIpAllowlistIntent field @@ -4867,6 +5582,7 @@ The public component of an API key. If null, removes the organization-level IP a + updateTvcAppLiveDeploymentIntent field @@ -4876,6 +5592,7 @@ The unique identifier of the TVC deployment to set as live for the app. + deleteTvcDeploymentIntent field @@ -4885,6 +5602,7 @@ The unique identifier of the TVC deployment to delete. + deleteTvcAppAndDeploymentsIntent field @@ -4894,6 +5612,7 @@ The unique identifier of the TVC app to delete. The app and all associated deplo + restoreTvcDeploymentIntent field @@ -4903,6 +5622,7 @@ The unique identifier of the TVC deployment to restore. + sparkSignFrostIntent field @@ -4927,6 +5647,7 @@ Unique identifier for the Spark signing leaf. + deposit field @@ -4939,12 +5660,19 @@ Index used to derive the static deposit key. - -htlcPreimage field + + + htlcPreimage field + Hex-encoded 32-byte sighash to sign. @@ -4966,8 +5694,21 @@ Binding commitment E, hex-encoded compressed secp256k1 point. - -Optional adaptor point T (hex-encoded 33-byte compressed secp256k1 pubkey). When set, Turnkey produces a Schnorr adaptor pre-signature with the FROST challenge bound to `R+T` (where `R` is the aggregate group nonce commitment from FROST). The party holding the discrete log `t` completes the pre-sig to a valid BIP-340 signature by adding `t` (or `-t`, for parity) to the signature scalar `s`. This is primarily used by Spark leaves-swap and other adaptor-bound flows; absent or empty leads to plain FROST signing (the typical case). + + + Optional adaptor point T (hex-encoded 33-byte compressed secp256k1 pubkey). + When set, Turnkey produces a Schnorr adaptor pre-signature with the FROST + challenge bound to `R+T` (where `R` is the aggregate group nonce commitment + from FROST). The party holding the discrete log `t` completes the pre-sig to a + valid BIP-340 signature by adding `t` (or `-t`, for parity) to the signature + scalar `s`. This is primarily used by Spark leaves-swap and other + adaptor-bound flows; absent or empty leads to plain FROST signing (the typical + case). @@ -4975,6 +5716,7 @@ Optional adaptor point T (hex-encoded 33-byte compressed secp256k1 pubkey). When + sparkPrepareTransferIntent field @@ -5008,6 +5750,7 @@ Unique identifier for the Spark signing leaf. + deposit field @@ -5020,12 +5763,19 @@ Index used to derive the static deposit key. - -htlcPreimage field + + + htlcPreimage field + newLeafDerivation field @@ -5041,6 +5791,7 @@ Unique identifier for the Spark signing leaf. + deposit field @@ -5053,24 +5804,51 @@ Index used to derive the static deposit key. - -htlcPreimage field + + + htlcPreimage field - -Client-produced CPFP refund signature (hex-encoded), passed through verbatim into the per-operator SendLeafKeyTweak. Empty omits the field from the operator package. + + + Client-produced CPFP refund signature (hex-encoded), passed through verbatim + into the per-operator SendLeafKeyTweak. Empty omits the field from the + operator package. - -Client-produced direct refund signature (hex-encoded). Passed through verbatim. + + Client-produced direct refund signature (hex-encoded). Passed through + verbatim. - -Client-produced direct-from-CPFP refund signature (hex-encoded). Passed through verbatim. + + Client-produced direct-from-CPFP refund signature (hex-encoded). Passed + through verbatim. + Feldman VSS threshold for reconstructing the per-leaf tweak scalar. @@ -5086,8 +5864,16 @@ Operator's ECIES encryption pubkey (hex-encoded compressed secp256k1 point). - -Recipient's identity pubkey (hex-encoded compressed secp256k1 point). Each leaf's new_priv is ECIES-encrypted to this key and embedded in the per-operator package for claim-time delivery. + + + Recipient's identity pubkey (hex-encoded compressed secp256k1 point). Each + leaf's new_priv is ECIES-encrypted to this key and embedded in the + per-operator package for claim-time delivery. @@ -5095,6 +5881,7 @@ Recipient's identity pubkey (hex-encoded compressed secp256k1 point). Each leaf' + sparkClaimTransferIntent field @@ -5119,6 +5906,7 @@ Hex-encoded 64-byte compact ECDSA signature binding (leaf_id, transfer_id, ciphe + Shamir threshold for reconstructing the per-leaf claim secret. @@ -5134,11 +5922,24 @@ Operator's ECIES encryption pubkey (hex-encoded compressed secp256k1 point). - -Spark transfer identifier (UUID). Used together with each leaf's sender_signature to verify the sender bound this ciphertext to this transfer. + + + Spark transfer identifier (UUID). Used together with each leaf's + sender_signature to verify the sender bound this ciphertext to this transfer. - -Sender's compressed secp256k1 identity public key (hex-encoded, 33 bytes). Used to verify the per-leaf sender_signature fields. + + Sender's compressed secp256k1 identity public key (hex-encoded, 33 bytes). + Used to verify the per-leaf sender_signature fields. @@ -5146,6 +5947,7 @@ Sender's compressed secp256k1 identity public key (hex-encoded, 33 bytes). Used + sparkPrepareLightningReceiveIntent field @@ -5176,6 +5978,7 @@ Operator's ECIES encryption pubkey (hex-encoded compressed secp256k1 point). + postTvcQuorumKeyShareIntent field @@ -5206,6 +6009,7 @@ Signature from the share set operator approving the manifest + result field @@ -5218,6 +6022,7 @@ Unique identifier for a given Organization. + createAuthenticatorsResult field @@ -5233,6 +6038,7 @@ item field + createUsersResult field @@ -5248,6 +6054,7 @@ item field + createPrivateKeysResult field @@ -5263,6 +6070,7 @@ item field + createInvitationsResult field @@ -5278,6 +6086,7 @@ item field + acceptInvitationResult field @@ -5290,6 +6099,7 @@ Unique identifier for a given User. + signRawPayloadResult field @@ -5305,6 +6115,7 @@ Component of an ECSDA signature. + createPolicyResult field @@ -5314,6 +6125,7 @@ Unique identifier for a given Policy. + disablePrivateKeyResult field @@ -5323,6 +6135,7 @@ Unique identifier for a given Private Key. + deleteUsersResult field @@ -5338,6 +6151,7 @@ item field + deleteAuthenticatorsResult field @@ -5353,6 +6167,7 @@ item field + deleteInvitationResult field @@ -5362,6 +6177,7 @@ Unique identifier for a given Invitation. + deleteOrganizationResult field @@ -5371,6 +6187,7 @@ Unique identifier for a given Organization. + deletePolicyResult field @@ -5380,6 +6197,7 @@ Unique identifier for a given Policy. + createUserTagResult field @@ -5398,6 +6216,7 @@ item field + deleteUserTagsResult field @@ -5410,6 +6229,7 @@ item field + A list of User IDs. @@ -5422,6 +6242,7 @@ item field + signTransactionResult field @@ -5431,6 +6252,7 @@ signedTransaction field + deleteApiKeysResult field @@ -5446,6 +6268,7 @@ item field + createApiKeysResult field @@ -5461,6 +6284,7 @@ item field + createPrivateKeyTagResult field @@ -5479,6 +6303,7 @@ item field + deletePrivateKeyTagsResult field @@ -5491,6 +6316,7 @@ item field + A list of Private Key IDs. @@ -5503,6 +6329,7 @@ item field + setPaymentMethodResult field @@ -5518,6 +6345,7 @@ The email address associated with the payment method. + activateBillingTierResult field @@ -5527,6 +6355,7 @@ The id of the product being subscribed to. + deletePaymentMethodResult field @@ -5536,6 +6365,7 @@ The payment method that was removed. + createApiOnlyUsersResult field @@ -5551,6 +6381,7 @@ item field + updateRootQuorumResult field @@ -5563,6 +6394,7 @@ Unique identifier for a given User Tag. + updatePrivateKeyTagResult field @@ -5572,6 +6404,7 @@ Unique identifier for a given Private Key Tag. + createSubOrganizationResult field @@ -5590,6 +6423,7 @@ item field + updateAllowedOriginsResult field @@ -5623,6 +6457,7 @@ address field + updateUserResult field @@ -5632,6 +6467,7 @@ A User ID. + updatePolicyResult field @@ -5641,6 +6477,7 @@ Unique identifier for a given Policy. + createSubOrganizationResultV3 field @@ -5671,6 +6508,7 @@ address field + rootUserIds field @@ -5683,6 +6521,7 @@ item field + createWalletResult field @@ -5701,6 +6540,7 @@ item field + createWalletAccountsResult field @@ -5716,6 +6556,7 @@ item field + initUserEmailRecoveryResult field @@ -5725,6 +6566,7 @@ Unique identifier for the user being recovered. + recoverUserResult field @@ -5740,6 +6582,7 @@ item field + setOrganizationFeatureResult field @@ -5761,6 +6604,7 @@ value field + removeOrganizationFeatureResult field @@ -5782,6 +6626,7 @@ value field + exportPrivateKeyResult field @@ -5794,6 +6639,7 @@ Export bundle containing a private key encrypted to the client's target public k + exportWalletResult field @@ -5806,6 +6652,7 @@ Export bundle containing a wallet mnemonic + optional newline passphrase encrypt + createSubOrganizationResultV4 field @@ -5830,6 +6677,7 @@ item field + rootUserIds field @@ -5842,6 +6690,7 @@ item field + emailAuthResult field @@ -5854,6 +6703,7 @@ Unique identifier for the created API key. + exportWalletAccountResult field @@ -5866,6 +6716,7 @@ Export bundle containing a private key encrypted by the client's target public k + initImportWalletResult field @@ -5875,6 +6726,7 @@ Import bundle containing a public key and signature to use for importing client + importWalletResult field @@ -5893,6 +6745,7 @@ item field + initImportPrivateKeyResult field @@ -5902,6 +6755,7 @@ Import bundle containing a public key and signature to use for importing client + importPrivateKeyResult field @@ -5926,6 +6780,7 @@ address field + createPoliciesResult field @@ -5941,6 +6796,7 @@ item field + signRawPayloadsResult field @@ -5962,6 +6818,7 @@ Component of an ECSDA signature. + createReadOnlySessionResult field @@ -5986,6 +6843,7 @@ UTC timestamp in seconds representing the expiry time for the read only session. + createOauthProvidersResult field @@ -6001,6 +6859,7 @@ item field + deleteOauthProvidersResult field @@ -6016,6 +6875,7 @@ item field + createSubOrganizationResultV5 field @@ -6040,6 +6900,7 @@ item field + rootUserIds field @@ -6052,6 +6913,7 @@ item field + oauthResult field @@ -6067,6 +6929,7 @@ HPKE encrypted credential bundle + createReadWriteSessionResult field @@ -6091,6 +6954,7 @@ HPKE encrypted credential bundle + createSubOrganizationResultV6 field @@ -6115,6 +6979,7 @@ item field + rootUserIds field @@ -6127,6 +6992,7 @@ item field + deletePrivateKeysResult field @@ -6142,6 +7008,7 @@ item field + deleteWalletsResult field @@ -6157,6 +7024,7 @@ item field + createReadWriteSessionResultV2 field @@ -6181,6 +7049,7 @@ HPKE encrypted credential bundle + deleteSubOrganizationResult field @@ -6190,6 +7059,7 @@ Unique identifier of the sub organization that was removed + initOtpAuthResult field @@ -6199,6 +7069,7 @@ Unique identifier for an OTP authentication + otpAuthResult field @@ -6214,6 +7085,7 @@ HPKE encrypted credential bundle + createSubOrganizationResultV7 field @@ -6238,6 +7110,7 @@ item field + rootUserIds field @@ -6250,6 +7123,7 @@ item field + updateWalletResult field @@ -6259,6 +7133,7 @@ A Wallet ID. + updatePolicyResultV2 field @@ -6268,6 +7143,7 @@ Unique identifier for a given Policy. + initOtpAuthResultV2 field @@ -6277,6 +7153,7 @@ Unique identifier for an OTP authentication + initOtpResult field @@ -6286,6 +7163,7 @@ Unique identifier for an OTP authentication + verifyOtpResult field @@ -6295,6 +7173,7 @@ Signed JWT containing a unique id, expiry, verification type, contact. Verificat + otpLoginResult field @@ -6304,6 +7183,7 @@ Signed JWT containing an expiry, public key, session type, user id, and organiza + stampLoginResult field @@ -6313,6 +7193,7 @@ Signed JWT containing an expiry, public key, session type, user id, and organiza + oauthLoginResult field @@ -6322,6 +7203,7 @@ Signed JWT containing an expiry, public key, session type, user id, and organiza + updateUserNameResult field @@ -6331,6 +7213,7 @@ Unique identifier of the User whose name was updated. + updateUserEmailResult field @@ -6340,6 +7223,7 @@ Unique identifier of the User whose email was updated. + updateUserPhoneNumberResult field @@ -6349,6 +7233,7 @@ Unique identifier of the User whose phone number was updated. + initFiatOnRampResult field @@ -6364,6 +7249,7 @@ Optional signature of the MoonPay Widget URL. The signature is generated if the + createSmartContractInterfaceResult field @@ -6373,6 +7259,7 @@ The ID of the created Smart Contract Interface. + deleteSmartContractInterfaceResult field @@ -6382,6 +7269,7 @@ The ID of the deleted Smart Contract Interface. + enableAuthProxyResult field @@ -6391,6 +7279,7 @@ A User ID with permission to initiate authentication. + disableAuthProxyResult field @@ -6403,6 +7292,7 @@ Unique identifier for a given User. (representing the turnkey signer user id) + createOauth2CredentialResult field @@ -6412,6 +7302,7 @@ Unique identifier of the OAuth 2.0 credential that was created + updateOauth2CredentialResult field @@ -6421,6 +7312,7 @@ Unique identifier of the OAuth 2.0 credential that was updated + deleteOauth2CredentialResult field @@ -6430,6 +7322,7 @@ Unique identifier of the OAuth 2.0 credential that was deleted + oauth2AuthenticateResult field @@ -6439,6 +7332,7 @@ Base64 encoded OIDC token issued by Turnkey to be used with the LoginWithOAuth a + deleteWalletAccountsResult field @@ -6454,6 +7348,7 @@ item field + deletePoliciesResult field @@ -6469,6 +7364,7 @@ item field + ethSendRawTransactionResult field @@ -6478,6 +7374,7 @@ The transaction hash of the sent transaction + createFiatOnRampCredentialResult field @@ -6487,6 +7384,7 @@ Unique identifier of the Fiat On-Ramp credential that was created + updateFiatOnRampCredentialResult field @@ -6496,6 +7394,7 @@ Unique identifier of the Fiat On-Ramp credential that was updated + deleteFiatOnRampCredentialResult field @@ -6505,6 +7404,7 @@ Unique identifier of the Fiat On-Ramp credential that was deleted + ethSendTransactionResult field @@ -6514,6 +7414,7 @@ The send_transaction_status ID associated with the transaction submission + upsertGasUsageConfigResult field @@ -6523,6 +7424,7 @@ Unique identifier for the gas usage configuration that was created or updated. + createTvcAppResult field @@ -6541,12 +7443,19 @@ item field - -The required number of approvals for the manifest set + + + The required number of approvals for the manifest set + createTvcDeploymentResult field @@ -6559,6 +7468,7 @@ The unique identifier for the TVC manifest + createTvcManifestApprovalsResult field @@ -6574,6 +7484,7 @@ item field + solSendTransactionResult field @@ -6583,6 +7494,7 @@ The send_transaction_status ID associated with the transaction submission + initOtpResultV2 field @@ -6595,6 +7507,7 @@ Signed bundle containing a target encryption key to use when submitting OTP code + updateOrganizationNameResult field @@ -6607,6 +7520,7 @@ The updated organization name. + createSubOrganizationResultV8 field @@ -6631,6 +7545,7 @@ item field + rootUserIds field @@ -6643,6 +7558,7 @@ item field + createOauthProvidersResultV2 field @@ -6658,6 +7574,7 @@ item field + createWebhookEndpointResult field @@ -6703,6 +7620,7 @@ Whether this subscription is active. + updateWebhookEndpointResult field @@ -6748,6 +7666,7 @@ Whether this subscription is active. + deleteWebhookEndpointResult field @@ -6757,6 +7676,7 @@ Unique identifier of the deleted webhook endpoint. + setIpAllowlistResult field @@ -6775,6 +7695,7 @@ The unique identifier of the deleted TVC deployment. + deleteTvcAppAndDeploymentsResult field @@ -6784,6 +7705,7 @@ The unique identifier of the deleted TVC app. + restoreTvcDeploymentResult field @@ -6793,6 +7715,7 @@ The unique identifier of the restored TVC deployment. + sparkSignFrostResult field @@ -6814,6 +7737,7 @@ Turnkey's binding commitment E (hex-encoded compressed secp256k1 point). Forward + sparkPrepareTransferResult field @@ -6829,6 +7753,7 @@ ECIES ciphertext (hex-encoded) opaque to Turnkey after emission. + Hex-encoded ECDSA-DER signature of the TransferPackage signing payload, signed with the wallet's IDENTITY key. @@ -6847,6 +7772,7 @@ Hex-encoded compressed secp256k1 point (33 bytes) for the SigningLeaf derivation + sparkClaimTransferResult field @@ -6862,6 +7788,7 @@ ECIES ciphertext (hex-encoded) opaque to Turnkey after emission. + Newly-derived SigningLeaf public keys, one per leaf, in input order. @@ -6877,6 +7804,7 @@ Hex-encoded compressed secp256k1 point (33 bytes) for the SigningLeaf derivation + sparkPrepareLightningReceiveResult field @@ -6892,12 +7820,19 @@ ECIES ciphertext (hex-encoded) opaque to Turnkey after emission. - -Hex-encoded SHA256(preimage). Forward to the Lightning node. + + + Hex-encoded SHA256(preimage). Forward to the Lightning node. + postTvcQuorumKeyShareResult field @@ -6910,6 +7845,7 @@ The unique identifier for the provisioning quorum key share + A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. @@ -6949,6 +7885,7 @@ Enum options: `AUTHENTICATOR_TRANSPORT_BLE`, `AUTHENTICATOR_TRANSPORT_INTERNAL`, + attestationType field @@ -6976,6 +7913,7 @@ Enum options: `CREDENTIAL_TYPE_WEBAUTHN_AUTHENTICATOR`, `CREDENTIAL_TYPE_API_KEY + Unique identifier for a given Authenticator. @@ -6994,6 +7932,7 @@ nanos field + updatedAt field @@ -7009,6 +7948,7 @@ nanos field + A list of API Key parameters. This field, if not needed, should be an empty array in your request body. @@ -7027,6 +7967,7 @@ Enum options: `CREDENTIAL_TYPE_WEBAUTHN_AUTHENTICATOR`, `CREDENTIAL_TYPE_API_KEY + Unique identifier for a given API Key. @@ -7045,6 +7986,7 @@ nanos field + updatedAt field @@ -7057,12 +7999,19 @@ nanos field - -Optional window (in seconds) indicating how long the API Key should last. + + + Optional window (in seconds) indicating how long the API Key should last. + A list of User Tag IDs. @@ -7072,6 +8021,7 @@ item field + A list of Oauth Providers. @@ -7102,6 +8052,7 @@ nanos field + updatedAt field @@ -7117,6 +8068,7 @@ nanos field + createdAt field @@ -7129,6 +8081,7 @@ nanos field + updatedAt field @@ -7144,6 +8097,7 @@ nanos field + Unique identifier for a given Activity object. @@ -7180,6 +8134,7 @@ nanos field + A list of App Proofs generated by enclaves during activity execution, providing verifiable attestations of performed operations. @@ -7201,6 +8156,7 @@ Signature over hashed proof_payload. + An artifact verifying a User's action. @@ -7222,6 +8178,7 @@ nanos field + updatedAt field @@ -7234,6 +8191,7 @@ nanos field + failure field @@ -7315,9 +8273,7 @@ const response = await turnkeyClient.apiClient().getActivity({ "response": { "clientDataJson": "", "attestationObject": "", - "transports": [ - "" - ], + "transports": [""], "authenticatorAttachment": "" }, "clientExtensionResults": { @@ -7338,24 +8294,16 @@ const response = await turnkeyClient.apiClient().getActivity({ "organizationId": "" }, "createAuthenticatorsResult": { - "authenticatorIds": [ - "" - ] + "authenticatorIds": [""] }, "createUsersResult": { - "userIds": [ - "" - ] + "userIds": [""] }, "createPrivateKeysResult": { - "privateKeyIds": [ - "" - ] + "privateKeyIds": [""] }, "createInvitationsResult": { - "invitationIds": [ - "" - ] + "invitationIds": [""] }, "acceptInvitationResult": { "invitationId": "", @@ -7373,14 +8321,10 @@ const response = await turnkeyClient.apiClient().getActivity({ "privateKeyId": "" }, "deleteUsersResult": { - "userIds": [ - "" - ] + "userIds": [""] }, "deleteAuthenticatorsResult": { - "authenticatorIds": [ - "" - ] + "authenticatorIds": [""] }, "deleteInvitationResult": { "invitationId": "" @@ -7393,44 +8337,28 @@ const response = await turnkeyClient.apiClient().getActivity({ }, "createUserTagResult": { "userTagId": "", - "userIds": [ - "" - ] + "userIds": [""] }, "deleteUserTagsResult": { - "userTagIds": [ - "" - ], - "userIds": [ - "" - ] + "userTagIds": [""], + "userIds": [""] }, "signTransactionResult": { "signedTransaction": "" }, "deleteApiKeysResult": { - "apiKeyIds": [ - "" - ] + "apiKeyIds": [""] }, "createApiKeysResult": { - "apiKeyIds": [ - "" - ] + "apiKeyIds": [""] }, "createPrivateKeyTagResult": { "privateKeyTagId": "", - "privateKeyIds": [ - "" - ] + "privateKeyIds": [""] }, "deletePrivateKeyTagsResult": { - "privateKeyTagIds": [ - "" - ], - "privateKeyIds": [ - "" - ] + "privateKeyTagIds": [""], + "privateKeyIds": [""] }, "setPaymentMethodResult": { "lastFour": "", @@ -7444,9 +8372,7 @@ const response = await turnkeyClient.apiClient().getActivity({ "paymentMethodId": "" }, "createApiOnlyUsersResult": { - "userIds": [ - "" - ] + "userIds": [""] }, "updateRootQuorumResult": "", "updateUserTagResult": { @@ -7457,9 +8383,7 @@ const response = await turnkeyClient.apiClient().getActivity({ }, "createSubOrganizationResult": { "subOrganizationId": "", - "rootUserIds": [ - "" - ] + "rootUserIds": [""] }, "updateAllowedOriginsResult": "", "createPrivateKeysResultV2": { @@ -7494,28 +8418,20 @@ const response = await turnkeyClient.apiClient().getActivity({ ] } ], - "rootUserIds": [ - "" - ] + "rootUserIds": [""] }, "createWalletResult": { "walletId": "", - "addresses": [ - "" - ] + "addresses": [""] }, "createWalletAccountsResult": { - "addresses": [ - "" - ] + "addresses": [""] }, "initUserEmailRecoveryResult": { "userId": "" }, "recoverUserResult": { - "authenticatorId": [ - "" - ] + "authenticatorId": [""] }, "setOrganizationFeatureResult": { "features": [ @@ -7545,13 +8461,9 @@ const response = await turnkeyClient.apiClient().getActivity({ "subOrganizationId": "", "wallet": { "walletId": "", - "addresses": [ - "" - ] + "addresses": [""] }, - "rootUserIds": [ - "" - ] + "rootUserIds": [""] }, "emailAuthResult": { "userId": "", @@ -7566,9 +8478,7 @@ const response = await turnkeyClient.apiClient().getActivity({ }, "importWalletResult": { "walletId": "", - "addresses": [ - "" - ] + "addresses": [""] }, "initImportPrivateKeyResult": { "importBundle": "" @@ -7583,9 +8493,7 @@ const response = await turnkeyClient.apiClient().getActivity({ ] }, "createPoliciesResult": { - "policyIds": [ - "" - ] + "policyIds": [""] }, "signRawPayloadsResult": { "signatures": [ @@ -7605,26 +8513,18 @@ const response = await turnkeyClient.apiClient().getActivity({ "sessionExpiry": "" }, "createOauthProvidersResult": { - "providerIds": [ - "" - ] + "providerIds": [""] }, "deleteOauthProvidersResult": { - "providerIds": [ - "" - ] + "providerIds": [""] }, "createSubOrganizationResultV5": { "subOrganizationId": "", "wallet": { "walletId": "", - "addresses": [ - "" - ] + "addresses": [""] }, - "rootUserIds": [ - "" - ] + "rootUserIds": [""] }, "oauthResult": { "userId": "", @@ -7643,23 +8543,15 @@ const response = await turnkeyClient.apiClient().getActivity({ "subOrganizationId": "", "wallet": { "walletId": "", - "addresses": [ - "" - ] + "addresses": [""] }, - "rootUserIds": [ - "" - ] + "rootUserIds": [""] }, "deletePrivateKeysResult": { - "privateKeyIds": [ - "" - ] + "privateKeyIds": [""] }, "deleteWalletsResult": { - "walletIds": [ - "" - ] + "walletIds": [""] }, "createReadWriteSessionResultV2": { "organizationId": "", @@ -7684,13 +8576,9 @@ const response = await turnkeyClient.apiClient().getActivity({ "subOrganizationId": "", "wallet": { "walletId": "", - "addresses": [ - "" - ] + "addresses": [""] }, - "rootUserIds": [ - "" - ] + "rootUserIds": [""] }, "updateWalletResult": { "walletId": "" @@ -7756,14 +8644,10 @@ const response = await turnkeyClient.apiClient().getActivity({ "oidcToken": "" }, "deleteWalletAccountsResult": { - "walletAccountIds": [ - "" - ] + "walletAccountIds": [""] }, "deletePoliciesResult": { - "policyIds": [ - "" - ] + "policyIds": [""] }, "ethSendRawTransactionResult": { "transactionHash": "" @@ -7786,9 +8670,7 @@ const response = await turnkeyClient.apiClient().getActivity({ "createTvcAppResult": { "appId": "", "manifestSetId": "", - "manifestSetOperatorIds": [ - "" - ], + "manifestSetOperatorIds": [""], "manifestSetThreshold": "" }, "createTvcDeploymentResult": { @@ -7796,9 +8678,7 @@ const response = await turnkeyClient.apiClient().getActivity({ "manifestId": "" }, "createTvcManifestApprovalsResult": { - "approvalIds": [ - "" - ] + "approvalIds": [""] }, "solSendTransactionResult": { "sendTransactionStatusId": "" @@ -7815,18 +8695,12 @@ const response = await turnkeyClient.apiClient().getActivity({ "subOrganizationId": "", "wallet": { "walletId": "", - "addresses": [ - "" - ] + "addresses": [""] }, - "rootUserIds": [ - "" - ] + "rootUserIds": [""] }, "createOauthProvidersResultV2": { - "providerIds": [ - "" - ] + "providerIds": [""] }, "createWebhookEndpointResult": { "endpointId": "", @@ -7939,9 +8813,7 @@ const response = await turnkeyClient.apiClient().getActivity({ "userPhoneNumber": "", "authenticators": [ { - "transports": [ - "" - ], + "transports": [""], "attestationType": "", "aaguid": "", "credentialId": "", @@ -7981,9 +8853,7 @@ const response = await turnkeyClient.apiClient().getActivity({ "expirationSeconds": "" } ], - "userTags": [ - "" - ], + "userTags": [""], "oauthProviders": [ { "providerId": "", diff --git a/api-reference/queries/get-api-key.mdx b/api-reference/queries/get-api-key.mdx index 62e4981a..2ce5e0cd 100644 --- a/api-reference/queries/get-api-key.mdx +++ b/api-reference/queries/get-api-key.mdx @@ -17,16 +17,17 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Unique identifier for a given organization. + Unique identifier for a given API key. - + - -A successful response returns the following fields: +A successful response returns the following +fields: apiKey field @@ -46,6 +47,7 @@ Enum options: `CREDENTIAL_TYPE_WEBAUTHN_AUTHENTICATOR`, `CREDENTIAL_TYPE_API_KEY + Unique identifier for a given API Key. @@ -64,6 +66,7 @@ nanos field + updatedAt field @@ -76,8 +79,14 @@ nanos field - -Optional window (in seconds) indicating how long the API Key should last. + + + Optional window (in seconds) indicating how long the API Key should last. diff --git a/api-reference/queries/get-api-keys.mdx b/api-reference/queries/get-api-keys.mdx index 14564eef..f60f8b10 100644 --- a/api-reference/queries/get-api-keys.mdx +++ b/api-reference/queries/get-api-keys.mdx @@ -17,16 +17,17 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Unique identifier for a given organization. + Unique identifier for a given user. - + - -A successful response returns the following fields: +A successful response returns the following +fields: A list of API keys. @@ -46,6 +47,7 @@ Enum options: `CREDENTIAL_TYPE_WEBAUTHN_AUTHENTICATOR`, `CREDENTIAL_TYPE_API_KEY + Unique identifier for a given API Key. @@ -64,6 +66,7 @@ nanos field + updatedAt field @@ -76,8 +79,14 @@ nanos field - -Optional window (in seconds) indicating how long the API Key should last. + + + Optional window (in seconds) indicating how long the API Key should last. diff --git a/api-reference/queries/get-authenticator.mdx b/api-reference/queries/get-authenticator.mdx index 7f6ceb14..d985dbf6 100644 --- a/api-reference/queries/get-authenticator.mdx +++ b/api-reference/queries/get-authenticator.mdx @@ -17,16 +17,17 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Unique identifier for a given organization. + Unique identifier for a given authenticator. - + - -A successful response returns the following fields: +A successful response returns the following +fields: authenticator field @@ -43,6 +44,7 @@ Enum options: `AUTHENTICATOR_TRANSPORT_BLE`, `AUTHENTICATOR_TRANSPORT_INTERNAL`, + attestationType field @@ -70,6 +72,7 @@ Enum options: `CREDENTIAL_TYPE_WEBAUTHN_AUTHENTICATOR`, `CREDENTIAL_TYPE_API_KEY + Unique identifier for a given Authenticator. @@ -88,6 +91,7 @@ nanos field + updatedAt field @@ -141,9 +145,7 @@ const response = await turnkeyClient.apiClient().getAuthenticator({ ```json 200 { "authenticator": { - "transports": [ - "" - ], + "transports": [""], "attestationType": "", "aaguid": "", "credentialId": "", diff --git a/api-reference/queries/get-authenticators.mdx b/api-reference/queries/get-authenticators.mdx index d51fda9f..e0977a80 100644 --- a/api-reference/queries/get-authenticators.mdx +++ b/api-reference/queries/get-authenticators.mdx @@ -17,16 +17,17 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Unique identifier for a given organization. + Unique identifier for a given user. - + - -A successful response returns the following fields: +A successful response returns the following +fields: A list of authenticators. @@ -43,6 +44,7 @@ Enum options: `AUTHENTICATOR_TRANSPORT_BLE`, `AUTHENTICATOR_TRANSPORT_INTERNAL`, + attestationType field @@ -70,6 +72,7 @@ Enum options: `CREDENTIAL_TYPE_WEBAUTHN_AUTHENTICATOR`, `CREDENTIAL_TYPE_API_KEY + Unique identifier for a given Authenticator. @@ -88,6 +91,7 @@ nanos field + updatedAt field @@ -142,9 +146,7 @@ const response = await turnkeyClient.apiClient().getAuthenticators({ { "authenticators": [ { - "transports": [ - "" - ], + "transports": [""], "attestationType": "", "aaguid": "", "credentialId": "", diff --git a/api-reference/queries/get-balances.mdx b/api-reference/queries/get-balances.mdx index 3c897eee..ce2c8c0b 100644 --- a/api-reference/queries/get-balances.mdx +++ b/api-reference/queries/get-balances.mdx @@ -17,21 +17,23 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Unique identifier for a given organization. + Address corresponding to a wallet account. Private key addresses are not supported. + Enum options: `eip155:1`, `eip155:11155111`, `eip155:8453`, `eip155:84532`, `eip155:137`, `eip155:80002`, `eip155:42161`, `eip155:421614`, `solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp`, `solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1` - + - -A successful response returns the following fields: +A successful response returns the following +fields: List of asset balances @@ -60,8 +62,14 @@ Normalized crypto value for display purposes only. Do not do any arithmetic or c - -The asset name + + + The asset name diff --git a/api-reference/queries/get-configs.mdx b/api-reference/queries/get-configs.mdx index e85998a0..0892c35f 100644 --- a/api-reference/queries/get-configs.mdx +++ b/api-reference/queries/get-configs.mdx @@ -17,11 +17,11 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Unique identifier for a given organization. - + - -A successful response returns the following fields: +A successful response returns the following +fields: configs field @@ -41,6 +41,7 @@ value field + quorum field @@ -106,9 +107,7 @@ const response = await turnkeyClient.apiClient().getOrganizationConfigs({ ], "quorum": { "threshold": "", - "userIds": [ - "" - ] + "userIds": [""] } } } diff --git a/api-reference/queries/get-gas-usage.mdx b/api-reference/queries/get-gas-usage.mdx index 0416ef9f..480d30bd 100644 --- a/api-reference/queries/get-gas-usage.mdx +++ b/api-reference/queries/get-gas-usage.mdx @@ -17,15 +17,22 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Unique identifier for a given Organization. - - - -A successful response returns the following fields: + -The window duration (in minutes) for the organization or sub-organization. -The window limit (in USD) for the organization or sub-organization. -The total gas usage (in USD) of all sponsored transactions processed over the last `window_duration_minutes` +A successful response returns the following +fields: + + + The window duration (in minutes) for the organization or sub-organization. + + + The window limit (in USD) for the organization or sub-organization. + + + The total gas usage (in USD) of all sponsored transactions processed over the + last `window_duration_minutes` + diff --git a/api-reference/queries/get-ip-allowlist.mdx b/api-reference/queries/get-ip-allowlist.mdx index 5a3e5c4a..ad2962db 100644 --- a/api-reference/queries/get-ip-allowlist.mdx +++ b/api-reference/queries/get-ip-allowlist.mdx @@ -17,16 +17,17 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Unique identifier for a given organization. + If provided, return only the allowlist for this specific API key. - + - -A successful response returns the following fields: +A successful response returns the following +fields: allowlist field @@ -49,14 +50,34 @@ Creation timestamp as millisecond epoch string. - -Public key of the API key this allowlist applies to. Null means the allowlist applies to the entire organization. + + + Public key of the API key this allowlist applies to. Null means the allowlist + applies to the entire organization. - -Whether the IP allowlist is enabled. Only present for organization-level allowlists. Null for API key-level allowlists (presence of the allowlist implies enablement). + + Whether the IP allowlist is enabled. Only present for organization-level + allowlists. Null for API key-level allowlists (presence of the allowlist + implies enablement). - -Behavior when an error occurs during IP allowlist evaluation. Valid values: ALLOW, DENY. Defaults to DENY. + + Behavior when an error occurs during IP allowlist evaluation. Valid values: + ALLOW, DENY. Defaults to DENY. diff --git a/api-reference/queries/get-nonces.mdx b/api-reference/queries/get-nonces.mdx index 39dcf578..59457ee8 100644 --- a/api-reference/queries/get-nonces.mdx +++ b/api-reference/queries/get-nonces.mdx @@ -17,34 +17,42 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Unique identifier for a given Organization. + The Ethereum address to query nonces for. + Enum options: `eip155:1`, `eip155:11155111`, `eip155:8453`, `eip155:84532`, `eip155:137`, `eip155:80002` + Whether to fetch the standard on-chain nonce. + Whether to fetch the gas station nonce used for sponsored transactions. - + - -A successful response returns the following fields: +A successful response returns the following +fields: -The standard on-chain nonce for the address, if requested. -The gas station nonce for sponsored transactions, if requested. + + The standard on-chain nonce for the address, if requested. + + + The gas station nonce for sponsored transactions, if requested. + diff --git a/api-reference/queries/get-oauth-20-credential.mdx b/api-reference/queries/get-oauth-20-credential.mdx index 60f547da..e21f8485 100644 --- a/api-reference/queries/get-oauth-20-credential.mdx +++ b/api-reference/queries/get-oauth-20-credential.mdx @@ -17,16 +17,17 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Unique identifier for a given Organization. + Unique identifier for a given OAuth 2.0 Credential. - + - -A successful response returns the following fields: +A successful response returns the following +fields: oauth2Credential field @@ -61,6 +62,7 @@ nanos field + updatedAt field diff --git a/api-reference/queries/get-oauth-providers.mdx b/api-reference/queries/get-oauth-providers.mdx index 3ea3c7fa..9e3c49bc 100644 --- a/api-reference/queries/get-oauth-providers.mdx +++ b/api-reference/queries/get-oauth-providers.mdx @@ -17,16 +17,17 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Unique identifier for a given organization. + Unique identifier for a given user. - + - -A successful response returns the following fields: +A successful response returns the following +fields: A list of Oauth providers. @@ -58,6 +59,7 @@ nanos field + updatedAt field diff --git a/api-reference/queries/get-on-ramp-transaction-status.mdx b/api-reference/queries/get-on-ramp-transaction-status.mdx index dacadf74..4e7d2865 100644 --- a/api-reference/queries/get-on-ramp-transaction-status.mdx +++ b/api-reference/queries/get-on-ramp-transaction-status.mdx @@ -17,23 +17,27 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Unique identifier for a given organization. + The unique identifier for the fiat on ramp transaction. + Optional flag to specify if the transaction status should be refreshed from the fiat on ramp provider. Default = false. - + - -A successful response returns the following fields: +A successful response returns the following +fields: -The status of the fiat on ramp transaction. + + The status of the fiat on ramp transaction. + diff --git a/api-reference/queries/get-policy-evaluations.mdx b/api-reference/queries/get-policy-evaluations.mdx index c5eadc95..87d053dd 100644 --- a/api-reference/queries/get-policy-evaluations.mdx +++ b/api-reference/queries/get-policy-evaluations.mdx @@ -17,16 +17,17 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Unique identifier for a given organization. + Unique identifier for a given activity. - + - -A successful response returns the following fields: +A successful response returns the following +fields: policyEvaluations field @@ -58,6 +59,7 @@ Enum options: `OUTCOME_ALLOW`, `OUTCOME_DENY_EXPLICIT`, `OUTCOME_DENY_IMPLICIT`, + createdAt field diff --git a/api-reference/queries/get-policy.mdx b/api-reference/queries/get-policy.mdx index 7c668be4..49708a3e 100644 --- a/api-reference/queries/get-policy.mdx +++ b/api-reference/queries/get-policy.mdx @@ -17,16 +17,17 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Unique identifier for a given organization. + Unique identifier for a given policy. - + - -A successful response returns the following fields: +A successful response returns the following +fields: policy field @@ -55,6 +56,7 @@ nanos field + updatedAt field @@ -67,14 +69,25 @@ nanos field + -Human-readable notes added by a User to describe a particular policy. + Human-readable notes added by a User to describe a particular policy. - -A consensus expression that evalutes to true or false. + + A consensus expression that evalutes to true or false. - -A condition expression that evalutes to true or false. + + A condition expression that evalutes to true or false. diff --git a/api-reference/queries/get-private-key.mdx b/api-reference/queries/get-private-key.mdx index b5f64552..6535d0e4 100644 --- a/api-reference/queries/get-private-key.mdx +++ b/api-reference/queries/get-private-key.mdx @@ -17,16 +17,17 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Unique identifier for a given organization. + Unique identifier for a given private key. - + - -A successful response returns the following fields: +A successful response returns the following +fields: privateKey field @@ -61,6 +62,7 @@ address field + A list of Private Key Tag IDs. @@ -70,6 +72,7 @@ item field + createdAt field @@ -82,6 +85,7 @@ nanos field + updatedAt field @@ -94,11 +98,22 @@ nanos field - -True when a given Private Key is exported, false otherwise. + + + True when a given Private Key is exported, false otherwise. - -True when a given Private Key is imported, false otherwise. + + True when a given Private Key is imported, false otherwise. @@ -151,9 +166,7 @@ const response = await turnkeyClient.apiClient().getPrivateKey({ "address": "" } ], - "privateKeyTags": [ - "" - ], + "privateKeyTags": [""], "createdAt": { "seconds": "", "nanos": "" diff --git a/api-reference/queries/get-send-transaction-status.mdx b/api-reference/queries/get-send-transaction-status.mdx index f06e7916..869fd2a9 100644 --- a/api-reference/queries/get-send-transaction-status.mdx +++ b/api-reference/queries/get-send-transaction-status.mdx @@ -17,16 +17,17 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Unique identifier for a given organization. + The unique identifier of a send transaction request. - + - -A successful response returns the following fields: +A successful response returns the following +fields: The current status of the send transaction. @@ -78,6 +79,7 @@ The raw error data, hex-encoded. + native field @@ -93,6 +95,7 @@ The panic code for Panic(uint256) reverts. + custom field @@ -108,6 +111,7 @@ The decoded parameters as a JSON object. + solana field @@ -132,15 +136,27 @@ item field - -Compute units consumed during simulation or preflight, if available. + + + Compute units consumed during simulation or preflight, if available. - -The raw Solana inner instructions payload serialized as JSON, if available. + + The raw Solana inner instructions payload serialized as JSON, if available. + eth field @@ -168,6 +184,7 @@ The raw error data, hex-encoded. + native field @@ -183,6 +200,7 @@ The panic code for Panic(uint256) reverts. + custom field @@ -276,9 +294,7 @@ const response = await turnkeyClient.apiClient().getSendTransactionStatus({ "rpcCode": "", "rpcMessage": "", "transactionErrorJson": "", - "logs": [ - "" - ], + "logs": [""], "unitsConsumed": "", "innerInstructionsJson": "" }, diff --git a/api-reference/queries/get-smart-contract-interface.mdx b/api-reference/queries/get-smart-contract-interface.mdx index 41d7493b..bc8dfda5 100644 --- a/api-reference/queries/get-smart-contract-interface.mdx +++ b/api-reference/queries/get-smart-contract-interface.mdx @@ -17,16 +17,17 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Unique identifier for a given organization. + Unique identifier for a given smart contract interface. - + - -A successful response returns the following fields: +A successful response returns the following +fields: smartContractInterface field @@ -64,6 +65,7 @@ nanos field + updatedAt field diff --git a/api-reference/queries/get-sub-organizations.mdx b/api-reference/queries/get-sub-organizations.mdx index 87fe4c88..a6fca71b 100644 --- a/api-reference/queries/get-sub-organizations.mdx +++ b/api-reference/queries/get-sub-organizations.mdx @@ -17,37 +17,66 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Unique identifier for the parent organization. This is used to find sub-organizations within it. + Specifies the type of filter to apply, i.e 'CREDENTIAL_ID', 'NAME', 'USERNAME', 'EMAIL', 'PHONE_NUMBER', 'OIDC_TOKEN', 'WALLET_ACCOUNT_ADDRESS' or 'PUBLIC_KEY' + The value of the filter to apply for the specified type. For example, a specific email or name string. + - +

paginationOptions field

- - A limit of the number of object to be returned, between 1 and 100. Defaults to 10. + + A limit of the number of object to be returned, between 1 and 100. + Defaults to 10. - - - A pagination cursor. This is an object ID that enables you to fetch all objects before this ID. + + + A pagination cursor. This is an object ID that enables you to fetch all + objects before this ID. - - - A pagination cursor. This is an object ID that enables you to fetch all objects after this ID. + + + A pagination cursor. This is an object ID that enables you to fetch all + objects after this ID.
- -A successful response returns the following fields: +A successful response returns the following +fields: List of unique identifiers for the matching sub-organizations. @@ -107,9 +136,7 @@ const response = await turnkeyClient.apiClient().getSubOrgIds({ ```json 200 { - "organizationIds": [ - "" - ] + "organizationIds": [""] } ``` diff --git a/api-reference/queries/get-the-latest-boot-proof-for-an-app.mdx b/api-reference/queries/get-the-latest-boot-proof-for-an-app.mdx index 481eb74d..635fa8c5 100644 --- a/api-reference/queries/get-the-latest-boot-proof-for-an-app.mdx +++ b/api-reference/queries/get-the-latest-boot-proof-for-an-app.mdx @@ -17,16 +17,17 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Unique identifier for a given Organization. + Name of enclave app. - +
- -A successful response returns the following fields: +A successful response returns the following +fields: bootProof field @@ -64,8 +65,14 @@ nanos field
- -QOS manifest schema version. + + + QOS manifest schema version. diff --git a/api-reference/queries/get-tvc-app-status.mdx b/api-reference/queries/get-tvc-app-status.mdx index 27fa9f04..36521643 100644 --- a/api-reference/queries/get-tvc-app-status.mdx +++ b/api-reference/queries/get-tvc-app-status.mdx @@ -17,16 +17,17 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Unique identifier for a given Organization. + Unique identifier for a given TVC App. - + - -A successful response returns the following fields: +A successful response returns the following +fields: appStatus field @@ -61,8 +62,14 @@ nanos field - -The deployment ID currently serving traffic for this app + + + The deployment ID currently serving traffic for this app diff --git a/api-reference/queries/get-tvc-app.mdx b/api-reference/queries/get-tvc-app.mdx index 03471ff3..fb7e1d99 100644 --- a/api-reference/queries/get-tvc-app.mdx +++ b/api-reference/queries/get-tvc-app.mdx @@ -17,16 +17,17 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Unique identifier for a given organization. + Unique identifier for a given TVC App. - + - -A successful response returns the following fields: +A successful response returns the following +fields: tvcApp field @@ -79,6 +80,7 @@ nanos field + updatedAt field @@ -94,6 +96,7 @@ nanos field + Threshold number of operators required for quorum. @@ -109,6 +112,7 @@ nanos field
+ updatedAt field @@ -124,6 +128,7 @@ nanos field + shareSet field @@ -160,6 +165,7 @@ nanos field + updatedAt field @@ -175,6 +181,7 @@ nanos field + Threshold number of operators required for quorum. @@ -190,6 +197,7 @@ nanos field
+ updatedAt field @@ -205,6 +213,7 @@ nanos field + Whether or not this TVC App has network egress enabled. @@ -220,6 +229,7 @@ nanos field
+ updatedAt field @@ -232,11 +242,24 @@ nanos field - -The deployment currently designated to receive traffic. Null if no deployment for this app is deployed. - - -The public domain for ingress to this TVC App (in the format "app-<ID>.turnkey.cloud"). + + + The deployment currently designated to receive traffic. Null if no deployment + for this app is deployed. + + + The public domain for ingress to this TVC App (in the format + "app-<ID>.turnkey.cloud"). diff --git a/api-reference/queries/get-tvc-deployment.mdx b/api-reference/queries/get-tvc-deployment.mdx index af44808d..57d4d8f5 100644 --- a/api-reference/queries/get-tvc-deployment.mdx +++ b/api-reference/queries/get-tvc-deployment.mdx @@ -17,16 +17,17 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Unique identifier for a given organization. + Unique identifier for a given TVC Deployment. - + - -A successful response returns the following fields: +A successful response returns the following +fields: tvcDeployment field @@ -76,6 +77,7 @@ nanos field + updatedAt field @@ -91,6 +93,7 @@ nanos field + Threshold number of operators required for quorum. @@ -106,6 +109,7 @@ nanos field
+ updatedAt field @@ -121,6 +125,7 @@ nanos field + shareSet field @@ -157,6 +162,7 @@ nanos field + updatedAt field @@ -172,6 +178,7 @@ nanos field + Threshold number of operators required for quorum. @@ -187,6 +194,7 @@ nanos field
+ updatedAt field @@ -202,6 +210,7 @@ nanos field + manifest field @@ -223,6 +232,7 @@ nanos field + updatedAt field @@ -238,6 +248,7 @@ nanos field + List of operator approvals for this manifest @@ -271,6 +282,7 @@ nanos field + updatedAt field @@ -286,6 +298,7 @@ nanos field + Signature of the operator over the deployment manifest @@ -301,6 +314,7 @@ nanos field + updatedAt field @@ -316,6 +330,7 @@ nanos field + QOS Version used for this deployment @@ -337,6 +352,7 @@ item field + Whether or not this container requires a pull secret to access. @@ -355,6 +371,7 @@ The port to use for public ingress to this executable. + createdAt field @@ -367,6 +384,7 @@ nanos field + updatedAt field @@ -379,8 +397,14 @@ nanos field - -Whether or not the user wants this deployment deleted from the cluster. + + + Whether or not the user wants this deployment deleted from the cluster. @@ -528,9 +552,7 @@ const response = await turnkeyClient.apiClient().getTvcDeployment({ "pivotContainer": { "containerUrl": "", "path": "", - "args": [ - "" - ], + "args": [""], "hasPullSecret": "", "healthCheckType": "", "healthCheckPort": "", diff --git a/api-reference/queries/get-user.mdx b/api-reference/queries/get-user.mdx index 907c21b5..69b6e592 100644 --- a/api-reference/queries/get-user.mdx +++ b/api-reference/queries/get-user.mdx @@ -17,16 +17,17 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Unique identifier for a given organization. + Unique identifier for a given user. - + - -A successful response returns the following fields: +A successful response returns the following +fields: user field @@ -58,6 +59,7 @@ Enum options: `AUTHENTICATOR_TRANSPORT_BLE`, `AUTHENTICATOR_TRANSPORT_INTERNAL`, + attestationType field @@ -85,6 +87,7 @@ Enum options: `CREDENTIAL_TYPE_WEBAUTHN_AUTHENTICATOR`, `CREDENTIAL_TYPE_API_KEY + Unique identifier for a given Authenticator. @@ -103,6 +106,7 @@ nanos field + updatedAt field @@ -118,6 +122,7 @@ nanos field + A list of API Key parameters. This field, if not needed, should be an empty array in your request body. @@ -136,6 +141,7 @@ Enum options: `CREDENTIAL_TYPE_WEBAUTHN_AUTHENTICATOR`, `CREDENTIAL_TYPE_API_KEY + Unique identifier for a given API Key. @@ -154,6 +160,7 @@ nanos field + updatedAt field @@ -166,12 +173,19 @@ nanos field - -Optional window (in seconds) indicating how long the API Key should last. + + + Optional window (in seconds) indicating how long the API Key should last. + A list of User Tag IDs. @@ -181,6 +195,7 @@ item field + A list of Oauth Providers. @@ -211,6 +226,7 @@ nanos field + updatedAt field @@ -226,6 +242,7 @@ nanos field + createdAt field @@ -238,6 +255,7 @@ nanos field + updatedAt field @@ -297,9 +315,7 @@ const response = await turnkeyClient.apiClient().getUser({ "userPhoneNumber": "", "authenticators": [ { - "transports": [ - "" - ], + "transports": [""], "attestationType": "", "aaguid": "", "credentialId": "", @@ -339,9 +355,7 @@ const response = await turnkeyClient.apiClient().getUser({ "expirationSeconds": "" } ], - "userTags": [ - "" - ], + "userTags": [""], "oauthProviders": [ { "providerId": "", diff --git a/api-reference/queries/get-verified-sub-organizations.mdx b/api-reference/queries/get-verified-sub-organizations.mdx index d5d6abf1..363133ae 100644 --- a/api-reference/queries/get-verified-sub-organizations.mdx +++ b/api-reference/queries/get-verified-sub-organizations.mdx @@ -17,37 +17,66 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Unique identifier for the parent organization. This is used to find sub-organizations within it. + Specifies the type of filter to apply, i.e 'EMAIL', 'PHONE_NUMBER'. + The value of the filter to apply for the specified type. For example, a specific email or phone number string. + - +

paginationOptions field

- - A limit of the number of object to be returned, between 1 and 100. Defaults to 10. + + A limit of the number of object to be returned, between 1 and 100. + Defaults to 10. - - - A pagination cursor. This is an object ID that enables you to fetch all objects before this ID. + + + A pagination cursor. This is an object ID that enables you to fetch all + objects before this ID. - - - A pagination cursor. This is an object ID that enables you to fetch all objects after this ID. + + + A pagination cursor. This is an object ID that enables you to fetch all + objects after this ID.
- -A successful response returns the following fields: +A successful response returns the following +fields: List of unique identifiers for the matching sub-organizations. @@ -107,9 +136,7 @@ const response = await turnkeyClient.apiClient().getVerifiedSubOrgIds({ ```json 200 { - "organizationIds": [ - "" - ] + "organizationIds": [""] } ``` diff --git a/api-reference/queries/get-wallet-account.mdx b/api-reference/queries/get-wallet-account.mdx index 451cee83..e386fd10 100644 --- a/api-reference/queries/get-wallet-account.mdx +++ b/api-reference/queries/get-wallet-account.mdx @@ -17,26 +17,29 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Unique identifier for a given organization. + Unique identifier for a given wallet. + Address corresponding to a wallet account. + Path corresponding to a wallet account. - +
- -A successful response returns the following fields: +A successful response returns the following +fields: account field @@ -86,6 +89,7 @@ nanos field
+ updatedAt field @@ -98,6 +102,7 @@ nanos field + The public component of this wallet account's underlying cryptographic key pair. @@ -122,6 +127,7 @@ nanos field + updatedAt field @@ -134,11 +140,22 @@ nanos field - -True when a given Wallet is exported, false otherwise. - - -True when a given Wallet is imported, false otherwise. + + + True when a given Wallet is exported, false otherwise. + + + True when a given Wallet is imported, false otherwise. diff --git a/api-reference/queries/get-wallet.mdx b/api-reference/queries/get-wallet.mdx index 09f6d84a..62dfe50b 100644 --- a/api-reference/queries/get-wallet.mdx +++ b/api-reference/queries/get-wallet.mdx @@ -17,16 +17,17 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Unique identifier for a given organization. + Unique identifier for a given wallet. - + - -A successful response returns the following fields: +A successful response returns the following +fields: wallet field @@ -49,6 +50,7 @@ nanos field + updatedAt field @@ -61,11 +63,22 @@ nanos field - -True when a given Wallet is exported, false otherwise. + + + True when a given Wallet is exported, false otherwise. - -True when a given Wallet is imported, false otherwise. + + True when a given Wallet is imported, false otherwise. diff --git a/api-reference/queries/list-activities.mdx b/api-reference/queries/list-activities.mdx index 0d2140ec..4e63161f 100644 --- a/api-reference/queries/list-activities.mdx +++ b/api-reference/queries/list-activities.mdx @@ -17,11 +17,13 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Unique identifier for a given organization. + Enum options: `ACTIVITY_STATUS_CREATED`, `ACTIVITY_STATUS_PENDING`, `ACTIVITY_STATUS_COMPLETED`, `ACTIVITY_STATUS_FAILED`, `ACTIVITY_STATUS_CONSENSUS_NEEDED`, `ACTIVITY_STATUS_REJECTED` + @@ -43,11 +45,11 @@ Enum options: `ACTIVITY_STATUS_CREATED`, `ACTIVITY_STATUS_PENDING`, `ACTIVITY_ST Enum options: `ACTIVITY_TYPE_CREATE_API_KEYS`, `ACTIVITY_TYPE_CREATE_USERS`, `ACTIVITY_TYPE_CREATE_PRIVATE_KEYS`, `ACTIVITY_TYPE_SIGN_RAW_PAYLOAD`, `ACTIVITY_TYPE_CREATE_INVITATIONS`, `ACTIVITY_TYPE_ACCEPT_INVITATION`, `ACTIVITY_TYPE_CREATE_POLICY`, `ACTIVITY_TYPE_DISABLE_PRIVATE_KEY`, `ACTIVITY_TYPE_DELETE_USERS`, `ACTIVITY_TYPE_DELETE_API_KEYS`, `ACTIVITY_TYPE_DELETE_INVITATION`, `ACTIVITY_TYPE_DELETE_ORGANIZATION`, `ACTIVITY_TYPE_DELETE_POLICY`, `ACTIVITY_TYPE_CREATE_USER_TAG`, `ACTIVITY_TYPE_DELETE_USER_TAGS`, `ACTIVITY_TYPE_CREATE_ORGANIZATION`, `ACTIVITY_TYPE_SIGN_TRANSACTION`, `ACTIVITY_TYPE_APPROVE_ACTIVITY`, `ACTIVITY_TYPE_REJECT_ACTIVITY`, `ACTIVITY_TYPE_DELETE_AUTHENTICATORS`, `ACTIVITY_TYPE_CREATE_AUTHENTICATORS`, `ACTIVITY_TYPE_CREATE_PRIVATE_KEY_TAG`, `ACTIVITY_TYPE_DELETE_PRIVATE_KEY_TAGS`, `ACTIVITY_TYPE_SET_PAYMENT_METHOD`, `ACTIVITY_TYPE_ACTIVATE_BILLING_TIER`, `ACTIVITY_TYPE_DELETE_PAYMENT_METHOD`, `ACTIVITY_TYPE_CREATE_POLICY_V2`, `ACTIVITY_TYPE_CREATE_POLICY_V3`, `ACTIVITY_TYPE_CREATE_API_ONLY_USERS`, `ACTIVITY_TYPE_UPDATE_ROOT_QUORUM`, `ACTIVITY_TYPE_UPDATE_USER_TAG`, `ACTIVITY_TYPE_UPDATE_PRIVATE_KEY_TAG`, `ACTIVITY_TYPE_CREATE_AUTHENTICATORS_V2`, `ACTIVITY_TYPE_CREATE_ORGANIZATION_V2`, `ACTIVITY_TYPE_CREATE_USERS_V2`, `ACTIVITY_TYPE_ACCEPT_INVITATION_V2`, `ACTIVITY_TYPE_CREATE_SUB_ORGANIZATION`, `ACTIVITY_TYPE_CREATE_SUB_ORGANIZATION_V2`, `ACTIVITY_TYPE_UPDATE_ALLOWED_ORIGINS`, `ACTIVITY_TYPE_CREATE_PRIVATE_KEYS_V2`, `ACTIVITY_TYPE_UPDATE_USER`, `ACTIVITY_TYPE_UPDATE_POLICY`, `ACTIVITY_TYPE_SET_PAYMENT_METHOD_V2`, `ACTIVITY_TYPE_CREATE_SUB_ORGANIZATION_V3`, `ACTIVITY_TYPE_CREATE_WALLET`, `ACTIVITY_TYPE_CREATE_WALLET_ACCOUNTS`, `ACTIVITY_TYPE_INIT_USER_EMAIL_RECOVERY`, `ACTIVITY_TYPE_RECOVER_USER`, `ACTIVITY_TYPE_SET_ORGANIZATION_FEATURE`, `ACTIVITY_TYPE_REMOVE_ORGANIZATION_FEATURE`, `ACTIVITY_TYPE_SIGN_RAW_PAYLOAD_V2`, `ACTIVITY_TYPE_SIGN_TRANSACTION_V2`, `ACTIVITY_TYPE_EXPORT_PRIVATE_KEY`, `ACTIVITY_TYPE_EXPORT_WALLET`, `ACTIVITY_TYPE_CREATE_SUB_ORGANIZATION_V4`, `ACTIVITY_TYPE_EMAIL_AUTH`, `ACTIVITY_TYPE_EXPORT_WALLET_ACCOUNT`, `ACTIVITY_TYPE_INIT_IMPORT_WALLET`, `ACTIVITY_TYPE_IMPORT_WALLET`, `ACTIVITY_TYPE_INIT_IMPORT_PRIVATE_KEY`, `ACTIVITY_TYPE_IMPORT_PRIVATE_KEY`, `ACTIVITY_TYPE_CREATE_POLICIES`, `ACTIVITY_TYPE_SIGN_RAW_PAYLOADS`, `ACTIVITY_TYPE_CREATE_READ_ONLY_SESSION`, `ACTIVITY_TYPE_CREATE_OAUTH_PROVIDERS`, `ACTIVITY_TYPE_DELETE_OAUTH_PROVIDERS`, `ACTIVITY_TYPE_CREATE_SUB_ORGANIZATION_V5`, `ACTIVITY_TYPE_OAUTH`, `ACTIVITY_TYPE_CREATE_API_KEYS_V2`, `ACTIVITY_TYPE_CREATE_READ_WRITE_SESSION`, `ACTIVITY_TYPE_EMAIL_AUTH_V2`, `ACTIVITY_TYPE_CREATE_SUB_ORGANIZATION_V6`, `ACTIVITY_TYPE_DELETE_PRIVATE_KEYS`, `ACTIVITY_TYPE_DELETE_WALLETS`, `ACTIVITY_TYPE_CREATE_READ_WRITE_SESSION_V2`, `ACTIVITY_TYPE_DELETE_SUB_ORGANIZATION`, `ACTIVITY_TYPE_INIT_OTP_AUTH`, `ACTIVITY_TYPE_OTP_AUTH`, `ACTIVITY_TYPE_CREATE_SUB_ORGANIZATION_V7`, `ACTIVITY_TYPE_UPDATE_WALLET`, `ACTIVITY_TYPE_UPDATE_POLICY_V2`, `ACTIVITY_TYPE_CREATE_USERS_V3`, `ACTIVITY_TYPE_INIT_OTP_AUTH_V2`, `ACTIVITY_TYPE_INIT_OTP`, `ACTIVITY_TYPE_VERIFY_OTP`, `ACTIVITY_TYPE_OTP_LOGIN`, `ACTIVITY_TYPE_STAMP_LOGIN`, `ACTIVITY_TYPE_OAUTH_LOGIN`, `ACTIVITY_TYPE_UPDATE_USER_NAME`, `ACTIVITY_TYPE_UPDATE_USER_EMAIL`, `ACTIVITY_TYPE_UPDATE_USER_PHONE_NUMBER`, `ACTIVITY_TYPE_INIT_FIAT_ON_RAMP`, `ACTIVITY_TYPE_CREATE_SMART_CONTRACT_INTERFACE`, `ACTIVITY_TYPE_DELETE_SMART_CONTRACT_INTERFACE`, `ACTIVITY_TYPE_ENABLE_AUTH_PROXY`, `ACTIVITY_TYPE_DISABLE_AUTH_PROXY`, `ACTIVITY_TYPE_UPDATE_AUTH_PROXY_CONFIG`, `ACTIVITY_TYPE_CREATE_OAUTH2_CREDENTIAL`, `ACTIVITY_TYPE_UPDATE_OAUTH2_CREDENTIAL`, `ACTIVITY_TYPE_DELETE_OAUTH2_CREDENTIAL`, `ACTIVITY_TYPE_OAUTH2_AUTHENTICATE`, `ACTIVITY_TYPE_DELETE_WALLET_ACCOUNTS`, `ACTIVITY_TYPE_DELETE_POLICIES`, `ACTIVITY_TYPE_ETH_SEND_RAW_TRANSACTION`, `ACTIVITY_TYPE_ETH_SEND_TRANSACTION`, `ACTIVITY_TYPE_CREATE_FIAT_ON_RAMP_CREDENTIAL`, `ACTIVITY_TYPE_UPDATE_FIAT_ON_RAMP_CREDENTIAL`, `ACTIVITY_TYPE_DELETE_FIAT_ON_RAMP_CREDENTIAL`, `ACTIVITY_TYPE_EMAIL_AUTH_V3`, `ACTIVITY_TYPE_INIT_USER_EMAIL_RECOVERY_V2`, `ACTIVITY_TYPE_INIT_OTP_AUTH_V3`, `ACTIVITY_TYPE_INIT_OTP_V2`, `ACTIVITY_TYPE_UPSERT_GAS_USAGE_CONFIG`, `ACTIVITY_TYPE_CREATE_TVC_APP`, `ACTIVITY_TYPE_CREATE_TVC_DEPLOYMENT`, `ACTIVITY_TYPE_CREATE_TVC_MANIFEST_APPROVALS`, `ACTIVITY_TYPE_SOL_SEND_TRANSACTION`, `ACTIVITY_TYPE_INIT_OTP_V3`, `ACTIVITY_TYPE_VERIFY_OTP_V2`, `ACTIVITY_TYPE_OTP_LOGIN_V2`, `ACTIVITY_TYPE_UPDATE_ORGANIZATION_NAME`, `ACTIVITY_TYPE_CREATE_SUB_ORGANIZATION_V8`, `ACTIVITY_TYPE_CREATE_OAUTH_PROVIDERS_V2`, `ACTIVITY_TYPE_CREATE_USERS_V4`, `ACTIVITY_TYPE_CREATE_WEBHOOK_ENDPOINT`, `ACTIVITY_TYPE_UPDATE_WEBHOOK_ENDPOINT`, `ACTIVITY_TYPE_DELETE_WEBHOOK_ENDPOINT`, `ACTIVITY_TYPE_SET_IP_ALLOWLIST`, `ACTIVITY_TYPE_REMOVE_IP_ALLOWLIST`, `ACTIVITY_TYPE_UPDATE_TVC_APP_LIVE_DEPLOYMENT`, `ACTIVITY_TYPE_DELETE_TVC_DEPLOYMENT`, `ACTIVITY_TYPE_DELETE_TVC_APP_AND_DEPLOYMENTS`, `ACTIVITY_TYPE_RESTORE_TVC_DEPLOYMENT`, `ACTIVITY_TYPE_SPARK_SIGN_FROST`, `ACTIVITY_TYPE_SPARK_PREPARE_TRANSFER`, `ACTIVITY_TYPE_SPARK_CLAIM_TRANSFER`, `ACTIVITY_TYPE_SPARK_PREPARE_LIGHTNING_RECEIVE`, `ACTIVITY_TYPE_POST_TVC_QUORUM_KEY_SHARE` - + - -A successful response returns the following fields: +A successful response returns the following +fields: A list of activities. @@ -133,6 +135,7 @@ Enum options: `AUTHENTICATOR_TRANSPORT_BLE`, `AUTHENTICATOR_TRANSPORT_INTERNAL`, + authenticatorAttachment field @@ -142,6 +145,7 @@ Enum options: `cross-platform`, `platform` + clientExtensionResults field @@ -166,18 +170,31 @@ rk field - -Challenge presented for authentication purposes. + + + Challenge presented for authentication purposes. - -Unique identifier for the root user object. + + + Unique identifier for the root user object. + createAuthenticatorsIntent field @@ -232,6 +249,7 @@ Enum options: `AUTHENTICATOR_TRANSPORT_BLE`, `AUTHENTICATOR_TRANSPORT_INTERNAL`, + authenticatorAttachment field @@ -241,6 +259,7 @@ Enum options: `cross-platform`, `platform` + clientExtensionResults field @@ -265,18 +284,31 @@ rk field - -Challenge presented for authentication purposes. + + + Challenge presented for authentication purposes. - -Unique identifier for a given User. + + + Unique identifier for a given User. + createUsersIntent field @@ -310,6 +342,7 @@ Optional window (in seconds) indicating how long the API Key should last. + A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. @@ -361,6 +394,7 @@ Enum options: `AUTHENTICATOR_TRANSPORT_BLE`, `AUTHENTICATOR_TRANSPORT_INTERNAL`, + authenticatorAttachment field @@ -370,6 +404,7 @@ Enum options: `cross-platform`, `platform` + clientExtensionResults field @@ -394,12 +429,19 @@ rk field - -Challenge presented for authentication purposes. + + + Challenge presented for authentication purposes. + A list of User Tag IDs. This field, if not needed, should be an empty array in your request body. @@ -415,6 +457,7 @@ item field + createPrivateKeysIntent field @@ -439,6 +482,7 @@ item field + Cryptocurrency-specific formats for a derived address (e.g., Ethereum). @@ -457,6 +501,7 @@ Enum options: `ADDRESS_FORMAT_UNCOMPRESSED`, `ADDRESS_FORMAT_COMPRESSED`, `ADDRE + signRawPayloadIntent field @@ -481,6 +526,7 @@ Enum options: `HASH_FUNCTION_NO_OP`, `HASH_FUNCTION_SHA256`, `HASH_FUNCTION_KECC + createInvitationsIntent field @@ -502,6 +548,7 @@ item field + accessType field @@ -517,6 +564,7 @@ Unique identifier for the Sender of an Invitation. + acceptInvitationIntent field @@ -577,6 +625,7 @@ Enum options: `AUTHENTICATOR_TRANSPORT_BLE`, `AUTHENTICATOR_TRANSPORT_INTERNAL`, + authenticatorAttachment field @@ -586,6 +635,7 @@ Enum options: `cross-platform`, `platform` + clientExtensionResults field @@ -610,8 +660,14 @@ rk field - -Challenge presented for authentication purposes. + + + Challenge presented for authentication purposes. @@ -619,6 +675,7 @@ Challenge presented for authentication purposes. + createPolicyIntent field @@ -643,6 +700,7 @@ target field + effect field @@ -655,6 +713,7 @@ notes field + disablePrivateKeyIntent field @@ -664,6 +723,7 @@ Unique identifier for a given Private Key. + deleteUsersIntent field @@ -679,6 +739,7 @@ item field + deleteAuthenticatorsIntent field @@ -697,6 +758,7 @@ item field + deleteInvitationIntent field @@ -706,6 +768,7 @@ Unique identifier for a given Invitation object. + deleteOrganizationIntent field @@ -715,6 +778,7 @@ Unique identifier for a given Organization. + deletePolicyIntent field @@ -724,6 +788,7 @@ Unique identifier for a given Policy. + createUserTagIntent field @@ -742,6 +807,7 @@ item field + deleteUserTagsIntent field @@ -757,6 +823,7 @@ item field + signTransactionIntent field @@ -775,6 +842,7 @@ Enum options: `TRANSACTION_TYPE_ETHEREUM`, `TRANSACTION_TYPE_SOLANA`, `TRANSACTI + createApiKeysIntent field @@ -793,12 +861,19 @@ Optional window (in seconds) indicating how long the API Key should last. - -Unique identifier for a given User. + + + Unique identifier for a given User. + deleteApiKeysIntent field @@ -817,6 +892,7 @@ item field + approveActivityIntent field @@ -826,6 +902,7 @@ An artifact verifying a User's action. + rejectActivityIntent field @@ -835,6 +912,7 @@ An artifact verifying a User's action. + createPrivateKeyTagIntent field @@ -853,6 +931,7 @@ item field + deletePrivateKeyTagsIntent field @@ -868,6 +947,7 @@ item field + createPolicyIntentV2 field @@ -898,6 +978,7 @@ item field + effect field @@ -910,6 +991,7 @@ notes field + setPaymentMethodIntent field @@ -934,6 +1016,7 @@ The name associated with the credit card. + activateBillingTierIntent field @@ -946,6 +1029,7 @@ orbPlanId field + deletePaymentMethodIntent field @@ -955,6 +1039,7 @@ The payment method that the customer wants to remove. + createPolicyIntentV3 field @@ -979,6 +1064,7 @@ Notes for a Policy. + createApiOnlyUsersIntent field @@ -1000,6 +1086,7 @@ item field + A list of API Key parameters. This field, if not needed, should be an empty array in your request body. @@ -1021,6 +1108,7 @@ Optional window (in seconds) indicating how long the API Key should last. + updateRootQuorumIntent field @@ -1039,6 +1127,7 @@ item field + updateUserTagIntent field @@ -1057,6 +1146,7 @@ item field + A list of User IDs to remove this tag from. @@ -1069,6 +1159,7 @@ item field + updatePrivateKeyTagIntent field @@ -1087,6 +1178,7 @@ item field + A list of Private Key IDs to remove this tag from. @@ -1099,6 +1191,7 @@ item field + createAuthenticatorsIntentV2 field @@ -1141,12 +1234,19 @@ Enum options: `AUTHENTICATOR_TRANSPORT_BLE`, `AUTHENTICATOR_TRANSPORT_INTERNAL`, - -Unique identifier for a given User. + + + Unique identifier for a given User. + acceptInvitationIntentV2 field @@ -1198,6 +1298,7 @@ Enum options: `AUTHENTICATOR_TRANSPORT_BLE`, `AUTHENTICATOR_TRANSPORT_INTERNAL`, + createOrganizationIntentV2 field @@ -1246,12 +1347,19 @@ Enum options: `AUTHENTICATOR_TRANSPORT_BLE`, `AUTHENTICATOR_TRANSPORT_INTERNAL`, - -Unique identifier for the root user object. + + + Unique identifier for the root user object. + createUsersIntentV2 field @@ -1279,6 +1387,7 @@ Optional window (in seconds) indicating how long the API Key should last. + A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. @@ -1318,6 +1427,7 @@ Enum options: `AUTHENTICATOR_TRANSPORT_BLE`, `AUTHENTICATOR_TRANSPORT_INTERNAL`, + A list of User Tag IDs. This field, if not needed, should be an empty array in your request body. @@ -1333,6 +1443,7 @@ item field + createSubOrganizationIntent field @@ -1381,6 +1492,7 @@ Enum options: `AUTHENTICATOR_TRANSPORT_BLE`, `AUTHENTICATOR_TRANSPORT_INTERNAL`, + createSubOrganizationIntentV2 field @@ -1411,6 +1523,7 @@ Optional window (in seconds) indicating how long the API Key should last. + A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. @@ -1453,12 +1566,20 @@ Enum options: `AUTHENTICATOR_TRANSPORT_BLE`, `AUTHENTICATOR_TRANSPORT_INTERNAL`, - -The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users + + + The threshold of unique approvals to reach root quorum. This value must be + less than or equal to the number of root users + updateAllowedOriginsIntent field @@ -1474,6 +1595,7 @@ item field + createPrivateKeysIntentV2 field @@ -1498,6 +1620,7 @@ item field + Cryptocurrency-specific formats for a derived address (e.g., Ethereum). @@ -1516,6 +1639,7 @@ Enum options: `ADDRESS_FORMAT_UNCOMPRESSED`, `ADDRESS_FORMAT_COMPRESSED`, `ADDRE + updateUserIntent field @@ -1537,12 +1661,19 @@ item field - -The user's phone number in E.164 format e.g. +13214567890 + + + The user's phone number in E.164 format e.g. +13214567890 + updatePolicyIntent field @@ -1570,6 +1701,7 @@ Accompanying notes for a Policy (optional). + setPaymentMethodIntentV2 field @@ -1585,6 +1717,7 @@ The name associated with the credit card. + createSubOrganizationIntentV3 field @@ -1615,6 +1748,7 @@ Optional window (in seconds) indicating how long the API Key should last. + A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. @@ -1657,6 +1791,7 @@ Enum options: `AUTHENTICATOR_TRANSPORT_BLE`, `AUTHENTICATOR_TRANSPORT_INTERNAL`, + The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users @@ -1681,6 +1816,7 @@ item field + Cryptocurrency-specific formats for a derived address (e.g., Ethereum). @@ -1699,6 +1835,7 @@ Enum options: `ADDRESS_FORMAT_UNCOMPRESSED`, `ADDRESS_FORMAT_COMPRESSED`, `ADDRE + createWalletIntent field @@ -1732,12 +1869,20 @@ Enum options: `ADDRESS_FORMAT_UNCOMPRESSED`, `ADDRESS_FORMAT_COMPRESSED`, `ADDRE - -Length of mnemonic to generate the Wallet seed. Defaults to 12. Accepted values: 12, 15, 18, 21, 24. + + + Length of mnemonic to generate the Wallet seed. Defaults to 12. Accepted + values: 12, 15, 18, 21, 24. + createWalletAccountsIntent field @@ -1771,12 +1916,21 @@ Enum options: `ADDRESS_FORMAT_UNCOMPRESSED`, `ADDRESS_FORMAT_COMPRESSED`, `ADDRE - -Indicates if the wallet accounts should be persisted. This is helpful if you'd like to see the addresses of different derivation paths without actually creating the accounts. Defaults to true. + + + Indicates if the wallet accounts should be persisted. This is helpful if you'd + like to see the addresses of different derivation paths without actually + creating the accounts. Defaults to true. + initUserEmailRecoveryIntent field @@ -1810,18 +1964,36 @@ Unique identifier for a given Email Template. If not specified, the default is t - -Optional custom email address from which to send the OTP email + + + Optional custom email address from which to send the OTP email - -Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications' + + Optional custom sender name for use with sendFromEmailAddress; if left empty, + will default to 'Notifications' - -Optional custom email address to use as reply-to + + Optional custom email address to use as reply-to + recoverUserIntent field @@ -1864,12 +2036,19 @@ Enum options: `AUTHENTICATOR_TRANSPORT_BLE`, `AUTHENTICATOR_TRANSPORT_INTERNAL`, - -Unique identifier for the user performing recovery. + + + Unique identifier for the user performing recovery. + setOrganizationFeatureIntent field @@ -1885,6 +2064,7 @@ Optional value for the feature. Will override existing values if feature is alre + removeOrganizationFeatureIntent field @@ -1897,6 +2077,7 @@ Enum options: `FEATURE_NAME_ROOT_USER_EMAIL_RECOVERY`, `FEATURE_NAME_WEBAUTHN_OR + signRawPayloadIntentV2 field @@ -1921,6 +2102,7 @@ Enum options: `HASH_FUNCTION_NO_OP`, `HASH_FUNCTION_SHA256`, `HASH_FUNCTION_KECC + signTransactionIntentV2 field @@ -1939,6 +2121,7 @@ Enum options: `TRANSACTION_TYPE_ETHEREUM`, `TRANSACTION_TYPE_SOLANA`, `TRANSACTI + exportPrivateKeyIntent field @@ -1951,6 +2134,7 @@ Client-side public key generated by the user, to which the export bundle will be + exportWalletIntent field @@ -1969,6 +2153,7 @@ Enum options: `MNEMONIC_LANGUAGE_ENGLISH`, `MNEMONIC_LANGUAGE_SIMPLIFIED_CHINESE + createSubOrganizationIntentV4 field @@ -1999,6 +2184,7 @@ Optional window (in seconds) indicating how long the API Key should last. + A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. @@ -2041,6 +2227,7 @@ Enum options: `AUTHENTICATOR_TRANSPORT_BLE`, `AUTHENTICATOR_TRANSPORT_INTERNAL`, + The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users @@ -2077,21 +2264,40 @@ Enum options: `ADDRESS_FORMAT_UNCOMPRESSED`, `ADDRESS_FORMAT_COMPRESSED`, `ADDRE - -Length of mnemonic to generate the Wallet seed. Defaults to 12. Accepted values: 12, 15, 18, 21, 24. + + + Length of mnemonic to generate the Wallet seed. Defaults to 12. Accepted + values: 12, 15, 18, 21, 24. - -Disable email recovery for the sub-organization + + + Disable email recovery for the sub-organization - -Disable email auth for the sub-organization + + Disable email auth for the sub-organization + emailAuthIntent field @@ -2128,21 +2334,44 @@ Unique identifier for a given Email Template. If not specified, the default is t - -Invalidate all other previously generated Email Auth API keys + + + Invalidate all other previously generated Email Auth API keys - -Optional custom email address from which to send the email + + Optional custom email address from which to send the email - -Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications' + + Optional custom sender name for use with sendFromEmailAddress; if left empty, + will default to 'Notifications' - -Optional custom email address to use as reply-to + + Optional custom email address to use as reply-to + exportWalletAccountIntent field @@ -2155,6 +2384,7 @@ Client-side public key generated by the user, to which the export bundle will be + initImportWalletIntent field @@ -2164,6 +2394,7 @@ The ID of the User importing a Wallet. + importWalletIntent field @@ -2206,6 +2437,7 @@ Enum options: `ADDRESS_FORMAT_UNCOMPRESSED`, `ADDRESS_FORMAT_COMPRESSED`, `ADDRE + initImportPrivateKeyIntent field @@ -2215,6 +2447,7 @@ The ID of the User importing a Private Key. + importPrivateKeyIntent field @@ -2248,6 +2481,7 @@ Enum options: `ADDRESS_FORMAT_UNCOMPRESSED`, `ADDRESS_FORMAT_COMPRESSED`, `ADDRE + createPoliciesIntent field @@ -2278,6 +2512,7 @@ Notes for a Policy. + signRawPayloadsIntent field @@ -2293,6 +2528,7 @@ item field + encoding field @@ -2308,6 +2544,7 @@ Enum options: `HASH_FUNCTION_NO_OP`, `HASH_FUNCTION_SHA256`, `HASH_FUNCTION_KECC + createReadOnlySessionIntent field @@ -2332,6 +2569,7 @@ Base64 encoded OIDC token + deleteOauthProvidersIntent field @@ -2350,6 +2588,7 @@ item field + createSubOrganizationIntentV5 field @@ -2380,6 +2619,7 @@ Optional window (in seconds) indicating how long the API Key should last. + A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. @@ -2419,6 +2659,7 @@ Enum options: `AUTHENTICATOR_TRANSPORT_BLE`, `AUTHENTICATOR_TRANSPORT_INTERNAL`, + A list of Oauth providers. This field, if not needed, should be an empty array in your request body. @@ -2434,6 +2675,7 @@ Base64 encoded OIDC token + The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users @@ -2470,21 +2712,40 @@ Enum options: `ADDRESS_FORMAT_UNCOMPRESSED`, `ADDRESS_FORMAT_COMPRESSED`, `ADDRE - -Length of mnemonic to generate the Wallet seed. Defaults to 12. Accepted values: 12, 15, 18, 21, 24. + + + Length of mnemonic to generate the Wallet seed. Defaults to 12. Accepted + values: 12, 15, 18, 21, 24. - -Disable email recovery for the sub-organization + + + Disable email recovery for the sub-organization - -Disable email auth for the sub-organization + + Disable email auth for the sub-organization + oauthIntent field @@ -2506,6 +2767,7 @@ Invalidate all other previously generated Oauth API keys + createApiKeysIntentV2 field @@ -2530,12 +2792,19 @@ Optional window (in seconds) indicating how long the API Key should last. - -Unique identifier for a given User. + + + Unique identifier for a given User. + createReadWriteSessionIntent field @@ -2554,6 +2823,7 @@ Expiration window (in seconds) indicating how long the API key is valid for. If + emailAuthIntentV2 field @@ -2590,21 +2860,44 @@ Unique identifier for a given Email Template. If not specified, the default is t - -Invalidate all other previously generated Email Auth API keys + + + Invalidate all other previously generated Email Auth API keys - -Optional custom email address from which to send the email + + Optional custom email address from which to send the email - -Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications' + + Optional custom sender name for use with sendFromEmailAddress; if left empty, + will default to 'Notifications' - -Optional custom email address to use as reply-to + + Optional custom email address to use as reply-to + createSubOrganizationIntentV6 field @@ -2641,6 +2934,7 @@ Optional window (in seconds) indicating how long the API Key should last. + A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. @@ -2680,6 +2974,7 @@ Enum options: `AUTHENTICATOR_TRANSPORT_BLE`, `AUTHENTICATOR_TRANSPORT_INTERNAL`, + A list of Oauth providers. This field, if not needed, should be an empty array in your request body. @@ -2695,6 +2990,7 @@ Base64 encoded OIDC token + The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users @@ -2731,21 +3027,40 @@ Enum options: `ADDRESS_FORMAT_UNCOMPRESSED`, `ADDRESS_FORMAT_COMPRESSED`, `ADDRE - -Length of mnemonic to generate the Wallet seed. Defaults to 12. Accepted values: 12, 15, 18, 21, 24. + + + Length of mnemonic to generate the Wallet seed. Defaults to 12. Accepted + values: 12, 15, 18, 21, 24. - -Disable email recovery for the sub-organization + + + Disable email recovery for the sub-organization - -Disable email auth for the sub-organization + + Disable email auth for the sub-organization + deletePrivateKeysIntent field @@ -2758,12 +3073,20 @@ item field - -Optional parameter for deleting the private keys, even if any have not been previously exported. If they have been exported, this field is ignored. + + + Optional parameter for deleting the private keys, even if any have not been + previously exported. If they have been exported, this field is ignored. + deleteWalletsIntent field @@ -2776,12 +3099,20 @@ item field - -Optional parameter for deleting the wallets, even if any have not been previously exported. If they have been exported, this field is ignored. + + + Optional parameter for deleting the wallets, even if any have not been + previously exported. If they have been exported, this field is ignored. + createReadWriteSessionIntentV2 field @@ -2803,6 +3134,7 @@ Invalidate all other previously generated ReadWriteSession API keys + deleteSubOrganizationIntent field @@ -2812,6 +3144,7 @@ Sub-organization deletion, by default, requires associated wallets and private k + initOtpAuthIntent field @@ -2842,6 +3175,7 @@ Unique identifier for a given Email Template. If not specified, the default is t + smsCustomization field @@ -2851,21 +3185,45 @@ Template containing references to .OtpCode i.e Your OTP is \{\{.OtpCode\}\} - -Optional client-generated user identifier to enable per-user rate limiting for SMS auth. We recommend using a hash of the client-side IP address. + + + Optional client-generated user identifier to enable per-user rate limiting for + SMS auth. We recommend using a hash of the client-side IP address. - -Optional custom email address from which to send the OTP email + + Optional custom email address from which to send the OTP email - -Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications' + + Optional custom sender name for use with sendFromEmailAddress; if left empty, + will default to 'Notifications' - -Optional custom email address to use as reply-to + + Optional custom email address to use as reply-to + otpAuthIntent field @@ -2890,6 +3248,7 @@ Invalidate all other previously generated OTP Auth API keys + createSubOrganizationIntentV7 field @@ -2929,6 +3288,7 @@ Optional window (in seconds) indicating how long the API Key should last. + A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. @@ -2968,6 +3328,7 @@ Enum options: `AUTHENTICATOR_TRANSPORT_BLE`, `AUTHENTICATOR_TRANSPORT_INTERNAL`, + A list of Oauth providers. This field, if not needed, should be an empty array in your request body. @@ -2983,6 +3344,7 @@ Base64 encoded OIDC token + The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users @@ -3019,12 +3381,20 @@ Enum options: `ADDRESS_FORMAT_UNCOMPRESSED`, `ADDRESS_FORMAT_COMPRESSED`, `ADDRE - -Length of mnemonic to generate the Wallet seed. Defaults to 12. Accepted values: 12, 15, 18, 21, 24. + + + Length of mnemonic to generate the Wallet seed. Defaults to 12. Accepted + values: 12, 15, 18, 21, 24. + Disable email recovery for the sub-organization @@ -3064,6 +3434,7 @@ The cryptographic signature over the message. + updateWalletIntent field @@ -3076,6 +3447,7 @@ Human-readable name for a Wallet. + updatePolicyIntentV2 field @@ -3103,6 +3475,7 @@ Accompanying notes for a Policy (optional). + createUsersIntentV3 field @@ -3139,6 +3512,7 @@ Optional window (in seconds) indicating how long the API Key should last. + A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. @@ -3178,6 +3552,7 @@ Enum options: `AUTHENTICATOR_TRANSPORT_BLE`, `AUTHENTICATOR_TRANSPORT_INTERNAL`, + A list of Oauth providers. This field, if not needed, should be an empty array in your request body. @@ -3190,6 +3565,7 @@ Base64 encoded OIDC token + A list of User Tag IDs. This field, if not needed, should be an empty array in your request body. @@ -3205,6 +3581,7 @@ item field + initOtpAuthIntentV2 field @@ -3238,6 +3615,7 @@ Unique identifier for a given Email Template. If not specified, the default is t + smsCustomization field @@ -3247,24 +3625,54 @@ Template containing references to .OtpCode i.e Your OTP is \{\{.OtpCode\}\} - -Optional client-generated user identifier to enable per-user rate limiting for SMS auth. We recommend using a hash of the client-side IP address. + + + Optional client-generated user identifier to enable per-user rate limiting for + SMS auth. We recommend using a hash of the client-side IP address. - -Optional custom email address from which to send the OTP email + + Optional custom email address from which to send the OTP email - -Optional flag to specify if the OTP code should be alphanumeric (Crockford’s Base32). Default = true + + Optional flag to specify if the OTP code should be alphanumeric (Crockford’s + Base32). Default = true - -Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications' + + Optional custom sender name for use with sendFromEmailAddress; if left empty, + will default to 'Notifications' - -Optional custom email address to use as reply-to + + Optional custom email address to use as reply-to + initOtpIntent field @@ -3298,6 +3706,7 @@ Unique identifier for a given Email Template. If not specified, the default is t + smsCustomization field @@ -3307,27 +3716,64 @@ Template containing references to .OtpCode i.e Your OTP is \{\{.OtpCode\}\} - -Optional client-generated user identifier to enable per-user rate limiting for SMS auth. We recommend using a hash of the client-side IP address. + + + Optional client-generated user identifier to enable per-user rate limiting for + SMS auth. We recommend using a hash of the client-side IP address. - -Optional custom email address from which to send the OTP email + + Optional custom email address from which to send the OTP email - -Optional flag to specify if the OTP code should be alphanumeric (Crockford’s Base32). Default = true + + Optional flag to specify if the OTP code should be alphanumeric (Crockford’s + Base32). Default = true - -Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications' + + Optional custom sender name for use with sendFromEmailAddress; if left empty, + will default to 'Notifications' - -Expiration window (in seconds) indicating how long the OTP is valid for. If not provided, a default of 5 minutes will be used. Maximum value is 600 seconds (10 minutes) + + Expiration window (in seconds) indicating how long the OTP is valid for. If + not provided, a default of 5 minutes will be used. Maximum value is 600 + seconds (10 minutes) - -Optional custom email address to use as reply-to + + Optional custom email address to use as reply-to + verifyOtpIntent field @@ -3346,6 +3792,7 @@ Client-side public key generated by the user, which will be added to the JWT res + otpLoginIntent field @@ -3385,6 +3832,7 @@ The cryptographic signature over the message. + stampLoginIntent field @@ -3400,6 +3848,7 @@ Invalidate all other previously generated Login API keys + oauthLoginIntent field @@ -3418,6 +3867,7 @@ Invalidate all other previously generated Login API keys + updateUserNameIntent field @@ -3430,6 +3880,7 @@ Human-readable name for a User. + updateUserEmailIntent field @@ -3445,6 +3896,7 @@ Signed JWT containing a unique id, expiry, verification type, contact + updateUserPhoneNumberIntent field @@ -3460,6 +3912,7 @@ Signed JWT containing a unique id, expiry, verification type, contact + initFiatOnRampIntent field @@ -3514,6 +3967,7 @@ Optional MoonPay Widget URL to sign when using MoonPay client SDKs with URL Sign + createSmartContractInterfaceIntent field @@ -3538,6 +3992,7 @@ Notes for a Smart Contract Interface. + deleteSmartContractInterfaceIntent field @@ -3547,6 +4002,7 @@ The ID of a Smart Contract Interface intended for deletion. + enableAuthProxyIntent field @@ -3565,6 +4021,7 @@ item field + Updated list of allowed proxy authentication methods. @@ -3574,6 +4031,7 @@ item field + Custom 'from' address for auth-related emails. @@ -3607,6 +4065,7 @@ Unique identifier for a given Email Template. If not specified, the default is t + smsCustomizationParams field @@ -3616,6 +4075,7 @@ Template containing references to .OtpCode i.e Your OTP is \{\{.OtpCode\}\} + walletKitSettings field @@ -3628,15 +4088,27 @@ item field - -Mapping of social login providers to their Oauth client IDs. + + + Mapping of social login providers to their Oauth client IDs. - -Oauth redirect URL to be used for social login flows. + + Oauth redirect URL to be used for social login flows. + OTP code lifetime in seconds. @@ -3670,6 +4142,7 @@ item field + createOauth2CredentialIntent field @@ -3688,6 +4161,7 @@ The client secret issued by the OAuth 2.0 provider encrypted to the TLS Fetcher + updateOauth2CredentialIntent field @@ -3709,6 +4183,7 @@ The client secret issued by the OAuth 2.0 provider encrypted to the TLS Fetcher + deleteOauth2CredentialIntent field @@ -3718,6 +4193,7 @@ The ID of the OAuth 2.0 credential to delete + oauth2AuthenticateIntent field @@ -3742,6 +4218,7 @@ An optional P256 public key to which, if provided, the bearer token will be encr + deleteWalletAccountsIntent field @@ -3754,12 +4231,20 @@ item field - -Optional parameter for deleting the wallet accounts, even if any have not been previously exported. If they have been exported, this field is ignored. + + + Optional parameter for deleting the wallet accounts, even if any have not been + previously exported. If they have been exported, this field is ignored. + deletePoliciesIntent field @@ -3775,6 +4260,7 @@ item field + ethSendRawTransactionIntent field @@ -3790,6 +4276,7 @@ Enum options: `eip155:1`, `eip155:11155111`, `eip155:8453`, `eip155:84532`, `eip + ethSendTransactionIntent field @@ -3835,6 +4322,7 @@ The gas station delegate contract nonce. Only used when sponsor=true. Include th + createFiatOnRampCredentialIntent field @@ -3862,6 +4350,7 @@ If the on-ramp credential is a sandbox credential + updateFiatOnRampCredentialIntent field @@ -3889,6 +4378,7 @@ Private API key for the on-ramp provider encrypted to our on-ramp encryption pub + deleteFiatOnRampCredentialIntent field @@ -3898,6 +4388,7 @@ The ID of the fiat on-ramp credential to delete + emailAuthIntentV3 field @@ -3934,21 +4425,44 @@ Unique identifier for a given Email Template. If not specified, the default is t - -Invalidate all other previously generated Email Auth API keys + + + Invalidate all other previously generated Email Auth API keys - -Optional custom email address from which to send the email + + Optional custom email address from which to send the email - -Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications' + + Optional custom sender name for use with sendFromEmailAddress; if left empty, + will default to 'Notifications' - -Optional custom email address to use as reply-to + + Optional custom email address to use as reply-to + initUserEmailRecoveryIntentV2 field @@ -3982,18 +4496,36 @@ Unique identifier for a given Email Template. If not specified, the default is t - -Optional custom email address from which to send the OTP email + + + Optional custom email address from which to send the OTP email - -Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications' + + Optional custom sender name for use with sendFromEmailAddress; if left empty, + will default to 'Notifications' - -Optional custom email address to use as reply-to + + Optional custom email address to use as reply-to + initOtpIntentV2 field @@ -4027,6 +4559,7 @@ Unique identifier for a given Email Template. If not specified, the default is t + smsCustomization field @@ -4036,27 +4569,64 @@ Template containing references to .OtpCode i.e Your OTP is \{\{.OtpCode\}\} - -Optional client-generated user identifier to enable per-user rate limiting for SMS auth. We recommend using a hash of the client-side IP address. + + + Optional client-generated user identifier to enable per-user rate limiting for + SMS auth. We recommend using a hash of the client-side IP address. - -Optional custom email address from which to send the OTP email + + Optional custom email address from which to send the OTP email - -Optional flag to specify if the OTP code should be alphanumeric (Crockford’s Base32). Default = true + + Optional flag to specify if the OTP code should be alphanumeric (Crockford’s + Base32). Default = true - -Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications' + + Optional custom sender name for use with sendFromEmailAddress; if left empty, + will default to 'Notifications' - -Expiration window (in seconds) indicating how long the OTP is valid for. If not provided, a default of 5 minutes will be used. Maximum value is 600 seconds (10 minutes) + + Expiration window (in seconds) indicating how long the OTP is valid for. If + not provided, a default of 5 minutes will be used. Maximum value is 600 + seconds (10 minutes) - -Optional custom email address to use as reply-to + + Optional custom email address to use as reply-to + initOtpAuthIntentV3 field @@ -4090,6 +4660,7 @@ Unique identifier for a given Email Template. If not specified, the default is t + smsCustomization field @@ -4099,27 +4670,64 @@ Template containing references to .OtpCode i.e Your OTP is \{\{.OtpCode\}\} - -Optional client-generated user identifier to enable per-user rate limiting for SMS auth. We recommend using a hash of the client-side IP address. + + + Optional client-generated user identifier to enable per-user rate limiting for + SMS auth. We recommend using a hash of the client-side IP address. - -Optional custom email address from which to send the OTP email + + Optional custom email address from which to send the OTP email - -Optional flag to specify if the OTP code should be alphanumeric (Crockford’s Base32). Default = true + + Optional flag to specify if the OTP code should be alphanumeric (Crockford’s + Base32). Default = true - -Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications' + + Optional custom sender name for use with sendFromEmailAddress; if left empty, + will default to 'Notifications' - -Expiration window (in seconds) indicating how long the OTP is valid for. If not provided, a default of 5 minutes will be used. Maximum value is 600 seconds (10 minutes) + + Expiration window (in seconds) indicating how long the OTP is valid for. If + not provided, a default of 5 minutes will be used. Maximum value is 600 + seconds (10 minutes) - -Optional custom email address to use as reply-to + + Optional custom email address to use as reply-to + upsertGasUsageConfigIntent field @@ -4147,6 +4755,7 @@ Whether Solana rent prefunding is enabled for the organization. When omitted, th + createTvcAppIntent field @@ -4177,6 +4786,7 @@ Public key for this operator + Existing operators to use as part of this new operator set @@ -4186,12 +4796,19 @@ item field - -The threshold of operators needed to reach consensus in this new Operator Set + + + The threshold of operators needed to reach consensus in this new Operator Set + Unique identifier for an existing TVC operator set to use as the Share Set for this TVC application. If left empty, a new Share Set configuration is required @@ -4213,6 +4830,7 @@ Public key for this operator + Existing operators to use as part of this new operator set @@ -4222,18 +4840,31 @@ item field - -The threshold of operators needed to reach consensus in this new Operator Set + + + The threshold of operators needed to reach consensus in this new Operator Set - -Enables network egress for this TVC app. Default if not provided: false. + + + Enables network egress for this TVC app. Default if not provided: false. + createTvcDeploymentIntent field @@ -4258,6 +4889,7 @@ item field + Digest of the pivot binary in the pivot container. This value will be inserted in the QOS manifest to ensure application integrity. @@ -4285,6 +4917,7 @@ Port to use for public ingress. + createTvcManifestApprovalsIntent field @@ -4306,6 +4939,7 @@ Signature from the operator approving the manifest + solSendTransactionIntent field @@ -4330,6 +4964,7 @@ user-provided blockhash for replay protection / deadline control. If omitted and + initOtpIntentV3 field @@ -4363,6 +4998,7 @@ Unique identifier for a given Email Template. If not specified, the default is t + smsCustomization field @@ -4372,27 +5008,64 @@ Template containing references to .OtpCode i.e Your OTP is \{\{.OtpCode\}\} - -Optional client-generated user identifier to enable per-user rate limiting for SMS auth. We recommend using a hash of the client-side IP address. + + + Optional client-generated user identifier to enable per-user rate limiting for + SMS auth. We recommend using a hash of the client-side IP address. - -Optional custom email address from which to send the OTP email + + Optional custom email address from which to send the OTP email - -Optional flag to specify if the OTP code should be alphanumeric (Crockford’s Base32). If set to false, OTP code will only be numeric. Default = true + + Optional flag to specify if the OTP code should be alphanumeric (Crockford’s + Base32). If set to false, OTP code will only be numeric. Default = true - -Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications' + + Optional custom sender name for use with sendFromEmailAddress; if left empty, + will default to 'Notifications' - -Expiration window (in seconds) indicating how long the OTP is valid for. If not provided, a default of 5 minutes will be used. Maximum value is 600 seconds (10 minutes) + + Expiration window (in seconds) indicating how long the OTP is valid for. If + not provided, a default of 5 minutes will be used. Maximum value is 600 + seconds (10 minutes) - -Optional custom email address to use as reply-to + + Optional custom email address to use as reply-to + verifyOtpIntentV2 field @@ -4408,6 +5081,7 @@ Expiration window (in seconds) indicating how long the verification token is val + otpLoginIntentV2 field @@ -4438,15 +5112,28 @@ The cryptographic signature over the message. - -Expiration window (in seconds) indicating how long the Session is valid for. If not provided, a default of 15 minutes will be used. + + + Expiration window (in seconds) indicating how long the Session is valid for. + If not provided, a default of 15 minutes will be used. - -Invalidate all other previously generated Login sessions + + Invalidate all other previously generated Login sessions + updateOrganizationNameIntent field @@ -4456,6 +5143,7 @@ New name for the Organization. + createSubOrganizationIntentV8 field @@ -4495,6 +5183,7 @@ Optional window (in seconds) indicating how long the API Key should last. + A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. @@ -4534,6 +5223,7 @@ Enum options: `AUTHENTICATOR_TRANSPORT_BLE`, `AUTHENTICATOR_TRANSPORT_INTERNAL`, + A list of Oauth providers. This field, if not needed, should be an empty array in your request body. @@ -4564,6 +5254,7 @@ The audience from the OIDC token (aud claim) + The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users @@ -4600,12 +5291,20 @@ Enum options: `ADDRESS_FORMAT_UNCOMPRESSED`, `ADDRESS_FORMAT_COMPRESSED`, `ADDRE - -Length of mnemonic to generate the Wallet seed. Defaults to 12. Accepted values: 12, 15, 18, 21, 24. + + + Length of mnemonic to generate the Wallet seed. Defaults to 12. Accepted + values: 12, 15, 18, 21, 24. + Disable email recovery for the sub-organization @@ -4645,6 +5344,7 @@ The cryptographic signature over the message. + createOauthProvidersIntentV2 field @@ -4681,6 +5381,7 @@ The audience from the OIDC token (aud claim) + createUsersIntentV4 field @@ -4717,6 +5418,7 @@ Optional window (in seconds) indicating how long the API Key should last. + A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. @@ -4756,6 +5458,7 @@ Enum options: `AUTHENTICATOR_TRANSPORT_BLE`, `AUTHENTICATOR_TRANSPORT_INTERNAL`, + A list of Oauth providers. This field, if not needed, should be an empty array in your request body. @@ -4783,6 +5486,7 @@ The audience from the OIDC token (aud claim) + A list of User Tag IDs. This field, if not needed, should be an empty array in your request body. @@ -4798,6 +5502,7 @@ item field + createWebhookEndpointIntent field @@ -4825,6 +5530,7 @@ Whether this subscription is active. + updateWebhookEndpointIntent field @@ -4843,6 +5549,7 @@ Whether this webhook endpoint is active. + deleteWebhookEndpointIntent field @@ -4852,6 +5559,7 @@ Unique identifier of the webhook endpoint to delete. + setIpAllowlistIntent field @@ -4873,12 +5581,20 @@ Optional human-readable label for this rule (e.g., 'Office VPN'). - -Behavior when an error occurs during IP allowlist evaluation. Valid values: ALLOW, DENY. Defaults to DENY. + + + Behavior when an error occurs during IP allowlist evaluation. Valid values: + ALLOW, DENY. Defaults to DENY. + removeIpAllowlistIntent field @@ -4888,6 +5604,7 @@ The public component of an API key. If null, removes the organization-level IP a + updateTvcAppLiveDeploymentIntent field @@ -4897,6 +5614,7 @@ The unique identifier of the TVC deployment to set as live for the app. + deleteTvcDeploymentIntent field @@ -4906,6 +5624,7 @@ The unique identifier of the TVC deployment to delete. + deleteTvcAppAndDeploymentsIntent field @@ -4915,6 +5634,7 @@ The unique identifier of the TVC app to delete. The app and all associated deplo + restoreTvcDeploymentIntent field @@ -4924,6 +5644,7 @@ The unique identifier of the TVC deployment to restore. + sparkSignFrostIntent field @@ -4948,6 +5669,7 @@ Unique identifier for the Spark signing leaf. + deposit field @@ -4960,12 +5682,19 @@ Index used to derive the static deposit key. - -htlcPreimage field + + + htlcPreimage field + Hex-encoded 32-byte sighash to sign. @@ -4987,8 +5716,21 @@ Binding commitment E, hex-encoded compressed secp256k1 point. - -Optional adaptor point T (hex-encoded 33-byte compressed secp256k1 pubkey). When set, Turnkey produces a Schnorr adaptor pre-signature with the FROST challenge bound to `R+T` (where `R` is the aggregate group nonce commitment from FROST). The party holding the discrete log `t` completes the pre-sig to a valid BIP-340 signature by adding `t` (or `-t`, for parity) to the signature scalar `s`. This is primarily used by Spark leaves-swap and other adaptor-bound flows; absent or empty leads to plain FROST signing (the typical case). + + + Optional adaptor point T (hex-encoded 33-byte compressed secp256k1 pubkey). + When set, Turnkey produces a Schnorr adaptor pre-signature with the FROST + challenge bound to `R+T` (where `R` is the aggregate group nonce commitment + from FROST). The party holding the discrete log `t` completes the pre-sig to a + valid BIP-340 signature by adding `t` (or `-t`, for parity) to the signature + scalar `s`. This is primarily used by Spark leaves-swap and other + adaptor-bound flows; absent or empty leads to plain FROST signing (the typical + case). @@ -4996,6 +5738,7 @@ Optional adaptor point T (hex-encoded 33-byte compressed secp256k1 pubkey). When + sparkPrepareTransferIntent field @@ -5029,6 +5772,7 @@ Unique identifier for the Spark signing leaf. + deposit field @@ -5041,12 +5785,19 @@ Index used to derive the static deposit key. - -htlcPreimage field + + + htlcPreimage field + newLeafDerivation field @@ -5062,6 +5813,7 @@ Unique identifier for the Spark signing leaf. + deposit field @@ -5074,24 +5826,51 @@ Index used to derive the static deposit key. - -htlcPreimage field + + + htlcPreimage field - -Client-produced CPFP refund signature (hex-encoded), passed through verbatim into the per-operator SendLeafKeyTweak. Empty omits the field from the operator package. + + + Client-produced CPFP refund signature (hex-encoded), passed through verbatim + into the per-operator SendLeafKeyTweak. Empty omits the field from the + operator package. - -Client-produced direct refund signature (hex-encoded). Passed through verbatim. + + Client-produced direct refund signature (hex-encoded). Passed through + verbatim. - -Client-produced direct-from-CPFP refund signature (hex-encoded). Passed through verbatim. + + Client-produced direct-from-CPFP refund signature (hex-encoded). Passed + through verbatim. + Feldman VSS threshold for reconstructing the per-leaf tweak scalar. @@ -5107,8 +5886,16 @@ Operator's ECIES encryption pubkey (hex-encoded compressed secp256k1 point). - -Recipient's identity pubkey (hex-encoded compressed secp256k1 point). Each leaf's new_priv is ECIES-encrypted to this key and embedded in the per-operator package for claim-time delivery. + + + Recipient's identity pubkey (hex-encoded compressed secp256k1 point). Each + leaf's new_priv is ECIES-encrypted to this key and embedded in the + per-operator package for claim-time delivery. @@ -5116,6 +5903,7 @@ Recipient's identity pubkey (hex-encoded compressed secp256k1 point). Each leaf' + sparkClaimTransferIntent field @@ -5140,6 +5928,7 @@ Hex-encoded 64-byte compact ECDSA signature binding (leaf_id, transfer_id, ciphe + Shamir threshold for reconstructing the per-leaf claim secret. @@ -5155,11 +5944,24 @@ Operator's ECIES encryption pubkey (hex-encoded compressed secp256k1 point). - -Spark transfer identifier (UUID). Used together with each leaf's sender_signature to verify the sender bound this ciphertext to this transfer. + + + Spark transfer identifier (UUID). Used together with each leaf's + sender_signature to verify the sender bound this ciphertext to this transfer. - -Sender's compressed secp256k1 identity public key (hex-encoded, 33 bytes). Used to verify the per-leaf sender_signature fields. + + Sender's compressed secp256k1 identity public key (hex-encoded, 33 bytes). + Used to verify the per-leaf sender_signature fields. @@ -5167,6 +5969,7 @@ Sender's compressed secp256k1 identity public key (hex-encoded, 33 bytes). Used + sparkPrepareLightningReceiveIntent field @@ -5197,6 +6000,7 @@ Operator's ECIES encryption pubkey (hex-encoded compressed secp256k1 point). + postTvcQuorumKeyShareIntent field @@ -5227,6 +6031,7 @@ Signature from the share set operator approving the manifest + result field @@ -5239,6 +6044,7 @@ Unique identifier for a given Organization. + createAuthenticatorsResult field @@ -5254,6 +6060,7 @@ item field + createUsersResult field @@ -5269,6 +6076,7 @@ item field + createPrivateKeysResult field @@ -5284,6 +6092,7 @@ item field + createInvitationsResult field @@ -5299,6 +6108,7 @@ item field + acceptInvitationResult field @@ -5311,6 +6121,7 @@ Unique identifier for a given User. + signRawPayloadResult field @@ -5326,6 +6137,7 @@ Component of an ECSDA signature. + createPolicyResult field @@ -5335,6 +6147,7 @@ Unique identifier for a given Policy. + disablePrivateKeyResult field @@ -5344,6 +6157,7 @@ Unique identifier for a given Private Key. + deleteUsersResult field @@ -5359,6 +6173,7 @@ item field + deleteAuthenticatorsResult field @@ -5374,6 +6189,7 @@ item field + deleteInvitationResult field @@ -5383,6 +6199,7 @@ Unique identifier for a given Invitation. + deleteOrganizationResult field @@ -5392,6 +6209,7 @@ Unique identifier for a given Organization. + deletePolicyResult field @@ -5401,6 +6219,7 @@ Unique identifier for a given Policy. + createUserTagResult field @@ -5419,6 +6238,7 @@ item field + deleteUserTagsResult field @@ -5431,6 +6251,7 @@ item field + A list of User IDs. @@ -5443,6 +6264,7 @@ item field + signTransactionResult field @@ -5452,6 +6274,7 @@ signedTransaction field + deleteApiKeysResult field @@ -5467,6 +6290,7 @@ item field + createApiKeysResult field @@ -5482,6 +6306,7 @@ item field + createPrivateKeyTagResult field @@ -5500,6 +6325,7 @@ item field + deletePrivateKeyTagsResult field @@ -5512,6 +6338,7 @@ item field + A list of Private Key IDs. @@ -5524,6 +6351,7 @@ item field + setPaymentMethodResult field @@ -5539,6 +6367,7 @@ The email address associated with the payment method. + activateBillingTierResult field @@ -5548,6 +6377,7 @@ The id of the product being subscribed to. + deletePaymentMethodResult field @@ -5557,6 +6387,7 @@ The payment method that was removed. + createApiOnlyUsersResult field @@ -5572,6 +6403,7 @@ item field + updateRootQuorumResult field @@ -5584,6 +6416,7 @@ Unique identifier for a given User Tag. + updatePrivateKeyTagResult field @@ -5593,6 +6426,7 @@ Unique identifier for a given Private Key Tag. + createSubOrganizationResult field @@ -5611,6 +6445,7 @@ item field + updateAllowedOriginsResult field @@ -5644,6 +6479,7 @@ address field + updateUserResult field @@ -5653,6 +6489,7 @@ A User ID. + updatePolicyResult field @@ -5662,6 +6499,7 @@ Unique identifier for a given Policy. + createSubOrganizationResultV3 field @@ -5692,6 +6530,7 @@ address field + rootUserIds field @@ -5704,6 +6543,7 @@ item field + createWalletResult field @@ -5722,6 +6562,7 @@ item field + createWalletAccountsResult field @@ -5737,6 +6578,7 @@ item field + initUserEmailRecoveryResult field @@ -5746,6 +6588,7 @@ Unique identifier for the user being recovered. + recoverUserResult field @@ -5761,6 +6604,7 @@ item field + setOrganizationFeatureResult field @@ -5782,6 +6626,7 @@ value field + removeOrganizationFeatureResult field @@ -5803,6 +6648,7 @@ value field + exportPrivateKeyResult field @@ -5815,6 +6661,7 @@ Export bundle containing a private key encrypted to the client's target public k + exportWalletResult field @@ -5827,6 +6674,7 @@ Export bundle containing a wallet mnemonic + optional newline passphrase encrypt + createSubOrganizationResultV4 field @@ -5851,6 +6699,7 @@ item field + rootUserIds field @@ -5863,6 +6712,7 @@ item field + emailAuthResult field @@ -5875,6 +6725,7 @@ Unique identifier for the created API key. + exportWalletAccountResult field @@ -5887,6 +6738,7 @@ Export bundle containing a private key encrypted by the client's target public k + initImportWalletResult field @@ -5896,6 +6748,7 @@ Import bundle containing a public key and signature to use for importing client + importWalletResult field @@ -5914,6 +6767,7 @@ item field + initImportPrivateKeyResult field @@ -5923,6 +6777,7 @@ Import bundle containing a public key and signature to use for importing client + importPrivateKeyResult field @@ -5947,6 +6802,7 @@ address field + createPoliciesResult field @@ -5962,6 +6818,7 @@ item field + signRawPayloadsResult field @@ -5983,6 +6840,7 @@ Component of an ECSDA signature. + createReadOnlySessionResult field @@ -6007,6 +6865,7 @@ UTC timestamp in seconds representing the expiry time for the read only session. + createOauthProvidersResult field @@ -6022,6 +6881,7 @@ item field + deleteOauthProvidersResult field @@ -6037,6 +6897,7 @@ item field + createSubOrganizationResultV5 field @@ -6061,6 +6922,7 @@ item field + rootUserIds field @@ -6073,6 +6935,7 @@ item field + oauthResult field @@ -6088,6 +6951,7 @@ HPKE encrypted credential bundle + createReadWriteSessionResult field @@ -6112,6 +6976,7 @@ HPKE encrypted credential bundle + createSubOrganizationResultV6 field @@ -6136,6 +7001,7 @@ item field + rootUserIds field @@ -6148,6 +7014,7 @@ item field + deletePrivateKeysResult field @@ -6163,6 +7030,7 @@ item field + deleteWalletsResult field @@ -6178,6 +7046,7 @@ item field + createReadWriteSessionResultV2 field @@ -6202,6 +7071,7 @@ HPKE encrypted credential bundle + deleteSubOrganizationResult field @@ -6211,6 +7081,7 @@ Unique identifier of the sub organization that was removed + initOtpAuthResult field @@ -6220,6 +7091,7 @@ Unique identifier for an OTP authentication + otpAuthResult field @@ -6235,6 +7107,7 @@ HPKE encrypted credential bundle + createSubOrganizationResultV7 field @@ -6259,6 +7132,7 @@ item field + rootUserIds field @@ -6271,6 +7145,7 @@ item field + updateWalletResult field @@ -6280,6 +7155,7 @@ A Wallet ID. + updatePolicyResultV2 field @@ -6289,6 +7165,7 @@ Unique identifier for a given Policy. + initOtpAuthResultV2 field @@ -6298,6 +7175,7 @@ Unique identifier for an OTP authentication + initOtpResult field @@ -6307,6 +7185,7 @@ Unique identifier for an OTP authentication + verifyOtpResult field @@ -6316,6 +7195,7 @@ Signed JWT containing a unique id, expiry, verification type, contact. Verificat + otpLoginResult field @@ -6325,6 +7205,7 @@ Signed JWT containing an expiry, public key, session type, user id, and organiza + stampLoginResult field @@ -6334,6 +7215,7 @@ Signed JWT containing an expiry, public key, session type, user id, and organiza + oauthLoginResult field @@ -6343,6 +7225,7 @@ Signed JWT containing an expiry, public key, session type, user id, and organiza + updateUserNameResult field @@ -6352,6 +7235,7 @@ Unique identifier of the User whose name was updated. + updateUserEmailResult field @@ -6361,6 +7245,7 @@ Unique identifier of the User whose email was updated. + updateUserPhoneNumberResult field @@ -6370,6 +7255,7 @@ Unique identifier of the User whose phone number was updated. + initFiatOnRampResult field @@ -6385,6 +7271,7 @@ Optional signature of the MoonPay Widget URL. The signature is generated if the + createSmartContractInterfaceResult field @@ -6394,6 +7281,7 @@ The ID of the created Smart Contract Interface. + deleteSmartContractInterfaceResult field @@ -6403,6 +7291,7 @@ The ID of the deleted Smart Contract Interface. + enableAuthProxyResult field @@ -6412,6 +7301,7 @@ A User ID with permission to initiate authentication. + disableAuthProxyResult field @@ -6424,6 +7314,7 @@ Unique identifier for a given User. (representing the turnkey signer user id) + createOauth2CredentialResult field @@ -6433,6 +7324,7 @@ Unique identifier of the OAuth 2.0 credential that was created + updateOauth2CredentialResult field @@ -6442,6 +7334,7 @@ Unique identifier of the OAuth 2.0 credential that was updated + deleteOauth2CredentialResult field @@ -6451,6 +7344,7 @@ Unique identifier of the OAuth 2.0 credential that was deleted + oauth2AuthenticateResult field @@ -6460,6 +7354,7 @@ Base64 encoded OIDC token issued by Turnkey to be used with the LoginWithOAuth a + deleteWalletAccountsResult field @@ -6475,6 +7370,7 @@ item field + deletePoliciesResult field @@ -6490,6 +7386,7 @@ item field + ethSendRawTransactionResult field @@ -6499,6 +7396,7 @@ The transaction hash of the sent transaction + createFiatOnRampCredentialResult field @@ -6508,6 +7406,7 @@ Unique identifier of the Fiat On-Ramp credential that was created + updateFiatOnRampCredentialResult field @@ -6517,6 +7416,7 @@ Unique identifier of the Fiat On-Ramp credential that was updated + deleteFiatOnRampCredentialResult field @@ -6526,6 +7426,7 @@ Unique identifier of the Fiat On-Ramp credential that was deleted + ethSendTransactionResult field @@ -6535,6 +7436,7 @@ The send_transaction_status ID associated with the transaction submission + upsertGasUsageConfigResult field @@ -6544,6 +7446,7 @@ Unique identifier for the gas usage configuration that was created or updated. + createTvcAppResult field @@ -6562,12 +7465,19 @@ item field - -The required number of approvals for the manifest set + + + The required number of approvals for the manifest set + createTvcDeploymentResult field @@ -6580,6 +7490,7 @@ The unique identifier for the TVC manifest + createTvcManifestApprovalsResult field @@ -6595,6 +7506,7 @@ item field + solSendTransactionResult field @@ -6604,6 +7516,7 @@ The send_transaction_status ID associated with the transaction submission + initOtpResultV2 field @@ -6616,6 +7529,7 @@ Signed bundle containing a target encryption key to use when submitting OTP code + updateOrganizationNameResult field @@ -6628,6 +7542,7 @@ The updated organization name. + createSubOrganizationResultV8 field @@ -6652,6 +7567,7 @@ item field + rootUserIds field @@ -6664,6 +7580,7 @@ item field + createOauthProvidersResultV2 field @@ -6679,6 +7596,7 @@ item field + createWebhookEndpointResult field @@ -6724,6 +7642,7 @@ Whether this subscription is active. + updateWebhookEndpointResult field @@ -6769,6 +7688,7 @@ Whether this subscription is active. + deleteWebhookEndpointResult field @@ -6778,6 +7698,7 @@ Unique identifier of the deleted webhook endpoint. + setIpAllowlistResult field @@ -6796,6 +7717,7 @@ The unique identifier of the deleted TVC deployment. + deleteTvcAppAndDeploymentsResult field @@ -6805,6 +7727,7 @@ The unique identifier of the deleted TVC app. + restoreTvcDeploymentResult field @@ -6814,6 +7737,7 @@ The unique identifier of the restored TVC deployment. + sparkSignFrostResult field @@ -6835,6 +7759,7 @@ Turnkey's binding commitment E (hex-encoded compressed secp256k1 point). Forward + sparkPrepareTransferResult field @@ -6850,6 +7775,7 @@ ECIES ciphertext (hex-encoded) opaque to Turnkey after emission. + Hex-encoded ECDSA-DER signature of the TransferPackage signing payload, signed with the wallet's IDENTITY key. @@ -6868,6 +7794,7 @@ Hex-encoded compressed secp256k1 point (33 bytes) for the SigningLeaf derivation + sparkClaimTransferResult field @@ -6883,6 +7810,7 @@ ECIES ciphertext (hex-encoded) opaque to Turnkey after emission. + Newly-derived SigningLeaf public keys, one per leaf, in input order. @@ -6898,6 +7826,7 @@ Hex-encoded compressed secp256k1 point (33 bytes) for the SigningLeaf derivation + sparkPrepareLightningReceiveResult field @@ -6913,12 +7842,19 @@ ECIES ciphertext (hex-encoded) opaque to Turnkey after emission. - -Hex-encoded SHA256(preimage). Forward to the Lightning node. + + + Hex-encoded SHA256(preimage). Forward to the Lightning node. + postTvcQuorumKeyShareResult field @@ -6931,6 +7867,7 @@ The unique identifier for the provisioning quorum key share + A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. @@ -6970,6 +7907,7 @@ Enum options: `AUTHENTICATOR_TRANSPORT_BLE`, `AUTHENTICATOR_TRANSPORT_INTERNAL`, + attestationType field @@ -6997,6 +7935,7 @@ Enum options: `CREDENTIAL_TYPE_WEBAUTHN_AUTHENTICATOR`, `CREDENTIAL_TYPE_API_KEY + Unique identifier for a given Authenticator. @@ -7015,6 +7954,7 @@ nanos field + updatedAt field @@ -7030,6 +7970,7 @@ nanos field + A list of API Key parameters. This field, if not needed, should be an empty array in your request body. @@ -7048,6 +7989,7 @@ Enum options: `CREDENTIAL_TYPE_WEBAUTHN_AUTHENTICATOR`, `CREDENTIAL_TYPE_API_KEY + Unique identifier for a given API Key. @@ -7066,6 +8008,7 @@ nanos field + updatedAt field @@ -7078,12 +8021,19 @@ nanos field - -Optional window (in seconds) indicating how long the API Key should last. + + + Optional window (in seconds) indicating how long the API Key should last. + A list of User Tag IDs. @@ -7093,6 +8043,7 @@ item field + A list of Oauth Providers. @@ -7123,6 +8074,7 @@ nanos field + updatedAt field @@ -7138,6 +8090,7 @@ nanos field + createdAt field @@ -7150,6 +8103,7 @@ nanos field + updatedAt field @@ -7165,6 +8119,7 @@ nanos field + Unique identifier for a given Activity object. @@ -7201,6 +8156,7 @@ nanos field + A list of App Proofs generated by enclaves during activity execution, providing verifiable attestations of performed operations. @@ -7222,6 +8178,7 @@ Signature over hashed proof_payload. + An artifact verifying a User's action. @@ -7243,6 +8200,7 @@ nanos field + updatedAt field @@ -7255,6 +8213,7 @@ nanos field + failure field @@ -7353,9 +8312,7 @@ const response = await turnkeyClient.apiClient().getActivities({ "response": { "clientDataJson": "", "attestationObject": "", - "transports": [ - "" - ], + "transports": [""], "authenticatorAttachment": "" }, "clientExtensionResults": { @@ -7383,9 +8340,7 @@ const response = await turnkeyClient.apiClient().getActivities({ "response": { "clientDataJson": "", "attestationObject": "", - "transports": [ - "" - ], + "transports": [""], "authenticatorAttachment": "" }, "clientExtensionResults": { @@ -7426,9 +8381,7 @@ const response = await turnkeyClient.apiClient().getActivities({ "response": { "clientDataJson": "", "attestationObject": "", - "transports": [ - "" - ], + "transports": [""], "authenticatorAttachment": "" }, "clientExtensionResults": { @@ -7442,9 +8395,7 @@ const response = await turnkeyClient.apiClient().getActivities({ "challenge": "" } ], - "userTags": [ - "" - ] + "userTags": [""] } ] }, @@ -7453,12 +8404,8 @@ const response = await turnkeyClient.apiClient().getActivities({ { "privateKeyName": "", "curve": "", - "privateKeyTags": [ - "" - ], - "addressFormats": [ - "" - ] + "privateKeyTags": [""], + "addressFormats": [""] } ] }, @@ -7473,9 +8420,7 @@ const response = await turnkeyClient.apiClient().getActivities({ { "receiverUserName": "", "receiverUserEmail": "", - "receiverUserTags": [ - "" - ], + "receiverUserTags": [""], "accessType": "", "senderUserId": "" } @@ -7495,9 +8440,7 @@ const response = await turnkeyClient.apiClient().getActivities({ "response": { "clientDataJson": "", "attestationObject": "", - "transports": [ - "" - ], + "transports": [""], "authenticatorAttachment": "" }, "clientExtensionResults": { @@ -7527,15 +8470,11 @@ const response = await turnkeyClient.apiClient().getActivities({ "privateKeyId": "" }, "deleteUsersIntent": { - "userIds": [ - "" - ] + "userIds": [""] }, "deleteAuthenticatorsIntent": { "userId": "", - "authenticatorIds": [ - "" - ] + "authenticatorIds": [""] }, "deleteInvitationIntent": { "invitationId": "" @@ -7548,14 +8487,10 @@ const response = await turnkeyClient.apiClient().getActivities({ }, "createUserTagIntent": { "userTagName": "", - "userIds": [ - "" - ] + "userIds": [""] }, "deleteUserTagsIntent": { - "userTagIds": [ - "" - ] + "userTagIds": [""] }, "signTransactionIntent": { "privateKeyId": "", @@ -7574,9 +8509,7 @@ const response = await turnkeyClient.apiClient().getActivities({ }, "deleteApiKeysIntent": { "userId": "", - "apiKeyIds": [ - "" - ] + "apiKeyIds": [""] }, "approveActivityIntent": { "fingerprint": "" @@ -7586,14 +8519,10 @@ const response = await turnkeyClient.apiClient().getActivities({ }, "createPrivateKeyTagIntent": { "privateKeyTagName": "", - "privateKeyIds": [ - "" - ] + "privateKeyIds": [""] }, "deletePrivateKeyTagsIntent": { - "privateKeyTagIds": [ - "" - ] + "privateKeyTagIds": [""] }, "createPolicyIntentV2": { "policyName": "", @@ -7601,9 +8530,7 @@ const response = await turnkeyClient.apiClient().getActivities({ { "subject": "", "operator": "", - "targets": [ - "" - ] + "targets": [""] } ], "effect": "", @@ -7636,9 +8563,7 @@ const response = await turnkeyClient.apiClient().getActivities({ { "userName": "", "userEmail": "", - "userTags": [ - "" - ], + "userTags": [""], "apiKeys": [ { "apiKeyName": "", @@ -7651,29 +8576,19 @@ const response = await turnkeyClient.apiClient().getActivities({ }, "updateRootQuorumIntent": { "threshold": "", - "userIds": [ - "" - ] + "userIds": [""] }, "updateUserTagIntent": { "userTagId": "", "newUserTagName": "", - "addUserIds": [ - "" - ], - "removeUserIds": [ - "" - ] + "addUserIds": [""], + "removeUserIds": [""] }, "updatePrivateKeyTagIntent": { "privateKeyTagId": "", "newPrivateKeyTagName": "", - "addPrivateKeyIds": [ - "" - ], - "removePrivateKeyIds": [ - "" - ] + "addPrivateKeyIds": [""], + "removePrivateKeyIds": [""] }, "createAuthenticatorsIntentV2": { "authenticators": [ @@ -7684,9 +8599,7 @@ const response = await turnkeyClient.apiClient().getActivities({ "credentialId": "", "clientDataJson": "", "attestationObject": "", - "transports": [ - "" - ] + "transports": [""] } } ], @@ -7702,9 +8615,7 @@ const response = await turnkeyClient.apiClient().getActivities({ "credentialId": "", "clientDataJson": "", "attestationObject": "", - "transports": [ - "" - ] + "transports": [""] } } }, @@ -7718,9 +8629,7 @@ const response = await turnkeyClient.apiClient().getActivities({ "credentialId": "", "clientDataJson": "", "attestationObject": "", - "transports": [ - "" - ] + "transports": [""] } }, "rootUserId": "" @@ -7745,15 +8654,11 @@ const response = await turnkeyClient.apiClient().getActivities({ "credentialId": "", "clientDataJson": "", "attestationObject": "", - "transports": [ - "" - ] + "transports": [""] } } ], - "userTags": [ - "" - ] + "userTags": [""] } ] }, @@ -7766,9 +8671,7 @@ const response = await turnkeyClient.apiClient().getActivities({ "credentialId": "", "clientDataJson": "", "attestationObject": "", - "transports": [ - "" - ] + "transports": [""] } } }, @@ -7793,9 +8696,7 @@ const response = await turnkeyClient.apiClient().getActivities({ "credentialId": "", "clientDataJson": "", "attestationObject": "", - "transports": [ - "" - ] + "transports": [""] } } ] @@ -7804,21 +8705,15 @@ const response = await turnkeyClient.apiClient().getActivities({ "rootQuorumThreshold": "" }, "updateAllowedOriginsIntent": { - "allowedOrigins": [ - "" - ] + "allowedOrigins": [""] }, "createPrivateKeysIntentV2": { "privateKeys": [ { "privateKeyName": "", "curve": "", - "privateKeyTags": [ - "" - ], - "addressFormats": [ - "" - ] + "privateKeyTags": [""], + "addressFormats": [""] } ] }, @@ -7826,9 +8721,7 @@ const response = await turnkeyClient.apiClient().getActivities({ "userId": "", "userName": "", "userEmail": "", - "userTagIds": [ - "" - ], + "userTagIds": [""], "userPhoneNumber": "" }, "updatePolicyIntent": { @@ -7865,9 +8758,7 @@ const response = await turnkeyClient.apiClient().getActivities({ "credentialId": "", "clientDataJson": "", "attestationObject": "", - "transports": [ - "" - ] + "transports": [""] } } ] @@ -7878,12 +8769,8 @@ const response = await turnkeyClient.apiClient().getActivities({ { "privateKeyName": "", "curve": "", - "privateKeyTags": [ - "" - ], - "addressFormats": [ - "" - ] + "privateKeyTags": [""], + "addressFormats": [""] } ] }, @@ -7934,9 +8821,7 @@ const response = await turnkeyClient.apiClient().getActivities({ "credentialId": "", "clientDataJson": "", "attestationObject": "", - "transports": [ - "" - ] + "transports": [""] } }, "userId": "" @@ -7989,9 +8874,7 @@ const response = await turnkeyClient.apiClient().getActivities({ "credentialId": "", "clientDataJson": "", "attestationObject": "", - "transports": [ - "" - ] + "transports": [""] } } ] @@ -8058,9 +8941,7 @@ const response = await turnkeyClient.apiClient().getActivities({ "privateKeyName": "", "encryptedBundle": "", "curve": "", - "addressFormats": [ - "" - ] + "addressFormats": [""] }, "createPoliciesIntent": { "policies": [ @@ -8075,9 +8956,7 @@ const response = await turnkeyClient.apiClient().getActivities({ }, "signRawPayloadsIntent": { "signWith": "", - "payloads": [ - "" - ], + "payloads": [""], "encoding": "", "hashFunction": "" }, @@ -8093,9 +8972,7 @@ const response = await turnkeyClient.apiClient().getActivities({ }, "deleteOauthProvidersIntent": { "userId": "", - "providerIds": [ - "" - ] + "providerIds": [""] }, "createSubOrganizationIntentV5": { "subOrganizationName": "", @@ -8118,9 +8995,7 @@ const response = await turnkeyClient.apiClient().getActivities({ "credentialId": "", "clientDataJson": "", "attestationObject": "", - "transports": [ - "" - ] + "transports": [""] } } ], @@ -8211,9 +9086,7 @@ const response = await turnkeyClient.apiClient().getActivities({ "credentialId": "", "clientDataJson": "", "attestationObject": "", - "transports": [ - "" - ] + "transports": [""] } } ], @@ -8242,15 +9115,11 @@ const response = await turnkeyClient.apiClient().getActivities({ "disableEmailAuth": "" }, "deletePrivateKeysIntent": { - "privateKeyIds": [ - "" - ], + "privateKeyIds": [""], "deleteWithoutExport": "" }, "deleteWalletsIntent": { - "walletIds": [ - "" - ], + "walletIds": [""], "deleteWithoutExport": "" }, "createReadWriteSessionIntentV2": { @@ -8312,9 +9181,7 @@ const response = await turnkeyClient.apiClient().getActivities({ "credentialId": "", "clientDataJson": "", "attestationObject": "", - "transports": [ - "" - ] + "transports": [""] } } ], @@ -8385,9 +9252,7 @@ const response = await turnkeyClient.apiClient().getActivities({ "credentialId": "", "clientDataJson": "", "attestationObject": "", - "transports": [ - "" - ] + "transports": [""] } } ], @@ -8397,9 +9262,7 @@ const response = await turnkeyClient.apiClient().getActivities({ "oidcToken": "" } ], - "userTags": [ - "" - ] + "userTags": [""] } ] }, @@ -8513,12 +9376,8 @@ const response = await turnkeyClient.apiClient().getActivities({ "enableAuthProxyIntent": "", "disableAuthProxyIntent": "", "updateAuthProxyConfigIntent": { - "allowedOrigins": [ - "" - ], - "allowedAuthMethods": [ - "" - ], + "allowedOrigins": [""], + "allowedAuthMethods": [""], "sendFromEmailAddress": "", "replyToEmailAddress": "", "emailAuthTemplateId": "", @@ -8534,9 +9393,7 @@ const response = await turnkeyClient.apiClient().getActivities({ "template": "" }, "walletKitSettings": { - "enabledSocialProviders": [ - "" - ], + "enabledSocialProviders": [""], "oauthClientIds": "", "oauthRedirectUrl": "" }, @@ -8547,9 +9404,7 @@ const response = await turnkeyClient.apiClient().getActivities({ "otpLength": "", "sendFromEmailSenderName": "", "verificationTokenRequiredForGetAccountPii": "", - "socialLinkingClientIds": [ - "" - ] + "socialLinkingClientIds": [""] }, "createOauth2CredentialIntent": { "provider": "", @@ -8574,15 +9429,11 @@ const response = await turnkeyClient.apiClient().getActivities({ "bearerTokenTargetPublicKey": "" }, "deleteWalletAccountsIntent": { - "walletAccountIds": [ - "" - ], + "walletAccountIds": [""], "deleteWithoutExport": "" }, "deletePoliciesIntent": { - "policyIds": [ - "" - ] + "policyIds": [""] }, "ethSendRawTransactionIntent": { "signedTransaction": "", @@ -8716,9 +9567,7 @@ const response = await turnkeyClient.apiClient().getActivities({ "publicKey": "" } ], - "existingOperatorIds": [ - "" - ], + "existingOperatorIds": [""], "threshold": "" }, "shareSetId": "", @@ -8730,9 +9579,7 @@ const response = await turnkeyClient.apiClient().getActivities({ "publicKey": "" } ], - "existingOperatorIds": [ - "" - ], + "existingOperatorIds": [""], "threshold": "" }, "enableEgress": "" @@ -8742,9 +9589,7 @@ const response = await turnkeyClient.apiClient().getActivities({ "qosVersion": "", "pivotContainerImageUrl": "", "pivotPath": "", - "pivotArgs": [ - "" - ], + "pivotArgs": [""], "expectedPivotDigest": "", "nonce": "", "pivotContainerEncryptedPullSecret": "", @@ -8833,9 +9678,7 @@ const response = await turnkeyClient.apiClient().getActivities({ "credentialId": "", "clientDataJson": "", "attestationObject": "", - "transports": [ - "" - ] + "transports": [""] } } ], @@ -8913,9 +9756,7 @@ const response = await turnkeyClient.apiClient().getActivities({ "credentialId": "", "clientDataJson": "", "attestationObject": "", - "transports": [ - "" - ] + "transports": [""] } } ], @@ -8930,9 +9771,7 @@ const response = await turnkeyClient.apiClient().getActivities({ } } ], - "userTags": [ - "" - ] + "userTags": [""] } ] }, @@ -9102,24 +9941,16 @@ const response = await turnkeyClient.apiClient().getActivities({ "organizationId": "" }, "createAuthenticatorsResult": { - "authenticatorIds": [ - "" - ] + "authenticatorIds": [""] }, "createUsersResult": { - "userIds": [ - "" - ] + "userIds": [""] }, "createPrivateKeysResult": { - "privateKeyIds": [ - "" - ] + "privateKeyIds": [""] }, "createInvitationsResult": { - "invitationIds": [ - "" - ] + "invitationIds": [""] }, "acceptInvitationResult": { "invitationId": "", @@ -9137,14 +9968,10 @@ const response = await turnkeyClient.apiClient().getActivities({ "privateKeyId": "" }, "deleteUsersResult": { - "userIds": [ - "" - ] + "userIds": [""] }, "deleteAuthenticatorsResult": { - "authenticatorIds": [ - "" - ] + "authenticatorIds": [""] }, "deleteInvitationResult": { "invitationId": "" @@ -9157,44 +9984,28 @@ const response = await turnkeyClient.apiClient().getActivities({ }, "createUserTagResult": { "userTagId": "", - "userIds": [ - "" - ] + "userIds": [""] }, "deleteUserTagsResult": { - "userTagIds": [ - "" - ], - "userIds": [ - "" - ] + "userTagIds": [""], + "userIds": [""] }, "signTransactionResult": { "signedTransaction": "" }, "deleteApiKeysResult": { - "apiKeyIds": [ - "" - ] + "apiKeyIds": [""] }, "createApiKeysResult": { - "apiKeyIds": [ - "" - ] + "apiKeyIds": [""] }, "createPrivateKeyTagResult": { "privateKeyTagId": "", - "privateKeyIds": [ - "" - ] + "privateKeyIds": [""] }, "deletePrivateKeyTagsResult": { - "privateKeyTagIds": [ - "" - ], - "privateKeyIds": [ - "" - ] + "privateKeyTagIds": [""], + "privateKeyIds": [""] }, "setPaymentMethodResult": { "lastFour": "", @@ -9208,9 +10019,7 @@ const response = await turnkeyClient.apiClient().getActivities({ "paymentMethodId": "" }, "createApiOnlyUsersResult": { - "userIds": [ - "" - ] + "userIds": [""] }, "updateRootQuorumResult": "", "updateUserTagResult": { @@ -9221,9 +10030,7 @@ const response = await turnkeyClient.apiClient().getActivities({ }, "createSubOrganizationResult": { "subOrganizationId": "", - "rootUserIds": [ - "" - ] + "rootUserIds": [""] }, "updateAllowedOriginsResult": "", "createPrivateKeysResultV2": { @@ -9258,28 +10065,20 @@ const response = await turnkeyClient.apiClient().getActivities({ ] } ], - "rootUserIds": [ - "" - ] + "rootUserIds": [""] }, "createWalletResult": { "walletId": "", - "addresses": [ - "" - ] + "addresses": [""] }, "createWalletAccountsResult": { - "addresses": [ - "" - ] + "addresses": [""] }, "initUserEmailRecoveryResult": { "userId": "" }, "recoverUserResult": { - "authenticatorId": [ - "" - ] + "authenticatorId": [""] }, "setOrganizationFeatureResult": { "features": [ @@ -9309,13 +10108,9 @@ const response = await turnkeyClient.apiClient().getActivities({ "subOrganizationId": "", "wallet": { "walletId": "", - "addresses": [ - "" - ] + "addresses": [""] }, - "rootUserIds": [ - "" - ] + "rootUserIds": [""] }, "emailAuthResult": { "userId": "", @@ -9330,9 +10125,7 @@ const response = await turnkeyClient.apiClient().getActivities({ }, "importWalletResult": { "walletId": "", - "addresses": [ - "" - ] + "addresses": [""] }, "initImportPrivateKeyResult": { "importBundle": "" @@ -9347,9 +10140,7 @@ const response = await turnkeyClient.apiClient().getActivities({ ] }, "createPoliciesResult": { - "policyIds": [ - "" - ] + "policyIds": [""] }, "signRawPayloadsResult": { "signatures": [ @@ -9369,26 +10160,18 @@ const response = await turnkeyClient.apiClient().getActivities({ "sessionExpiry": "" }, "createOauthProvidersResult": { - "providerIds": [ - "" - ] + "providerIds": [""] }, "deleteOauthProvidersResult": { - "providerIds": [ - "" - ] + "providerIds": [""] }, "createSubOrganizationResultV5": { "subOrganizationId": "", "wallet": { "walletId": "", - "addresses": [ - "" - ] + "addresses": [""] }, - "rootUserIds": [ - "" - ] + "rootUserIds": [""] }, "oauthResult": { "userId": "", @@ -9407,23 +10190,15 @@ const response = await turnkeyClient.apiClient().getActivities({ "subOrganizationId": "", "wallet": { "walletId": "", - "addresses": [ - "" - ] + "addresses": [""] }, - "rootUserIds": [ - "" - ] + "rootUserIds": [""] }, "deletePrivateKeysResult": { - "privateKeyIds": [ - "" - ] + "privateKeyIds": [""] }, "deleteWalletsResult": { - "walletIds": [ - "" - ] + "walletIds": [""] }, "createReadWriteSessionResultV2": { "organizationId": "", @@ -9448,13 +10223,9 @@ const response = await turnkeyClient.apiClient().getActivities({ "subOrganizationId": "", "wallet": { "walletId": "", - "addresses": [ - "" - ] + "addresses": [""] }, - "rootUserIds": [ - "" - ] + "rootUserIds": [""] }, "updateWalletResult": { "walletId": "" @@ -9520,14 +10291,10 @@ const response = await turnkeyClient.apiClient().getActivities({ "oidcToken": "" }, "deleteWalletAccountsResult": { - "walletAccountIds": [ - "" - ] + "walletAccountIds": [""] }, "deletePoliciesResult": { - "policyIds": [ - "" - ] + "policyIds": [""] }, "ethSendRawTransactionResult": { "transactionHash": "" @@ -9550,9 +10317,7 @@ const response = await turnkeyClient.apiClient().getActivities({ "createTvcAppResult": { "appId": "", "manifestSetId": "", - "manifestSetOperatorIds": [ - "" - ], + "manifestSetOperatorIds": [""], "manifestSetThreshold": "" }, "createTvcDeploymentResult": { @@ -9560,9 +10325,7 @@ const response = await turnkeyClient.apiClient().getActivities({ "manifestId": "" }, "createTvcManifestApprovalsResult": { - "approvalIds": [ - "" - ] + "approvalIds": [""] }, "solSendTransactionResult": { "sendTransactionStatusId": "" @@ -9579,18 +10342,12 @@ const response = await turnkeyClient.apiClient().getActivities({ "subOrganizationId": "", "wallet": { "walletId": "", - "addresses": [ - "" - ] + "addresses": [""] }, - "rootUserIds": [ - "" - ] + "rootUserIds": [""] }, "createOauthProvidersResultV2": { - "providerIds": [ - "" - ] + "providerIds": [""] }, "createWebhookEndpointResult": { "endpointId": "", @@ -9703,9 +10460,7 @@ const response = await turnkeyClient.apiClient().getActivities({ "userPhoneNumber": "", "authenticators": [ { - "transports": [ - "" - ], + "transports": [""], "attestationType": "", "aaguid": "", "credentialId": "", @@ -9745,9 +10500,7 @@ const response = await turnkeyClient.apiClient().getActivities({ "expirationSeconds": "" } ], - "userTags": [ - "" - ], + "userTags": [""], "oauthProviders": [ { "providerId": "", diff --git a/api-reference/queries/list-app-proofs-for-an-activity.mdx b/api-reference/queries/list-app-proofs-for-an-activity.mdx index 600e4086..ff2d14dc 100644 --- a/api-reference/queries/list-app-proofs-for-an-activity.mdx +++ b/api-reference/queries/list-app-proofs-for-an-activity.mdx @@ -17,16 +17,17 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Unique identifier for a given Organization. + Unique identifier for a given activity. - + - -A successful response returns the following fields: +A successful response returns the following +fields: appProofs field diff --git a/api-reference/queries/list-fiat-on-ramp-credentials.mdx b/api-reference/queries/list-fiat-on-ramp-credentials.mdx index fe9e0284..cba4b686 100644 --- a/api-reference/queries/list-fiat-on-ramp-credentials.mdx +++ b/api-reference/queries/list-fiat-on-ramp-credentials.mdx @@ -17,11 +17,11 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Unique identifier for a given Organization. - + - -A successful response returns the following fields: +A successful response returns the following +fields: fiatOnRampCredentials field @@ -65,6 +65,7 @@ nanos field + updatedAt field diff --git a/api-reference/queries/list-oauth-20-credentials.mdx b/api-reference/queries/list-oauth-20-credentials.mdx index 4e61803f..eda0551b 100644 --- a/api-reference/queries/list-oauth-20-credentials.mdx +++ b/api-reference/queries/list-oauth-20-credentials.mdx @@ -17,11 +17,11 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Unique identifier for a given Organization. - + - -A successful response returns the following fields: +A successful response returns the following +fields: oauth2Credentials field @@ -56,6 +56,7 @@ nanos field + updatedAt field diff --git a/api-reference/queries/list-policies.mdx b/api-reference/queries/list-policies.mdx index a389c0ac..dd15f0ee 100644 --- a/api-reference/queries/list-policies.mdx +++ b/api-reference/queries/list-policies.mdx @@ -17,11 +17,11 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Unique identifier for a given organization. - + - -A successful response returns the following fields: +A successful response returns the following +fields: A list of policies. @@ -50,6 +50,7 @@ nanos field + updatedAt field @@ -62,14 +63,30 @@ nanos field - -Human-readable notes added by a User to describe a particular policy. + + + Human-readable notes added by a User to describe a particular policy. - -A consensus expression that evalutes to true or false. + + A consensus expression that evalutes to true or false. - -A condition expression that evalutes to true or false. + + A condition expression that evalutes to true or false. diff --git a/api-reference/queries/list-private-key-tags.mdx b/api-reference/queries/list-private-key-tags.mdx index 806d876f..282ebec2 100644 --- a/api-reference/queries/list-private-key-tags.mdx +++ b/api-reference/queries/list-private-key-tags.mdx @@ -17,11 +17,11 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Unique identifier for a given organization. - + - -A successful response returns the following fields: +A successful response returns the following +fields: A list of private key tags. @@ -50,6 +50,7 @@ nanos field + updatedAt field diff --git a/api-reference/queries/list-private-keys.mdx b/api-reference/queries/list-private-keys.mdx index e8dd67bf..e1b15b4b 100644 --- a/api-reference/queries/list-private-keys.mdx +++ b/api-reference/queries/list-private-keys.mdx @@ -17,11 +17,11 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Unique identifier for a given organization. - + - -A successful response returns the following fields: +A successful response returns the following +fields: A list of private keys. @@ -56,6 +56,7 @@ address field + A list of Private Key Tag IDs. @@ -65,6 +66,7 @@ item field + createdAt field @@ -77,6 +79,7 @@ nanos field + updatedAt field @@ -89,11 +92,22 @@ nanos field - -True when a given Private Key is exported, false otherwise. + + + True when a given Private Key is exported, false otherwise. - -True when a given Private Key is imported, false otherwise. + + True when a given Private Key is imported, false otherwise. @@ -145,9 +159,7 @@ const response = await turnkeyClient.apiClient().getPrivateKeys({ "address": "" } ], - "privateKeyTags": [ - "" - ], + "privateKeyTags": [""], "createdAt": { "seconds": "", "nanos": "" diff --git a/api-reference/queries/list-smart-contract-interfaces.mdx b/api-reference/queries/list-smart-contract-interfaces.mdx index 05d88eb9..37cc9283 100644 --- a/api-reference/queries/list-smart-contract-interfaces.mdx +++ b/api-reference/queries/list-smart-contract-interfaces.mdx @@ -17,11 +17,11 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Unique identifier for a given organization. - + - -A successful response returns the following fields: +A successful response returns the following +fields: A list of smart contract interfaces. @@ -59,6 +59,7 @@ nanos field + updatedAt field diff --git a/api-reference/queries/list-supported-assets.mdx b/api-reference/queries/list-supported-assets.mdx index a834303e..7bca3203 100644 --- a/api-reference/queries/list-supported-assets.mdx +++ b/api-reference/queries/list-supported-assets.mdx @@ -17,16 +17,17 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Unique identifier for a given organization. + Enum options: `eip155:1`, `eip155:11155111`, `eip155:8453`, `eip155:84532`, `eip155:137`, `eip155:80002`, `eip155:42161`, `eip155:421614`, `solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp`, `solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1` - + - -A successful response returns the following fields: +A successful response returns the following +fields: List of asset metadata diff --git a/api-reference/queries/list-tvc-apps.mdx b/api-reference/queries/list-tvc-apps.mdx index df9298be..90a026fb 100644 --- a/api-reference/queries/list-tvc-apps.mdx +++ b/api-reference/queries/list-tvc-apps.mdx @@ -17,11 +17,11 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Unique identifier for a given organization. - + - -A successful response returns the following fields: +A successful response returns the following +fields: A list of TVC Apps. @@ -74,6 +74,7 @@ nanos field + updatedAt field @@ -89,6 +90,7 @@ nanos field + Threshold number of operators required for quorum. @@ -104,6 +106,7 @@ nanos field + updatedAt field @@ -119,6 +122,7 @@ nanos field + shareSet field @@ -155,6 +159,7 @@ nanos field + updatedAt field @@ -170,6 +175,7 @@ nanos field + Threshold number of operators required for quorum. @@ -185,6 +191,7 @@ nanos field + updatedAt field @@ -200,6 +207,7 @@ nanos field + Whether or not this TVC App has network egress enabled. @@ -215,6 +223,7 @@ nanos field + updatedAt field @@ -227,11 +236,24 @@ nanos field - -The deployment currently designated to receive traffic. Null if no deployment for this app is deployed. - - -The public domain for ingress to this TVC App (in the format "app-<ID>.turnkey.cloud"). + + + The deployment currently designated to receive traffic. Null if no deployment + for this app is deployed. + + + The public domain for ingress to this TVC App (in the format + "app-<ID>.turnkey.cloud"). diff --git a/api-reference/queries/list-tvc-deployments.mdx b/api-reference/queries/list-tvc-deployments.mdx index 16cdeb8f..41d23d75 100644 --- a/api-reference/queries/list-tvc-deployments.mdx +++ b/api-reference/queries/list-tvc-deployments.mdx @@ -17,16 +17,17 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Unique identifier for a given organization. + Unique identifier for a given TVC App. - + - -A successful response returns the following fields: +A successful response returns the following +fields: List of deployments for this TVC App @@ -76,6 +77,7 @@ nanos field + updatedAt field @@ -91,6 +93,7 @@ nanos field + Threshold number of operators required for quorum. @@ -106,6 +109,7 @@ nanos field + updatedAt field @@ -121,6 +125,7 @@ nanos field + shareSet field @@ -157,6 +162,7 @@ nanos field + updatedAt field @@ -172,6 +178,7 @@ nanos field + Threshold number of operators required for quorum. @@ -187,6 +194,7 @@ nanos field + updatedAt field @@ -202,6 +210,7 @@ nanos field + manifest field @@ -223,6 +232,7 @@ nanos field + updatedAt field @@ -238,6 +248,7 @@ nanos field + List of operator approvals for this manifest @@ -271,6 +282,7 @@ nanos field + updatedAt field @@ -286,6 +298,7 @@ nanos field + Signature of the operator over the deployment manifest @@ -301,6 +314,7 @@ nanos field + updatedAt field @@ -316,6 +330,7 @@ nanos field + QOS Version used for this deployment @@ -337,6 +352,7 @@ item field + Whether or not this container requires a pull secret to access. @@ -355,6 +371,7 @@ The port to use for public ingress to this executable. + createdAt field @@ -367,6 +384,7 @@ nanos field + updatedAt field @@ -379,8 +397,14 @@ nanos field - -Whether or not the user wants this deployment deleted from the cluster. + + + Whether or not the user wants this deployment deleted from the cluster. @@ -529,9 +553,7 @@ const response = await turnkeyClient.apiClient().getTvcAppDeployments({ "pivotContainer": { "containerUrl": "", "path": "", - "args": [ - "" - ], + "args": [""], "hasPullSecret": "", "healthCheckType": "", "healthCheckPort": "", diff --git a/api-reference/queries/list-user-tags.mdx b/api-reference/queries/list-user-tags.mdx index de564578..c7fb2436 100644 --- a/api-reference/queries/list-user-tags.mdx +++ b/api-reference/queries/list-user-tags.mdx @@ -17,11 +17,11 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Unique identifier for a given organization. - + - -A successful response returns the following fields: +A successful response returns the following +fields: A list of user tags. @@ -50,6 +50,7 @@ nanos field + updatedAt field diff --git a/api-reference/queries/list-users.mdx b/api-reference/queries/list-users.mdx index f0c2041d..14d41132 100644 --- a/api-reference/queries/list-users.mdx +++ b/api-reference/queries/list-users.mdx @@ -17,11 +17,11 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Unique identifier for a given organization. - + - -A successful response returns the following fields: +A successful response returns the following +fields: A list of users. @@ -53,6 +53,7 @@ Enum options: `AUTHENTICATOR_TRANSPORT_BLE`, `AUTHENTICATOR_TRANSPORT_INTERNAL`, + attestationType field @@ -80,6 +81,7 @@ Enum options: `CREDENTIAL_TYPE_WEBAUTHN_AUTHENTICATOR`, `CREDENTIAL_TYPE_API_KEY + Unique identifier for a given Authenticator. @@ -98,6 +100,7 @@ nanos field + updatedAt field @@ -113,6 +116,7 @@ nanos field + A list of API Key parameters. This field, if not needed, should be an empty array in your request body. @@ -131,6 +135,7 @@ Enum options: `CREDENTIAL_TYPE_WEBAUTHN_AUTHENTICATOR`, `CREDENTIAL_TYPE_API_KEY + Unique identifier for a given API Key. @@ -149,6 +154,7 @@ nanos field + updatedAt field @@ -161,12 +167,19 @@ nanos field - -Optional window (in seconds) indicating how long the API Key should last. + + + Optional window (in seconds) indicating how long the API Key should last. + A list of User Tag IDs. @@ -176,6 +189,7 @@ item field + A list of Oauth Providers. @@ -206,6 +220,7 @@ nanos field + updatedAt field @@ -221,6 +236,7 @@ nanos field + createdAt field @@ -233,6 +249,7 @@ nanos field + updatedAt field @@ -291,9 +308,7 @@ const response = await turnkeyClient.apiClient().getUsers({ "userPhoneNumber": "", "authenticators": [ { - "transports": [ - "" - ], + "transports": [""], "attestationType": "", "aaguid": "", "credentialId": "", @@ -333,9 +348,7 @@ const response = await turnkeyClient.apiClient().getUsers({ "expirationSeconds": "" } ], - "userTags": [ - "" - ], + "userTags": [""], "oauthProviders": [ { "providerId": "", diff --git a/api-reference/queries/list-wallets-accounts.mdx b/api-reference/queries/list-wallets-accounts.mdx index 510ca422..d4433bc1 100644 --- a/api-reference/queries/list-wallets-accounts.mdx +++ b/api-reference/queries/list-wallets-accounts.mdx @@ -17,37 +17,66 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Unique identifier for a given organization. + Unique identifier for a given wallet. If not provided, all accounts for the organization will be returned. + Optional flag to specify if the wallet details should be included in the response. Default = false. + - +

paginationOptions field

- - A limit of the number of object to be returned, between 1 and 100. Defaults to 10. + + A limit of the number of object to be returned, between 1 and 100. + Defaults to 10. - - - A pagination cursor. This is an object ID that enables you to fetch all objects before this ID. + + + A pagination cursor. This is an object ID that enables you to fetch all + objects before this ID. - - - A pagination cursor. This is an object ID that enables you to fetch all objects after this ID. + + + A pagination cursor. This is an object ID that enables you to fetch all + objects after this ID.
- -A successful response returns the following fields: +A successful response returns the following +fields: A list of accounts generated from a wallet that share a common seed. @@ -97,6 +126,7 @@ nanos field
+ updatedAt field @@ -109,6 +139,7 @@ nanos field + The public component of this wallet account's underlying cryptographic key pair. @@ -133,6 +164,7 @@ nanos field + updatedAt field @@ -145,11 +177,22 @@ nanos field - -True when a given Wallet is exported, false otherwise. + + + True when a given Wallet is exported, false otherwise. - -True when a given Wallet is imported, false otherwise. + + True when a given Wallet is imported, false otherwise. diff --git a/api-reference/queries/list-wallets.mdx b/api-reference/queries/list-wallets.mdx index 36fe45fc..36a829f7 100644 --- a/api-reference/queries/list-wallets.mdx +++ b/api-reference/queries/list-wallets.mdx @@ -17,11 +17,11 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Unique identifier for a given organization. - + - -A successful response returns the following fields: +A successful response returns the following +fields: A list of wallets. @@ -44,6 +44,7 @@ nanos field + updatedAt field @@ -56,11 +57,22 @@ nanos field - -True when a given Wallet is exported, false otherwise. + + + True when a given Wallet is exported, false otherwise. - -True when a given Wallet is imported, false otherwise. + + True when a given Wallet is imported, false otherwise. diff --git a/api-reference/queries/list-webhook-endpoints.mdx b/api-reference/queries/list-webhook-endpoints.mdx index 54cd809b..3ee91052 100644 --- a/api-reference/queries/list-webhook-endpoints.mdx +++ b/api-reference/queries/list-webhook-endpoints.mdx @@ -17,11 +17,11 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Unique identifier for a given Organization. - + - -A successful response returns the following fields: +A successful response returns the following +fields: webhookEndpoints field diff --git a/api-reference/queries/overview.mdx b/api-reference/queries/overview.mdx index e01be2d9..f814cd36 100644 --- a/api-reference/queries/overview.mdx +++ b/api-reference/queries/overview.mdx @@ -10,5 +10,3 @@ Queries are read-only operations that let you fetch information from Turnkey's A - **No Policy Enforcement:** Queries are not subject to the policy engine, so any authenticated user in your organization can perform them. - **Organization-wide Access:** All users within an organization can read any data within the organization. Parent organizations can also query data for all of their sub-organizations. - **Use Cases:** Common use cases include listing users, retrieving organization details, and fetching activity logs. - - diff --git a/api-reference/queries/validate-container-image-for-tvc.mdx b/api-reference/queries/validate-container-image-for-tvc.mdx index 0aecfe03..4a147c31 100644 --- a/api-reference/queries/validate-container-image-for-tvc.mdx +++ b/api-reference/queries/validate-container-image-for-tvc.mdx @@ -17,23 +17,27 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Unique identifier for a given Organization. + URL of the container image. + HPKE-encrypted pull secret for private images. - + - -A successful response returns the following fields: +A successful response returns the following +fields: -resolvedImageDigest field + + resolvedImageDigest field + diff --git a/api-reference/queries/who-am-i.mdx b/api-reference/queries/who-am-i.mdx index 4e56def7..a22ca440 100644 --- a/api-reference/queries/who-am-i.mdx +++ b/api-reference/queries/who-am-i.mdx @@ -17,16 +17,24 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; Unique identifier for a given organization. If the request is being made by a WebAuthN user and their sub-organization ID is unknown, this can be the parent organization ID; using the sub-organization ID when possible is preferred due to performance reasons. - - - -A successful response returns the following fields: + -Unique identifier for a given organization. -Human-readable name for an organization. -Unique identifier for a given user. -Human-readable name for a user. +A successful response returns the following +fields: + + + Unique identifier for a given organization. + + + Human-readable name for an organization. + + + Unique identifier for a given user. + + + Human-readable name for a user. + diff --git a/changelogs/api-key-stamper/readme.mdx b/changelogs/api-key-stamper/readme.mdx index a9ea0035..8f77ea63 100644 --- a/changelogs/api-key-stamper/readme.mdx +++ b/changelogs/api-key-stamper/readme.mdx @@ -179,4 +179,4 @@ mode: wide ## 0.1.0 -Initial release \ No newline at end of file +Initial release diff --git a/changelogs/core/readme.mdx b/changelogs/core/readme.mdx index c4a53f68..d1b9ddc3 100644 --- a/changelogs/core/readme.mdx +++ b/changelogs/core/readme.mdx @@ -529,4 +529,4 @@ mode: wide - @turnkey/api-key-stamper@0.4.8 - @turnkey/crypto@2.5.1 - @turnkey/http@3.8.1 - - @turnkey/react-native-passkey-stamper@1.1.2 \ No newline at end of file + - @turnkey/react-native-passkey-stamper@1.1.2 diff --git a/changelogs/cosmjs/readme.mdx b/changelogs/cosmjs/readme.mdx index 99d03aa1..8b5468ab 100644 --- a/changelogs/cosmjs/readme.mdx +++ b/changelogs/cosmjs/readme.mdx @@ -1045,4 +1045,4 @@ mode: wide ## 0.1.0 -- Initial release \ No newline at end of file +- Initial release diff --git a/changelogs/crypto/readme.mdx b/changelogs/crypto/readme.mdx index 9ffb78e8..c6114f84 100644 --- a/changelogs/crypto/readme.mdx +++ b/changelogs/crypto/readme.mdx @@ -290,4 +290,4 @@ mode: wide ## 0.1.0 -Initial release \ No newline at end of file +Initial release diff --git a/changelogs/eip-1193-provider/readme.mdx b/changelogs/eip-1193-provider/readme.mdx index 74d84434..62c1abd9 100644 --- a/changelogs/eip-1193-provider/readme.mdx +++ b/changelogs/eip-1193-provider/readme.mdx @@ -734,4 +734,4 @@ mode: wide ## 0.1.0 -Initial release! \ No newline at end of file +Initial release! diff --git a/changelogs/encoding/readme.mdx b/changelogs/encoding/readme.mdx index 5e524ba4..a0330404 100644 --- a/changelogs/encoding/readme.mdx +++ b/changelogs/encoding/readme.mdx @@ -85,4 +85,4 @@ mode: wide ## 0.1.0 -Initial release \ No newline at end of file +Initial release diff --git a/changelogs/ethers/readme.mdx b/changelogs/ethers/readme.mdx index 3c373876..17b56f11 100644 --- a/changelogs/ethers/readme.mdx +++ b/changelogs/ethers/readme.mdx @@ -1443,4 +1443,4 @@ const turnkeySigner = new TurnkeySigner({ - Initial release - Updated dependencies - - @turnkey/http@0.1.1 \ No newline at end of file + - @turnkey/http@0.1.1 diff --git a/changelogs/http/readme.mdx b/changelogs/http/readme.mdx index c6f6c337..031c48ed 100644 --- a/changelogs/http/readme.mdx +++ b/changelogs/http/readme.mdx @@ -915,4 +915,4 @@ Signing is now performed through Turnkey stampers. New dependencies: - Initial release - Updated dependencies - - @turnkey/jest-config@0.1.1 \ No newline at end of file + - @turnkey/jest-config@0.1.1 diff --git a/changelogs/iframe-stamper/readme.mdx b/changelogs/iframe-stamper/readme.mdx index c6bed60b..7664682a 100644 --- a/changelogs/iframe-stamper/readme.mdx +++ b/changelogs/iframe-stamper/readme.mdx @@ -151,4 +151,4 @@ mode: wide ## 0.1.0 -Initial release \ No newline at end of file +Initial release diff --git a/changelogs/react-native-passkey-stamper/readme.mdx b/changelogs/react-native-passkey-stamper/readme.mdx index 256f8ce5..eb667e28 100644 --- a/changelogs/react-native-passkey-stamper/readme.mdx +++ b/changelogs/react-native-passkey-stamper/readme.mdx @@ -461,4 +461,4 @@ This is a major change because the `transports` property, previously a string ar ## 0.1.0 -Initial release \ No newline at end of file +Initial release diff --git a/changelogs/react-wallet-kit/readme.mdx b/changelogs/react-wallet-kit/readme.mdx index dc882448..c1626aa9 100644 --- a/changelogs/react-wallet-kit/readme.mdx +++ b/changelogs/react-wallet-kit/readme.mdx @@ -473,4 +473,4 @@ mode: wide - Updated dependencies []: - @turnkey/core@1.0.0 - - @turnkey/sdk-types@0.4.0 \ No newline at end of file + - @turnkey/sdk-types@0.4.0 diff --git a/changelogs/sdk-browser/readme.mdx b/changelogs/sdk-browser/readme.mdx index c9479d9d..3e16be4b 100644 --- a/changelogs/sdk-browser/readme.mdx +++ b/changelogs/sdk-browser/readme.mdx @@ -1209,4 +1209,4 @@ These enhancements simplify integrations, improve UX, and deliver a more robust ## 0.0.1 -Initial (experimental) release! This is an alpha release and subject to change. \ No newline at end of file +Initial (experimental) release! This is an alpha release and subject to change. diff --git a/changelogs/sdk-react-native/readme.mdx b/changelogs/sdk-react-native/readme.mdx index 8df441c4..cf9b4e68 100644 --- a/changelogs/sdk-react-native/readme.mdx +++ b/changelogs/sdk-react-native/readme.mdx @@ -506,4 +506,4 @@ handleGoogleOAuth({ - Updated dependencies [3c44c4a] - @turnkey/http@2.20.0 - - @turnkey/crypto@2.3.1 \ No newline at end of file + - @turnkey/crypto@2.3.1 diff --git a/changelogs/sdk-react/readme.mdx b/changelogs/sdk-react/readme.mdx index 31fe3ae9..5eb96c22 100644 --- a/changelogs/sdk-react/readme.mdx +++ b/changelogs/sdk-react/readme.mdx @@ -1141,4 +1141,4 @@ This release significantly enhances authentication by integrating the new `index ## 0.0.1 -Initial (experimental) release! This is an alpha release and subject to change. \ No newline at end of file +Initial (experimental) release! This is an alpha release and subject to change. diff --git a/changelogs/sdk-server/readme.mdx b/changelogs/sdk-server/readme.mdx index 714faa61..e9ac461f 100644 --- a/changelogs/sdk-server/readme.mdx +++ b/changelogs/sdk-server/readme.mdx @@ -864,4 +864,4 @@ These changes standardize authentication processes, simplify integration, and st ## 0.0.1 -Initial (experimental) release! This is an alpha release and subject to change. \ No newline at end of file +Initial (experimental) release! This is an alpha release and subject to change. diff --git a/changelogs/solana/readme.mdx b/changelogs/solana/readme.mdx index e034b8fd..c6c9292a 100644 --- a/changelogs/solana/readme.mdx +++ b/changelogs/solana/readme.mdx @@ -873,4 +873,4 @@ Add support for signing Solana versioned transactions (#216) ## 0.1.0 -- Initial release \ No newline at end of file +- Initial release diff --git a/changelogs/telegram-cloud-storage-stamper/readme.mdx b/changelogs/telegram-cloud-storage-stamper/readme.mdx index d5567bc8..b1a0d7e6 100644 --- a/changelogs/telegram-cloud-storage-stamper/readme.mdx +++ b/changelogs/telegram-cloud-storage-stamper/readme.mdx @@ -162,4 +162,4 @@ mode: wide ### Major Changes -- Initial release of the telegram-cloud-storage-stamper package. This package is to be used alongside Telegram mini-app development and provides a stamping utility and an interface into Telegram Cloud Storage. More can be read in the [readme](../packages/telegram-cloud-storage-stamper/readme.md). \ No newline at end of file +- Initial release of the telegram-cloud-storage-stamper package. This package is to be used alongside Telegram mini-app development and provides a stamping utility and an interface into Telegram Cloud Storage. More can be read in the [readme](../packages/telegram-cloud-storage-stamper/readme.md). diff --git a/changelogs/viem/readme.mdx b/changelogs/viem/readme.mdx index 85511a06..12e3780e 100644 --- a/changelogs/viem/readme.mdx +++ b/changelogs/viem/readme.mdx @@ -1192,4 +1192,4 @@ const turnkeyAccount = await createAccount({ ## 0.1.0 -Initial release! \ No newline at end of file +Initial release! diff --git a/changelogs/wallet-stamper/readme.mdx b/changelogs/wallet-stamper/readme.mdx index 73a7330d..76d0b17b 100644 --- a/changelogs/wallet-stamper/readme.mdx +++ b/changelogs/wallet-stamper/readme.mdx @@ -300,4 +300,4 @@ mode: wide ### Patch Changes -- 68a14dd: Initial release! 🎉 \ No newline at end of file +- 68a14dd: Initial release! 🎉 diff --git a/changelogs/webauthn-stamper/readme.mdx b/changelogs/webauthn-stamper/readme.mdx index dc89920d..553bca35 100644 --- a/changelogs/webauthn-stamper/readme.mdx +++ b/changelogs/webauthn-stamper/readme.mdx @@ -64,4 +64,4 @@ mode: wide ## 0.1.0 -Initial release \ No newline at end of file +Initial release diff --git a/docs.json b/docs.json index f91d44dc..6bdf2612 100644 --- a/docs.json +++ b/docs.json @@ -8,12 +8,7 @@ "dark": "#050a0b" }, "contextual": { - "options": [ - "copy", - "view", - "chatgpt", - "claude" - ] + "options": ["copy", "view", "chatgpt", "claude"] }, "integrations": { "ga4": { @@ -38,9 +33,7 @@ "groups": [ { "group": "Welcome", - "pages": [ - "welcome" - ] + "pages": ["welcome"] } ] }, @@ -49,9 +42,7 @@ "groups": [ { "group": "Overview", - "pages": [ - "solutions/overview" - ] + "pages": ["solutions/overview"] }, { "group": "Embedded Wallets", @@ -275,10 +266,7 @@ "get-started/quickstart", { "group": "Using LLMs", - "pages": [ - "get-started/using-llms", - "get-started/ai-skills" - ] + "pages": ["get-started/using-llms", "get-started/ai-skills"] }, "get-started/examples", { @@ -450,9 +438,7 @@ }, { "group": "Webhooks", - "pages": [ - "features/webhooks/overview" - ] + "pages": ["features/webhooks/overview"] } ] }, @@ -944,15 +930,11 @@ }, { "group": "API changelog", - "pages": [ - "changelogs/api-changelog/readme" - ] + "pages": ["changelogs/api-changelog/readme"] }, { "group": "TVC changelog", - "pages": [ - "changelogs/tvc-changelog/readme" - ] + "pages": ["changelogs/tvc-changelog/readme"] } ] } diff --git a/features/authentication/auth-proxy.mdx b/features/authentication/auth-proxy.mdx index 735ed9d8..e4ce0b2e 100644 --- a/features/authentication/auth-proxy.mdx +++ b/features/authentication/auth-proxy.mdx @@ -20,13 +20,14 @@ Enable and configure the Auth Proxy from the **Dashboard** → AUTH section (all ## How it works -1. Enable in Dashboard. Toggle **Auth Proxy** ON. Turnkey creates a Proxy User and proxy API key, stored encrypted in the auth proxy config for your org. -2. Configure Allowed Origins. Only requests from these origins may call the proxy (CORS + origin validation). Each entry must be an exact URL (e.g. `https://myapp.com`). By default all origins are allowed (*). Note: partial wildcard patterns like `https://*.myapp.com` are not currently supported. +1. Enable in Dashboard. Toggle **Auth Proxy** ON. Turnkey creates a Proxy User and proxy API key, stored encrypted in the auth proxy config for your org. +2. Configure Allowed Origins. Only requests from these origins may call the proxy (CORS + origin validation). Each entry must be an exact URL (e.g. `https://myapp.com`). By default all origins are allowed (_). Note: partial wildcard patterns like `https://_.myapp.com` are not currently supported. 3. Your App Calls Auth Proxy. Your frontend hits `https://authproxy.turnkey.com/v1/...` with your auth proxy config id and the flow parameters. This should be passed to the X-Auth-Proxy-Config-Id header in your request -4. Proxy Signs & Forwards. Auth Proxy decrypts your proxy key in-memory, signs the activity, and forwards to Turnkey Coordinator. -5. Coordinator Responds. Proxy returns success / error, plus any response payload (e.g., organizationId, session). +4. Proxy Signs & Forwards. Auth Proxy decrypts your proxy key in-memory, signs the activity, and forwards to Turnkey Coordinator. +5. Coordinator Responds. Proxy returns success / error, plus any response payload (e.g., organizationId, session). **Security notes:** + - Proxy keys are HPKE encrypted inside our enclave; decrypted per request only in memory. - Strict separation from Turnkey’s core backend; communicates via public API only. - The Auth Proxy does not verify App Proofs produced by Turnkey's secure enclaves, it simply passes them on to its caller. End-users (SDKs) are expected to perform this verification procedure, not the Auth Proxy. Refer to [Turnkey Verified](/security/turnkey-verified) for more information on how App Proof verification works. @@ -37,10 +38,11 @@ All endpoints are under https://authproxy.turnkey.com ## Authentication & headers -- **Auth Proxy Config Id** (required): identifies your parent org’s proxy config. - - Send as header: +- **Auth Proxy Config Id** (required): identifies your parent org’s proxy config. + - Send as header: ``` X-Auth-Proxy-Config-Id: + ``` - **CORS & Origin:** Requests must originate from a whitelisted origin set in the dashboard. ## Endpoints @@ -52,6 +54,7 @@ All endpoints are under https://authproxy.turnkey.com Onboard a new user by creating a sub-organization. Optionally creates a wallet. **Request Body** + ```json { "userName": "newuser@example.com", @@ -68,6 +71,7 @@ Onboard a new user by creating a sub-organization. Optionally creates a wallet. ``` **Response** + ```json { "organizationId": "suborg-abc123" @@ -81,13 +85,16 @@ POST /v1/otp_init Initialize an OTP (SMS or email) for a user. **Request Body** + ```json { "otpType": "OTP_TYPE_SMS", "contact": "+12265550123" } ``` + **Response** + ```json { "otpId": "otp-xyz789" @@ -106,7 +113,7 @@ Verify the OTP code previously sent to the user’s contact. { "otpId": "otp-xyz789", "otpCode": "123456", - "public_key": "02ab...compressedP256", + "public_key": "02ab...compressedP256" } ``` @@ -130,7 +137,7 @@ Login using a verification token and public key. { "verificationToken": "verify-token-abc", "publicKey": "02ab...compressedP256", - "client_signature": "30453...hexEncodedSignatureOverVerificationToken", + "client_signature": "30453...hexEncodedSignatureOverVerificationToken" } ``` @@ -156,8 +163,8 @@ Authenticate with an OAuth 2.0 provider and receive an OIDC token issued by Turn "authCode": "your_oauth2_auth_code", "redirectUri": "https://yourapp.com/callback", "codeVerifier": "string-used-for-pkce", - "nonce":"sha256(publicKey)", - "clientId":"your-oauth2-client-id", + "nonce": "sha256(publicKey)", + "clientId": "your-oauth2-client-id" } ``` @@ -232,7 +239,15 @@ Return Wallet Kit feature toggles for the calling organization. ```json { - "enabledProviders": ["google", "facebook", "apple", "email", "sms", "passkey", "wallet"], + "enabledProviders": [ + "google", + "facebook", + "apple", + "email", + "sms", + "passkey", + "wallet" + ], "sessionExpirationSeconds": "1800", "organizationId": "org-abc123" } @@ -240,7 +255,7 @@ Return Wallet Kit feature toggles for the calling organization. ## Configuration (Dashboard → AUTH) -- Enable/Disable the Auth Proxy for your org -- Allowed Frontend Origins (CORS enforcement) -- Email/SMS Customization +- Enable/Disable the Auth Proxy for your org +- Allowed Frontend Origins (CORS enforcement) +- Email/SMS Customization - Session Expiration diff --git a/features/authentication/backend-setup.mdx b/features/authentication/backend-setup.mdx index e53e359b..d41d3844 100644 --- a/features/authentication/backend-setup.mdx +++ b/features/authentication/backend-setup.mdx @@ -3,7 +3,7 @@ title: "Backend authentication" description: "Guide for integrating Turnkey authentication into your backend, covering session JWT creation, validation, and enforcing user access controls." --- -import { FeatureCard } from '/snippets/feature-card.mdx' +import { FeatureCard } from "/snippets/feature-card.mdx"; ## Introduction @@ -12,6 +12,7 @@ This guide shows you how to use Turnkey as the foundation for your own backend a ## Why use backend authentication? There are several benefits to enforcing authenticated requests to your backend: + 1. **User data**: Store and retrieve user data associated with Turnkey sub-organizations 2. **Metrics and monitoring**: Add custom validations, rate limiting, and logging 3. **Co-signing capabilities**: Enable 2/2 signing patterns where your application is a co-signer @@ -48,15 +49,19 @@ sequenceDiagram ``` ### High-level flow + The overall pattern is similar, but may differ slightly depending on the auth method. Generally: + - The user authenticates (via passkey, OTP, etc.) - A session is created with Turnkey, returning a session JWT - That session JWT is used to make authenticated requests to your backend ## Getting the session JWT + Turnkey supports multiple authentication methods, each of which results in a session JWT that proves the user's identity. This section covers the two most common flows: passkey authentication and OTP (One-Time Passcode) authentication. It explains how each method ultimately produces a session JWT that your frontend can use to make authenticated requests to your backend. ### Passkey authentication + Turnkey supports passkey authentication, which allows users to log in using their device’s biometric system or a hardware security key. In this guide, we’ll separate login and signup flows, since most apps handle them independently and the implementation details differ slightly. #### Signup flow @@ -93,16 +98,21 @@ sequenceDiagram The frontend creates a passkey using WebAuthn, prompting the user for biometric or hardware authentication. At the same time, it silently generates a temporary API key in the background, which is used to stamp requests during the signup process. - **Note:** We use a temporary API key during signup to avoid prompting the user twice for a passkey tap. Without it, we’d need to use the passkey to stamp the `stampLogin()` request later in the flow, which would trigger a second prompt right after creating the passkey. Using the API key instead allows us to create the session in the background with just a single tap. - +**Note:** We use a temporary API key during signup to avoid prompting the user twice for a passkey tap. Without it, we’d need to use the passkey to stamp the `stampLogin()` request later in the flow, which would trigger a second prompt right after creating the passkey. Using the API key instead allows us to create the session in the background with just a single tap. - - The frontend sends the passkey and API public key to the backend. The backend then uses the Turnkey API to create a new sub-organization and register both credentials as authenticators. - - The frontend initializes a `TurnkeyClient` using the temporary API key and calls `stampLogin()`. Turnkey returns a session JWT representing the authenticated user session. - + + The frontend sends the passkey and API public key to the backend. The backend + then uses the Turnkey API to create a new sub-organization and register both + credentials as authenticators. + + + + The frontend initializes a `TurnkeyClient` using the temporary API key and + calls `stampLogin()`. Turnkey returns a session JWT representing the + authenticated user session. + Your frontend can now make requests to your backend and attach the session JWT. The backend will validate the token on each request and verify that the user has permission to perform the requested action. @@ -138,13 +148,17 @@ sequenceDiagram The user begins the login flow by tapping a button like “Log in with Passkey” on the frontend. - - The frontend initializes a `TurnkeyClient` with a `passkeyStamper` and calls `stampLogin()`. This triggers a WebAuthn prompt, prompting the user to approve the login request using their passkey. - + + The frontend initializes a `TurnkeyClient` with a `passkeyStamper` and calls + `stampLogin()`. This triggers a WebAuthn prompt, prompting the user to approve + the login request using their passkey. + - - Once the user approves the request, the signed login is sent to Turnkey. Turnkey then returns a session JWT representing the authenticated user session. - + + Once the user approves the request, the signed login is sent to Turnkey. + Turnkey then returns a session JWT representing the authenticated user + session. + Your frontend can now make requests to your backend and attach the session JWT. The backend will validate the token on each request and verify that the user has permission to perform the requested action. @@ -152,6 +166,7 @@ sequenceDiagram ### OTP authentication + Turnkey also supports SMS and email-based One-Time Passcode (OTP) authentication, allowing users to log in by entering a code sent to their email or phone number. We’ll cover OTP login and signup together, since the flows are similar and most apps handle them in a unified way. ```mermaid @@ -196,17 +211,23 @@ sequenceDiagram The user begins the login flow by entering their email or phone number on the frontend. - - The frontend sends the contact info to your backend, which requests an OTP from Turnkey. Once the user receives and enters the code, your backend verifies it with Turnkey and receives a verification token. - + + The frontend sends the contact info to your backend, which requests an OTP + from Turnkey. Once the user receives and enters the code, your backend + verifies it with Turnkey and receives a verification token. + - - The frontend generates an API key, then sends the API public key and verification token to the backend. The backend checks with Turnkey whether a sub-organization already exists for the contact. If not, it creates a new one. - + + The frontend generates an API key, then sends the API public key and + verification token to the backend. The backend checks with Turnkey whether a + sub-organization already exists for the contact. If not, it creates a new one. + - - The backend calls `otpLogin()` with the subOrgId, public key, and verification token. Turnkey returns a session JWT representing the authenticated user session, which the backend then returns to the frontend. - + + The backend calls `otpLogin()` with the subOrgId, public key, and verification + token. Turnkey returns a session JWT representing the authenticated user + session, which the backend then returns to the frontend. + Your frontend can now make requests to your backend and attach the session JWT. The backend will validate the token on each request and verify that the user has permission to perform the requested action. @@ -214,6 +235,7 @@ sequenceDiagram ## Sending the JWT from the frontend + After a user completes Turnkey authentication and a session is created (via passkey, OTP, or another supported method), your backend returns a session JWT to the frontend. This token proves the user’s identity and is the frontend’s responsibility to store and include in all future authenticated requests to your backend. The session JWT should be attached to each request using the `Authorization` header. This allows your backend to identify the authenticated user and enforce any necessary access control based on the `user_id` or `organization_id`. @@ -221,26 +243,34 @@ The session JWT should be attached to each request using the `Authorization` hea **Note:** These requests are sent to your own backend endpoints and may contain any application-specific payload, such as a form submission, a database mutation, or a business action. They are not necessarily related to Turnkey. Here’s an example of how the frontend might send the JWT: + ```typescript const response = await fetch("/api/your-backend-endpoint", { method: "POST", headers: { "Content-Type": "application/json", - "Authorization": `Bearer ${sessionJwt}`, + Authorization: `Bearer ${sessionJwt}`, }, - body: JSON.stringify({ /* your request payload */ }), + body: JSON.stringify({ + /* your request payload */ + }), }); ``` + This adds the following header to your HTTP request: + ```http Authorization: Bearer ``` ## Validating the JWT in your backend + After a user completes Turnkey authentication and a session is created (via passkey, OTP, or another supported method), your backend returns a session JWT to the frontend. This token proves the user's identity and is the frontend’s responsibility to store and include in all future authenticated requests. ### What does the session JWT contain? + Before diving into how to verify the session JWT, it’s helpful to understand what’s actually inside it. The JWT includes information that identifies the authenticated user and the organization they belong to, as well as metadata like expiration time and session type. Here’s an example of a decoded session JWT: + ```typescript { "exp": , @@ -252,20 +282,22 @@ Before diving into how to verify the session JWT, it’s helpful to understand w ``` ### Validating the JWT + To validate the session JWT: Use the helper function `verifySessionJwtSignature` from [`@turnkey/crypto`](https://github.com/tkhq/sdk/blob/e10342cd111fbb9b1d168ff386b5dc263e3a5ce3/packages/crypto/src/turnkey.ts#L409-L466) to confirm that the JWT was signed by Turnkey and hasn’t been modified. - ```typescript - import { verifySessionJwtSignature } from "@turnkey/crypto"; +```typescript +import { verifySessionJwtSignature } from "@turnkey/crypto"; + +const isValid = await verifySessionJwtSignature(sessionJwt); +if (!isValid) { + throw new Error("Invalid JWT: failed signature verification"); +} +``` - const isValid = await verifySessionJwtSignature(sessionJwt); - if (!isValid) { - throw new Error("Invalid JWT: failed signature verification"); - } - ``` @@ -306,34 +338,48 @@ To validate the session JWT: publicKey, }; } - ``` - - - Ensure that the token has not expired by validating the exp (expiration) claim. +```` + + + +Ensure that the token has not expired by validating the exp (expiration) claim. + +```typescript + if (decodedJwt.exp * 1000 < Date.now()) { + throw new Error("Token has expired"); + } +```` - ```typescript - if (decodedJwt.exp * 1000 < Date.now()) { - throw new Error("Token has expired"); - } - ``` Once the token is verified and decoded, use the `userId` and `organizationId` to enforce access control in your application. - This step is application-specific and depends on how your backend maps users to organizations. For example, you might: +This step is application-specific and depends on how your backend maps users to organizations. For example, you might: + +- Look up the user in your database by `userId` +- Confirm that the request targets the correct `organizationId` +- Reject the request if the user is not linked to that organization - - Look up the user in your database by `userId` - - Confirm that the request targets the correct `organizationId` - - Reject the request if the user is not linked to that organization +This ensures that even with a valid JWT, a user can only access resources associated with their own Turnkey sub-organization. - This ensures that even with a valid JWT, a user can only access resources associated with their own Turnkey sub-organization. ## Advanced topics -
- +
+
diff --git a/features/authentication/bring-your-own-auth.mdx b/features/authentication/bring-your-own-auth.mdx index 79c5b972..46bd1bc7 100644 --- a/features/authentication/bring-your-own-auth.mdx +++ b/features/authentication/bring-your-own-auth.mdx @@ -21,16 +21,20 @@ This works well and is easy to implement, but it is **custodial**: your backend await client.createSubOrganization({ subOrganizationName: `user-${userId}`, rootQuorumThreshold: 1, - rootUsers: [{ - userName: userEmail, - userEmail: userEmail, - apiKeys: [{ - apiKeyName: "backend-key", - publicKey: YOUR_BACKEND_PUBLIC_KEY, - }], - authenticators: [], - oauthProviders: [], - }], + rootUsers: [ + { + userName: userEmail, + userEmail: userEmail, + apiKeys: [ + { + apiKeyName: "backend-key", + publicKey: YOUR_BACKEND_PUBLIC_KEY, + }, + ], + authenticators: [], + oauthProviders: [], + }, + ], }); ``` @@ -45,16 +49,20 @@ If you want users to fully control their wallets, Turnkey must be able to indepe await client.createSubOrganization({ subOrganizationName: `user-${userId}`, rootQuorumThreshold: 1, - rootUsers: [{ - userName: userEmail, - userEmail: userEmail, - apiKeys: [], - authenticators: [], - oauthProviders: [{ - providerName: "my-auth-system", - oidcToken: idToken, - }], - }], + rootUsers: [ + { + userName: userEmail, + userEmail: userEmail, + apiKeys: [], + authenticators: [], + oauthProviders: [ + { + providerName: "my-auth-system", + oidcToken: idToken, + }, + ], + }, + ], }); ``` @@ -82,16 +90,20 @@ When a user first authenticates, create a Turnkey sub-org for them with your OID await client.createSubOrganization({ subOrganizationName: `user-${userId}`, rootQuorumThreshold: 1, - rootUsers: [{ - userName: userEmail, - userEmail: userEmail, - apiKeys: [], - authenticators: [], - oauthProviders: [{ - providerName: "my-auth-system", - oidcToken: idToken, - }], - }], + rootUsers: [ + { + userName: userEmail, + userEmail: userEmail, + apiKeys: [], + authenticators: [], + oauthProviders: [ + { + providerName: "my-auth-system", + oidcToken: idToken, + }, + ], + }, + ], }); ``` @@ -141,9 +153,11 @@ If a user already has a Turnkey sub-org (created via email OTP, passkey, etc.) a // Stamped with a credential that has authority in the sub-org await client.createOauthProviders({ userId: existingUserId, - oauthProviders: [{ - providerName: "my-auth-system", - oidcToken: idToken, - }], + oauthProviders: [ + { + providerName: "my-auth-system", + oidcToken: idToken, + }, + ], }); -``` \ No newline at end of file +``` diff --git a/features/authentication/email.mdx b/features/authentication/email.mdx index 4b80ec29..d962e1d6 100644 --- a/features/authentication/email.mdx +++ b/features/authentication/email.mdx @@ -35,16 +35,22 @@ 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 + Upon verification of the correct code, an API key credential is generated + and encrypted for the client ### Credential bundle method - This method is only supported by **legacy iframe-based flows** and is not available in the current Turnkey SDKs. + + {" "} + This method is only supported by **legacy iframe-based flows** and is not + available in the current Turnkey SDKs.{" "} + The API key credential is encrypted and delivered directly through email to the user. 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. @@ -80,7 +86,13 @@ For OTP Auth signup and login flows you will need a user with the following poli } ``` -Avoid using an API key that is also present in the sub-organization that you're targeting within the email activities. Turnkey identifies the user from the request signature and in case of an identical API key it will always prioritize the sub-organization user matching. As a result, it will try to evaluate the sub-organization policies instead of the parent ones. + + Avoid using an API key that is also present in the sub-organization that + you're targeting within the email activities. Turnkey identifies the user from + the request signature and in case of an identical API key it will always + prioritize the sub-organization user matching. As a result, it will try to + evaluate the sub-organization policies instead of the parent ones. + ## User experience @@ -109,13 +121,11 @@ After receiving the verification token, users complete OTP authentication flow w - `publicKey`: public key to add to organization data associated with the signing key in IndexedDB or SecureStorage. - `verificationToken`: JWT returned from successful `VERIFY_OTP` activity -- `clientSignature`: This proves authorization for the verification token being used, and is generated using the keypair whose public key was provided in the `encryptedOtpBundle` during verification. +- `clientSignature`: This proves authorization for the verification token being used, and is generated using the keypair whose public key was provided in the `encryptedOtpBundle` during verification. - `expirationSeconds`: optional validity window (defaults to 15 minutes) - `invalidateExisting`: optional boolean to invalidate previous login sessions - - ![auth otp email](/images/authentication/img/auth_otp_email.png) - +![auth otp email](/images/authentication/img/auth_otp_email.png) ### Sub-organization initiated OTP @@ -139,6 +149,7 @@ All activities are stamped using valid sub-organization credentials, with `organ The `verificationToken` is scoped to the issuing organization. Parent-issued tokens can be used by any sub-organization; sub-org-issued tokens are limited to that sub-org only. + @@ -161,9 +172,7 @@ This alternative method uses `ACTIVITY_TYPE_EMAIL_AUTH` with these parameters: - `emailCustomization`: optional parameters for customizing emails - `invalidateExisting`: optional boolean to invalidate previous Email Auth API keys - - ![auth email](/images/authentication/img/auth_email.png) - +![auth email](/images/authentication/img/auth_email.png) ## Email customization @@ -198,14 +207,15 @@ const response = await client.emailAuth({ **Effective December 16, 2025** - Beginning December 16, 2025, all email-based OTP and recovery activities will require the `appName` parameter. Existing SDK versions will continue working, but upgrading without setting an `appName` will break email-based flows. +Beginning December 16, 2025, all email-based OTP and recovery activities will require the `appName` parameter. Existing SDK versions will continue working, but upgrading without setting an `appName` will break email-based flows. - **Auth Proxy users** — Set `appName` under [email configuration](https://app.turnkey.com/dashboard/walletKit) in the dashboard. +**Auth Proxy users** — Set `appName` under [email configuration](https://app.turnkey.com/dashboard/walletKit) in the dashboard. - **Server SDK users** — If you call `init_otp_auth`, `init_otp`, `email_recovery`, or `email_auth` without `appName`: - - For `email_recovery` or `email_auth`: include `appName` in your request - - For `init_otp` or `init_otp_auth`: update your API call to match the new input structure when upgrading to the latest server SDK - +**Server SDK users** — If you call `init_otp_auth`, `init_otp`, `email_recovery`, or `email_auth` without `appName`: + +- For `email_recovery` or `email_auth`: include `appName` in your request +- For `init_otp` or `init_otp_auth`: update your API call to match the new input structure when upgrading to the latest server SDK + @@ -217,9 +227,9 @@ await client.emailAuth({ email: "user@example.com", targetPublicKey: "", emailCustomization: { - appName: "Your App Name" // this is now required - } - } + appName: "Your App Name", // this is now required + }, + }, }); ``` @@ -233,8 +243,8 @@ await client.initOtp({ appName: "Your App Name", // this is now required emailCustomization: { // other optional customization - } - } + }, + }, }); ``` @@ -244,18 +254,17 @@ await client.initOtp({ If you manage email flows with policies, update to the new activity types: -| **Flow** | **Old activity type** | **New activity type** | -| :--- | :--- | :--- | -| Email auth | `ACTIVITY_TYPE_EMAIL_AUTH`, `ACTIVITY_TYPE_EMAIL_AUTH_V2` | `ACTIVITY_TYPE_EMAIL_AUTH_V3` | -| Init OTP auth | `ACTIVITY_TYPE_INIT_OTP_AUTH`, `ACTIVITY_TYPE_INIT_OTP_AUTH_V2` | `ACTIVITY_TYPE_INIT_OTP_AUTH_V3` | -| Init OTP (signup) | `ACTIVITY_TYPE_INIT_OTP`, `ACTIVITY_TYPE_INIT_OTP_V2` | `ACTIVITY_TYPE_INIT_OTP_V3` | -| Verify OTP | `ACTIVITY_TYPE_VERIFY_OTP` | `ACTIVITY_TYPE_VERIFY_OTP_V2` | -| OTP login | `ACTIVITY_TYPE_OTP_LOGIN` | `ACTIVITY_TYPE_OTP_LOGIN_V2` | -| Email recovery | `ACTIVITY_TYPE_INIT_USER_EMAIL_RECOVERY` | `ACTIVITY_TYPE_INIT_USER_EMAIL_RECOVERY_V2` | +| **Flow** | **Old activity type** | **New activity type** | +| :---------------- | :-------------------------------------------------------------- | :------------------------------------------ | +| Email auth | `ACTIVITY_TYPE_EMAIL_AUTH`, `ACTIVITY_TYPE_EMAIL_AUTH_V2` | `ACTIVITY_TYPE_EMAIL_AUTH_V3` | +| Init OTP auth | `ACTIVITY_TYPE_INIT_OTP_AUTH`, `ACTIVITY_TYPE_INIT_OTP_AUTH_V2` | `ACTIVITY_TYPE_INIT_OTP_AUTH_V3` | +| Init OTP (signup) | `ACTIVITY_TYPE_INIT_OTP`, `ACTIVITY_TYPE_INIT_OTP_V2` | `ACTIVITY_TYPE_INIT_OTP_V3` | +| Verify OTP | `ACTIVITY_TYPE_VERIFY_OTP` | `ACTIVITY_TYPE_VERIFY_OTP_V2` | +| OTP login | `ACTIVITY_TYPE_OTP_LOGIN` | `ACTIVITY_TYPE_OTP_LOGIN_V2` | +| Email recovery | `ACTIVITY_TYPE_INIT_USER_EMAIL_RECOVERY` | `ACTIVITY_TYPE_INIT_USER_EMAIL_RECOVERY_V2` | - ### Email templates 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: @@ -282,14 +291,16 @@ For best compatibility across email providers, make sure to use PNG images withi - **Bespoke HTML templates** and **custom email sender domains** are available to [**Enterprise clients**](https://www.turnkey.com/pricing) on the **Scale tier** or higher. + **Bespoke HTML templates** and **custom email sender domains** are available + to [**Enterprise clients**](https://www.turnkey.com/pricing) on the **Scale + tier** or higher. If you are interested in implementing bespoke, fully-customized email templates, please reach out to [hello@turnkey.com](mailto:hello@turnkey.com). ### Custom email sender domain -[Enterprise](https://www.turnkey.com/pricing) clients can also customize the email sender domain. To get set up, please reach out to your Turnkey rep to get started but here is what you'll be able to configure: +[Enterprise](https://www.turnkey.com/pricing) clients can also customize the email sender domain. To get set up, please reach out to your Turnkey rep to get started but here is what you'll be able to configure: ```js // Optional custom email address from which to send the OTP email @@ -330,7 +341,8 @@ Specifically: - For credential bundle auth: `ACTIVITY_TYPE_EMAIL_AUTH` - ![email auth authorization](/images/authentication/img/diagrams/email_auth_authorization.png) + ![email auth + authorization](/images/authentication/img/diagrams/email_auth_authorization.png) ### Example implementations diff --git a/features/authentication/overview.mdx b/features/authentication/overview.mdx index 55d56e0a..e5b269e8 100644 --- a/features/authentication/overview.mdx +++ b/features/authentication/overview.mdx @@ -3,7 +3,7 @@ title: Overview description: Learn about supported authentication methods for Turnkey, how to add them, and usage details. --- -import { FeatureCard } from '/snippets/feature-card.mdx' +import { FeatureCard } from "/snippets/feature-card.mdx"; Turnkey's wallet system supports granular controls on who can access wallets and what actions different users can perform. @@ -42,10 +42,41 @@ For information about managing authenticated sessions, see our [Sessions](/featu ## Related resources -
- - - - - +
+ + + + +
diff --git a/features/authentication/passkeys/discoverable-vs-non-discoverable.mdx b/features/authentication/passkeys/discoverable-vs-non-discoverable.mdx index 1058f4a5..54ebe523 100644 --- a/features/authentication/passkeys/discoverable-vs-non-discoverable.mdx +++ b/features/authentication/passkeys/discoverable-vs-non-discoverable.mdx @@ -7,8 +7,8 @@ description: 'Also known as "resident" vs. "non-resident" credentials. From [the What does this mean exactly? -* "resident" credentials and "discoverable" credentials are the same -* "non-resident" credentials and "non-discoverable" credentials are the same. +- "resident" credentials and "discoverable" credentials are the same +- "non-resident" credentials and "non-discoverable" credentials are the same. The spec authors made this rename for clarity. @@ -20,10 +20,16 @@ A discoverable credential is a self-contained key pair, stored on the end-user's - device selection on Chrome + device selection on Chrome - passkey selection on Chrome + passkey selection on Chrome @@ -37,10 +43,10 @@ A non-discoverable credential isn’t stored on the end-user's device fully: Tur Why would you choose non-discoverable credentials? -* Most hardware security keys have limited slots to store discoverable credentials, or will refuse to create new discoverable credentials on the hardware altogether. YubiKey 5 [advertises 25 slots](https://support.yubico.com/hc/en-us/articles/4404456942738-FAQ#h_01FFHQFVBW0995G2MKZGCKQVEJ), SoloKeys [support 50](https://github.com/solokeys/solo1/issues/156#issuecomment-477645573), NitroKeys 3 [support 10](https://github.com/Nitrokey/nitrokey-3-firmware/blob/0e23c75318e2016ac1cfb8345de9279e3ad2eaf9/components/apps/src/lib.rs#L390). Non-discoverable credentials aren't subject to these limits because they work off of a single hardware secret. -* Security keys can only allow clearing of individual slots if they support [CTAP 2.1](https://fidoalliance.org/specs/fido-v2.1-rd-20201208/fido-client-to-authenticator-protocol-v2.1-rd-20201208.html). This is described in [this blog post](https://fy.blackhats.net.au/blog/2023-02-02-how-hype-will-turn-your-security-key-into-junk/). When security keys do not support CTAP 2.1, slots can only be freed up by resetting the hardware entirely, erasing all secrets at once. -* Non-discoverable credentials take less space. This is important in some environments, but unlikely to be relevant if your users are storing passkeys in their Google or Apple accounts (plenty of space available there!) -* Credential IDs have to be communicated during authentication (via the `allowCredentials` field). This allows browsers to offer better, more tailored prompts in some cases. For example: if the list contains a single authenticator with `"transports": ["AUTHENTICATOR_TRANSPORT_INTERNAL"]`, Chrome does “the right thing” by skipping the device selection popup: users go straight to the fingerprint popup, with no need to select “this device”! +- Most hardware security keys have limited slots to store discoverable credentials, or will refuse to create new discoverable credentials on the hardware altogether. YubiKey 5 [advertises 25 slots](https://support.yubico.com/hc/en-us/articles/4404456942738-FAQ#h_01FFHQFVBW0995G2MKZGCKQVEJ), SoloKeys [support 50](https://github.com/solokeys/solo1/issues/156#issuecomment-477645573), NitroKeys 3 [support 10](https://github.com/Nitrokey/nitrokey-3-firmware/blob/0e23c75318e2016ac1cfb8345de9279e3ad2eaf9/components/apps/src/lib.rs#L390). Non-discoverable credentials aren't subject to these limits because they work off of a single hardware secret. +- Security keys can only allow clearing of individual slots if they support [CTAP 2.1](https://fidoalliance.org/specs/fido-v2.1-rd-20201208/fido-client-to-authenticator-protocol-v2.1-rd-20201208.html). This is described in [this blog post](https://fy.blackhats.net.au/blog/2023-02-02-how-hype-will-turn-your-security-key-into-junk/). When security keys do not support CTAP 2.1, slots can only be freed up by resetting the hardware entirely, erasing all secrets at once. +- Non-discoverable credentials take less space. This is important in some environments, but unlikely to be relevant if your users are storing passkeys in their Google or Apple accounts (plenty of space available there!) +- Credential IDs have to be communicated during authentication (via the `allowCredentials` field). This allows browsers to offer better, more tailored prompts in some cases. For example: if the list contains a single authenticator with `"transports": ["AUTHENTICATOR_TRANSPORT_INTERNAL"]`, Chrome does “the right thing” by skipping the device selection popup: users go straight to the fingerprint popup, with no need to select “this device”! The downside to this is, of course, that you need to store credential IDs, and you need to make sure you can retrieve credentials for each user. This can be done with a table of credentials keyed by user email, for example. Or if you have your own authentication already, a list of credentials can be returned when the user logs in. diff --git a/features/authentication/passkeys/integration.mdx b/features/authentication/passkeys/integration.mdx index 39978ad2..7e48404e 100644 --- a/features/authentication/passkeys/integration.mdx +++ b/features/authentication/passkeys/integration.mdx @@ -6,9 +6,11 @@ title: "Integrating Passkeys" A typical passkey flow is composed of 4 main steps, depicted below: - - Passkey flow on Turnkey + Passkey flow on Turnkey 1. Your app frontend triggers a passkey prompt. @@ -18,16 +20,16 @@ A typical passkey flow is composed of 4 main steps, depicted below: This flow happens once for **registration** and for each subsequent **authentication** or signature request. The main difference is the browser APIs used to trigger the passkey prompt in step (1): -* **Passkey registration** uses `navigator.credentials.create`(as described in [this guide](https://web.dev/passkey-registration/)). `navigator.credentials.create` triggers the creation of a **new** passkey. -* **Passkey authentication** uses `navigator.credentials.get`. See [this guide](https://web.dev/passkey-form-autofill/) for more information. `navigator.credentials.get` triggers a signature prompt for an **existing** passkey. +- **Passkey registration** uses `navigator.credentials.create`(as described in [this guide](https://web.dev/passkey-registration/)). `navigator.credentials.create` triggers the creation of a **new** passkey. +- **Passkey authentication** uses `navigator.credentials.get`. See [this guide](https://web.dev/passkey-form-autofill/) for more information. `navigator.credentials.get` triggers a signature prompt for an **existing** passkey. ## Our SDK can help Our SDK has integrated passkey functionality, and we've built examples to help you get started. -* [`@turnkey/http`](https://www.npmjs.com/package/@turnkey/http) has a helper to trigger passkey registration (`getWebAuthnAttestation`). You can see it in action in our [`with-federated-passkeys`](https://github.com/tkhq/sdk/tree/main/examples/with-federated-passkeys) example: [direct code link](https://github.com/tkhq/sdk/blob/a2bfbf3cbd6040902bbe4c247900ac560be42925/examples/with-federated-passkeys/src/pages/index.tsx#L88) +- [`@turnkey/http`](https://www.npmjs.com/package/@turnkey/http) has a helper to trigger passkey registration (`getWebAuthnAttestation`). You can see it in action in our [`with-federated-passkeys`](https://github.com/tkhq/sdk/tree/main/examples/with-federated-passkeys) example: [direct code link](https://github.com/tkhq/sdk/blob/a2bfbf3cbd6040902bbe4c247900ac560be42925/examples/with-federated-passkeys/src/pages/index.tsx#L88) -* [`@turnkey/webauthn-stamper`](https://www.npmjs.com/package/@turnkey/webauthn-stamper) is a passkey-compatible stamper which integrates seamlessly with `TurnkeyClient`: +- [`@turnkey/webauthn-stamper`](https://www.npmjs.com/package/@turnkey/webauthn-stamper) is a passkey-compatible stamper which integrates seamlessly with `TurnkeyClient`: ```ts import { WebauthnStamper } from "@turnkey/webauthn-stamper"; @@ -61,18 +63,18 @@ const completedActivity = await activityPoller({ }) ``` -* [`@turnkey/viem`](https://www.npmjs.com/package/@turnkey/viem) is a package wrapping all of the above so that you work directly with Viem without worrying about passkeys. See [this demo](https://github.com/tkhq/demo-viem-passkeys). +- [`@turnkey/viem`](https://www.npmjs.com/package/@turnkey/viem) is a package wrapping all of the above so that you work directly with Viem without worrying about passkeys. See [this demo](https://github.com/tkhq/demo-viem-passkeys). Regardless of whether you use our helpers and abstractions, take a look at [our registration and authentication options guide](/features/authentication/passkeys/options). This will help you choose the right options for your passkey flow. If you have questions, feedback, or find yourself in need of an abstraction or integration that doesn't exist yet, please get in touch with us! You can -* Create an [issue on our SDK repo](https://github.com/tkhq/sdk/issues) -* Join our slack community [here](https://join.slack.com/t/clubturnkey/shared_invite/zt-3aemp2g38-zIh4V~3vNpbX5PsSmkKxcQ) -* Contact us at [hello@turnkey.com](mailto:hello@turnkey.com) +- Create an [issue on our SDK repo](https://github.com/tkhq/sdk/issues) +- Join our slack community [here](https://join.slack.com/t/clubturnkey/shared_invite/zt-3aemp2g38-zIh4V~3vNpbX5PsSmkKxcQ) +- Contact us at [hello@turnkey.com](mailto:hello@turnkey.com) We're here to make this as easy as possible for you and your team! ## Passkey wallets with sub-organizations -If you're wondering how to create independent, non-custodial wallets for your end-users, head to [Sub-Organizations](/features/sub-organizations). In short: you'll be able to pass the registered passkeys as part of a "create sub-organization" activity, making your end-users the sole owners of any resource created within the sub-organization (including private keys). Your organization will only have read permissions. \ No newline at end of file +If you're wondering how to create independent, non-custodial wallets for your end-users, head to [Sub-Organizations](/features/sub-organizations). In short: you'll be able to pass the registered passkeys as part of a "create sub-organization" activity, making your end-users the sole owners of any resource created within the sub-organization (including private keys). Your organization will only have read permissions. diff --git a/features/authentication/passkeys/introduction.mdx b/features/authentication/passkeys/introduction.mdx index 7697d31e..9c12c4cf 100644 --- a/features/authentication/passkeys/introduction.mdx +++ b/features/authentication/passkeys/introduction.mdx @@ -9,15 +9,15 @@ Google has a great high-level introduction to passkeys at [https://developers.go From a technical point of view, passkeys are cryptographic key pairs created on end-user devices. Apple and Google have done a great job making these key pairs usable: -* Key generation happens in secure end-user hardware. -* Using passkeys is easy thanks to native browser UIs and cross-device syncing. -* Passkey recovery for users is supported natively by Apple via iCloud Keychain and Google via the Google Password Manager. +- Key generation happens in secure end-user hardware. +- Using passkeys is easy thanks to native browser UIs and cross-device syncing. +- Passkey recovery for users is supported natively by Apple via iCloud Keychain and Google via the Google Password Manager. Passkeys come with big security upgrades compared to traditional passwords: -* Access to passkeys is gated with OS-level biometrics: faceID, touchID, lock screen patterns, and so on. -* Passkeys are bound to the web domain that creates them. This is important to thwart phishing attacks, where an attacker hosts a similar-looking website to steal user credentials. This is doable with passwords; impossible with passkeys. -* Because passkeys rely on public key cryptography, passkeys have two components: a public key and a private key. Private keys are never disclosed to websites or apps, making them a lot harder to steal. Only public keys are sent. To authenticate, passkeys sign messages (with their private keys) and provide signatures as proofs, similar to crypto wallets. +- Access to passkeys is gated with OS-level biometrics: faceID, touchID, lock screen patterns, and so on. +- Passkeys are bound to the web domain that creates them. This is important to thwart phishing attacks, where an attacker hosts a similar-looking website to steal user credentials. This is doable with passwords; impossible with passkeys. +- Because passkeys rely on public key cryptography, passkeys have two components: a public key and a private key. Private keys are never disclosed to websites or apps, making them a lot harder to steal. Only public keys are sent. To authenticate, passkeys sign messages (with their private keys) and provide signatures as proofs, similar to crypto wallets. ## Isn't this similar to WebAuthn? @@ -29,8 +29,8 @@ The difference? Passkeys are resident credentials and they can be synced between Synchronization and recovery are both supported natively by Apple and Google: -* With Apple, Passkeys created on one device are synced through [iCloud Keychain](https://support.apple.com/en-us/HT204085) as long as the user is logged in with their Apple ID. Apple covers both syncing and recovery in ["About the security of passkeys"](https://support.apple.com/en-us/102195). For some additional detail, see [this Q\&A with the passkey team](https://developer.apple.com/news/?id=21mnmxow). Apple's account recovery process is documented in [this support page](https://support.apple.com/en-us/HT204921). -* With Google, [Google Password Manager](https://passwords.google/) syncs passkeys across devices seamlessly. Google has plans to support syncing more broadly across different operating systems, see [this support summary](https://developers.google.com/identity/passkeys/supported-environments#chrome-passkey-support-summary). Recovery is covered in [this FAQ ("What happens if a user loses their device?")](https://developers.google.com/identity/passkeys/faq#what_happens_if_a_user_loses_their_device): it relies on Google's overall [account recovery process](https://support.google.com/accounts/answer/7682439?hl=en) because passkeys are attached to Google accounts. +- With Apple, Passkeys created on one device are synced through [iCloud Keychain](https://support.apple.com/en-us/HT204085) as long as the user is logged in with their Apple ID. Apple covers both syncing and recovery in ["About the security of passkeys"](https://support.apple.com/en-us/102195). For some additional detail, see [this Q\&A with the passkey team](https://developer.apple.com/news/?id=21mnmxow). Apple's account recovery process is documented in [this support page](https://support.apple.com/en-us/HT204921). +- With Google, [Google Password Manager](https://passwords.google/) syncs passkeys across devices seamlessly. Google has plans to support syncing more broadly across different operating systems, see [this support summary](https://developers.google.com/identity/passkeys/supported-environments#chrome-passkey-support-summary). Recovery is covered in [this FAQ ("What happens if a user loses their device?")](https://developers.google.com/identity/passkeys/faq#what_happens_if_a_user_loses_their_device): it relies on Google's overall [account recovery process](https://support.google.com/accounts/answer/7682439?hl=en) because passkeys are attached to Google accounts. ## OS and browser support diff --git a/features/authentication/passkeys/native.mdx b/features/authentication/passkeys/native.mdx index 8c2ca015..25b7c074 100644 --- a/features/authentication/passkeys/native.mdx +++ b/features/authentication/passkeys/native.mdx @@ -3,15 +3,15 @@ title: "Native Passkeys" description: "If you're unfamiliar with passkeys broadly, head to for an overview. TL;DR: passkeys are cryptographic key pairs generated and stored on secure hardware. Typically this is your Mac's or iPhone's , your Android's , or an external security key plugged in via USB." --- -* Registration ("sign up") creates a new key pair: this is your passkey -* Authentication ("sign in") uses an existing passkey to sign a message, proving ownership of the associated private key stored on your device. +- Registration ("sign up") creates a new key pair: this is your passkey +- Authentication ("sign in") uses an existing passkey to sign a message, proving ownership of the associated private key stored on your device. ## Passkeys on the web Creating and using passkeys on the web is straightforward: browsers offer APIs to do it! -* `navigator.credentials.create` creates a passkey -* `navigator.credentials.get` prompts the user to select a passkey to sign a message +- `navigator.credentials.create` creates a passkey +- `navigator.credentials.get` prompts the user to select a passkey to sign a message And this doesn't require a backend. Here's a demo proving it: [https://passkeyapp.tkhqlabs.xyz/](https://passkeyapp.tkhqlabs.xyz/) @@ -27,8 +27,8 @@ In the Android ecosystem the `CredentialManager` supports creating and using pas iOS APIs to create and use passkeys are available as well: -* `ASAuthorizationPlatformPublicKeyCredentialProvider(…).createCredentialRegistrationRequest` for passkey creation -* `ASAuthorizationPlatformPublicKeyCredentialProvider(…).createCredentialAssertionRequest` for passkey usage +- `ASAuthorizationPlatformPublicKeyCredentialProvider(…).createCredentialRegistrationRequest` for passkey creation +- `ASAuthorizationPlatformPublicKeyCredentialProvider(…).createCredentialAssertionRequest` for passkey usage See [these docs](https://developer.apple.com/documentation/authenticationservices/asauthorizationplatformpublickeycredentialprovider) for more info. And [this app](https://github.com/r-n-o/shiny) for a mini demo. @@ -54,9 +54,9 @@ If you're looking for a concrete example, head to [this repository](https://gith Passkeys on native apps aren't app-bound, they're **domain** bound just like web passkeys. This may come as a surprise: you'll have to configure a web domain to use passkeys natively! Configuration is done separately per ecosystem, but the idea is the same: -* iOS expects a JSON file at the domain root (`/.well-known /apple-app-site-association`) : [example](https://github.com/r-n-o/passkeyapp/blob/main/http/.well-known/apple-app-site-association) -* Android expects a JSON file at the domain root (`/.well-known/assetlinks.json`): [example](https://github.com/r-n-o/passkeyapp/blob/main/http/.well-known/assetlinks.json) +- iOS expects a JSON file at the domain root (`/.well-known /apple-app-site-association`) : [example](https://github.com/r-n-o/passkeyapp/blob/main/http/.well-known/apple-app-site-association) +- Android expects a JSON file at the domain root (`/.well-known/assetlinks.json`): [example](https://github.com/r-n-o/passkeyapp/blob/main/http/.well-known/assetlinks.json) -This unlocks interesting flows where users use their web-created passkeys in a "companion" native app, or vice-versa. For example: a native app linked to the wallet.tx.xyz domain would allow users to log into their account from a native mobile app *using their web-created passkey* as long as they're synced properly. +This unlocks interesting flows where users use their web-created passkeys in a "companion" native app, or vice-versa. For example: a native app linked to the wallet.tx.xyz domain would allow users to log into their account from a native mobile app _using their web-created passkey_ as long as they're synced properly. Note that these associations are "many-to-many": a website can link multiple associated apps, and a single native application can choose to create passkeys for multiple domains, via a dropdown for example. However (as far as we know) a single passkey is always bound to a single web domain: it can't be bound to multiple web domains. diff --git a/features/authentication/passkeys/options.mdx b/features/authentication/passkeys/options.mdx index 260f29dd..16f5a7b5 100644 --- a/features/authentication/passkeys/options.mdx +++ b/features/authentication/passkeys/options.mdx @@ -30,17 +30,21 @@ The `rp` options is an object with 2 fields: `id` and `name`. `rp.id`, or RPID, is a way to identify the website a passkey is associated with. Once set at registration time, it **determines the set of origins on which the passkey may be be used**. The [WebAuthn spec](https://www.w3.org/TR/webauthn-2/#relying-party-identifier) states that the RPID must be a “registrable domain suffix of, or equal to” the current domain. If the page creating a passkey is hosted at `https://your.app.xyz`, the RPID can thus be "your.app.xyz" or "app.xyz". - A passkey with RPID "your.app.xyz" **cannot** be used on `https://www.app.xyz` or `https://foo.app.xyz`. However a passkey created with RPID "app.xyz" **will** be usable on all `https://*.app.xyz` sub-domains: `https://your.app.xyz`, `https://www.app.xyz`, `https://foo.app.xyz`, and so on. Hence our general recommendation above to set `app.xyz` (top-level domain) as the RPID to maximize flexibility. +A passkey with RPID "your.app.xyz" **cannot** be used on `https://www.app.xyz` or `https://foo.app.xyz`. However a passkey created with RPID "app.xyz" **will** be usable on all `https://*.app.xyz` sub-domains: `https://your.app.xyz`, `https://www.app.xyz`, `https://foo.app.xyz`, and so on. Hence our general recommendation above to set `app.xyz` (top-level domain) as the RPID to maximize flexibility. - A reason why you might want to set the RPID to "your.app.xyz" instead of "app.xyz" like recommended above is extra security: if you are worried about user passkeys being usable across all your sub-domains, it makes sense to scope passkeys to the sub-domain they're meant to be used on, and only that sub-domain. +A reason why you might want to set the RPID to "your.app.xyz" instead of "app.xyz" like recommended above is extra security: if you are worried about user passkeys being usable across all your sub-domains, it makes sense to scope passkeys to the sub-domain they're meant to be used on, and only that sub-domain. + +If you scope passkeys to a specific sub-domain, be aware that migrating your app to a different sub-domain later will require a migration process where users have to re-enroll themselves by creating new passkeys on the new sub-domain. Passkeys cannot be transferred from one RPID to another. - If you scope passkeys to a specific sub-domain, be aware that migrating your app to a different sub-domain later will require a migration process where users have to re-enroll themselves by creating new passkeys on the new sub-domain. Passkeys cannot be transferred from one RPID to another. `rp.id` will show up in the initial registration popup: - RPID in registration prompt + RPID in registration prompt `rp.name` doesn't show up in the popup so can be set to anything. We recommend setting it to the correctly capitalized name of your app, in case browsers start showing it in their native UIs in the future. @@ -59,15 +63,18 @@ The integers `-7` and `-257` are algorithm identifiers for ES256 (aka P256) and The `user` field has three sub-fields: -* `id`: also known as "user handle", isn't visible to the end-user. We **strongly recommend setting this to a random value** (e.g. `const id = new Uint8Array(32); crypto.getRandomValues(id)`) to make sure a new passkey is created. Be aware: **if you accidentally set this value to an existing user handle, the corresponding passkey will be overridden!** [This section of spec](https://www.w3.org/TR/webauthn-2/#dictionary-user-credential-params) is clear on the matter: "the user handle ought not be a constant value across different accounts, even for non-discoverable credentials". +- `id`: also known as "user handle", isn't visible to the end-user. We **strongly recommend setting this to a random value** (e.g. `const id = new Uint8Array(32); crypto.getRandomValues(id)`) to make sure a new passkey is created. Be aware: **if you accidentally set this value to an existing user handle, the corresponding passkey will be overridden!** [This section of spec](https://www.w3.org/TR/webauthn-2/#dictionary-user-credential-params) is clear on the matter: "the user handle ought not be a constant value across different accounts, even for non-discoverable credentials". -* `name`: this will show up in the passkey list modal (see screenshot below). We recommend setting this to something the user will recognize: their email, the name of your app, or potentially leave this up to the user: +- `name`: this will show up in the passkey list modal (see screenshot below). We recommend setting this to something the user will recognize: their email, the name of your app, or potentially leave this up to the user: - User name and display name in passkey list + User name and display name in passkey list -* `displayName`: as far as we can tell this doesn't show up in current browser UIs. It might show up in future iterations so it's best to populate this with the same value as `name`. +- `displayName`: as far as we can tell this doesn't show up in current browser UIs. It might show up in future iterations so it's best to populate this with the same value as `name`. ### `authenticatorSelection` @@ -77,10 +84,10 @@ This option has lots of consequences for UX, and it has many sub-options, outlin This option, if set, restricts the type of authenticators that can be registered. See the table below for the values this option can take and their effect on registration prompts (captured via Chrome on a MacBook Pro). -| Empty (default) | `platform` | `cross-platform` | -| -------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | -| If you want broad compatibility, leave this option empty, and the browser UI will allow for both internal and external passkeys. | If set to `platform`, only internal authenticators (face ID, touch ID, and so on) can be registered. | If set to `cross-platform`, only passkeys from other devices or attached via USB are allowed. | -| authenticatorAttachment unspecified | authenticatorAttachment set to platform | authenticatorAttachment set to cross-platform | +| Empty (default) | `platform` | `cross-platform` | +| --------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | +| If you want broad compatibility, leave this option empty, and the browser UI will allow for both internal and external passkeys. | If set to `platform`, only internal authenticators (face ID, touch ID, and so on) can be registered. | If set to `cross-platform`, only passkeys from other devices or attached via USB are allowed. | +| authenticatorAttachment unspecified | authenticatorAttachment set to platform | authenticatorAttachment set to cross-platform | #### `requireResidentKey` and `residentKey` @@ -92,9 +99,9 @@ Important note: the default for `requireResidentKey` (`discouraged`) results in "User verification" refers to mechanisms on the authenticators themselves such as PIN codes or biometric/fingerprint readers. This flag can be set to: -* `discouraged`: yubikey PINs won't be required even if the device technically supports it. We've found that for TouchID/FaceID, authentication will still be required however. -* `preferred`: yubikey PINs and other authentication mechanisms will be required if supported, but devices without them will be accepted. -* `required`: authenticators without user verification support won't be accepted. +- `discouraged`: yubikey PINs won't be required even if the device technically supports it. We've found that for TouchID/FaceID, authentication will still be required however. +- `preferred`: yubikey PINs and other authentication mechanisms will be required if supported, but devices without them will be accepted. +- `required`: authenticators without user verification support won't be accepted. To maximize compatibility we recommend setting `userVerification` to "discouraged" or "preferred" because some authenticators do not support user verification. @@ -120,8 +127,8 @@ List of objects restricting which credentials can be used during authentication. Each object in this list has an ID (the credential ID) and a list of transports (e.g. "hybrid", "internal", "usb", etc). The `transports` list is **optional** but results in better, more targeted prompts. For example, here are screenshot of targeted prompts captured on Chrome, on a MacBook laptop: -| `transports: ["internal"]` | `transports: ["usb"]` | `transports: ["hybrid"]` | -| -------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- | +| `transports: ["internal"]` | `transports: ["usb"]` | `transports: ["hybrid"]` | +| ----------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | | authentication prompt with transports: internal | authentication prompt with transports: usb | authentication prompt with transport: hybrid | The credential ID needs to be passed as a buffer but is returned from registration as a base64-encoded value: make sure to decode it (in JavaScript: `Buffer.from(storedCredentialId, "base64")`) to avoid issues. @@ -129,13 +136,19 @@ The credential ID needs to be passed as a buffer but is returned from registrati If the wrong credential ID is specified, `transports: ["internal"]` is set, browsers error right away because they can enumerate internal credentials. Chrome, for example, displays the following error: - Chrome error when no matching passkey has been found for the provided Credential ID + Chrome error when no matching passkey has been found for the provided Credential ID However, if the wrong credential ID is specified without `transports` set (or with other-than-internal `transports` set), browsers won't error right away because they can't enumerate external credentials. They will display an error once the user has pressed their security key or gone through the cross-device passkey flow: - Chrome error when the credential ID used by the user is not in the allowCredentials list + Chrome error when the credential ID used by the user is not in the allowCredentials list ### `attestation` diff --git a/features/authentication/proxying-signed-requests.mdx b/features/authentication/proxying-signed-requests.mdx index 5dc4f12f..f8d5b679 100644 --- a/features/authentication/proxying-signed-requests.mdx +++ b/features/authentication/proxying-signed-requests.mdx @@ -5,10 +5,11 @@ description: "Turnkey has an open CORS policy for its public API. This means you How should you decide what to do? Here are some considerations: -* A backend proxy can be useful if you need to inspect and persist activity results. For example: if your users are creating wallets, you might want to persist the addresses. If your users are signing transactions, you might want to broadcast on their behalf. -* Another reason why a backend server could be beneficial is monitoring, feature toggles, and validation: with a proxy you're able to control which requests are proxied and which aren't. You can also perform additional validation before signed requests are forwarded to Turnkey. -* POSTing signed requests directly from your app frontend to Turnkey saves you the burden of running a proxy server, and takes you out of the loop so that your end-users interact directly with Turnkey. This is a "hands-off" approach that can work well if you want to give your end-users maximum flexibility and ownership over their sub-organization. +- A backend proxy can be useful if you need to inspect and persist activity results. For example: if your users are creating wallets, you might want to persist the addresses. If your users are signing transactions, you might want to broadcast on their behalf. +- Another reason why a backend server could be beneficial is monitoring, feature toggles, and validation: with a proxy you're able to control which requests are proxied and which aren't. You can also perform additional validation before signed requests are forwarded to Turnkey. +- POSTing signed requests directly from your app frontend to Turnkey saves you the burden of running a proxy server, and takes you out of the loop so that your end-users interact directly with Turnkey. This is a "hands-off" approach that can work well if you want to give your end-users maximum flexibility and ownership over their sub-organization. - For a working end-to-end implementation, see the [with-proxy-signed-requests example](https://github.com/tkhq/sdk/tree/main/examples/with-proxy-signed-requests). + For a working end-to-end implementation, see the [with-proxy-signed-requests + example](https://github.com/tkhq/sdk/tree/main/examples/with-proxy-signed-requests). diff --git a/features/authentication/sessions.mdx b/features/authentication/sessions.mdx index 2f99afa5..5a6f1183 100644 --- a/features/authentication/sessions.mdx +++ b/features/authentication/sessions.mdx @@ -7,8 +7,8 @@ description: "Turnkey sessions allow a user to take multiple, contiguous actions Such actions can be divided into two buckets: -* Read operations: Retrieving data (e.g., viewing wallet balances) -* Write operations: Modifying data or performing sensitive actions (e.g., signing transactions) +- Read operations: Retrieving data (e.g., viewing wallet balances) +- Write operations: Modifying data or performing sensitive actions (e.g., signing transactions) ## How can I create a session? @@ -38,12 +38,15 @@ In contrast to read-only sessions, a read-write session makes sense when a user There are several mechanisms to obtain read-write sessions: OTP, OAuth, Passkey sessions, and Session refreshing - Read-write sessions + Read-write sessions Our SDK contains several abstractions that manage authentication. You can checkout all of our examples leveraging these examples [here](https://github.com/tkhq/sdk/tree/main/examples) -**Note:** The session JWT is only metadata signed by Turnkey that references the client side stored API keypair, and is useful for verifying the session server-side or associating metadata, but it cannot be used to authenticate requests to Turnkey’s API. +**Note:** The session JWT is only metadata signed by Turnkey that references the client side stored API keypair, and is useful for verifying the session server-side or associating metadata, but it cannot be used to authenticate requests to Turnkey’s API. Only the session keypair can be used to create valid `x-stamp` signatures for API requests to Turnkey. In other words, solely the session JWT cannot be used to stamp requests outside of the client context. ### Mechanisms @@ -57,26 +60,27 @@ For web apps that want stronger session persistence without relying on iframes o This approach enables long-lived, client-held sessions that survive page reloads, tab closures, and even browser restarts – **without ever exposing the private key** to your JavaScript code. Turnkey’s SDK provides helpers to: + - Create a new session by generating a P-256 key pair via `crypto.subtle.generateKey()` - Sign requests - Store and retrieve the key using IndexedDB under a given session ID -- Abstractions built on top of the `IndexedDBStamper` that simplify authentication flows +- Abstractions built on top of the `IndexedDBStamper` that simplify authentication flows This is currently the **most persistent** session model for modern browsers that support WebCrypto. It is especially valuable in Progressive Web App (PWA) contexts or when iframe and Local Storage approaches are insufficient. To see the IndexedDB-backed session mechanism in action, check out our Turnkey react-wallet-kit [playground](https://github.com/tkhq/sdk/tree/main/examples/with-sdk-js) or dedicated authentication examples like [oauth](https://github.com/tkhq/sdk/tree/main/examples/oauth), [email OTP](https://github.com/tkhq/sdk/tree/main/examples/otp-auth), and [external wallet authentication](https://github.com/tkhq/sdk/tree/main/examples/wallet-auth). Our [Web demo application](https://github.com/tkhq/sdk/tree/main/examples/react-wallet-kit) hosted at [wallets.turnkey.com](https://wallets.turnkey.com) showcases complete end-to-end authentication flows and client-side session persistence backed by IndexedDB. - #### SecureStorage (mobile only) -Secure Storage operates essentially the same as IndexedDB with respect to authentication flows for Turnkey except it is mobile native and keys are generated using @turnkey/crypto rather than WebCrypto. +Secure Storage operates essentially the same as IndexedDB with respect to authentication flows for Turnkey except it is mobile native and keys are generated using @turnkey/crypto rather than WebCrypto. #### LocalStorage: Another option is to create an API key and store it directly within Local Storage. However, this is a riskier setup than IndexedDb/SecureStorage as anyone who is able to access this client-side API key has full access to a User. ### Sessions FAQ + Once a user has a valid session, it is trivial to use that session to create a new session. The `refreshSession` abstraction will create a brand new session and automatically store the resulting new session in local storage. @@ -96,6 +100,7 @@ Another option is to create an API key and store it directly within Local Storag return true; }; ``` + The expiration of session keys can be specified to any amount of time using the `expirationSeconds` parameter. The default length is 900 seconds (15 minutes). @@ -105,7 +110,9 @@ Another option is to create an API key and store it directly within Local Storag * Expired API keys are deleted first * If no expired keys exist, the oldest unexpired key is deleted + If you are looking to invalidate existing sessions, you can use the `invalidateExisting` parameter for all `_LOGIN` activities. This will clear all existing session keys. + Absolutely! Through leveraging IndexedDb you can handle sessions in the same way for Web and PWAs. However, for React Native/Mobile applications you will need to leverage Secure Storage. diff --git a/features/authentication/sms.mdx b/features/authentication/sms.mdx index 618667e5..649a80be 100644 --- a/features/authentication/sms.mdx +++ b/features/authentication/sms.mdx @@ -34,11 +34,10 @@ Make sure you have set up your primary Turnkey organization with at least one AP SMS authentication uses three activities: -1. `INIT_OTP_V3` — initiates a secure OTP flow and sends a 6–9 digit or alphanumeric OTP to the specified phone number. The response includes an `otpEncryptionTargetBundle` which is used in OTP verification. +1. `INIT_OTP_V3` — initiates a secure OTP flow and sends a 6–9 digit or alphanumeric OTP to the specified phone number. The response includes an `otpEncryptionTargetBundle` which is used in OTP verification. 2. `VERIFY_OTP_V2` — securely verifies the code and returns a signed verificationToken JWT 3. `OTP_LOGIN_V2` — validates the verificationToken and returns a session (signed with the verification token key) - ## Implementation ### Initiating SMS authentication @@ -78,7 +77,6 @@ After receiving the verification token, users complete OTP authentication flow w - `expirationSeconds`: optional validity window (defaults to 15 minutes) - `invalidateExisting`: optional boolean to invalidate previous login sessions - ## Authorization SMS authentication requires proper permissions through policies or parent organization status. diff --git a/features/authentication/social-logins.mdx b/features/authentication/social-logins.mdx index 005a65f6..503ee670 100644 --- a/features/authentication/social-logins.mdx +++ b/features/authentication/social-logins.mdx @@ -10,9 +10,9 @@ Similar to [email auth](/features/authentication/email), social login authentica Turnkey supports two different types of Social Login Providers: 1. **OIDC Providers** (Google, Apple, Auth0, Cognito…) These providers issue your app an **OIDC ID Token** identifying an end-user, which can subsequently be passed to Turnkey as a means of authentication. -2. **OAuth 2.0-Only Providers** (X/Twitter, Discord…) These providers do _not_ issue **OIDC ID Tokens** themselves, and instead provide only bare-bones OAuth 2.0. To work around this limitation, Turnkey runs the **OAuth 2.0 Authorization Code + PKCE** flow, calls the provider’s `who-am-I` endpoint using your app's credentials, and then uses the returned user data to **issue a short-lived OIDC ID token**. In effect, Turnkey acts as an "_OIDC Wrapper_" for these OAuth 2.0 Services. +2. **OAuth 2.0-Only Providers** (X/Twitter, Discord…) These providers do _not_ issue **OIDC ID Tokens** themselves, and instead provide only bare-bones OAuth 2.0. To work around this limitation, Turnkey runs the **OAuth 2.0 Authorization Code + PKCE** flow, calls the provider’s `who-am-I` endpoint using your app's credentials, and then uses the returned user data to **issue a short-lived OIDC ID token**. In effect, Turnkey acts as an "_OIDC Wrapper_" for these OAuth 2.0 Services. -While the backend flows associated with these two types of Providers differ upstream of **OIDC ID Token** generation, they converge at that point and have no downstream differences. In both cases, the goal is to get an **OIDC ID Token** identifying the end user. +While the backend flows associated with these two types of Providers differ upstream of **OIDC ID Token** generation, they converge at that point and have no downstream differences. In both cases, the goal is to get an **OIDC ID Token** identifying the end user. ### Social login provider types - comparison @@ -23,7 +23,7 @@ The table below can be helpful in understanding the similarities and differences | Providers | Google, Apple, Facebook, Auth0, Cognito | X/Twitter, Discord | | Token Transport | Returned to your App by Provider | Returned by Turnkey after the **OAuth 2.0 Auth Code + PKCE** flow | | Issuer (`iss`) | Provider (iss = Provider URL) | Turnkey (iss = Turnkey URL) | -| Audience (`aud`) | Provider’s `client_id` for your app | Provider’s `client_id` for your app | +| Audience (`aud`) | Provider’s `client_id` for your app | Provider’s `client_id` for your app | | Subject (`sub`) | Provider’s subject (stable user ID) | Derived from ID `who-am-I` response (e.g., `x:123456789`) | | Nonce (`nonce`) | Sent to Provider; echoed in ID token | Sent to Turnkey; echoed in ID token. | | Refresh/access | If the Provider returns them, you may use them | Not provided. | @@ -284,7 +284,7 @@ The main documentation for Google OIDC is available [here](https://github.com/tk ### Apple -Apple integration is also extensively tested and supported, and is integrated into our demo wallet (hosted at https://wallet.tx.xyz). The code provides an [example component](https://github.com/tkhq/demo-embedded-wallet/blob/bf0e2292cbd2ee9cde6b241591b077fadf7ee71b/src/components/apple-auth.tsx) as well as an [example redirect handler](https://github.com/tkhq/demo-embedded-wallet/blob/bf0e2292cbd2ee9cde6b241591b077fadf7ee71b/src/app/\(landing\)/oauth-callback/apple/page.tsx). +Apple integration is also extensively tested and supported, and is integrated into our demo wallet (hosted at https://wallet.tx.xyz). The code provides an [example component](https://github.com/tkhq/demo-embedded-wallet/blob/bf0e2292cbd2ee9cde6b241591b077fadf7ee71b/src/components/apple-auth.tsx) as well as an [example redirect handler](). Documentation for Apple OIDC can be found [here](https://developer.apple.com/documentation/signinwithapple/authenticating-users-with-sign-in-with-apple). @@ -302,7 +302,7 @@ In our example demo wallet, we opt to avoid using a database in the authenticati ![Facebook OAuth flow](/images/authentication/img/facebook-oauth.png) -Code for the [redirect component](https://github.com/tkhq/demo-embedded-wallet/blob/bf0e2292cbd2ee9cde6b241591b077fadf7ee71b/src/components/facebook-auth.tsx), [OAuth callback](https://github.com/tkhq/demo-embedded-wallet/blob/bf0e2292cbd2ee9cde6b241591b077fadf7ee71b/src/app/\(landing\)/oauth-callback/facebook/page.tsx), and [code exchange](https://github.com/tkhq/demo-embedded-wallet/blob/bf0e2292cbd2ee9cde6b241591b077fadf7ee71b/src/actions/turnkey.ts#L54) are all available in the example wallet repo. +Code for the [redirect component](https://github.com/tkhq/demo-embedded-wallet/blob/bf0e2292cbd2ee9cde6b241591b077fadf7ee71b/src/components/facebook-auth.tsx), [OAuth callback](), and [code exchange](https://github.com/tkhq/demo-embedded-wallet/blob/bf0e2292cbd2ee9cde6b241591b077fadf7ee71b/src/actions/turnkey.ts#L54) are all available in the example wallet repo. If you prefer to use a database such as Redis instead of reassembling the verification code, you can store the verification code and retrieve it in the exchange stage using a lookup key either passed as **state** or stored in local browser storage. @@ -334,7 +334,7 @@ For more information on how to implement social linking, see the [social linking ### Setting up X/Twitter -Navigate to the [X developer portal](https://developer.twitter.com/en/portal/dashboard) and create/setup your app. In the **Keys and Tokens** section, you'll need to save your **Client ID** and **Client Secret** so that these values can be uploaded to Turnkey's servers: +Navigate to the [X developer portal](https://developer.twitter.com/en/portal/dashboard) and create/setup your app. In the **Keys and Tokens** section, you'll need to save your **Client ID** and **Client Secret** so that these values can be uploaded to Turnkey's servers: ![alt text](../images/authentication/img/x_client_information.png) @@ -347,7 +347,7 @@ In order for Turnkey to access the `/2/users/me` endpoint, the following scopes ### Setting up Discord -Navigate to the [Discord developer portal](https://discord.com/developers) and create/setup your app. In the **General Information** section, you'll need to save your **Client ID** and **Client Secret** so that these values can be uploaded to Turnkey's servers: +Navigate to the [Discord developer portal](https://discord.com/developers) and create/setup your app. In the **General Information** section, you'll need to save your **Client ID** and **Client Secret** so that these values can be uploaded to Turnkey's servers: ![alt text](../images/authentication/img/discord_client_information.png) @@ -360,7 +360,7 @@ In order for Turnkey to access the `/api/users/@me` endpoint, the following scop ### Client secret upload -For every OAuth 2.0-Only Social Provider that you wish to integrate with, you must upload the **Client ID** and **Client Secret** issued by that Provider to Turnkey's Servers. In order to protect these sensitive credentials, they will be encrypted to the Quorum Key of the TLS Fetcher enclave, which ensures they cannot be accessed outside of that environment. +For every OAuth 2.0-Only Social Provider that you wish to integrate with, you must upload the **Client ID** and **Client Secret** issued by that Provider to Turnkey's Servers. In order to protect these sensitive credentials, they will be encrypted to the Quorum Key of the TLS Fetcher enclave, which ensures they cannot be accessed outside of that environment. You can upload these credentials through the Turnkey Dashboard. @@ -372,7 +372,7 @@ Select the provider you want to add from the dropdown, and fill in the required ![Adding an OAuth2.0 provider](/images/sdks/img/react/add-social-login.png) -Once uploaded, you can then use the **Credential Id** from the table shown to make requests to the `OAUTH2_AUTHENTICATE` activity. +Once uploaded, you can then use the **Credential Id** from the table shown to make requests to the `OAUTH2_AUTHENTICATE` activity. ![Facebook OAuth flow](/images/authentication/img/social-logins-table.png) @@ -384,4 +384,4 @@ When using OAuth 2.0-Only Social Providers, it is also possible to have the bear In order to guarantee the secure transfer of the bearer token, it must be encrypted to a P256 Encryption Key inside our secure enclave, returned to the caller, and then finally decrypted. Therefore, the return of the encrypted bearer token is dependent on the caller providing an optional `bearerTokenTargetPublicKey` parameter in the request to `OAuth2Authenticate`. -An example demonstrating this flow can be seen [here](https://github.com/tkhq/sdk/blob/main/examples/with-x/src/app/auth/turnkey/x/route.ts). \ No newline at end of file +An example demonstrating this flow can be seen [here](https://github.com/tkhq/sdk/blob/main/examples/with-x/src/app/auth/turnkey/x/route.ts). diff --git a/features/networks/aptos.mdx b/features/networks/aptos.mdx index bd649d13..18ece66e 100644 --- a/features/networks/aptos.mdx +++ b/features/networks/aptos.mdx @@ -40,7 +40,7 @@ class TurnkeyAptosSigner { apiPublicKey: string, organizationId: string, address: string, - nodeUrl: string = "https://fullnode.mainnet.aptoslabs.com/v1" + nodeUrl: string = "https://fullnode.mainnet.aptoslabs.com/v1", ) { this.turnkeyClient = new Turnkey({ apiBaseUrl: "https://api.turnkey.com", @@ -61,7 +61,7 @@ class TurnkeyAptosSigner { // Sign a transaction using Turnkey async signTransaction( - rawTxn: TxnBuilderTypes.RawTransaction + rawTxn: TxnBuilderTypes.RawTransaction, ): Promise { // Serialize the raw transaction to BCS const serializer = new BCS.Serializer(); @@ -93,20 +93,20 @@ class TurnkeyAptosSigner { const authenticator = new TxnBuilderTypes.TransactionAuthenticatorEd25519( new TxnBuilderTypes.Ed25519PublicKey( // Note: In a real implementation, you would need to get the actual public key - new Uint8Array(32) // Placeholder - replace with actual public key + new Uint8Array(32), // Placeholder - replace with actual public key ), - new TxnBuilderTypes.Ed25519Signature(signature) + new TxnBuilderTypes.Ed25519Signature(signature), ); // Create a signed transaction const signedTxn = new TxnBuilderTypes.SignedTransaction( rawTxn, - authenticator + authenticator, ); // Submit the transaction const pendingTxn = await this.aptosClient.submitSignedBCSTransaction( - BCS.bcsToBytes(signedTxn) + BCS.bcsToBytes(signedTxn), ); return pendingTxn.hash; @@ -118,7 +118,7 @@ class TurnkeyAptosSigner { // Helper method to create a raw transaction private async createRawTransaction( - payload: any + payload: any, ): Promise { const account = await this.aptosClient.getAccount(this.address); const chainId = await this.aptosClient.getChainId(); @@ -131,7 +131,7 @@ class TurnkeyAptosSigner { BigInt(2000), // Max gas amount BigInt(100), // Gas unit price BigInt(Math.floor(Date.now() / 1000) + 30), // Expiration timestamp (30 seconds from now) - new TxnBuilderTypes.ChainId(chainId) + new TxnBuilderTypes.ChainId(chainId), ); } } @@ -143,7 +143,7 @@ async function transferCoins() { process.env.API_PUBLIC_KEY!, process.env.ORGANIZATION_ID!, process.env.APTOS_ADDRESS!, // Your Aptos address in Turnkey - "https://fullnode.testnet.aptoslabs.com/v1" // Testnet URL + "https://fullnode.testnet.aptoslabs.com/v1", // Testnet URL ); const recipientAddress = "0x..."; // Recipient address @@ -156,16 +156,16 @@ async function transferCoins() { "transfer", [ new TxnBuilderTypes.TypeTagStruct( - TxnBuilderTypes.StructTag.fromString("0x1::aptos_coin::AptosCoin") + TxnBuilderTypes.StructTag.fromString("0x1::aptos_coin::AptosCoin"), ), ], [ BCS.bcsToBytes( - TxnBuilderTypes.AccountAddress.fromHex(recipientAddress) + TxnBuilderTypes.AccountAddress.fromHex(recipientAddress), ), BCS.bcsSerializeUint64(amount), - ] - ) + ], + ), ); try { diff --git a/features/networks/bitcoin.mdx b/features/networks/bitcoin.mdx index 4a926d91..30142b22 100644 --- a/features/networks/bitcoin.mdx +++ b/features/networks/bitcoin.mdx @@ -15,23 +15,23 @@ Turnkey supports importing and exporting keys in mnemonics form, following [BIP3 You can derive Bitcoin addresses when creating a Turnkey wallet or private key. The address types we support currently: -* P2PKH (Pay-To-Public-Key-Hash) -* P2SH (Pay-To-Script-Hash) -* P2WPKH (Pay-to-Witness-Public-Key-Hash) -- [segwit-enabled](https://learnmeabitcoin.com/technical/upgrades/segregated-witness/) -* P2WSH (Pay-to-Witness-Script-Hash) -- [segwit-enabled](https://learnmeabitcoin.com/technical/upgrades/segregated-witness/) -* P2TR (Pay-to-Taproot) -- [taproot-enabled](https://cointelegraph.com/learn/a-beginners-guide-to-the-bitcoin-taproot-upgrade) +- P2PKH (Pay-To-Public-Key-Hash) +- P2SH (Pay-To-Script-Hash) +- P2WPKH (Pay-to-Witness-Public-Key-Hash) -- [segwit-enabled](https://learnmeabitcoin.com/technical/upgrades/segregated-witness/) +- P2WSH (Pay-to-Witness-Script-Hash) -- [segwit-enabled](https://learnmeabitcoin.com/technical/upgrades/segregated-witness/) +- P2TR (Pay-to-Taproot) -- [taproot-enabled](https://cointelegraph.com/learn/a-beginners-guide-to-the-bitcoin-taproot-upgrade) Bitcoin addresses change depending on the network you're using (more precisely, their prefix!). When you derive an address the network will be part of the address format. We support the following networks: -* Mainnet (`MAINNET`) -* Testnet (`TESTNET`) -* Regtest (`REGTEST`) -* Signet (`SIGNET`) +- Mainnet (`MAINNET`) +- Testnet (`TESTNET`) +- Regtest (`REGTEST`) +- Signet (`SIGNET`) For example: -* To derive a P2TR address on testnet, use `ADDRESS_FORMAT_BITCOIN_TESTNET_P2TR`. -* To derive a P2SH address on mainnet, use `ADDRESS_FORMAT_BITCOIN_MAINNET_P2SH`. +- To derive a P2TR address on testnet, use `ADDRESS_FORMAT_BITCOIN_TESTNET_P2TR`. +- To derive a P2SH address on mainnet, use `ADDRESS_FORMAT_BITCOIN_MAINNET_P2SH`. ## Schnorr signatures and tweaks @@ -41,25 +41,26 @@ To sign with Schnorr, pass a taproot (P2TR) address inside of your activity's `s ## Policy-enabled Bitcoin transaction signing -Turnkey has built a Bitcoin transaction parser which runs in a secure enclave, to enable Bitcoin-based policies in the policy engine. +Turnkey has built a Bitcoin transaction parser which runs in a secure enclave, to enable Bitcoin-based policies in the policy engine. -To enable more policy engine use cases, and facilitate transaction construction completely, policy-enabled Bitcoin transactions requires passing a hex serialized representation of a Partially Signed Bitcoin Transaction (PSBT) to our `SIGN_TRANSACTION` endpoint using the transaction type `TRANSACTION_TYPE_BITCOIN`. +To enable more policy engine use cases, and facilitate transaction construction completely, policy-enabled Bitcoin transactions requires passing a hex serialized representation of a Partially Signed Bitcoin Transaction (PSBT) to our `SIGN_TRANSACTION` endpoint using the transaction type `TRANSACTION_TYPE_BITCOIN`. ### What are PSBTs and why do we use them? -Partially Signed Bitcoin Transaction or PSBT is a data format for passing around Bitcoin transactions to signing services. The PSBT format contains raw unsigned transaction data, along with extra “context” data required to get the transaction signed. Most modern wallets support and use PSBTs for transaction signing. +Partially Signed Bitcoin Transaction or PSBT is a data format for passing around Bitcoin transactions to signing services. The PSBT format contains raw unsigned transaction data, along with extra “context” data required to get the transaction signed. Most modern wallets support and use PSBTs for transaction signing. -For Turnkey’s policy-enabled Bitcoin transaction signing flow, PSBTs provide the context needed for the policy engine to make decisions based on transaction content, to generate the actual payloads that need to be signed (sighashes), and to reinsert those signed sighashes in the correct place. +For Turnkey’s policy-enabled Bitcoin transaction signing flow, PSBTs provide the context needed for the policy engine to make decisions based on transaction content, to generate the actual payloads that need to be signed (sighashes), and to reinsert those signed sighashes in the correct place. For more information on PSBTs look here: https://learnmeabitcoin.com/technical/transaction/psbt/ ### How to use Turnkey’s policy-enabled Bitcoin transaction signing flow -The transaction signing flow works as follows: -* Client creates Bitcoin policies for enabling or restriction transaction signing using the `bitcoin.tx` namespace. For reference look at the Policy Launguage documentation [language section](/features/policies/language#bitcoin) or the [Bitcoin policy examples](/features/policies/examples/bitcoin) documentation -* Client constructs a PSBT (using a library like bitcoinjs-lib[https://github.com/bitcoinjs/bitcoinjs-lib]) representing the transaction they need signed, hex serializes it and passes in the string of the hex representation of the PSBT into Turnkey’s Sign Transaction endpoint with type: `TRANSACTION_TYPE_BITCOIN` -* The `SIGN TRANSACTION` endpoint constructs the sighashes ONLY for inputs which are to be signed by the signing resource which was specified in the `SIGN TRANSACTION` request, and based on policy evaluation, signs these sighashes and reinserts them into the correct corresponding inputs in the PSBT. For more details on how reinsertion works across each address derivation type, look below. -* Client receives hex representation of PSBT with reinserted signatures, continues signing process for other inputs if needed, finalizes inputs, and broadcasts. +The transaction signing flow works as follows: + +- Client creates Bitcoin policies for enabling or restriction transaction signing using the `bitcoin.tx` namespace. For reference look at the Policy Launguage documentation [language section](/features/policies/language#bitcoin) or the [Bitcoin policy examples](/features/policies/examples/bitcoin) documentation +- Client constructs a PSBT (using a library like bitcoinjs-lib[https://github.com/bitcoinjs/bitcoinjs-lib]) representing the transaction they need signed, hex serializes it and passes in the string of the hex representation of the PSBT into Turnkey’s Sign Transaction endpoint with type: `TRANSACTION_TYPE_BITCOIN` +- The `SIGN TRANSACTION` endpoint constructs the sighashes ONLY for inputs which are to be signed by the signing resource which was specified in the `SIGN TRANSACTION` request, and based on policy evaluation, signs these sighashes and reinserts them into the correct corresponding inputs in the PSBT. For more details on how reinsertion works across each address derivation type, look below. +- Client receives hex representation of PSBT with reinserted signatures, continues signing process for other inputs if needed, finalizes inputs, and broadcasts. Note: Turnkey does NOT automatically finalize transactions for you. Turnkey will generate the sighashes for ALL inputs to be signed by the signing resource provided, sign the sighashes, reinsert the signed sighashes into the PSBT (as described in detail for each address derviation type below), and provide the updated PSBT back to the user as the signed payload WITHOUT finalizing. Moreover, if the PSBT represents a transaction that requires signing with a Turnkey signing resource, but is a non-supported signing use case (like a P2SH wrapped transaction input or a P2TR script path signing input), the transaction will be rejected! Before using Turnkey's policy-enabled `SIGN_TRANSACTION` flow, read the below PSBT requirements and assumptions to make sure that we support your specific use-case! @@ -67,30 +68,32 @@ Note: Turnkey does NOT automatically finalize transactions for you. Turnkey will For each chain with policy engine support, Turnkey's `SIGN TRANSACTION` API endpoint provides the experience of transaction signing and reinsertion - where the transaction is signed by the specified signing resource and reinserted into the provided transaction as per the rules of the chain in question. With Bitcoin, given the plethora of different locking and unlocking scripts that are possible, Turnkey has currently limited the scope of support of the SIGN TRANSACTION endpoint to the single standard flow for each of the following address derivation types: P2PKH, P2SH, P2WPKH, P2WSH and P2TR. We also assume the most common or default sighash type for each address derivation type (`SIGHASH_TYPE_ALL` for P2PKH, P2SH, P2WPKH and P2WSH and `SIGHASH_TYPE_DEFAULT` for P2TR) -Notably, we do not support sighash generation and reinsertion according to wrapped types like P2SH-P2WPKH and P2SH-P2WSH, or for Taproot (P2TR) script path signing (only Taproot key path signing is currently supported). +Notably, we do not support sighash generation and reinsertion according to wrapped types like P2SH-P2WPKH and P2SH-P2WSH, or for Taproot (P2TR) script path signing (only Taproot key path signing is currently supported). -Note: If you are implementing Bitcoin transaction signing for one of the above use-cases involving signing wrapped inputs like P2SH-P2WPKH or P2SH-P2WSH, or for P2TR script path signing, or with the usage of a non-standard sighash type you can use the `SIGN_RAW_PAYLOAD` endpoint to sign pre-generated sighashes, and use a library like bitcoinjs-lib[https://github.com/bitcoinjs/bitcoinjs-lib] to handle sighash generation and reinsertion as per your use-case. +Note: If you are implementing Bitcoin transaction signing for one of the above use-cases involving signing wrapped inputs like P2SH-P2WPKH or P2SH-P2WSH, or for P2TR script path signing, or with the usage of a non-standard sighash type you can use the `SIGN_RAW_PAYLOAD` endpoint to sign pre-generated sighashes, and use a library like bitcoinjs-lib[https://github.com/bitcoinjs/bitcoinjs-lib] to handle sighash generation and reinsertion as per your use-case. -For specific technical context on how Turnkey does reinsertion across address types: +For specific technical context on how Turnkey does reinsertion across address types: #### P2PKH, P2SH, P2WPKH, P2WSH -PSBT Input Requirements for Legacy and Segwit -- We assume usage of Sighash Type SIGHASH_TYPE_ALL for all Legacy and Segwit inputs +PSBT Input Requirements for Legacy and Segwit + +- We assume usage of Sighash Type SIGHASH_TYPE_ALL for all Legacy and Segwit inputs - For Legacy inputs (P2PKH, P2SH), we require that the `non_witness_utxo` field of the corresponding input IS populated, and the `witness_utxo` field IS NOT populated - For Segwit inputs (P2WPKH, P2WSH), we require that the `witness_utxo` field of the corresponding input IS populated, and the `non_witness_utxo` field IS NOT populated - For P2SH inputs, we require that the `redeem_script` field of the corresponding input IS populated - For P2WSH inputs, we require that the `witness_script` field of the corresponding input IS populated -For Legacy and Segwit Bitcoin address derivation types, for each input corresponding to the Turnkey signing resource specified in the `SIGN TRANSACTION` call, Turnkey constructs the DER encoded signature of the sighash and reinserts it into the Partial Signatures field of each relevant input in the PSBT, corresponding to the public key of the signing resource. +For Legacy and Segwit Bitcoin address derivation types, for each input corresponding to the Turnkey signing resource specified in the `SIGN TRANSACTION` call, Turnkey constructs the DER encoded signature of the sighash and reinserts it into the Partial Signatures field of each relevant input in the PSBT, corresponding to the public key of the signing resource. -NOTE: For constructing and reinserting sighashes for Legacy and Segwith Bitcoin address derivation types, by default, we use the sighash type `SIGHASH_ALL` as is the convention for these types. +NOTE: For constructing and reinserting sighashes for Legacy and Segwith Bitcoin address derivation types, by default, we use the sighash type `SIGHASH_ALL` as is the convention for these types. Context on Sighash types, conventions, and how it affects signing can be found on Learn Me a Bitcoin’s signature page: https://learnmeabitcoin.com/technical/keys/signature/ #### P2TR PSBT Input Requirements for Taproot + - We assume usage of Sighash Type SIGHASH_TYPE_DEFAULT for all Taproot inputs - For Taproot inputs we require that the `witness_utxo` field of the corresponding input IS populated, and the `non_witness_utxo` field IS NOT populated - For Taproot inputs we support key path signing, and NOT script path signing and require that the `tap_scripts`, `tap_merkle_root` and `tap_script_sigs` fields ARE NOT populated diff --git a/features/networks/cosmos.mdx b/features/networks/cosmos.mdx index 7d2ce76f..5c2108c1 100644 --- a/features/networks/cosmos.mdx +++ b/features/networks/cosmos.mdx @@ -43,7 +43,7 @@ const signer = await initializeCosmosSigner(turnkeyClient); const rpcEndpoint = "https://rpc.celestia-arabica-11.com"; const client = await SigningStargateClient.connectWithSigner( rpcEndpoint, - signer + signer, ); // Get account balance @@ -58,7 +58,7 @@ const result = await client.sendTokens( recipient, amount, fee, - "Sent via Turnkey" + "Sent via Turnkey", ); const result = await signingClient.sendTokens( @@ -69,7 +69,7 @@ const result = await signingClient.sendTokens( amount: [{ denom: "utia", amount: "20000" }], gas: "200000", }, - "Hello from Turnkey!" + "Hello from Turnkey!", ); ``` diff --git a/features/networks/doge.mdx b/features/networks/doge.mdx index 3b5734c4..357c2f15 100644 --- a/features/networks/doge.mdx +++ b/features/networks/doge.mdx @@ -8,7 +8,7 @@ Turnkey supports Doge address derivation with `ADDRESS_FORMAT_DOGE_MAINNET` and ## Transaction construction and signing -Turnkey supports Doge transaction signing through the core signing capabilities. +Turnkey supports Doge transaction signing through the core signing capabilities. Check out the [examples/with-doge](https://github.com/tkhq/sdk/tree/main/examples/with-doge) respository that demonstrates how to construct, sign and broadcast a Doge P2PKH transaction on Testnet. ### Key features @@ -25,4 +25,4 @@ Check out the [examples/with-doge](https://github.com/tkhq/sdk/tree/main/example - **Secure Key Management**: Private keys never leave Turnkey’s secure infrastructure - **Developer Friendly**: Integrate with existing Doge development workflows - **Signing Policies**: Apply custom policies to control transaction approvals -- **Multi-address Support**: Manage multiple Doge addresses under a single organization \ No newline at end of file +- **Multi-address Support**: Manage multiple Doge addresses under a single organization diff --git a/features/networks/ethereum.mdx b/features/networks/ethereum.mdx index cba803ef..e28104c9 100644 --- a/features/networks/ethereum.mdx +++ b/features/networks/ethereum.mdx @@ -31,6 +31,7 @@ When you submit a transaction via `ethSendTransaction`, Turnkey automatically ma Set `sponsor: true` to enable fee sponsorship — your users never need to hold native tokens to pay gas. Turnkey covers fees on your behalf and passes costs through as a monthly line item. **Supported networks:** + - Base (eip155:8453) - Polygon (eip155:137) - Ethereum (eip155:1) @@ -38,7 +39,8 @@ Set `sponsor: true` to enable fee sponsorship — your users never need to hold - Base Sepolia, Polygon Amoy, Ethereum Sepolia, Arbitrum Sepolia (testnets) - To enable gas sponsorship, ensure it is activated in your Turnkey dashboard before setting `sponsor: true`. + To enable gas sponsorship, ensure it is activated in your Turnkey dashboard + before setting `sponsor: true`. ### Non-sponsored transactions diff --git a/features/networks/hyperliquid.mdx b/features/networks/hyperliquid.mdx index d19650f1..dc2f6e57 100644 --- a/features/networks/hyperliquid.mdx +++ b/features/networks/hyperliquid.mdx @@ -18,4 +18,4 @@ To construct and sign a Hyperliquid (EVM) transaction with Turnkey, we offer: Please refer to our [Ethereum network page](/features/networks/ethereum) for details on transaction parsing, policies, and signing, as Hyperliquid shares the same EVM architecture. However, HyperCore notably uses EIP-712 messages to perform various actions. More information on defining EIP-712 policies, see [here](../networks/ethereum#eip-712). Additionally, top-level policy details can be found [here](../concepts/policies/language). -For an example of how to construct a policy targeting such Hyperliquid-specific EIP-712 messages, see [here](../concepts/policies/examples/ethereum#allow-signing-of-eip-712-payloads-for-hyperliquid-approveagent-operations). \ No newline at end of file +For an example of how to construct a policy targeting such Hyperliquid-specific EIP-712 messages, see [here](../concepts/policies/examples/ethereum#allow-signing-of-eip-712-payloads-for-hyperliquid-approveagent-operations). diff --git a/features/networks/iota.mdx b/features/networks/iota.mdx index 84797618..8794fad4 100644 --- a/features/networks/iota.mdx +++ b/features/networks/iota.mdx @@ -18,17 +18,17 @@ Turnkey supports IOTA transaction signing through the core signing capabilities. Here's a practical example showing how to integrate Turnkey with the [IOTA SDK](https://docs.iota.org/developer/ts-sdk/typescript/): ```typescript expandable -import * as dotenv from 'dotenv'; -import * as path from 'path'; -import { IotaClient, getFullnodeUrl } from '@iota/iota-sdk/client'; -import { Transaction } from '@iota/iota-sdk/transactions'; -import { Ed25519PublicKey } from '@iota/iota-sdk/keypairs/ed25519'; -import { messageWithIntent } from '@iota/iota-sdk/cryptography'; -import { Turnkey } from '@turnkey/sdk-server'; -import { blake2b } from '@noble/hashes/blake2b'; -import { bytesToHex } from '@noble/hashes/utils'; - -dotenv.config({ path: path.resolve(process.cwd(), '.env.local') }); +import * as dotenv from "dotenv"; +import * as path from "path"; +import { IotaClient, getFullnodeUrl } from "@iota/iota-sdk/client"; +import { Transaction } from "@iota/iota-sdk/transactions"; +import { Ed25519PublicKey } from "@iota/iota-sdk/keypairs/ed25519"; +import { messageWithIntent } from "@iota/iota-sdk/cryptography"; +import { Turnkey } from "@turnkey/sdk-server"; +import { blake2b } from "@noble/hashes/blake2b"; +import { bytesToHex } from "@noble/hashes/utils"; + +dotenv.config({ path: path.resolve(process.cwd(), ".env.local") }); function toSerializedSignature({ signature, pubKey, @@ -39,12 +39,12 @@ function toSerializedSignature({ const scheme = new Uint8Array([0x00]); // ED25519 flag const pubKeyBytes = pubKey.toRawBytes(); const serialized = new Uint8Array( - scheme.length + signature.length + pubKeyBytes.length + scheme.length + signature.length + pubKeyBytes.length, ); serialized.set(scheme, 0); serialized.set(signature, scheme.length); serialized.set(pubKeyBytes, scheme.length + signature.length); - return Buffer.from(serialized).toString('base64'); + return Buffer.from(serialized).toString("base64"); } async function main() { @@ -59,7 +59,7 @@ async function main() { } = process.env; if (IOTA_ADDRESS === undefined || IOTA_PUBLIC_KEY === undefined) { - throw new Error('IOTA_ADDRESS or IOTA_PUBLIC_KEY not set in .env.local'); + throw new Error("IOTA_ADDRESS or IOTA_PUBLIC_KEY not set in .env.local"); } // sending to the same address @@ -67,14 +67,14 @@ async function main() { const amount = 1_000_000n; // 0.001 IOTA const turnkeyClient = new Turnkey({ - apiBaseUrl: 'https://api.turnkey.com', + apiBaseUrl: "https://api.turnkey.com", apiPrivateKey: API_PRIVATE_KEY!, apiPublicKey: API_PUBLIC_KEY!, defaultOrganizationId: ORGANIZATION_ID!, }); - const provider = new IotaClient({ url: getFullnodeUrl('testnet') }); - const publicKey = new Ed25519PublicKey(Buffer.from(IOTA_PUBLIC_KEY!, 'hex')); + const provider = new IotaClient({ url: getFullnodeUrl("testnet") }); + const publicKey = new Ed25519PublicKey(Buffer.from(IOTA_PUBLIC_KEY!, "hex")); // if (publicKey.toIotaAddress() !== IOTA_ADDRESS) { // throw new Error('IOTA_PUBLIC_KEY does not match IOTA_ADDRESS'); @@ -83,9 +83,9 @@ async function main() { // fetch the user's IOTA coin objects const coins = await provider.getCoins({ owner: IOTA_ADDRESS!, - coinType: '0x2::iota::IOTA', + coinType: "0x2::iota::IOTA", }); - if (!coins.data.length) throw new Error('No IOTA coins'); + if (!coins.data.length) throw new Error("No IOTA coins"); const tx = new Transaction(); tx.setSender(IOTA_ADDRESS!); @@ -98,36 +98,36 @@ async function main() { digest: coins.data[0]!.digest, }, ]); - const coin = tx.splitCoins(tx.gas, [tx.pure('u64', amount)]); + const coin = tx.splitCoins(tx.gas, [tx.pure("u64", amount)]); tx.transferObjects([coin], tx.pure.address(recipient)); const txBytes = await tx.build(); - const intentMsg = messageWithIntent('TransactionData', txBytes); + const intentMsg = messageWithIntent("TransactionData", txBytes); const digest = blake2b(intentMsg, { dkLen: 32 }); const { r, s } = await turnkeyClient.apiClient().signRawPayload({ signWith: IOTA_ADDRESS!, payload: bytesToHex(digest), - encoding: 'PAYLOAD_ENCODING_HEXADECIMAL', - hashFunction: 'HASH_FUNCTION_NOT_APPLICABLE', + encoding: "PAYLOAD_ENCODING_HEXADECIMAL", + hashFunction: "HASH_FUNCTION_NOT_APPLICABLE", }); - const signature = Buffer.from(r + s, 'hex'); + const signature = Buffer.from(r + s, "hex"); const serialized = toSerializedSignature({ signature, pubKey: publicKey }); const result = await provider.executeTransactionBlock({ - transactionBlock: Buffer.from(txBytes).toString('base64'), + transactionBlock: Buffer.from(txBytes).toString("base64"), signature: serialized, - requestType: 'WaitForEffectsCert', + requestType: "WaitForEffectsCert", options: { showEffects: true }, }); - console.log('Transaction digest:', result.digest); + console.log("Transaction digest:", result.digest); } main().catch((err) => { - console.error('Error:', err); + console.error("Error:", err); process.exit(1); }); ``` diff --git a/features/networks/overview.mdx b/features/networks/overview.mdx index a958c6ac..192a136d 100644 --- a/features/networks/overview.mdx +++ b/features/networks/overview.mdx @@ -36,12 +36,12 @@ Our SDK provides tools and scripts to help in constructing and signing basic tra At our highest level of support, Turnkey offers the ability to parse transactions and define custom policies based on transaction parameters. -| Tier | Depth of support | EVM | SVM | BTC | ATOM | TRON | SUI | APT | TON | XRP | SEI | -| ------ | :------------------------------- | --------------------------------------------- | --------------------------------------------- | --------------------------------------------- | --------------------------------------------- | --------------------------------------------- | --------------------------------------------- | --------------------------------------------- | --------------------------------------------- | --------------------------------------------- | --------------------------------------------- | -| Tier 1 | Curve-level | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| Tier 2 | Address derivation | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| Tier 3 | SDK construction and signing | ✓ | ✓ | | | | | | | | | -| Tier 4 | Transaction parsing and policies | ✓ | ✓ | ✓ | | ✓ | | | | | | +| Tier | Depth of support | EVM | SVM | BTC | ATOM | TRON | SUI | APT | TON | XRP | SEI | +| ------ | :------------------------------- | --- | --- | --- | ---- | ---- | --- | --- | --- | --- | --- | +| Tier 1 | Curve-level | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| Tier 2 | Address derivation | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| Tier 3 | SDK construction and signing | ✓ | ✓ | | | | | | | | | +| Tier 4 | Transaction parsing and policies | ✓ | ✓ | ✓ | | ✓ | | | | | | We are continuously evaluating and adding support for emerging assets and protocols. If there are specific cryptocurrencies you'd like to see us offer deeper support for, please let us know by contacting us at [hello@turnkey.com](mailto:hello@turnkey.com), on [X](https://x.com/turnkeyhq/), or [on Slack](https://join.slack.com/t/clubturnkey/shared_invite/zt-3aemp2g38-zIh4V~3vNpbX5PsSmkKxcQ). diff --git a/features/networks/sei.mdx b/features/networks/sei.mdx index 758f6dfc..d43b4397 100644 --- a/features/networks/sei.mdx +++ b/features/networks/sei.mdx @@ -48,7 +48,7 @@ const client = await SigningStargateClient.connectWithSigner( signer, { gasPrice: GasPrice.fromString("0.01usei"), - } + }, ); const recipient = "sei1recipient..."; // Recipient address @@ -60,7 +60,7 @@ const result = await client.sendTokens( recipient, amount, fee, - "Sent via Turnkey" + "Sent via Turnkey", ); console.log("Transaction hash:", result.transactionHash); ``` diff --git a/features/networks/solana-rent-refunds.mdx b/features/networks/solana-rent-refunds.mdx index 6c6afefc..88c5a9cc 100644 --- a/features/networks/solana-rent-refunds.mdx +++ b/features/networks/solana-rent-refunds.mdx @@ -32,8 +32,8 @@ If your product sponsors transactions that create accounts and you want rent cov /> - Refunded rent from later-closed accounts follows Solana account rules. It - does not automatically return to the sponsor. + Refunded rent from later-closed accounts follows Solana account rules. It does + not automatically return to the sponsor. ## Rent extraction risk @@ -108,7 +108,7 @@ body: JSON.stringify({ wrapAndUnwrapSol: false, dynamicComputeUnitLimit: true, prioritizationFeeLamports: "auto", -}) +}); ``` With this setting disabled, your application should manage wSOL explicitly instead of relying on Jupiter to create and close a temporary account on the user's behalf. diff --git a/features/networks/solana.mdx b/features/networks/solana.mdx index d4efd0e2..bce1f6fa 100644 --- a/features/networks/solana.mdx +++ b/features/networks/solana.mdx @@ -28,11 +28,13 @@ When you submit a transaction via `solSendTransaction`, Turnkey automatically ma Set `sponsor: true` to enable fee sponsorship — your users never need to hold SOL to pay transaction fees. Turnkey covers fees on your behalf and passes costs through as a monthly line item. **Supported networks:** + - Solana mainnet - Solana devnet (for testing) - To enable gas sponsorship, ensure it is activated in your Turnkey dashboard before setting `sponsor: true`. + To enable gas sponsorship, ensure it is activated in your Turnkey dashboard + before setting `sponsor: true`. For sponsored Solana flows, especially when you accept prebuilt transactions, see [Solana transaction construction for sponsored flows](/features/networks/solana-transaction-construction) for the current payload constraints and account-creation caveats. diff --git a/features/networks/spark.mdx b/features/networks/spark.mdx index d4c5f7ee..7fb391eb 100644 --- a/features/networks/spark.mdx +++ b/features/networks/spark.mdx @@ -7,10 +7,10 @@ sidebarTitle: "Spark" The supported address formats are: -| Network | Address Format | HRP | -| -------- | -------------------------------- | --------- | -| Mainnet | `ADDRESS_FORMAT_SPARK_MAINNET` | `spark` | -| Regtest | `ADDRESS_FORMAT_SPARK_REGTEST` | `sparkrt` | +| Network | Address Format | HRP | +| ------- | ------------------------------ | --------- | +| Mainnet | `ADDRESS_FORMAT_SPARK_MAINNET` | `spark` | +| Regtest | `ADDRESS_FORMAT_SPARK_REGTEST` | `sparkrt` | ### BIP-32 derivation path @@ -23,7 +23,8 @@ m/8797555'/{account}'/0' When creating a wallet account via the Turnkey dashboard or API, select `ADDRESS_FORMAT_SPARK_MAINNET` or `ADDRESS_FORMAT_SPARK_REGTEST` and the path will be set automatically. - Only `secp256k1` keys are supported for Spark. Attempting to use an ed25519 key will result in an error. + Only `secp256k1` keys are supported for Spark. Attempting to use an ed25519 + key will result in an error. ## Schnorr signing @@ -38,11 +39,11 @@ The returned signature will always have `V = "00"` since Schnorr signatures do n Turnkey automatically selects the correct signing scheme based on the address format associated with your key: -| Address type | Signing scheme | -| ------------------- | ---------------------- | -| Bitcoin P2TR | Tweaked Schnorr (BIP-341) | -| Spark Mainnet/Regtest | Plain Schnorr (BIP-340) | -| All others | ECDSA | +| Address type | Signing scheme | +| --------------------- | ------------------------- | +| Bitcoin P2TR | Tweaked Schnorr (BIP-341) | +| Spark Mainnet/Regtest | Plain Schnorr (BIP-340) | +| All others | ECDSA | ## Networks supported diff --git a/features/networks/stacks.mdx b/features/networks/stacks.mdx index af65159e..954385a2 100644 --- a/features/networks/stacks.mdx +++ b/features/networks/stacks.mdx @@ -23,4 +23,4 @@ Turnkey supports Stacks transaction signing through the core signing capabilitie - **Secure Key Management**: Private keys never leave Turnkey’s secure infrastructure - **Developer Friendly**: Integrate with existing Stacks development workflows - **Signing Policies**: Apply custom policies to control transaction approvals -- **Multi-address Support**: Manage multiple Stacks addresses under a single organization \ No newline at end of file +- **Multi-address Support**: Manage multiple Stacks addresses under a single organization diff --git a/features/networks/sui.mdx b/features/networks/sui.mdx index 6e5651f0..38a0f46a 100644 --- a/features/networks/sui.mdx +++ b/features/networks/sui.mdx @@ -18,17 +18,17 @@ Turnkey supports Sui transaction signing through the core signing capabilities. Here's a practical example showing how to integrate Turnkey with the [Sui SDK](https://sdk.mystenlabs.com/typescript): ```typescript expandable -import * as dotenv from 'dotenv'; -import * as path from 'path'; -import { SuiClient, getFullnodeUrl } from '@mysten/sui/client'; -import { Transaction } from '@mysten/sui/transactions'; -import { Ed25519PublicKey } from '@mysten/sui/keypairs/ed25519'; -import { messageWithIntent } from '@mysten/sui/cryptography'; -import { Turnkey } from '@turnkey/sdk-server'; -import { blake2b } from '@noble/hashes/blake2b'; -import { bytesToHex } from '@noble/hashes/utils'; - -dotenv.config({ path: path.resolve(process.cwd(), '.env.local') }); +import * as dotenv from "dotenv"; +import * as path from "path"; +import { SuiClient, getFullnodeUrl } from "@mysten/sui/client"; +import { Transaction } from "@mysten/sui/transactions"; +import { Ed25519PublicKey } from "@mysten/sui/keypairs/ed25519"; +import { messageWithIntent } from "@mysten/sui/cryptography"; +import { Turnkey } from "@turnkey/sdk-server"; +import { blake2b } from "@noble/hashes/blake2b"; +import { bytesToHex } from "@noble/hashes/utils"; + +dotenv.config({ path: path.resolve(process.cwd(), ".env.local") }); function toSerializedSignature({ signature, @@ -40,12 +40,12 @@ function toSerializedSignature({ const scheme = new Uint8Array([0x00]); // ED25519 flag const pubKeyBytes = pubKey.toRawBytes(); const serialized = new Uint8Array( - scheme.length + signature.length + pubKeyBytes.length + scheme.length + signature.length + pubKeyBytes.length, ); serialized.set(scheme, 0); serialized.set(signature, scheme.length); serialized.set(pubKeyBytes, scheme.length + signature.length); - return Buffer.from(serialized).toString('base64'); + return Buffer.from(serialized).toString("base64"); } async function main() { @@ -64,25 +64,25 @@ async function main() { const amount = 1_000_000n; // 0.001 SUI const turnkeyClient = new Turnkey({ - apiBaseUrl: 'https://api.turnkey.com', + apiBaseUrl: "https://api.turnkey.com", apiPrivateKey: API_PRIVATE_KEY!, apiPublicKey: API_PUBLIC_KEY!, defaultOrganizationId: ORGANIZATION_ID!, }); - const provider = new SuiClient({ url: getFullnodeUrl('testnet') }); - const publicKey = new Ed25519PublicKey(Buffer.from(SUI_PUBLIC_KEY!, 'hex')); + const provider = new SuiClient({ url: getFullnodeUrl("testnet") }); + const publicKey = new Ed25519PublicKey(Buffer.from(SUI_PUBLIC_KEY!, "hex")); if (publicKey.toSuiAddress() !== SUI_ADDRESS) { - throw new Error('SUI_PUBLIC_KEY does not match SUI_ADDRESS'); + throw new Error("SUI_PUBLIC_KEY does not match SUI_ADDRESS"); } // fetch the user's SUI coin objects const coins = await provider.getCoins({ owner: SUI_ADDRESS!, - coinType: '0x2::sui::SUI', + coinType: "0x2::sui::SUI", }); - if (!coins.data.length) throw new Error('No SUI coins'); + if (!coins.data.length) throw new Error("No SUI coins"); const tx = new Transaction(); tx.setSender(SUI_ADDRESS!); @@ -95,36 +95,36 @@ async function main() { digest: coins.data[0]!.digest, }, ]); - const coin = tx.splitCoins(tx.gas, [tx.pure('u64', amount)]); + const coin = tx.splitCoins(tx.gas, [tx.pure("u64", amount)]); tx.transferObjects([coin], tx.pure.address(recipient)); const txBytes = await tx.build(); - const intentMsg = messageWithIntent('TransactionData', txBytes); + const intentMsg = messageWithIntent("TransactionData", txBytes); const digest = blake2b(intentMsg, { dkLen: 32 }); const { r, s } = await turnkeyClient.apiClient().signRawPayload({ signWith: SUI_ADDRESS!, payload: bytesToHex(digest), - encoding: 'PAYLOAD_ENCODING_HEXADECIMAL', - hashFunction: 'HASH_FUNCTION_NOT_APPLICABLE', + encoding: "PAYLOAD_ENCODING_HEXADECIMAL", + hashFunction: "HASH_FUNCTION_NOT_APPLICABLE", }); - const signature = Buffer.from(r + s, 'hex'); + const signature = Buffer.from(r + s, "hex"); const serialized = toSerializedSignature({ signature, pubKey: publicKey }); const result = await provider.executeTransactionBlock({ - transactionBlock: Buffer.from(txBytes).toString('base64'), + transactionBlock: Buffer.from(txBytes).toString("base64"), signature: serialized, - requestType: 'WaitForEffectsCert', + requestType: "WaitForEffectsCert", options: { showEffects: true }, }); - console.log('Transaction digest:', result.digest); + console.log("Transaction digest:", result.digest); } main().catch((err) => { - console.error('Error:', err); + console.error("Error:", err); process.exit(1); }); ``` @@ -150,4 +150,4 @@ Turnkey supports: - **Signing Policies**: Apply custom policies to control transaction approvals - **Multi-user Support**: Manage multiple Sui addresses under a single organization -If you're building on Sui and need assistance with Turnkey integration, feel free to contact us at [hello@turnkey.com](mailto:hello@turnkey.com), on [X](https://x.com/turnkeyhq/), or [on Slack](https://join.slack.com/t/clubturnkey/shared_invite/zt-3aemp2g38-zIh4V~3vNpbX5PsSmkKxcQ). \ No newline at end of file +If you're building on Sui and need assistance with Turnkey integration, feel free to contact us at [hello@turnkey.com](mailto:hello@turnkey.com), on [X](https://x.com/turnkeyhq/), or [on Slack](https://join.slack.com/t/clubturnkey/shared_invite/zt-3aemp2g38-zIh4V~3vNpbX5PsSmkKxcQ). diff --git a/features/networks/tempo.mdx b/features/networks/tempo.mdx index ee4115cc..8bd814b9 100644 --- a/features/networks/tempo.mdx +++ b/features/networks/tempo.mdx @@ -12,6 +12,7 @@ Turnkey supports Tempo address derivation with `ADDRESS_TYPE_ETHEREUM`. ## Transaction construction and signing Turnkey supports both transaction types on Tempo: + - [Ethereum legacy transactions](https://docs.tempo.xyz/quickstart/evm-compatibility#transaction-differences) with full parsing & policy support - Tempo transactions with full parsing & policy support via the `tempo.tx` namespace @@ -20,6 +21,7 @@ Tempo transactions natively support batched calls — multiple calls can be sent ## Examples We have an example repository that demonstrates how to construct and sign Tempo transactions: + - [`examples/with-tempo`](https://github.com/tkhq/sdk/tree/main/examples/with-tempo): demonstrates single and batched (multicall) transaction construction and broadcast on Tempo, including fee sponsorship. Legacy Ethereum transactions on Tempo can be utilized on Turnkey with [viem](https://github.com/tkhq/sdk/tree/main/examples/with-viem) and [ethers](https://github.com/tkhq/sdk/tree/main/examples/with-ethers). diff --git a/features/networks/tron.mdx b/features/networks/tron.mdx index 78b709ad..2099667a 100644 --- a/features/networks/tron.mdx +++ b/features/networks/tron.mdx @@ -40,7 +40,7 @@ const amount = 100; // Amount in SUN (1 TRX = 1,000,000 SUN) const unsignedTx = await tronWeb.transactionBuilder.sendTrx( recipientAddress, amount, - turnkeyAddress + turnkeyAddress, ); // Sign with Turnkey diff --git a/features/organizations.mdx b/features/organizations.mdx index 2c9c34e6..909a82df 100644 --- a/features/organizations.mdx +++ b/features/organizations.mdx @@ -14,8 +14,8 @@ Organization features are Turnkey product offerings that organizations can opt-i | Name | Description | Default | Notes | | ----------------------------- | --------------------------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| FEATURE_NAME_EMAIL_AUTH | Enables email bundle authentication | Enabled | The `email_auth` activity can only be initiated by a parent organization for a sub-organization. | -| FEATURE_NAME_OTP_EMAIL_AUTH | Enables email OTP authentication | Enabled | The `init_otp`, `verify_otp` and `otp_login` activities can only be initiated by a parent organization for a sub-organization. | +| FEATURE_NAME_EMAIL_AUTH | Enables email bundle authentication | Enabled | The `email_auth` activity can only be initiated by a parent organization for a sub-organization. | +| FEATURE_NAME_OTP_EMAIL_AUTH | Enables email OTP authentication | Enabled | The `init_otp`, `verify_otp` and `otp_login` activities can only be initiated by a parent organization for a sub-organization. | | FEATURE_NAME_WEBAUTHN_ORIGINS | The origin Webauthn credentials are scoped to | Disabled | Parent organization feature applies to all sub-organizations. If not enabled, sub-organizations default to allowing all origins: "\*". For Passkey WaaS, we highly recommend enabling this feature. Example value: "[https://www.turnkey.com"](https://www.turnkey.com%22) | | FEATURE_NAME_WEBHOOK | A URL to receive activity notification events | Disabled | Example value: "[https://your.service.com/webhook"](https://your.service.com/webhook%22) | @@ -45,4 +45,4 @@ Organizations have [resource limits](/reference/resource-limits) for performance A sub-organization is an isolated organization that has a pointer to a parent organization. The parent organization has **read** access to all sub-organizations, but no **write** access. This means users within the parent organization have no ability to use wallets or alter any resources in the sub-organization. -For more information on sub-organizations and common use cases for this functionality, follow along in the next section. \ No newline at end of file +For more information on sub-organizations and common use cases for this functionality, follow along in the next section. diff --git a/features/policies/delegated-access/agentic-wallets.mdx b/features/policies/delegated-access/agentic-wallets.mdx index 31616157..4e5f765a 100644 --- a/features/policies/delegated-access/agentic-wallets.mdx +++ b/features/policies/delegated-access/agentic-wallets.mdx @@ -4,7 +4,7 @@ sidebarTitle: "Agent signing" description: "Let embedded wallet users delegate scoped signing authority to AI agents, controlled by granular policies" --- -import { FeatureCard } from '/snippets/feature-card.mdx' +import { FeatureCard } from "/snippets/feature-card.mdx"; ## What is an agentic wallet? @@ -33,9 +33,7 @@ This enables a new class of onchain applications: The diagram below shows how an AI agent gets scoped access through [Delegated Access](/features/policies/delegated-access/overview): - - ![Agentic Wallet](/assets/files/agentic-wallet.png) - +![Agentic Wallet](/assets/files/agentic-wallet.png) 1. **Setup**: The end user (root) creates a Delegated Access user and policies 2. **Request**: The AI agent sends signing requests using its P-256 API key @@ -51,7 +49,10 @@ The diagram below shows how an AI agent gets scoped access through [Delegated Ac ## Quick start - For a working end-to-end implementation, see the [with-agent-wallet example](https://github.com/tkhq/sdk/tree/main/examples/with-agent-wallet) — it covers wallet creation, agent user setup, policy creation, and a human approval flow. + For a working end-to-end implementation, see the [with-agent-wallet + example](https://github.com/tkhq/sdk/tree/main/examples/with-agent-wallet) — + it covers wallet creation, agent user setup, policy creation, and a human + approval flow. ### 1. create the wallet @@ -63,12 +64,14 @@ const suborgParams = { userName: "User", customWallet: { walletName: "Agent-Enabled Wallet", - walletAccounts: [{ - curve: "CURVE_SECP256K1", - pathFormat: "PATH_FORMAT_BIP32", - path: "m/44'/60'/0'/0/0", - addressFormat: "ADDRESS_FORMAT_ETHEREUM", - }], + walletAccounts: [ + { + curve: "CURVE_SECP256K1", + pathFormat: "PATH_FORMAT_BIP32", + path: "m/44'/60'/0'/0/0", + addressFormat: "ADDRESS_FORMAT_ETHEREUM", + }, + ], }, }; ``` @@ -96,12 +99,14 @@ const daUser = await fetchOrCreateP256ApiKeyUser({ Scope the agent's authority with policies: ```typescript -const policies = [{ - policyName: "Allow agent to send to treasury", - effect: "EFFECT_ALLOW", - consensus: `approvers.any(user, user.id == '${daUser.userId}')`, - condition: `eth.tx.to == '${TREASURY_ADDRESS}'`, -}]; +const policies = [ + { + policyName: "Allow agent to send to treasury", + effect: "EFFECT_ALLOW", + consensus: `approvers.any(user, user.id == '${daUser.userId}')`, + condition: `eth.tx.to == '${TREASURY_ADDRESS}'`, + }, +]; await fetchOrCreatePolicies({ policies }); ``` @@ -165,7 +170,7 @@ Multiple specialized agents share access to a wallet, each with different policy **Principle of Least Privilege**: This is the single most important security practice for agentic wallets. An agent should only be able to do the minimum set of actions required for its task. If your agent sweeps funds to a treasury, it doesn't need permission to call arbitrary contracts. If it trades on Uniswap, restrict it to that router's address and the specific function selectors it uses. -**Prefer Client-Side DA Setup**: When the end-user sets up delegated access from the frontend using their authenticated session, the DA user is created as non-root from the start. There is never a window where the agent has elevated privileges. The server-side approach requires temporarily adding the DA user to the root quorum, which introduces risk if the subsequent quorum update fails. +**Prefer Client-Side DA Setup**: When the end-user sets up delegated access from the frontend using their authenticated session, the DA user is created as non-root from the start. There is never a window where the agent has elevated privileges. The server-side approach requires temporarily adding the DA user to the root quorum, which introduces risk if the subsequent quorum update fails. **Use DENY Policies as Circuit Breakers**: DENY always overrides ALLOW in Turnkey's policy engine. Use DENY policies as circuit-breakers: for example, a DENY policy that blocks all signing for a specific wallet can be toggled on programmatically if anomalous behavior is detected, and it will override any ALLOW policies in place. @@ -198,9 +203,35 @@ For sensitive operations, require multiple approvers: ## Next steps -
- - - - +
+ + + +
diff --git a/features/policies/delegated-access/backend.mdx b/features/policies/delegated-access/backend.mdx index 719c9be4..50f54ac4 100644 --- a/features/policies/delegated-access/backend.mdx +++ b/features/policies/delegated-access/backend.mdx @@ -43,7 +43,7 @@ A simple example demonstrating the server-side delegated access setup can be fou } ], "apiKeys": [], - "oidcProviders": [] + "oidcProviders": [] }, { "userName": "Delegated Account", @@ -55,7 +55,7 @@ A simple example demonstrating the server-side delegated access setup can be fou "publicKey": "" } ], - "oidcProviders": [] + "oidcProviders": [] } ], "rootQuorumThreshold": 1, @@ -95,7 +95,7 @@ Here’s one example, granting the Delegated Account only the permission to sign "effect": "EFFECT_ALLOW", "consensus": "approvers.any(user, user.id == )", "condition": "eth.tx.to == " - }, + } } } ``` @@ -110,9 +110,7 @@ Here’s one example, granting the Delegated Account only the permission to sign "organizationId": "", "parameters": { "threshold": 1, - "userIds": [ - "" - ] + "userIds": [""] } } ``` @@ -186,7 +184,7 @@ dotenv.config(); console.log("sub-org id:", subOrg.subOrganizationId); // Initializing the Turkey client used by the Delegated Access User - // Notice the subOrganizationId created above + // Notice the subOrganizationId created above const turnkeyDelegatedAccessClient = new Turnkey({ apiBaseUrl: "https://api.turnkey.com", apiPrivateKey: process.env.DELEGATED_API_PRIVATE_KEY!, @@ -196,7 +194,7 @@ dotenv.config(); // STEP 2: Create a policy allowing the Delegated access user to send Ethereum transactions to a particular address - // Creating a policy for the Delegated account + // Creating a policy for the Delegated account const delegated_userid = subOrg.rootUserIds[0]; const policyName = "Allow Delegated Account to sign transactions to specific address"; const effect = "EFFECT_ALLOW"; diff --git a/features/policies/delegated-access/frontend.mdx b/features/policies/delegated-access/frontend.mdx index ccd6d1a0..a9e1a894 100644 --- a/features/policies/delegated-access/frontend.mdx +++ b/features/policies/delegated-access/frontend.mdx @@ -19,7 +19,7 @@ This works whether you use the [Auth Proxy](https://docs.turnkey.com/reference/a Both approaches follow the same principle — using an authenticated session to add a Delegated Access (DA) user and defining policies for that user within the sub-organization. -### Step 1: create an embedded wallet +### Step 1: create an embedded wallet In this guide we'll be using [@turnkey/react-wallet-kit](https://www.npmjs.com/package/@turnkey/react-wallet-kit) together with [Auth Proxy](https://docs.turnkey.com/sdks/react/getting-started). @@ -67,19 +67,16 @@ export function Providers({ children }: { children: React.ReactNode }) { - Handle authentication is using the `handleLogin` function from the useTurnkey hook. It’s idempotent — existing users simply log in to their sub-org. - ```tsx page.tsx "use client"; import { useTurnkey } from "@turnkey/react-wallet-kit"; function LoginButton() { - const { handleLogin } = useTurnkey(); - return ; + const { handleLogin } = useTurnkey(); + return ; } export default function Home() { - return ( - - ); + return ; } ``` @@ -94,31 +91,32 @@ You can create this user at any point, either immediately after login or on-dema ```tsx src/dashboard/page.tsx const handleDaSetup = async () => { - if (!isHexCompressedPubKey(daPublicKey)) { - setPublicKeyErr( - "Public key must be a 66-hex-character compressed key (no 0x prefix).", - ); - return; - } - setPublicKeyErr(null); - - try { - const res = await fetchOrCreateP256ApiKeyUser({ - publicKey: daPublicKey, - createParams: { - userName: "Delegated Access", - apiKeyName: "Delegated User API Key", - }, - }); - setDaUser(res); - } catch (err) { - console.error("Error setting up DA user:", err); - setDaUser({ error: "Failed to set up DA user." }); - } + if (!isHexCompressedPubKey(daPublicKey)) { + setPublicKeyErr( + "Public key must be a 66-hex-character compressed key (no 0x prefix).", + ); + return; + } + setPublicKeyErr(null); + + try { + const res = await fetchOrCreateP256ApiKeyUser({ + publicKey: daPublicKey, + createParams: { + userName: "Delegated Access", + apiKeyName: "Delegated User API Key", + }, + }); + setDaUser(res); + } catch (err) { + console.error("Error setting up DA user:", err); + setDaUser({ error: "Failed to set up DA user." }); + } }; ``` **Note:** At this stage, the DA user is non-root, so any signing attempts will be denied by the policy engine because: + - the user is not part of the root quorum, and - no policy has been added yet to allow that action. @@ -129,56 +127,58 @@ In this example, we’ll allow the DA user to sign Ethereum transactions **only* ```tsx src/dashboard/page.tsx const handleBuildPolicyTemplate = () => { - if (!daUser?.userId) { - setPolicyError("Set up the Delegated Access user first."); - return; - } - if (!isEthAddress(recipientAddress)) { - setRecipientErr("Enter a valid 0x-prefixed, 40-hex Ethereum address."); - return; - } - setRecipientErr(null); - setPolicyError(null); - - const template = [ - { - policyName: `Allow user ${daUser.userId} to sign only to ${recipientAddress}`, - effect: "EFFECT_ALLOW", - consensus: `approvers.any(user, user.id == '${daUser.userId}')`, - condition: `eth.tx.to == '${recipientAddress}'`, - notes: - "Allow Delegated Access user to sign Ethereum transactions only to the specified recipient", - }, - ]; - setPolicyJson(JSON.stringify(template, null, 2)); - }; + if (!daUser?.userId) { + setPolicyError("Set up the Delegated Access user first."); + return; + } + if (!isEthAddress(recipientAddress)) { + setRecipientErr("Enter a valid 0x-prefixed, 40-hex Ethereum address."); + return; + } + setRecipientErr(null); + setPolicyError(null); + + const template = [ + { + policyName: `Allow user ${daUser.userId} to sign only to ${recipientAddress}`, + effect: "EFFECT_ALLOW", + consensus: `approvers.any(user, user.id == '${daUser.userId}')`, + condition: `eth.tx.to == '${recipientAddress}'`, + notes: + "Allow Delegated Access user to sign Ethereum transactions only to the specified recipient", + }, + ]; + setPolicyJson(JSON.stringify(template, null, 2)); +}; - // Keep in sync setToAllowed if recipientAddress changes manually - useEffect(() => { - if (recipientAddress) { - setToAllowed(recipientAddress); - } - }, [recipientAddress]); - - const handleSubmitPolicies = async () => { - setPolicyError(null); - setPolicyResult(null); - setSubmittingPolicy(true); - try { - const parsed = JSON.parse(policyJson); - if (!Array.isArray(parsed)) { - throw new Error("JSON must be an array of policy objects."); - } - const res = await fetchOrCreatePolicies({ policies: parsed }); - setPolicyResult(res); - } catch (e: any) { - setPolicyError(e?.message || "Failed to submit policies."); - } finally { - setSubmittingPolicy(false); +// Keep in sync setToAllowed if recipientAddress changes manually +useEffect(() => { + if (recipientAddress) { + setToAllowed(recipientAddress); + } +}, [recipientAddress]); + +const handleSubmitPolicies = async () => { + setPolicyError(null); + setPolicyResult(null); + setSubmittingPolicy(true); + try { + const parsed = JSON.parse(policyJson); + if (!Array.isArray(parsed)) { + throw new Error("JSON must be an array of policy objects."); } - }; + const res = await fetchOrCreatePolicies({ policies: parsed }); + setPolicyResult(res); + } catch (e: any) { + setPolicyError(e?.message || "Failed to submit policies."); + } finally { + setSubmittingPolicy(false); + } +}; ``` -**Note:** + +**Note:** + - Reminder, until this policy is added, the DA user cannot sign any transactions — it’s a non-root user with no permissions by default. - The `fetchOrCreatePolicies` method compares the full intent signature of each policy you pass in: - If a policy already exists with the **exact same fields**, it will be reused. diff --git a/features/policies/delegated-access/overview.mdx b/features/policies/delegated-access/overview.mdx index 8d57ccf0..f37eec21 100644 --- a/features/policies/delegated-access/overview.mdx +++ b/features/policies/delegated-access/overview.mdx @@ -17,16 +17,19 @@ You can implement Delegated Access for an embedded wallet in two ways, depending ### 1. Frontend (recommended) This approach uses the **end-user’s authenticated session** to configure delegated access directly within their sub-organization. The flow is: + - Create an **API-only user (Delegated User)** with a P-256 API key authenticator that you control. This key can then be used server-side to sign transactions on the user’s behalf. - Define **policies** for the Delegated User that strictly limit which transactions they are allowed to sign. -**Why this approach:** +**Why this approach:** This avoids temporarily granting the Delegated User root access — see [Caution](#caution) for more details. Since you’re using the client-side authenticated session, the API-only user is created directly as a **non-root** user within the sub-organization. **Advantages:** + - There’s no possibility of elevated (root-level) access for the delegated user. **Limitations:** + - You can’t assume the delegated user or its policies already exist. Before referencing it, you’ll need to call `fetchOrCreateP256ApiKeyUser` and `fetchOrCreatePolicies` to ensure the user and permissions are properly set up. For a detailed step-by-step guide see [Client-side Delegated Access setup](/features/policies/delegated-access/frontend). @@ -34,23 +37,31 @@ For a detailed step-by-step guide see [Client-side Delegated Access setup](/feat ### 2. Backend If you prefer to configure delegated access entirely server-side, the flow differs because the end-user in the embedded wallet model does not hold an API key. In this case, you must: + - Create the sub-organization with **two root users**: the end-user and your Delegated User (API key authenticator). - Use the delegated access API key to add policies explicitly granting the DA user the limited actions you want them to perform. - Update the root quorum so that only the end-user remains a root user. -

Caution ⚠️

-When the delegated access setup is performed from the backend, your service (not the end-user) initiates and approves the sub-organization creation, delegated user addition, and root quorum updates. -This means the delegated user is temporarily added to the root quorum without direct end-user consent. If any of these operations fail — particularly the quorum update — the delegated user may unintentionally retain root privileges, effectively gaining unrestricted access to the user’s wallet. +When the delegated access setup is performed from the backend, your service (not +the end-user) initiates and approves the sub-organization creation, delegated +user addition, and root quorum updates. This means the delegated user is +temporarily added to the root quorum without direct end-user consent. If any of +these operations fail — particularly the quorum update — the delegated user may +unintentionally retain root privileges, effectively gaining unrestricted access +to the user’s wallet. If you adopt this approach, implement strict validation to confirm that: + - The root quorum was successfully updated; and - The delegated user no longer retains unintended permissions once setup completes. **Advantages:** + - Guarantees that the delegated user exists and can perform the required actions without additional setup. **Limitations:** + - Risk of elevated access if the delegated user isn’t successfully removed as a root user, it may retain unintended control. - Since all actions are service-initiated, there’s no explicit end-user approval in this flow. @@ -65,21 +76,29 @@ For a detailed step-by-step guide see [Server-side Delegated Access setup](/feat Yes — if the delegated access (DA) user is part of the root quorum, they can create policies unilaterally. Once removed from the root quorum, only the remaining quorum member (typically the end-user) can make further policy changes. - Note: This can also be done even if the initiating (delegated) user is not a root user, provided a policy explicitly grants them permission to create policies. However, such a configuration should be carefully scoped — additional restrictive policies are typically required to prevent the delegated user from granting themselves broader or unintended access. +Note: This can also be done even if the initiating (delegated) user is not a root user, provided a policy explicitly grants them permission to create policies. However, such a configuration should be carefully scoped — additional restrictive policies are typically required to prevent the delegated user from granting themselves broader or unintended access. + - When the delegated access setup is performed **client-side**, all actions are initiated and approved by the authenticated end-user within their session. This ensures full transparency and explicit user consent for every operation. + When the delegated access setup is performed **client-side**, all actions are + initiated and approved by the authenticated end-user within their session. + This ensures full transparency and explicit user consent for every operation.
- When performed **server-side**, the setup happens without direct user involvement. This approach is generally used only in **enterprise or custodial environments**, where your backend manages sub-organizations and delegated users on behalf of end-users. + When performed **server-side**, the setup happens without direct user + involvement. This approach is generally used only in **enterprise or custodial + environments**, where your backend manages sub-organizations and delegated + users on behalf of end-users.
- For typical end-user applications, the client-side setup is the recommended and more secure approach. + For typical end-user applications, the client-side setup is the recommended + and more secure approach.
As long as the DA user remains authorized, they can remove policies programmatically. If they’ve been removed from the quorum, policy deletion will require the user’s explicit approval. - **NOTE:** Turnkey is looking to support the concept of 'one-time-use policies' to make it easier to manage redundant policies. +**NOTE:** Turnkey is looking to support the concept of 'one-time-use policies' to make it easier to manage redundant policies. + ### Security and risk management @@ -88,81 +107,91 @@ For a detailed step-by-step guide see [Server-side Delegated Access setup](/feat Yes — if the key is attached to a broad policy. That’s why it’s important to limit the scope of policies and enforce API hygiene practices. It's also recommended to have a policy in place that would allow this user to self-delete in case of a potential key leak: - ```json - { - policyName: `Allow the Delegated user to self-delete`, - effect: "EFFECT_ALLOW", - consensus: `approvers.any(user, user.id == '${delegated_userid}')`, - condition: `activity.type == 'ACTIVITY_TYPE_DELETE_USERS' && activity.params.user_ids.count() == 1 && '${delegated_userid}' in activity.params.user_ids`, - notes: "Allow the Delegated user to delete itself in case of a key leak" - } - ``` +```json +{ + policyName: `Allow the Delegated user to self-delete`, + effect: "EFFECT_ALLOW", + consensus: `approvers.any(user, user.id == '${delegated_userid}')`, + condition: `activity.type == 'ACTIVITY_TYPE_DELETE_USERS' && activity.params.user_ids.count() == 1 && '${delegated_userid}' in activity.params.user_ids`, + notes: "Allow the Delegated user to delete itself in case of a key leak" +} +``` + - In effect, yes. The key difference is that granular policies **can restrict** what a DA user can do, offering better security hygiene even if there's still elevated access. + In effect, yes. The key difference is that granular policies **can restrict** + what a DA user can do, offering better security hygiene even if there's still + elevated access. Typically this is a combination of, or all of the following practices, though not exclusive to just these: - - Using short-lived keys whenever viable - - Rotating API keys regularly - - Monitoring the usage - - Secure storage (e.g. in HSMs or vaults) - +- Using short-lived keys whenever viable +- Rotating API keys regularly +- Monitoring the usage +- Secure storage (e.g. in HSMs or vaults) + ### Best practices You can define strict transaction conditions. For example: - ```javascript - solana.tx.instructions.count() == 1 && +```javascript +solana.tx.instructions.count() == 1 && solana.tx.transfers.count() == 1 && - solana.tx.transfers.all(transfer, transfer.to == '') - ``` + solana.tx.transfers.all(transfer, transfer.to == ""); +``` - You can also consider the following: +You can also consider the following: - - Recipient address restrictions (ie allowlisting addresses) - - Contract method selectors - - Transaction structure invariants - - Blockhash constraints (on Solana) - +- Recipient address restrictions (ie allowlisting addresses) +- Contract method selectors +- Transaction structure invariants +- Blockhash constraints (on Solana) + - Yes — this is a common pattern. You can add a policy per order (limit, stop loss, TWAP, etc.) using either the end-user’s authenticated session or a Delegated Access (DA) user, as long as the DA user has the necessary permissions defined by policy. + Yes — this is a common pattern. You can add a policy per order (limit, stop + loss, TWAP, etc.) using either the end-user’s authenticated session or a + Delegated Access (DA) user, as long as the DA user has the necessary + permissions defined by policy. Turnkey's Policy Engine shines through its flexibility. There are many different approaches you can take based on your requirements, but various themes we see include: - - Using **broad policies** with business-controlled API keys - - Using \*\*fine-grained policies, \*\*scoped to predictable transaction shapes - - Using delegated access to implement **limit orders, automation flows, or advanced trading logic** (e.g. perps, TWAPs) - - Ensuring **strong operational security** (e.g. tight scoping & expiring keys) is increasingly common - +- Using **broad policies** with business-controlled API keys +- Using \*\*fine-grained policies, \*\*scoped to predictable transaction shapes +- Using delegated access to implement **limit orders, automation flows, or advanced trading logic** (e.g. perps, TWAPs) +- Ensuring **strong operational security** (e.g. tight scoping & expiring keys) is increasingly common + ### EVM and SVM-specific strategies - Yes, on Solana via `solana.tx.recent_blockhash`, which restricts a transaction’s validity to a ~60–90 second window. Not ideal for delayed executions (e.g. limit orders), but useful for immediate, single-use actions. + Yes, on Solana via `solana.tx.recent_blockhash`, which restricts a + transaction’s validity to a ~60–90 second window. Not ideal for delayed + executions (e.g. limit orders), but useful for immediate, single-use actions. Yes, though it’s limited today. You can inspect calldata (e.g., using `eth.tx.data[...]`) and enforce conditions like: - ```javascript - eth.tx.to == '' && - eth.tx.data[0..4] == '' - ``` +```javascript +eth.tx.to == '' && +eth.tx.data[0..4] == '' +``` + +Granular support for calldata parsing and value limits is coming soon. - Granular support for calldata parsing and value limits is coming soon. Not entirely. Even if you allowlist the router, it could still be abused to swap all assets. You can’t control downstream behavior unless you control the contract. - > **Suggestion:** Only allow DA keys to interact with contracts you fully trust or control. Limit scope as much as possible (e.g., to specific instructions, amounts, or recipients). +> **Suggestion:** Only allow DA keys to interact with contracts you fully trust or control. Limit scope as much as possible (e.g., to specific instructions, amounts, or recipients). + diff --git a/features/policies/examples/bitcoin.mdx b/features/policies/examples/bitcoin.mdx index 8e3a342d..b4ccec94 100644 --- a/features/policies/examples/bitcoin.mdx +++ b/features/policies/examples/bitcoin.mdx @@ -6,7 +6,6 @@ sidebarTitle: "Bitcoin" Note: see the [language section](/features/policies/language#bitcoin) for more details. For context on Bitcoin transaction reinsertion, see the [Bitcoin network support](/features/networks/bitcoin) page - #### Allow signing Bitcoin transactions ONLY if all outputs are being sent to a certain address ```json @@ -55,4 +54,4 @@ Note: see the [language section](/features/policies/language#bitcoin) for more d "effect": "EFFECT_DENY", "condition": "bitcoin.tx.fee > 50000" } -``` \ No newline at end of file +``` diff --git a/features/policies/examples/co-signing-transactions.mdx b/features/policies/examples/co-signing-transactions.mdx index 484433ec..7a65d4b7 100644 --- a/features/policies/examples/co-signing-transactions.mdx +++ b/features/policies/examples/co-signing-transactions.mdx @@ -9,7 +9,10 @@ sidebarTitle: "Multi-sig approvals" Co-signing, often referred to as multi-signature (multi-sig), provides an enhanced layer of security for blockchain transactions. It requires approvals from multiple parties before a transaction can be executed. This guide details how to implement a 2/2 co-signing setup using Turnkey, where both the end-user and your application backend (via API key) must approve transactions. - See the [with-cosigning example](https://github.com/tkhq/sdk/tree/main/examples/with-cosigning) for a full working implementation using Next.js, OTP login, SSE webhooks, and a 2-of-2 root quorum. + See the [with-cosigning + example](https://github.com/tkhq/sdk/tree/main/examples/with-cosigning) for a + full working implementation using Next.js, OTP login, SSE webhooks, and a + 2-of-2 root quorum. ## Co-signing architecture @@ -151,7 +154,6 @@ sequenceDiagram The transaction won't be fully signed yet - it will be in a `CONSENSUS_NEEDED` status until your backend approves it. Here's how to implement this flow in your frontend: - ```typescript import { useTurnkey, StamperType } from "@turnkey/react-wallet-kit"; @@ -245,11 +247,15 @@ sequenceDiagram ``` + - The quorum is symmetric — the backend can also initiate signing (vote 1) and the user approves (vote 2). See the [with-cosigning example](https://github.com/tkhq/sdk/tree/main/examples/with-cosigning) for a full walkthrough of both flows. + The quorum is symmetric — the backend can also initiate signing (vote 1) and + the user approves (vote 2). See the [with-cosigning + example](https://github.com/tkhq/sdk/tree/main/examples/with-cosigning) for a + full walkthrough of both flows. #### Security considerations and best practices diff --git a/features/policies/examples/ethereum.mdx b/features/policies/examples/ethereum.mdx index 191fa723..b4395fbd 100644 --- a/features/policies/examples/ethereum.mdx +++ b/features/policies/examples/ethereum.mdx @@ -55,6 +55,7 @@ See [here](../../../concepts/policies/smart-contract-interfaces) for more inform The `eth.eip_712.message` map supports nested field access using bracket notation, allowing policies to inspect typed data contents beyond just the domain and primary type. **Syntax:** + - Nested struct fields: `eth.eip_712.message['outerField']['innerField']` - Array element fields: `eth.eip_712.message['arrayField'][0]['innerField']` @@ -86,7 +87,11 @@ To allow only orders for a specific asset (e.g. ETH = asset index `3`): ``` -Array access is index-based (`[0]`, `[1]`, etc.). The condition `message['orders'][0]['a'] == '3'` only checks the first order — any additional orders in the array are not evaluated. To restrict all orders in a known-size batch, add a condition for each index: `message['orders'][0]['a'] == '3' && message['orders'][1]['a'] == '3'`. + Array access is index-based (`[0]`, `[1]`, etc.). The condition + `message['orders'][0]['a'] == '3'` only checks the first order — any + additional orders in the array are not evaluated. To restrict all orders in a + known-size batch, add a condition for each index: `message['orders'][0]['a'] + == '3' && message['orders'][1]['a'] == '3'`. ### Deny signing of `NO_OP` keccak256 payloads diff --git a/features/policies/examples/solana.mdx b/features/policies/examples/solana.mdx index a6086eec..dab530ad 100644 --- a/features/policies/examples/solana.mdx +++ b/features/policies/examples/solana.mdx @@ -7,8 +7,8 @@ sidebarTitle: "Solana" Note: see the [language section](/features/policies/language#solana) for various approaches on writing Solana policies. - For sponsored Solana transactions, start with - [Solana Rent Sponsorship](/features/networks/solana-rent-refunds) before applying the + For sponsored Solana transactions, start with [Solana Rent + Sponsorship](/features/networks/solana-rent-refunds) before applying the examples below. That guide covers account-creation risk, rent refunds, and mitigation strategy for sponsored flows. diff --git a/features/policies/language.mdx b/features/policies/language.mdx index a0050690..2d18e61c 100644 --- a/features/policies/language.mdx +++ b/features/policies/language.mdx @@ -219,7 +219,7 @@ The language is strongly typed which makes policies easy to author and maintain. | | sequence | int | The sequence field on this input which is set whether the transaction can be replaced or when it can be mined | | **BitcoinTxOutput** | value | int | The value of this output in Satoshis | | | script_pubkey | string | The locking code for this transaction output | -| | address | string | The onchain address representation for this transaction output | +| | address | string | The onchain address representation for this transaction output | | | address_type | string | The address derivation type of the address for this transaction output | | **BitcoinTxLocktime** | amount | int | The amount represented in this transaction's locktime | | | type | string | The type of locktime represented (either 'Seconds' or 'Blocks') | @@ -304,9 +304,9 @@ The language is strongly typed which makes policies easy to author and maintain. | **AUTH_PROXY** | CREATE | ACTIVITY_TYPE_ENABLE_AUTH_PROXY | | | DELETE | ACTIVITY_TYPE_DISABLE_AUTH_PROXY | | | UPDATE | ACTIVITY_TYPE_UPDATE_AUTH_PROXY_CONFIG | -| **WEBHOOK_ENDPOINT** | CREATE | ACTIVITY_TYPE_CREATE_WEBHOOK_ENDPOINT | -| | UPDATE | ACTIVITY_TYPE_UPDATE_WEBHOOK_ENDPOINT | -| | DELETE | ACTIVITY_TYPE_DELETE_WEBHOOK_ENDPOINT | +| **WEBHOOK_ENDPOINT** | CREATE | ACTIVITY_TYPE_CREATE_WEBHOOK_ENDPOINT | +| | UPDATE | ACTIVITY_TYPE_UPDATE_WEBHOOK_ENDPOINT | +| | DELETE | ACTIVITY_TYPE_DELETE_WEBHOOK_ENDPOINT | ** Legacy features, deprecated in the latest SDKs. @@ -316,38 +316,38 @@ The language is strongly typed which makes policies easy to author and maintain. Note that our policy engine does not short circuit during evaluation. In practice, this means that if any clause within the `condition` field of a policy results in an error, the evaluated `outcome` for that policy will be an error. In such cases, consider breaking up complex policies into separate policies. -For example, suppose you're looking to construct a policy with the condition `wallet.id == '\' || private_key.id == '\'. This condition will _always_ error out during evaluation, because only one of the two clauses can ever be valid: an activity cannot target both a wallet and private key. That means if you're trying to, say, sign with a private key, then the wallet clause will fail (because a wallet isn't being passed into the policy evaluation). Conversely, if you're trying to sign with a wallet, the private key clause will fail for the same reason. +For example, suppose you're looking to construct a policy with the condition `wallet.id == '\' || private*key.id == '\'. This condition will \_always* error out during evaluation, because only one of the two clauses can ever be valid: an activity cannot target both a wallet and private key. That means if you're trying to, say, sign with a private key, then the wallet clause will fail (because a wallet isn't being passed into the policy evaluation). Conversely, if you're trying to sign with a wallet, the private key clause will fail for the same reason. ### Activity parameters The `activity.params` field exposes specific parameters based on the activity type. Most activities do not expose any parameters, but certain activities expose fields that can be used in policy conditions. -| Category | Activity Type | Field | Type | Description | -| ----------------- | ----------------------------------- | --------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Signing | `ACTIVITY_TYPE_SIGN_RAW_PAYLOAD` | `hash_function` | string | The hash function used (e.g., `HASH_FUNCTION_NO_OP`, `HASH_FUNCTION_KECCAK256`) | -| | | `encoding` | string | The payload encoding (e.g., `PAYLOAD_ENCODING_HEXADECIMAL`, `PAYLOAD_ENCODING_EIP712`) | -| | `ACTIVITY_TYPE_SIGN_RAW_PAYLOAD_V2` | `hash_function` | string | The hash function used | -| | | `encoding` | string | The payload encoding | -| | `ACTIVITY_TYPE_SIGN_RAW_PAYLOADS` | `hash_function` | string | The hash function used | -| | | `encoding` | string | The payload encoding | -| | `ACTIVITY_TYPE_SIGN_TRANSACTION_V2` | `type` | string | The transaction type (one of `[TRANSACTION_TYPE_ETHEREUM, TRANSACTION_TYPE_SOLANA, TRANSACTION_TYPE_BITCOIN, TRANSACTION_TYPE_TRON, TRANSACTION_TYPE_TEMPO`]) | -| User Management | `ACTIVITY_TYPE_DELETE_USERS` | `user_ids` | list\ | The list of user IDs being deleted | -| Wallet Management | `ACTIVITY_TYPE_UPDATE_WALLET` | `wallet_id` | string | The ID of the wallet being updated | -| Authentication | `ACTIVITY_TYPE_INIT_OTP_AUTH_V2` | `otp_length` | int | The length of the OTP code | -| | `ACTIVITY_TYPE_INIT_OTP_AUTH_V3` | `otp_length` | int | The length of the OTP code | -| Policy Management | `ACTIVITY_TYPE_DELETE_POLICY` | `policy_id` | string | The ID of the policy being deleted | -| | `ACTIVITY_TYPE_DELETE_POLICIES` | `policy_ids` | list\ | The list of policy IDs being deleted | -| Webhook Endpoint | `ACTIVITY_TYPE_CREATE_WEBHOOK_ENDPOINT` | `url` | string | The URL of the webhook endpoint | -| | | `name` | string | The display name of the webhook endpoint | -| | | `subscriptions` | list\ | The list of event subscriptions for this endpoint | -| | | `subscriptions.event_type` | string | The event type to subscribe to (e.g., `ACTIVITY_UPDATES`, `BALANCE_CONFIRMED_UPDATES`) | -| | | `subscriptions.filters_json` | string | JSON-encoded filter criteria for the subscription | -| | | `subscriptions.is_active` | bool | Whether this subscription is active | -| | `ACTIVITY_TYPE_UPDATE_WEBHOOK_ENDPOINT` | `endpoint_id` | string | The ID of the webhook endpoint being updated | -| | | `url` | string | The updated URL of the webhook endpoint | -| | | `name` | string | The updated display name of the webhook endpoint | -| | | `is_active` | bool | Whether the webhook endpoint is active | -| | `ACTIVITY_TYPE_DELETE_WEBHOOK_ENDPOINT` | `endpoint_id` | string | The ID of the webhook endpoint being deleted | +| Category | Activity Type | Field | Type | Description | +| ----------------- | --------------------------------------- | ---------------------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Signing | `ACTIVITY_TYPE_SIGN_RAW_PAYLOAD` | `hash_function` | string | The hash function used (e.g., `HASH_FUNCTION_NO_OP`, `HASH_FUNCTION_KECCAK256`) | +| | | `encoding` | string | The payload encoding (e.g., `PAYLOAD_ENCODING_HEXADECIMAL`, `PAYLOAD_ENCODING_EIP712`) | +| | `ACTIVITY_TYPE_SIGN_RAW_PAYLOAD_V2` | `hash_function` | string | The hash function used | +| | | `encoding` | string | The payload encoding | +| | `ACTIVITY_TYPE_SIGN_RAW_PAYLOADS` | `hash_function` | string | The hash function used | +| | | `encoding` | string | The payload encoding | +| | `ACTIVITY_TYPE_SIGN_TRANSACTION_V2` | `type` | string | The transaction type (one of `[TRANSACTION_TYPE_ETHEREUM, TRANSACTION_TYPE_SOLANA, TRANSACTION_TYPE_BITCOIN, TRANSACTION_TYPE_TRON, TRANSACTION_TYPE_TEMPO`]) | +| User Management | `ACTIVITY_TYPE_DELETE_USERS` | `user_ids` | list\ | The list of user IDs being deleted | +| Wallet Management | `ACTIVITY_TYPE_UPDATE_WALLET` | `wallet_id` | string | The ID of the wallet being updated | +| Authentication | `ACTIVITY_TYPE_INIT_OTP_AUTH_V2` | `otp_length` | int | The length of the OTP code | +| | `ACTIVITY_TYPE_INIT_OTP_AUTH_V3` | `otp_length` | int | The length of the OTP code | +| Policy Management | `ACTIVITY_TYPE_DELETE_POLICY` | `policy_id` | string | The ID of the policy being deleted | +| | `ACTIVITY_TYPE_DELETE_POLICIES` | `policy_ids` | list\ | The list of policy IDs being deleted | +| Webhook Endpoint | `ACTIVITY_TYPE_CREATE_WEBHOOK_ENDPOINT` | `url` | string | The URL of the webhook endpoint | +| | | `name` | string | The display name of the webhook endpoint | +| | | `subscriptions` | list\ | The list of event subscriptions for this endpoint | +| | | `subscriptions.event_type` | string | The event type to subscribe to (e.g., `ACTIVITY_UPDATES`, `BALANCE_CONFIRMED_UPDATES`) | +| | | `subscriptions.filters_json` | string | JSON-encoded filter criteria for the subscription | +| | | `subscriptions.is_active` | bool | Whether this subscription is active | +| | `ACTIVITY_TYPE_UPDATE_WEBHOOK_ENDPOINT` | `endpoint_id` | string | The ID of the webhook endpoint being updated | +| | | `url` | string | The updated URL of the webhook endpoint | +| | | `name` | string | The updated display name of the webhook endpoint | +| | | `is_active` | bool | Whether the webhook endpoint is active | +| | `ACTIVITY_TYPE_DELETE_WEBHOOK_ENDPOINT` | `endpoint_id` | string | The ID of the webhook endpoint being deleted | #### Examples diff --git a/features/policies/quickstart.mdx b/features/policies/quickstart.mdx index 7e036d49..4c804663 100644 --- a/features/policies/quickstart.mdx +++ b/features/policies/quickstart.mdx @@ -6,22 +6,28 @@ sidebarTitle: "Quickstart" This assumes that you previously completed the [Sign a transaction](/get-started/quickstart) guide, and thus have already set up: -* Your Turnkey organization -* An API key for the Root User -* A Wallet with an Ethereum account +- Your Turnkey organization +- An API key for the Root User +- A Wallet with an Ethereum account ## Create your new users New users in your Turnkey organization can be created by navigating to the "Users" tab and clicking "Add User". - Screen Shot 2023-02-17 at 9.42.29 AM.png + Screen Shot 2023-02-17 at 9.42.29 AM.png In the create user flow, you have the option to grant API key or web access to your new user. For this example, we're going to create an API-only user. - Screen Shot 2023-02-21 at 6.17.11 PM.png + Screen Shot 2023-02-21 at 6.17.11 PM.png Under access types, select "API key". Enter the user name "Policy Test". This will be an API-only user, and therefore an email is not required. Click continue and create a new API key to associate with the user using the following command: @@ -30,14 +36,17 @@ Under access types, select "API key". Enter the user name "Policy Test". This wi turnkey generate api-key --organization $ORGANIZATION_ID --key-name policy_test ``` -This will create 2 files, "policy\_test.public" and "policy\_test.private". Copy the contents of the ".public" file and paste it into "API public key". Finish the create user flow and authenticate. Your new user will appear in the Users table. Note down the user ID as you will use it in the next step. +This will create 2 files, "policy_test.public" and "policy_test.private". Copy the contents of the ".public" file and paste it into "API public key". Finish the create user flow and authenticate. Your new user will appear in the Users table. Note down the user ID as you will use it in the next step. ## Create policies for your new users. Next we will create a policy to grant permissions to the new user. Navigate to the "Policies" tab and click on "Add new policy". - Screen Shot 2023-05-10 at 1.29.00 PM.png + Screen Shot 2023-05-10 at 1.29.00 PM.png Choose a name and note to describe your new policy. Next, enter the following policy, making sure to replace `` with an Ethereum address of your choosing and `` with the user ID of your recently created API user. @@ -73,6 +82,6 @@ You'll see that the activity to allowlisted address comes back as `COMPLETED`, w ## Extra credit -* Try out some of our [policy examples](/features/policies/examples/ethereum) -* Check out the [policy overview](/features/policies/overview) -* Learn how to author policies with our [policy language](/features/policies/overview) +- Try out some of our [policy examples](/features/policies/examples/ethereum) +- Check out the [policy overview](/features/policies/overview) +- Learn how to author policies with our [policy language](/features/policies/overview) diff --git a/features/policies/smart-contract-interfaces.mdx b/features/policies/smart-contract-interfaces.mdx index 5ac87e62..f2a2d21c 100644 --- a/features/policies/smart-contract-interfaces.mdx +++ b/features/policies/smart-contract-interfaces.mdx @@ -10,11 +10,12 @@ With the introduction of Turnkey's smart contract interface functionality, our p The following guide will walk you through uploading a specific ABI or IDL, and then crafting a policy that targets specific contract call arguments. -For an example usage flow, please navigate to the [Usage Walkthrough](#usage-walkthrough) section. +For an example usage flow, please navigate to the [Usage Walkthrough](#usage-walkthrough) section. ### Ethereum #### ABI format + Ethereum ABIs are represented in JSON format as an array of objects, each describing a function, constructor, event, or error. Each object contains specific fields that fully describe the callable interface or event signature. See [ABI documentation reference](https://docs.ethers.org/v5/api/utils/abi/formats/) for more. **Example ABI** @@ -65,6 +66,7 @@ Ethereum ABIs are represented in JSON format as an array of objects, each descri #### Policy formats For Ethereum, if an ABI corresponding to a contract has been uploaded, then ABI related policies for transactions calling that contract will be available under the following namespaces: + - **function_name**: This field contains the string representation of the name of the function as defined in the ABI - **function_signature**: This field contains the bytes making up the function signature - **contract_call_args**: This field contains all the arguments in a mapping of arg name to argument @@ -73,21 +75,21 @@ For Ethereum, if an ABI corresponding to a contract has been uploaded, then ABI ```json { - "condition": "eth.tx.contract_call_args['arg_name'] == 1" + "condition": "eth.tx.contract_call_args['arg_name'] == 1" } ``` ### Solana -For Turnkey's Solana IDL support, we accept IDLs formatted according to [Anchor's IDL language](https://www.anchor-lang.com/docs) standardization. While other standards do exist, most commonly used IDLs that aren't Solana's own native IDLs, adhere to the Anchor IDL format, and there exist tools like [native-to-anchor](https://github.com/acheroncrypto/native-to-anchor) which can help create anchor formatted IDLs for native solana programs. +For Turnkey's Solana IDL support, we accept IDLs formatted according to [Anchor's IDL language](https://www.anchor-lang.com/docs) standardization. While other standards do exist, most commonly used IDLs that aren't Solana's own native IDLs, adhere to the Anchor IDL format, and there exist tools like [native-to-anchor](https://github.com/acheroncrypto/native-to-anchor) which can help create anchor formatted IDLs for native solana programs. #### Turnkey formatting requirements -**NOTE**: this is just included for reference and troubleshooting, most Anchor IDLs should work straight out of the box. Also, some older formats of IDLs are supported (such as using the optional boolean `signer` instead of `isSigner`, or the optional boolean `writable` instead of `isMut`) – the format detailed below is the most widely used format, for reference. +**NOTE**: this is just included for reference and troubleshooting, most Anchor IDLs should work straight out of the box. Also, some older formats of IDLs are supported (such as using the optional boolean `signer` instead of `isSigner`, or the optional boolean `writable` instead of `isMut`) – the format detailed below is the most widely used format, for reference. **Instructions Array** -*The instructions array is a list of objects, each defining an instruction callable by the program.* +_The instructions array is a list of objects, each defining an instruction callable by the program._ - **instructions** (array of objects) - **name** (string): Name of the instruction. @@ -103,7 +105,7 @@ For Turnkey's Solana IDL support, we accept IDLs formatted according to [Anchor' **Types Array** -*The types array defines custom data structures used by the program.* +_The types array defines custom data structures used by the program._ - **types** (array of objects) - **name** (string): Name of the custom type. @@ -162,6 +164,7 @@ For Turnkey's Solana IDL support, we accept IDLs formatted according to [Anchor' Solana IDLs support various different types of arguments to instructions. The following argument types are supported for Solana IDL parsing and call data parsing. **IdlType** + - **Fixed arrays:** Array\ - **Booleans:** Bool - **Byte strings:** Bytes @@ -175,6 +178,7 @@ Solana IDLs support various different types of arguments to instructions. The fo - **Custom Defined Types:** DefinedType The most notable here are **Defined Types.** Defined types in IDLs refer to custom types—such as structs and enums—that are created by the Solana program developer and used as argument types in instructions or as fields in accounts. The following defined types are currently supported: + - Enum - Struct - Alias @@ -193,6 +197,7 @@ Solana IDL JSON objects, as formatted for use with Turnkey, can be obtained by t #### Policy formats On the Solana side, if an IDL corresponding to a program has been uploaded, then IDL related policies for instructions calling that program will be available in each instruction under the `parsed_instruction_data` namespace. The subfields will be as follows: + - **instruction_name:** Name of the instruction that is being called in call data - **discriminator:** the bytes at the beginning of the instruction call data that signifies which instruction is being called - **named_accounts:** a mapping of account names (as defined in the IDL) to the actual accounts that were entered to this instruction @@ -202,7 +207,7 @@ On the Solana side, if an IDL corresponding to a program has been uploaded, then ```json { - "condition": "solana.tx.instructions[0].parsed_instruction_data.program_call_args['arg_name'] == 1" + "condition": "solana.tx.instructions[0].parsed_instruction_data.program_call_args['arg_name'] == 1" } ``` @@ -213,9 +218,9 @@ Let's say that the IDL for Jupiter has been uploaded, as found [here](https://ex Here's an example policy related to its `route` instruction: ```json -{ - "effect": "EFFECT_ALLOW", - "condition": "solana.tx.instructions.any(i, i.program_key == 'JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4' && i.parsed_instruction_data.instruction_name == 'route' && i.parsed_instruction_data.program_call_args['in_amount'] == 995500000)" +{ + "effect": "EFFECT_ALLOW", + "condition": "solana.tx.instructions.any(i, i.program_key == 'JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4' && i.parsed_instruction_data.instruction_name == 'route' && i.parsed_instruction_data.program_call_args['in_amount'] == 995500000)" } ``` @@ -223,8 +228,160 @@ Here's an example policy related to its `route` instruction: Let's walk through an example flow of how to explicitly reference smart contract arguments in policies by uploading the ABI for the smart contract which you will be invoking in your transactions. Let's take the Wrapped ETH (WETH) smart contract as an example. Its ABI can be found [here](https://etherscan.io/address/0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2#code), and we've included the JSON down below: -```json -[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"guy","type":"address"},{"name":"wad","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"src","type":"address"},{"name":"dst","type":"address"},{"name":"wad","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"wad","type":"uint256"}],"name":"withdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"dst","type":"address"},{"name":"wad","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"deposit","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"name":"src","type":"address"},{"indexed":true,"name":"guy","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"src","type":"address"},{"indexed":true,"name":"dst","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"dst","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"src","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Withdrawal","type":"event"}] +```json +[ + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [{ "name": "", "type": "string" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { "name": "guy", "type": "address" }, + { "name": "wad", "type": "uint256" } + ], + "name": "approve", + "outputs": [{ "name": "", "type": "bool" }], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [{ "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { "name": "src", "type": "address" }, + { "name": "dst", "type": "address" }, + { "name": "wad", "type": "uint256" } + ], + "name": "transferFrom", + "outputs": [{ "name": "", "type": "bool" }], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [{ "name": "wad", "type": "uint256" }], + "name": "withdraw", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [{ "name": "", "type": "uint8" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [{ "name": "", "type": "address" }], + "name": "balanceOf", + "outputs": [{ "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [{ "name": "", "type": "string" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { "name": "dst", "type": "address" }, + { "name": "wad", "type": "uint256" } + ], + "name": "transfer", + "outputs": [{ "name": "", "type": "bool" }], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "deposit", + "outputs": [], + "payable": true, + "stateMutability": "payable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { "name": "", "type": "address" }, + { "name": "", "type": "address" } + ], + "name": "allowance", + "outputs": [{ "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { "payable": true, "stateMutability": "payable", "type": "fallback" }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "name": "src", "type": "address" }, + { "indexed": true, "name": "guy", "type": "address" }, + { "indexed": false, "name": "wad", "type": "uint256" } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "name": "src", "type": "address" }, + { "indexed": true, "name": "dst", "type": "address" }, + { "indexed": false, "name": "wad", "type": "uint256" } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "name": "dst", "type": "address" }, + { "indexed": false, "name": "wad", "type": "uint256" } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "name": "src", "type": "address" }, + { "indexed": false, "name": "wad", "type": "uint256" } + ], + "name": "Withdrawal", + "type": "event" + } +] ``` We'll first navigate to the Security tab of your [Turnkey dashboard](https://app.turnkey.com/dashboard/welcome): @@ -256,7 +413,7 @@ Upon clicking the Create interface button, you can enter in your Smart Contract Finally, you can confirm the details: -NOTE: It's important to make sure that the `Address` section of the smart contract interface creation is populated with the correct Address. It is case insensitive with Ethereum, but case sensitive with Solana. +NOTE: It's important to make sure that the `Address` section of the smart contract interface creation is populated with the correct Address. It is case insensitive with Ethereum, but case sensitive with Solana. \ No newline at end of file + diff --git a/features/transaction-management/sending-sponsored-solana-transactions.mdx b/features/transaction-management/sending-sponsored-solana-transactions.mdx index b64d4a1b..b9d73cfe 100644 --- a/features/transaction-management/sending-sponsored-solana-transactions.mdx +++ b/features/transaction-management/sending-sponsored-solana-transactions.mdx @@ -13,8 +13,8 @@ import SendSolanaTxSdkOverview from "/snippets/shared/send-solana-tx-sdk-overvie transaction may create accounts that require rent, ensure `Sponsor Solana Rent` has been enabled in the dashboard first. Review whether the unsigned transaction creates accounts, closes accounts, or routes rent refunds back to - the signer. See - [Solana Rent Sponsorship](/features/networks/solana-rent-refunds) for rent setup and + the signer. See [Solana Rent + Sponsorship](/features/networks/solana-rent-refunds) for rent setup and refund-path guidance, and [Solana transaction construction for sponsored flows](/features/networks/solana-transaction-construction) for payer-model and account-creation caveats. @@ -25,6 +25,7 @@ import SendSolanaTxSdkOverview from "/snippets/shared/send-solana-tx-sdk-overvie This handler wraps everything: intent creation, signing, Turnkey submission, polling, modal UX, and final success UI. ### Step 1 — configure the provider + ```tsx import { TurnkeyProvider } from "@turnkey/react-wallet-kit"; @@ -36,15 +37,12 @@ const turnkeyConfig = { }; export default function App({ children }) { - return ( - - {children} - - ); + return {children}; } ``` ### Step 2 — use `handleSendTransaction` for Solana + ```tsx const { handleSendTransaction, wallets } = useTurnkey(); @@ -67,6 +65,7 @@ await handleSendTransaction({ ``` This automatically: + - Opens the Turnkey modal - Shows the chain logo - Polls until `INCLUDED` @@ -75,6 +74,7 @@ This automatically: ## Checking gas usage You can configure gas limits for both sub-orgs and all orgs. We recommend checking sub-org gas usage against the limit on the client side so your application can handle edge cases when approaching or exceeding the gas limit. + ```tsx const resp = await httpClient?.getGasUsage({}); if (resp?.usageUsd! > resp?.windowLimitUsd!) { diff --git a/features/users/best-practices.mdx b/features/users/best-practices.mdx index f1368b3e..285d7e1e 100644 --- a/features/users/best-practices.mdx +++ b/features/users/best-practices.mdx @@ -6,7 +6,7 @@ description: "This page describes some best practices to consider as you set up ## Managing users **Enforce a security policy of least privilege for your users** - Users on Turnkey should have the minimum required privilege to accomplish their job. When setting up users, consider this for their access type and policies that will grant the user permissions. +Users on Turnkey should have the minimum required privilege to accomplish their job. When setting up users, consider this for their access type and policies that will grant the user permissions. **Use user tags to create groups of users with equal permissions** Referencing user tags in policies instead of individual users allows for clearer management of permissions. @@ -66,8 +66,8 @@ Within this principle of least privilege, Some actions should be treated more sensitively: -* Adding policies -* Signing transactions +- Adding policies +- Signing transactions **Use allowlisting if you only send to a set of addresses** diff --git a/features/users/credentials.mdx b/features/users/credentials.mdx index 20225c2b..96bbe9ae 100644 --- a/features/users/credentials.mdx +++ b/features/users/credentials.mdx @@ -9,22 +9,23 @@ sidebarTitle: "Credentials" **Authenticators** — WebAuthn devices registered on Turnkey: passkeys, biometrics, and hardware keys. Used to sign requests directly, using the [WebAuthn standard](https://www.w3.org/TR/webauthn-2/) (no passwords). **API keys** — P-256 key pairs used to sign API requests. Come in two forms: -- *Long-lived* — created via the dashboard, CLI, or [API](/api-reference/activities/create-api-keys). You generate the key pair; Turnkey stores the public key. -- *Expiring* — issued automatically when a user authenticates via email, SMS, OAuth, or wallet auth. Short-lived by default (15 minutes), with a configurable expiration window. + +- _Long-lived_ — created via the dashboard, CLI, or [API](/api-reference/activities/create-api-keys). You generate the key pair; Turnkey stores the public key. +- _Expiring_ — issued automatically when a user authenticates via email, SMS, OAuth, or wallet auth. Short-lived by default (15 minutes), with a configurable expiration window. ## Credential types Each issuance path produces a credential of a specific type, which Turnkey returns in API responses. You can retrieve the type and public key for any API key via [GetAPIKey](/api-reference/queries/get-api-key). -| Credential type | Issued by | -|---|---| -| `CREDENTIAL_TYPE_WEBAUTHN_AUTHENTICATOR` | [Passkeys](/features/authentication/passkeys/introduction) | -| `CREDENTIAL_TYPE_API_KEY_P256` | [Manually created API keys](/api-reference/activities/create-api-keys) | -| `CREDENTIAL_TYPE_OTP_AUTH_KEY_P256` | [Email OTP](/features/authentication/email) or [SMS](/features/authentication/sms) auth | -| `CREDENTIAL_TYPE_EMAIL_AUTH_KEY_P256` | [Email auth — credential bundle method](/features/authentication/email) (legacy) | -| `CREDENTIAL_TYPE_RECOVER_USER_KEY_P256` | [Email recovery](/features/authentication/email) (legacy) | -| `CREDENTIAL_TYPE_OAUTH_KEY_P256` | [Social logins](/features/authentication/social-logins) | -| `CREDENTIAL_TYPE_API_KEY_SECP256K1` | [Wallet auth — Ethereum/SECP256K1](/solutions/embedded-wallets/integration-guide/react/using-external-wallets/overview) | -| `CREDENTIAL_TYPE_API_KEY_ED25519` | [Wallet auth — Solana/ED25519](/solutions/embedded-wallets/integration-guide/react/using-external-wallets/overview) | -| `CREDENTIAL_TYPE_READ_WRITE_SESSION_KEY_P256` | [Read-write sessions](/api-reference/activities/create-read-write-session) | -| `CREDENTIAL_TYPE_LOGIN` | [IndexedDB auth](/sdks/javascript-browser#indexeddbclient) — OTP, passkey, or OAuth | +| Credential type | Issued by | +| --------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | +| `CREDENTIAL_TYPE_WEBAUTHN_AUTHENTICATOR` | [Passkeys](/features/authentication/passkeys/introduction) | +| `CREDENTIAL_TYPE_API_KEY_P256` | [Manually created API keys](/api-reference/activities/create-api-keys) | +| `CREDENTIAL_TYPE_OTP_AUTH_KEY_P256` | [Email OTP](/features/authentication/email) or [SMS](/features/authentication/sms) auth | +| `CREDENTIAL_TYPE_EMAIL_AUTH_KEY_P256` | [Email auth — credential bundle method](/features/authentication/email) (legacy) | +| `CREDENTIAL_TYPE_RECOVER_USER_KEY_P256` | [Email recovery](/features/authentication/email) (legacy) | +| `CREDENTIAL_TYPE_OAUTH_KEY_P256` | [Social logins](/features/authentication/social-logins) | +| `CREDENTIAL_TYPE_API_KEY_SECP256K1` | [Wallet auth — Ethereum/SECP256K1](/solutions/embedded-wallets/integration-guide/react/using-external-wallets/overview) | +| `CREDENTIAL_TYPE_API_KEY_ED25519` | [Wallet auth — Solana/ED25519](/solutions/embedded-wallets/integration-guide/react/using-external-wallets/overview) | +| `CREDENTIAL_TYPE_READ_WRITE_SESSION_KEY_P256` | [Read-write sessions](/api-reference/activities/create-read-write-session) | +| `CREDENTIAL_TYPE_LOGIN` | [IndexedDB auth](/sdks/javascript-browser#indexeddbclient) — OTP, passkey, or OAuth | diff --git a/features/users/introduction.mdx b/features/users/introduction.mdx index 822d198a..701e5d08 100644 --- a/features/users/introduction.mdx +++ b/features/users/introduction.mdx @@ -5,14 +5,14 @@ mode: wide sidebarTitle: "Overview" --- - These requests can be made either by making direct API calls or through the Turnkey Dashboard. Users must have at least one valid credential (one of API key, passkey), with upper limits on credentials defined here in our [resource limits](/reference/resource-limits). Users can also have associated “tags” which are logical groupings that can be referenced in policies. Users can only submit activities within their given organization — they cannot take action across organizations. +These requests can be made either by making direct API calls or through the Turnkey Dashboard. Users must have at least one valid credential (one of API key, passkey), with upper limits on credentials defined here in our [resource limits](/reference/resource-limits). Users can also have associated “tags” which are logical groupings that can be referenced in policies. Users can only submit activities within their given organization — they cannot take action across organizations. A User's attributes are: -* UUID: a globally unique ID (e.g. `fc6372d1-723d-4f7e-8554-dc3a212e4aec`), used as a unique identifier for a User in the context of Policies or User Tags, or Quorums. -* Name and email -* Authenticators: a list of authenticators (see below for information) -* API key: a list of API keys (see below for information) -* User tags: a list of User Tag UUIDs +- UUID: a globally unique ID (e.g. `fc6372d1-723d-4f7e-8554-dc3a212e4aec`), used as a unique identifier for a User in the context of Policies or User Tags, or Quorums. +- Name and email +- Authenticators: a list of authenticators (see below for information) +- API key: a list of API keys (see below for information) +- User tags: a list of User Tag UUIDs A **user belongs to one organization**, and one organization can have many (**up to 100**) users. If you need to create more users, consider using Sub-Organizations. diff --git a/features/users/root-quorum.mdx b/features/users/root-quorum.mdx index b482437c..6fa9edfb 100644 --- a/features/users/root-quorum.mdx +++ b/features/users/root-quorum.mdx @@ -9,8 +9,8 @@ The root quorum is a group of users who can execute any action and bypass the po The root quorum is defined by -* `userIds`: the Ids of users who compose the quorum set -* `threshold`: the number of quorum members required to execute an action as root +- `userIds`: the Ids of users who compose the quorum set +- `threshold`: the number of quorum members required to execute an action as root Actions approved by the root quorum do not go through the policy engine; thus it is impossible to limit root quorum actions with any policies. @@ -49,28 +49,28 @@ In other words, even if your organization enforces a root quorum with a threshol There are primarily two factors to consider when setting the root quorum -* how hard is it to get locked out of root? I.E. how many authenticators need to be lost/destroyed so the threshold cannot be met. -* how many authenticators need to be compromised for an attacker to take root actions? +- how hard is it to get locked out of root? I.E. how many authenticators need to be lost/destroyed so the threshold cannot be met. +- how many authenticators need to be compromised for an attacker to take root actions? For example, if a quorum is configured as 2/5, then -* if 4 users lost all their authenticators, no root actions could be taken (including updating the quorum itself). -* if 2 different users authenticators are compromised, an attacker could steal all the organizations funds. +- if 4 users lost all their authenticators, no root actions could be taken (including updating the quorum itself). +- if 2 different users authenticators are compromised, an attacker could steal all the organizations funds. **Example Setups** The below examples are provided as a convenience only. It is up to you to ensure that the root quorum setup you design is appropriate for your particular circumstances in order to secure your organization and minimize the risk of lockout of root functionality. Failure to properly configure your root quorum setup could result in complete loss of funds. -*High Value Organization* +_High Value Organization_ Special users should be created that are only used for root actions. Those users' authenticators should be stored in geographically distributed locations that have personal access controls, are natural disaster resistant, and have redundancy in case of hardware failure. These would only be used in the case of a disaster. For day to day admin operations, admin policies that use consensus can be put in place. These can be a set of finely scoped policies. -*Low Value, End-User Directed Organization* +_Low Value, End-User Directed Organization_ The end-user and the business both have one user in the organization. The root quorum would be configured as a 1/2, which includes the business and end-users' Users. This allows the business support channel to unbrick the user if they lose access to their account or otherwise add overly restrictive policies. ### Monitor for unintended use -Monitor your account for any unexpected activities coming from the root users. If you see an unexpected activity, you should remove any compromised authenticators or API keys. \ No newline at end of file +Monitor your account for any unexpected activities coming from the root users. If you see an unexpected activity, you should remove any compromised authenticators or API keys. diff --git a/features/verifiable-cloud/onboarding.mdx b/features/verifiable-cloud/onboarding.mdx index f12bbd24..84500082 100644 --- a/features/verifiable-cloud/onboarding.mdx +++ b/features/verifiable-cloud/onboarding.mdx @@ -24,25 +24,26 @@ Verify it comes up healthy, and confirm one or more endpoints respond correctly. ## Known platform limitations -| Limitation | Workaround | -| :-----------| :----------- | -| Deployment deletion not implemented | Ask our team on Slack, or simply kick-off another deploy. There can only be one live deployment at a time. Kicking off a new deployment automatically deletes any existing one | -| No metrics or logs in dashboard | Ask our team on Slack | -| No egress connectivity | Pass signed data as input to your API instead of fetching it from within the TEE | -| No custom provisioning | Use static provisioning for now. This feature is coming sometime in May. +| Limitation | Workaround | +| :---------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Deployment deletion not implemented | Ask our team on Slack, or simply kick-off another deploy. There can only be one live deployment at a time. Kicking off a new deployment automatically deletes any existing one | +| No metrics or logs in dashboard | Ask our team on Slack | +| No egress connectivity | Pass signed data as input to your API instead of fetching it from within the TEE | +| No custom provisioning | Use static provisioning for now. This feature is coming sometime in May. | ## Getting help Slack is the primary channel for async questions, debugging, and quick turnaround on deployment issues. Don't hesitate to use it – especially early on. What to ask for: -* Code snippet for reading the quorum key and signing within the TEE -* Help interpreting deployment config fields -* Assistance debugging a deployment that isn't coming up as expected -* Observability you'd want surfaced in the dashboard + +- Code snippet for reading the quorum key and signing within the TEE +- Help interpreting deployment config fields +- Assistance debugging a deployment that isn't coming up as expected +- Observability you'd want surfaced in the dashboard **Feedback welcome**: You are among the first developers building a brand-new app on this platform, end-to-end. Your experience with gaps, sharp edges, and missing features is genuinely valuable – please share it! ## Getting access to TVC -TVC is currently in private Beta. A select group of design partners are already building on it and getting exclusive access to the latest features and capabilities. If you're interested in being an early design partner, or if you want to be notified when TVC is generally available for all, please [join the waitlist](https://www.turnkey.com/turnkey-verifiable-cloud#waitlist). \ No newline at end of file +TVC is currently in private Beta. A select group of design partners are already building on it and getting exclusive access to the latest features and capabilities. If you're interested in being an early design partner, or if you want to be notified when TVC is generally available for all, please [join the waitlist](https://www.turnkey.com/turnkey-verifiable-cloud#waitlist). diff --git a/features/verifiable-cloud/overview.mdx b/features/verifiable-cloud/overview.mdx index 84493c53..f8f21294 100644 --- a/features/verifiable-cloud/overview.mdx +++ b/features/verifiable-cloud/overview.mdx @@ -12,10 +12,11 @@ To establish the foundations for our key management system, we went deep on buil This work, developed over 3+ years, is broadly applicable. Any team building at scale within Trusted Execution Environments will encounter the same challenges. TVC solves these problems transparently for the industry at large, within and outside of web3. A few of the hard problems solved by TVC: -* **Reproducible builds**: These are crucial to leverage remote attestations (see [this blog post](https://quorum.tkhq.xyz/posts/remote-attestations-useless-without-reproducible-builds/)). To support this, we bootstrapped [StageX](https://stagex.tools), an open-source distro focused on reproducibility. TVC works with StageX so reproducibility is handled for you. Learn more about it [here](https://quorum.tkhq.xyz/posts/reproducible-builds-made-easy-introducing-stagex/). -* **Packaging**: Packaging applications into EIF files is [easy on the surface](https://docs.aws.amazon.com/enclaves/latest/user/building-eif.html) but leaves application developers with load-bearing security decisions: which base OS do I use? How do I handle application upgrades? How do I persist state? Turnkey built [QuorumOS](https://github.com/tkhq/qos) to solve these problems in the context of our own key management platform. TVC is integrated with QOS to handle these problems for you. In TVC, you provide the binary application you'd like to run, and we take care of the rest. -* **Running at production scale**: Turnkey has invested years of engineering time to get this right. We are running enclaves with autoscaling to ensure your application can transparently scale up and down with traffic. We have automated provisioning and invented [key forwarding](https://github.com/tkhq/qos/blob/main/docs/key_forward.md) to ensure enclaves going down are automatically replaced and provisioned from already-running enclaves, Operators do not have to wake up in the middle of the night. -* **Verification tooling**: Turnkey is regularly audited by top security firms to guarantee verification procedures and the code implementing them remains secure and correct over time. + +- **Reproducible builds**: These are crucial to leverage remote attestations (see [this blog post](https://quorum.tkhq.xyz/posts/remote-attestations-useless-without-reproducible-builds/)). To support this, we bootstrapped [StageX](https://stagex.tools), an open-source distro focused on reproducibility. TVC works with StageX so reproducibility is handled for you. Learn more about it [here](https://quorum.tkhq.xyz/posts/reproducible-builds-made-easy-introducing-stagex/). +- **Packaging**: Packaging applications into EIF files is [easy on the surface](https://docs.aws.amazon.com/enclaves/latest/user/building-eif.html) but leaves application developers with load-bearing security decisions: which base OS do I use? How do I handle application upgrades? How do I persist state? Turnkey built [QuorumOS](https://github.com/tkhq/qos) to solve these problems in the context of our own key management platform. TVC is integrated with QOS to handle these problems for you. In TVC, you provide the binary application you'd like to run, and we take care of the rest. +- **Running at production scale**: Turnkey has invested years of engineering time to get this right. We are running enclaves with autoscaling to ensure your application can transparently scale up and down with traffic. We have automated provisioning and invented [key forwarding](https://github.com/tkhq/qos/blob/main/docs/key_forward.md) to ensure enclaves going down are automatically replaced and provisioned from already-running enclaves, Operators do not have to wake up in the middle of the night. +- **Verification tooling**: Turnkey is regularly audited by top security firms to guarantee verification procedures and the code implementing them remains secure and correct over time. TVC is the first TEE platform to offer autoscaling and strong security defaults. Your secure workloads run at scale, on the same infrastructure as Turnkey's own secure workloads. @@ -23,20 +24,20 @@ TVC is the first TEE platform to offer autoscaling and strong security defaults. Many different types of workloads can benefit from verifiability. Below is a list of use cases supported by TVC. -| Workload type | Advantages to verifiability | -| :-------------------------| :-------------------------------------------------------------------------------------------------- | -| Chain Abstraction | Trustworthy cosigners for cross-chain resource locks (e.g. [OneBalance](https://www.onebalance.io)) | -| Transaction Construction | Users know that the unsigned transaction bytes are legitimate. | -| Transaction Parsing | Provide accurate metadata about the effects of a transaction. This is critical for trusted wallet UX. See [VisualSign Parser](https://github.com/anchorageoss/visualsign-parser/). | -| Oracles | Leverage external data without the overhead of full decentralization, onchain or offchain. Replace economic incentives with verifiability. | -| Blockchain nodes | Allow for private balance lookups, verifiable mempool inclusion, and more. | -| Web2 data bridging | Import and use data from web2 providers (centralized exchange balances, credit scores, X follower counts) in decentralized computation | -| AI training & inference | Verifiable training to prove no hidden backdoors; guarantee user prompts remain private | -| Sequencers | Prove correct behavior and eliminate the need for challenge periods and economic incentives around them (e.g. [Base sequencer](https://github.com/base/base/tree/main/crates/proof/tee)) | -| Identity verification | Prove no identity is leaked as part of the verification process. | -| VPN nodes | Guarantees privacy by proving that forwarded traffic isn't logged anywhere. | -| Exchanges | Ensure no malicious behavior (frontrunning), and create verifiable order books. | -| PII processing | Prove that processing does not leak or misuse PII (Personally Identifiable Information). | +| Workload type | Advantages to verifiability | +| :----------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Chain Abstraction | Trustworthy cosigners for cross-chain resource locks (e.g. [OneBalance](https://www.onebalance.io)) | +| Transaction Construction | Users know that the unsigned transaction bytes are legitimate. | +| Transaction Parsing | Provide accurate metadata about the effects of a transaction. This is critical for trusted wallet UX. See [VisualSign Parser](https://github.com/anchorageoss/visualsign-parser/). | +| Oracles | Leverage external data without the overhead of full decentralization, onchain or offchain. Replace economic incentives with verifiability. | +| Blockchain nodes | Allow for private balance lookups, verifiable mempool inclusion, and more. | +| Web2 data bridging | Import and use data from web2 providers (centralized exchange balances, credit scores, X follower counts) in decentralized computation | +| AI training & inference | Verifiable training to prove no hidden backdoors; guarantee user prompts remain private | +| Sequencers | Prove correct behavior and eliminate the need for challenge periods and economic incentives around them (e.g. [Base sequencer](https://github.com/base/base/tree/main/crates/proof/tee)) | +| Identity verification | Prove no identity is leaked as part of the verification process. | +| VPN nodes | Guarantees privacy by proving that forwarded traffic isn't logged anywhere. | +| Exchanges | Ensure no malicious behavior (frontrunning), and create verifiable order books. | +| PII processing | Prove that processing does not leak or misuse PII (Personally Identifiable Information). | These are just a subset of possible use cases. Any computation where two parties need to agree on what was executed can benefit from or require verifiability. @@ -45,8 +46,9 @@ These are just a subset of possible use cases. Any computation where two parties We’ve engineered TVC to fit within the existing Turnkey products and APIs. You will interact with TVC via our [dashboard](https://app.turnkey.com/), via the [TVC CLI](https://github.com/tkhq/rust-sdk/tree/main/tvc), or programmatically via [APIs](/api-reference/overview/intro). TVC provides a secure harness ([QuorumOS](https://github.com/tkhq/qos)) to verifiably run a **single program**. This program is also called "binary", "executable" or sometimes "pivot", and contains the secure workload to execute in TEEs. TVC relies on [OCI container images](https://github.com/opencontainers/image-spec) to transport this executable program from where it's built (typically, Github Action, or other CI platforms) to within TVC. This has several advantages: -* OCI containers can be hosted on many container image registries. These registries ensure integrity of the images, and clients can "pin" an image to ensure that they download the image they expect. Typically a container image URL will look like `registry.com/org/repo:some-tag@sha256:digest`. -* Registries also support authentication, which means TVC supports private image registries. Our infrastructure is Kubernetes-based: we support [Pull Secrets](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/) generically to allow for maximum flexibility: [Docker Hub](https://hub.docker.com/), [ECR](https://aws.amazon.com/ecr/), [GHCR](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry), [ACR](https://azure.microsoft.com/en-us/products/container-registry), [GAR](https://docs.cloud.google.com/artifact-registry/docs) are all supported. + +- OCI containers can be hosted on many container image registries. These registries ensure integrity of the images, and clients can "pin" an image to ensure that they download the image they expect. Typically a container image URL will look like `registry.com/org/repo:some-tag@sha256:digest`. +- Registries also support authentication, which means TVC supports private image registries. Our infrastructure is Kubernetes-based: we support [Pull Secrets](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/) generically to allow for maximum flexibility: [Docker Hub](https://hub.docker.com/), [ECR](https://aws.amazon.com/ecr/), [GHCR](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry), [ACR](https://azure.microsoft.com/en-us/products/container-registry), [GAR](https://docs.cloud.google.com/artifact-registry/docs) are all supported. Once the container image details and other configuration (ports, protocol, program path, arguments, etc) are received, a QOS manifest is generated. The QOS manifest has to be cryptographically approved by operator(s) before TVC infrastructure can proceed with the deployment. @@ -59,9 +61,10 @@ Read more about Applications, Deployments, Manifests, and Operators in the follo ## Applications TVC is programmable infrastructure, enabling you to create and manage verifiable apps. Each TVC App is deployed on Turnkey infrastructure in the exact same way as Turnkey's own [core enclave apps](https://github.com/tkhq/core-enclaves). -* TVC Applications are deployed within Kubernetes clusters operated by Turnkey, using [QuorumOS](https://github.com/tkhq/qos) ("QOS") as a base OS. -* Key provisioning, high-availability deployments (minimum of 3 replicas), and in-depth verification workflows are supported by default. -* Because TVC relies on Turnkey for its own operations, it's possible to use Consensus in the context of TVC activities (with [Turnkey Policies](/features/policies/overview) or [Root Quorum](/features/users/root-quorum)) + +- TVC Applications are deployed within Kubernetes clusters operated by Turnkey, using [QuorumOS](https://github.com/tkhq/qos) ("QOS") as a base OS. +- Key provisioning, high-availability deployments (minimum of 3 replicas), and in-depth verification workflows are supported by default. +- Because TVC relies on Turnkey for its own operations, it's possible to use Consensus in the context of TVC activities (with [Turnkey Policies](/features/policies/overview) or [Root Quorum](/features/users/root-quorum)) A TVC Application has a stable [Quorum Key](https://github.com/tkhq/qos#quorum-key) and set of approvers. @@ -69,21 +72,21 @@ A TVC Application has a stable [Quorum Key](https://github.com/tkhq/qos#quorum-k Each TVC application can be deployed many times. For every TVC deployment, you will specify: -* An OCI image URL (e.g. `ghcr.io/myorg/myrepo:tag@sha256:…`). This container is pulled by our Kubernetes infrastructure. If the container is private, TVC supports uploading encrypted [pull secrets](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/). -* An executable path + args: within the container, you must indicate where the desired binary lives such that Turnkey’s infrastructure can extract this binary from its OCI container, and run it within a TEE on your behalf. -* The port on which external requests should be forwarded. This is typically port 3000. For convenience TVC lets you specify different ports for user requests and health requests made by Turnkey infrastructure. -* Your expected executable digest: this is a security measure, to ensure the binary pulled by Turnkey's infrastructure is the binary you expect. +- An OCI image URL (e.g. `ghcr.io/myorg/myrepo:tag@sha256:…`). This container is pulled by our Kubernetes infrastructure. If the container is private, TVC supports uploading encrypted [pull secrets](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/). +- An executable path + args: within the container, you must indicate where the desired binary lives such that Turnkey’s infrastructure can extract this binary from its OCI container, and run it within a TEE on your behalf. +- The port on which external requests should be forwarded. This is typically port 3000. For convenience TVC lets you specify different ports for user requests and health requests made by Turnkey infrastructure. +- Your expected executable digest: this is a security measure, to ensure the binary pulled by Turnkey's infrastructure is the binary you expect. Once the deployment is submitted and approved, our infrastructure deploys and makes it available on a dedicated subdomain. -| Resource | Default Allocation | -| :-----------| :----------- | -| vCPUs | 2 | -| RAM | 1 GiB | -| Filesystem | RAM-based (no persistence) | -| Replicas | 3 | -| Ingress | Load-balanced across all replicas | -| Sub-domain | Automated (`.turnkey.cloud`) | +| Resource | Default Allocation | +| :--------- | :--------------------------------- | +| vCPUs | 2 | +| RAM | 1 GiB | +| Filesystem | RAM-based (no persistence) | +| Replicas | 3 | +| Ingress | Load-balanced across all replicas | +| Sub-domain | Automated (`.turnkey.cloud`) | ## Manifests @@ -101,8 +104,8 @@ QuorumOS uses operators to cryptographically control deployments: operators must Your TVC app has access to two keys when it boots: -* **Ephemeral Key**: a key which is created at boot. This key **never leaves the enclave** and is different for every enclave. A signature by this key is a signature bound to a particular enclave, hence bound to a particular **code version** of your TVC application. -* **Quorum Key**: a key which is injected at boot and is the same across all enclaves. This key can be used to encrypt state which needs to survive application upgrades. Internally at Turnkey we use this key to sign or encrypt long-lived data. +- **Ephemeral Key**: a key which is created at boot. This key **never leaves the enclave** and is different for every enclave. A signature by this key is a signature bound to a particular enclave, hence bound to a particular **code version** of your TVC application. +- **Quorum Key**: a key which is injected at boot and is the same across all enclaves. This key can be used to encrypt state which needs to survive application upgrades. Internally at Turnkey we use this key to sign or encrypt long-lived data. Both of these keys follow the [QOS Key Set](https://github.com/tkhq/qos/blob/main/src/qos_p256/SPEC.md) specification. Ephemeral Keys and Quorum Keys can be used to sign data, or to encrypt/decrypt data. @@ -113,11 +116,12 @@ Together, App Proofs and Boot Proofs can be used to verify workloads end-to-end. ## Pricing TVC pricing has two components: -* A fixed per-month platform fee. -* Variable pricing based on wall-clock enclave uptime + +- A fixed per-month platform fee. +- Variable pricing based on wall-clock enclave uptime [Get in touch with us](https://www.turnkey.com/turnkey-verifiable-cloud#waitlist) for more details. ## Getting access to TVC -TVC is currently in private Beta. A select group of design partners are already building on it and getting exclusive access to the latest features and capabilities. If you're interested in being an early design partner, or if you want to be notified when TVC is generally available for all, please [join the waitlist](https://www.turnkey.com/turnkey-verifiable-cloud#waitlist). \ No newline at end of file +TVC is currently in private Beta. A select group of design partners are already building on it and getting exclusive access to the latest features and capabilities. If you're interested in being an early design partner, or if you want to be notified when TVC is generally available for all, please [join the waitlist](https://www.turnkey.com/turnkey-verifiable-cloud#waitlist). diff --git a/features/verifiable-cloud/quickstart.mdx b/features/verifiable-cloud/quickstart.mdx index 041f3ffb..2bfc8359 100644 --- a/features/verifiable-cloud/quickstart.mdx +++ b/features/verifiable-cloud/quickstart.mdx @@ -6,12 +6,13 @@ tag: "Beta" --- -Turnkey Verifiable Cloud is currently in Private Beta. Join the waitlist [here](https://www.turnkey.com/turnkey-verifiable-cloud#waitlist). + Turnkey Verifiable Cloud is currently in Private Beta. Join the waitlist + [here](https://www.turnkey.com/turnkey-verifiable-cloud#waitlist). ## Prerequisites -This guide assumes you've been enabled for Turnkey Verifiable Cloud, and you've completed the steps to create an account and an organization +This guide assumes you've been enabled for Turnkey Verifiable Cloud, and you've completed the steps to create an account and an organization as described in the [account setup](/get-started/quickstart) section. ⚠️ To be enabled for TVC you will need to get in touch with our team (via Slack, typically) and tell us your new organization ID. @@ -49,14 +50,13 @@ The public key will be used in the following steps. Visit the [TVC dashboard](https://app.turnkey.com/dashboard/tvc) and click on "Create app". - ![Create app button on the TVC dashboard](/assets/files/tvc_create-app-dashboard.png) + ![Create app button on the TVC + dashboard](/assets/files/tvc_create-app-dashboard.png) A modal should appear: - - ![Create app modal](/assets/files/tvc_create-app-modal.png) - +![Create app modal](/assets/files/tvc_create-app-modal.png) Name your app something identifiable; for this demo it can be `"TVC Hello World"`. Paste in your operator public key from the TVC CLI login step, then click "Create new TVC App" to create your app. @@ -96,8 +96,9 @@ Your manifest set is currently just the public key generated during login; give it an easy to remember name, such as `"TVC Manifest"`. -The CLI has also automatically populated this template with a known quorum key, which is sufficient for -running verifiable code but not advised for encrypting sensitive data. + The CLI has also automatically populated this template with a known quorum + key, which is sufficient for running verifiable code but not advised for + encrypting sensitive data. Create your app in TVC by running @@ -108,15 +109,20 @@ tvc app create my-app-template.json This creates your app, and saves its quorum key and manifest settings to the Turnkey Verifiable Cloud platform. Check out your new app on the [TVC dashboard](https://app.turnkey.com/dashboard/tvc). + Once your app is created, click into it on the [dashboard](https://app.turnkey.com/dashboard/tvc). Click on "Create deployment" -to start a new deployment for your app. +to start a new deployment for your app. -Create deployment button +Create deployment button This should open a modal with all your deployment settings: @@ -125,6 +131,7 @@ This should open a modal with all your deployment settings: If you do not have your own app, try our helloworld template: + - **Container Image URL**: `ghcr.io/tkhq/helloworld:latest@sha256:c9c18f78b05d29ebfc2c60ab7143df4b0a808765a34d6a88bbf99523f473cafd` - If you are bringing private container images, TVC supports uploading pull secrets by encrypting them to a known public key. This will be used by TVC infrastructure to access your container images. Read more about pull secrets [here](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/). - **Executable Path**: `/tvc_app` @@ -133,6 +140,7 @@ If you do not have your own app, try our helloworld template: - **Health check port**: `3000`. Our `tvc_app` binary answers healthchecks on `/health` on the same port (3000) - **Health check type**: `HTTP`. - **Executable digest**: the hash of the binary file inside the container. For our helloworld example this should be `cbe01169428f144086bfaef348bbf3db70f9217628996cafd2ecb85d5f2b47a1`. You can compute it locally with: + ``` # Pull the container image, create a "tmp-extract" container, and extract our helloworld binary docker create --name tmp-extract ghcr.io/tkhq/helloworld@sha256:c9c18f78b05d29ebfc2c60ab7143df4b0a808765a34d6a88bbf99523f473cafd /bin/true \ @@ -143,11 +151,11 @@ If you do not have your own app, try our helloworld template: sha256sum ./tvc_app cbe01169428f144086bfaef348bbf3db70f9217628996cafd2ecb85d5f2b47a1 ``` + This digest will be to ensure TVC is running the code you expect. When ready, click "Deploy TVC App"! - Start with this local-only step, which generates a deployment template: @@ -159,13 +167,13 @@ The generated JSON file is named by its time of creation, but you can name it an a name after the `--output` flag. Open it and fill in each field: - `appId` is populated with the last app you created. You may edit it to be the id of any app you've created in the past. -- `pivotContainerImageUrl`: link to a public image. For this demo, feel free to use +- `pivotContainerImageUrl`: link to a public image. For this demo, feel free to use ```json "ghcr.io/tkhq/helloworld@sha256:c9c18f78b05d29ebfc2c60ab7143df4b0a808765a34d6a88bbf99523f473cafd" ``` - `pivotPath`: location of your binary in the container. Use `"/tvc_app"` for the demo app. - `pivotArgs`: leave this empty unless you have arguments to pass to your application -- `expectedPivotDigest`: for the demo, use +- `expectedPivotDigest`: for the demo, use ```json "cbe01169428f144086bfaef348bbf3db70f9217628996cafd2ecb85d5f2b47a1" ``` @@ -175,6 +183,7 @@ a name after the `--output` flag. Open it and fill in each field: - `healthCheckType`: `TVC_HEALTH_CHECK_TYPE_HTTP` For an arbitrary app, compute the expected digest with + ```bash docker create --name tmp-extract /bin/true \ && docker cp tmp-extract:/path/to/binary ./binary \ @@ -190,6 +199,7 @@ tvc deploy create deploy-YYYY-MM-DD.json [--pull-secret .js ``` Find the newly created deployment by clicking into your app on the [TVC dashboard](https://app.turnkey.com/dashboard/tvc). + @@ -199,7 +209,11 @@ Find the newly created deployment by clicking into your app on the [TVC dashboar By design, your deployment is not live yet. TVC requires approvals by the manifest set to fully deploy your application. Your app should be at the `Approve` stage on the dashboard: -Approve stage on the dashboard +Approve stage on the dashboard For this demo app, your manifest set is the public key you created at login. To approve your deployment, use the TVC CLI: @@ -210,14 +224,23 @@ tvc deploy approve \ ``` You may find your operator ID by clicking into your app, then under **Manifest Operators**: -Manifest Operators in app page + +Manifest Operators in app page This command generates an approval from the public keys created in step 1. If you didn't change anything during the demo, that should be the only required approval from your manifest set. In the dashboard you will see the "stage" transition to "LIVE". This means everything is done on your side. You can look at the deployment details in the recap table on on the individual deployment page to know whether your deployment is coming up healthy and whether it's receiving traffic. -Deployment details when LIVE +Deployment details when LIVE Our infrastructure automatically provisions network ingress for your application. You can visit `https://app-.turnkey.cloud` to interact with it. If you used our `helloworld` template, try visiting `/time` in your browser! @@ -230,5 +253,5 @@ Once the deployment is approved, your app can serve traffic and produce App Proo signatures that prove TVC is running the correct, expected software on a legitimate AWS Nitro Enclave. Learn more about app proofs in [our documentation](/security/turnkey-verified#app-proofs). -If you are not yet signed up for Turnkey Verifiable Cloud, join the waitlist +If you are not yet signed up for Turnkey Verifiable Cloud, join the waitlist [here](https://www.turnkey.com/turnkey-verifiable-cloud#waitlist)! diff --git a/features/wallets/aa-wallets.mdx b/features/wallets/aa-wallets.mdx index 6d5a5e58..01dc52c8 100644 --- a/features/wallets/aa-wallets.mdx +++ b/features/wallets/aa-wallets.mdx @@ -4,7 +4,10 @@ description: "Turnkey offers flexible infrastructure to create and manage keys. --- - For gas sponsorship without third-party AA providers, Turnkey's native Transaction Management supports sponsored transactions for EVM and Solana directly. See [Transaction Management](/features/transaction-management) to get started without an AA stack. + For gas sponsorship without third-party AA providers, Turnkey's native + Transaction Management supports sponsored transactions for EVM and Solana + directly. See [Transaction Management](/features/transaction-management) to + get started without an AA stack. ## Alchemy's account kit diff --git a/features/wallets/claim-links.mdx b/features/wallets/claim-links.mdx index 1767c0da..dfbb2dd0 100644 --- a/features/wallets/claim-links.mdx +++ b/features/wallets/claim-links.mdx @@ -28,7 +28,7 @@ When an existing user (the “Sender”) wants to send funds to someone new, her - This sub-org acts as the escrow environment. It will:  + This sub-org acts as the escrow environment. It will: - Contain a new “escrow” wallet  - Contain a root user with two authenticators:  diff --git a/features/webhooks/overview.mdx b/features/webhooks/overview.mdx index 44c763de..c7816b50 100644 --- a/features/webhooks/overview.mdx +++ b/features/webhooks/overview.mdx @@ -14,12 +14,12 @@ Webhooks deliver real-time notifications as signed HTTPS POST requests. Register ## Event types -| Event type | Description | Scope | -|---|---|---| -| `ACTIVITY_UPDATES` | Sends activity status updates. Parent-owned endpoints receive events for the parent and all sub-organizations; sub-organization-owned endpoints receive only their own events. | Organization-scoped | -| `BALANCE_CONFIRMED_UPDATES` | Sends confirmed balance update events when a transaction containing a balance change is first seen in a block onchain. | Billing organization scoped | -| `BALANCE_FINALIZED_UPDATES` | Sends finalized balance update events when the containing block has reached the finalization threshold. Add this alongside `BALANCE_CONFIRMED_UPDATES` if you need finalization signals. | Billing organization scoped | -| `SEND_TRANSACTION_STATUS_UPDATES` | Sends transaction status updates when a transaction changes state (e.g. from `BROADCASTING` to `INCLUDED` or `FAILED`). | Billing organization scoped | +| Event type | Description | Scope | +| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | +| `ACTIVITY_UPDATES` | Sends activity status updates. Parent-owned endpoints receive events for the parent and all sub-organizations; sub-organization-owned endpoints receive only their own events. | Organization-scoped | +| `BALANCE_CONFIRMED_UPDATES` | Sends confirmed balance update events when a transaction containing a balance change is first seen in a block onchain. | Billing organization scoped | +| `BALANCE_FINALIZED_UPDATES` | Sends finalized balance update events when the containing block has reached the finalization threshold. Add this alongside `BALANCE_CONFIRMED_UPDATES` if you need finalization signals. | Billing organization scoped | +| `SEND_TRANSACTION_STATUS_UPDATES` | Sends transaction status updates when a transaction changes state (e.g. from `BROADCASTING` to `INCLUDED` or `FAILED`). | Billing organization scoped | Balance and transaction status webhook endpoints must be managed from the billing organization. Sub-organization attempts to create, update, or delete these endpoints return `PermissionDenied`. @@ -27,6 +27,7 @@ Balance and transaction status webhook endpoints must be managed from the billin Only documented event types produce deliveries. Unknown event types should not be used and may be rejected in the future. For further information on balances, including supported chains and assets, see [Balances](/features/transaction-management/balances). + ## Create an endpoint @@ -75,19 +76,21 @@ const balanceWebhook = await turnkey.apiClient().createWebhookEndpoint({ ``` -The `name` field is a human-readable endpoint name and should be non-empty. Event types must be passed in `subscriptions[]`; do not pass a top-level `eventTypes` field. + The `name` field is a human-readable endpoint name and should be non-empty. + Event types must be passed in `subscriptions[]`; do not pass a top-level + `eventTypes` field. ## Manage endpoints Use the webhook endpoint APIs or the Dashboard UI to manage existing endpoints: -| Operation | Path | Notes | -|---|---|---| +| Operation | Path | Notes | +| -------------------------------------------------------------------- | ------------------------------------------- | ----------------------------------------------------------------- | | [Create endpoint](/api-reference/activities/create-webhook-endpoint) | `/public/v1/submit/create_webhook_endpoint` | Requires `url` and `subscriptions[]`; `name` should be non-empty. | -| [Update endpoint](/api-reference/activities/update-webhook-endpoint) | `/public/v1/submit/update_webhook_endpoint` | Updates `url`, `name`, or `isActive`. | -| [Delete endpoint](/api-reference/activities/delete-webhook-endpoint) | `/public/v1/submit/delete_webhook_endpoint` | Deletes an endpoint and its subscriptions. | -| [List endpoints](/api-reference/queries/list-webhook-endpoints) | `/public/v1/query/list_webhook_endpoints` | Returns endpoints and their subscriptions for an organization. | +| [Update endpoint](/api-reference/activities/update-webhook-endpoint) | `/public/v1/submit/update_webhook_endpoint` | Updates `url`, `name`, or `isActive`. | +| [Delete endpoint](/api-reference/activities/delete-webhook-endpoint) | `/public/v1/submit/delete_webhook_endpoint` | Deletes an endpoint and its subscriptions. | +| [List endpoints](/api-reference/queries/list-webhook-endpoints) | `/public/v1/query/list_webhook_endpoints` | Returns endpoints and their subscriptions for an organization. | Set `isActive` to `false` to pause delivery without deleting the endpoint. @@ -105,17 +108,17 @@ Turnkey sends each webhook as an HTTPS `POST` request. The request body is JSON ### Headers -| Header | Description | -|---|---| -| `X-Turnkey-Organization-Id` | Organization used for webhook routing and delivery. For billing-scoped events such as balance and transaction status updates, this is the billing/parent organization. The event owner is available in the payload `organizationId`. | -| `X-Turnkey-Event-Type` | Event type, such as `ACTIVITY_UPDATES` or `BALANCE_CONFIRMED_UPDATES`. | -| `X-Turnkey-Timestamp` | Unix timestamp in milliseconds for the delivery attempt. | -| `X-Turnkey-Webhook-Version` | Webhook delivery contract version. The current value is `1`. | -| `X-Turnkey-Event-Id` | Signed delivery metadata. This value is stable across retry attempts for the same webhook event. | -| `X-Turnkey-Signature-Key-Id` | Identifier for the Turnkey signing key. | -| `X-Turnkey-Signature-Algorithm` | Signature algorithm. The current value is `ed25519`. | -| `X-Turnkey-Signature-Version` | Signature contract version. The current value is `v1`. | -| `X-Turnkey-Signature` | Hex-encoded Ed25519 signature. | +| Header | Description | +| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `X-Turnkey-Organization-Id` | Organization used for webhook routing and delivery. For billing-scoped events such as balance and transaction status updates, this is the billing/parent organization. The event owner is available in the payload `organizationId`. | +| `X-Turnkey-Event-Type` | Event type, such as `ACTIVITY_UPDATES` or `BALANCE_CONFIRMED_UPDATES`. | +| `X-Turnkey-Timestamp` | Unix timestamp in milliseconds for the delivery attempt. | +| `X-Turnkey-Webhook-Version` | Webhook delivery contract version. The current value is `1`. | +| `X-Turnkey-Event-Id` | Signed delivery metadata. This value is stable across retry attempts for the same webhook event. | +| `X-Turnkey-Signature-Key-Id` | Identifier for the Turnkey signing key. | +| `X-Turnkey-Signature-Algorithm` | Signature algorithm. The current value is `ed25519`. | +| `X-Turnkey-Signature-Version` | Signature contract version. The current value is `v1`. | +| `X-Turnkey-Signature` | Hex-encoded Ed25519 signature. | ### Retry behavior @@ -140,7 +143,8 @@ Signature verification signs only the signature contract fields shown above plus To verify a delivery, reconstruct the signed message from the headers and raw body, then verify the Ed25519 signature against the signing key identified by `X-Turnkey-Signature-Key-Id`. Ensure the timestamp is within an acceptable freshness window (e.g. 5 minutes) to guard against replay attacks. -An SDK verification helper and a key discovery endpoint are releasing soon to simplify this process. + An SDK verification helper and a key discovery endpoint are releasing soon to + simplify this process. ## Payloads @@ -182,21 +186,23 @@ The `type` field is `"balances:confirmed"` when a balance change is first seen o } ``` -| Field | Description | -|---|---| -| `type` | `"balances:confirmed"` when first seen onchain, or `"balances:finalized"` when the block has reached the finalization threshold. | -| `organizationId` | Organization that owns the address. | -| `parentOrganizationId` | Billing/parent organization that owns webhook configuration and delivery. | -| `msg.operation` | Either `"deposit"` (incoming) or `"withdraw"` (outgoing). | -| `msg.caip2` | The chain identifier where the event occurred. | -| `msg.txHash` | The transaction hash that triggered the balance change. | -| `msg.address` | The address whose balance changed. | -| `msg.idempotencyKey` | A stable, unique key for this event. Use this to safely deduplicate webhook deliveries. | -| `msg.asset` | Asset metadata: symbol, name, decimals, CAIP-19 identifier, and the amount transferred (in the asset's smallest unit). | -| `msg.block` | Block number, hash, and timestamp of the block in which the transaction was first seen. | +| Field | Description | +| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------- | +| `type` | `"balances:confirmed"` when first seen onchain, or `"balances:finalized"` when the block has reached the finalization threshold. | +| `organizationId` | Organization that owns the address. | +| `parentOrganizationId` | Billing/parent organization that owns webhook configuration and delivery. | +| `msg.operation` | Either `"deposit"` (incoming) or `"withdraw"` (outgoing). | +| `msg.caip2` | The chain identifier where the event occurred. | +| `msg.txHash` | The transaction hash that triggered the balance change. | +| `msg.address` | The address whose balance changed. | +| `msg.idempotencyKey` | A stable, unique key for this event. Use this to safely deduplicate webhook deliveries. | +| `msg.asset` | Asset metadata: symbol, name, decimals, CAIP-19 identifier, and the amount transferred (in the asset's smallest unit). | +| `msg.block` | Block number, hash, and timestamp of the block in which the transaction was first seen. | -Balance webhooks fire only for assets in the [supported asset list](/api-reference/queries/list-supported-assets) and are not supported for private key addresses. + Balance webhooks fire only for assets in the [supported asset + list](/api-reference/queries/list-supported-assets) and are not supported for + private key addresses. ### Transaction status updates @@ -224,19 +230,19 @@ Each delivery fires when a transaction changes state. The `type` is always `"tra } ``` -| Field | Description | -|---|---| -| `type` | Always `"transaction:status"`. | -| `organizationId` | Organization that initiated the transaction. | -| `parentOrganizationId` | Billing/parent organization that owns webhook configuration and delivery. | -| `msg.sendTransactionStatusId` | The ID of the send transaction status record. | -| `msg.activityId` | The ID of the originating Turnkey activity. | -| `msg.status` | One of `BROADCASTING`, `INCLUDED`, or `FAILED`. | -| `msg.caip2` | The chain identifier where the transaction was sent. | -| `msg.idempotencyKey` | A stable, unique key for this status event. Use this to safely deduplicate webhook deliveries. | -| `msg.timestamp` | Unix timestamp (seconds) when the notification was generated. | -| `msg.txHash` | _(INCLUDED only)_ The onchain transaction hash or Solana signature. | -| `msg.error` | Structured error object. Contains `message`, and either `eth.revertChain` (EVM) or `solana` (Solana) details. | +| Field | Description | +| ----------------------------- | ------------------------------------------------------------------------------------------------------------- | +| `type` | Always `"transaction:status"`. | +| `organizationId` | Organization that initiated the transaction. | +| `parentOrganizationId` | Billing/parent organization that owns webhook configuration and delivery. | +| `msg.sendTransactionStatusId` | The ID of the send transaction status record. | +| `msg.activityId` | The ID of the originating Turnkey activity. | +| `msg.status` | One of `BROADCASTING`, `INCLUDED`, or `FAILED`. | +| `msg.caip2` | The chain identifier where the transaction was sent. | +| `msg.idempotencyKey` | A stable, unique key for this status event. Use this to safely deduplicate webhook deliveries. | +| `msg.timestamp` | Unix timestamp (seconds) when the notification was generated. | +| `msg.txHash` | _(INCLUDED only)_ The onchain transaction hash or Solana signature. | +| `msg.error` | Structured error object. Contains `message`, and either `eth.revertChain` (EVM) or `solana` (Solana) details. | For more details on transaction broadcasting, see [Broadcasting](/features/transaction-management/broadcasting). @@ -254,11 +260,11 @@ Read operations, such as listing webhook endpoints, use standard authenticated q ## Troubleshooting -| Symptom | What to check | -|---|---| -| `createWebhookEndpoint` is unavailable in your SDK | Upgrade to a webhooks-capable SDK release. The minimum SDK version will be listed in the SDK changelog once published. | -| `PermissionDenied` on create/update/delete | Confirm the user has an allow policy for the webhook activity type, and confirm balance webhooks are being managed from the billing organization. | -| Empty or unclear endpoint names | Set `parameters.name` to a non-empty, human-readable name. | -| Subscription shape errors | Pass event types inside `parameters.subscriptions[]`, not as top-level `eventTypes`. | -| Invalid webhook URL errors | Use an HTTPS URL that resolves to a public destination. Localhost, private IPs, link-local addresses, metadata endpoints, and URLs with user info are rejected. | -| Signature verification fails | Verify against the exact raw request body bytes, use the millisecond timestamp and event id from the headers, check clock skew, and select the public key matching the signature key id. | +| Symptom | What to check | +| -------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `createWebhookEndpoint` is unavailable in your SDK | Upgrade to a webhooks-capable SDK release. The minimum SDK version will be listed in the SDK changelog once published. | +| `PermissionDenied` on create/update/delete | Confirm the user has an allow policy for the webhook activity type, and confirm balance webhooks are being managed from the billing organization. | +| Empty or unclear endpoint names | Set `parameters.name` to a non-empty, human-readable name. | +| Subscription shape errors | Pass event types inside `parameters.subscriptions[]`, not as top-level `eventTypes`. | +| Invalid webhook URL errors | Use an HTTPS URL that resolves to a public destination. Localhost, private IPs, link-local addresses, metadata endpoints, and URLs with user info are rejected. | +| Signature verification fails | Verify against the exact raw request body bytes, use the millisecond timestamp and event id from the headers, check clock skew, and select the public key matching the signature key id. | diff --git a/ga.js b/ga.js index 2412517a..01db3ce1 100644 --- a/ga.js +++ b/ga.js @@ -13,25 +13,25 @@ e.reduce(function (r, n) { return ( (r[n] = function () { - return o.push([n, [].slice.call(arguments)]), o; + return (o.push([n, [].slice.call(arguments)]), o); }), r ); - }, {}) + }, {}), ); } - window.unify || (window.unify = t(window.unify)), - window.unifyBrowser || (window.unifyBrowser = t(window.unifyBrowser)); + (window.unify || (window.unify = t(window.unify)), + window.unifyBrowser || (window.unifyBrowser = t(window.unifyBrowser))); var n = document.createElement("script"); - (n.async = !0), + ((n.async = !0), n.setAttribute( "src", - "https://tag.unifyintent.com/v1/7Kk92osLC7vgqrstznftZA/script.js" + "https://tag.unifyintent.com/v1/7Kk92osLC7vgqrstznftZA/script.js", ), n.setAttribute( "data-api-key", - "wk_gHe63XaT_7Ayfg866Ci5SHWgeNTkqUjxYGdKDUfT7" + "wk_gHe63XaT_7Ayfg866Ci5SHWgeNTkqUjxYGdKDUfT7", ), n.setAttribute("id", "unifytag"), - (document.body || document.head).appendChild(n); + (document.body || document.head).appendChild(n)); })(); diff --git a/get-started/about-turnkey.mdx b/get-started/about-turnkey.mdx index 7f507bcb..f3711867 100644 --- a/get-started/about-turnkey.mdx +++ b/get-started/about-turnkey.mdx @@ -17,7 +17,10 @@ Keys never leave the enclave. Turnkey returns signed payloads and supports trans Turnkey operates based on a [shared responsibility model](/security/shared-responsibility-model). Turnkey is responsible for the security of the platform itself, including enclave infrastructure, policy engine correctness, key confidentiality, and service availability. You are responsible for securing your integration: configuring your root quorum, scoping user permissions, authoring policies, and managing credentials. See the [full model](/security/shared-responsibility-model) for details. - Turnkey architecture: organizations, sub-organizations, users, authenticators, policies, and wallets + Turnkey architecture: organizations, sub-organizations, users, authenticators, policies, and wallets ## Core concepts diff --git a/get-started/ai-skills.mdx b/get-started/ai-skills.mdx index 1cd9e3fc..6a8d2c71 100644 --- a/get-started/ai-skills.mdx +++ b/get-started/ai-skills.mdx @@ -3,8 +3,8 @@ title: "Agent Skills" description: "Opinionated instructions that tell AI agents how to interact with Turnkey through conversation, not code." --- -import { FeatureCard } from '/snippets/feature-card.mdx' -import { SolutionCard } from '/snippets/solution-card.mdx' +import { FeatureCard } from "/snippets/feature-card.mdx"; +import { SolutionCard } from "/snippets/solution-card.mdx"; Each agent skill is a `SKILL.md` file with opinionated, step-by-step instructions for a specific Turnkey operation. Instead of an agent reasoning about API docs, parameter formatting, and chain-specific details on its own, skills give it exactly what it needs to execute correctly. Skills work with Claude Code, OpenAI, and other third-party agent frameworks. @@ -16,16 +16,17 @@ Skills are open source at [**tkhq/turnkey-agent-skills**](https://github.com/tkh Skills are composable. Each skill handles a single domain (wallets, signing, policies, etc.) and can be combined for any workflow. Common starting points: -| Use case | What you can do | Start with | -| :--- | :--- | :--- | -| **Explore and test** | Create wallets, sign transactions, and set policies without writing integration code | `getting-started` | -| **Administer your org** | Manage users, rotate API keys, configure policies, and monitor activities conversationally | `managing-users`, `managing-policies` | -| **Provision autonomous agents** | Set up a scoped wallet with constrained credentials and governance policies for onchain automation | `provisioning-agent` | +| Use case | What you can do | Start with | +| :------------------------------ | :------------------------------------------------------------------------------------------------- | :------------------------------------ | +| **Explore and test** | Create wallets, sign transactions, and set policies without writing integration code | `getting-started` | +| **Administer your org** | Manage users, rotate API keys, configure policies, and monitor activities conversationally | `managing-users`, `managing-policies` | +| **Provision autonomous agents** | Set up a scoped wallet with constrained credentials and governance policies for onchain automation | `provisioning-agent` | ## Credentials and security - Read the following carefully before giving any AI agent access to your Turnkey organization. + Read the following carefully before giving any AI agent access to your Turnkey + organization. - **LLMs can misinterpret instructions or execute unintended actions.** Scoped credentials ensure mistakes are bounded. Turnkey policies are the technical enforcement mechanism. @@ -36,10 +37,10 @@ Skills are composable. Each skill handles a single domain (wallets, signing, pol All skills require an API key pair and organization ID from the [Turnkey Dashboard](https://app.turnkey.com) (**Settings > API Keys**). Which credentials you use depends on your setup: -| Setup | Credential type | When to use | -| :--- | :--- | :--- | -| **Interactive assistant** (human approves each action) | Root API key (with extreme caution) or a scoped, non-root API key | Organization administration, testing, and exploration. Human should review every action before it executes. | -| **Autonomous agent** (acts without human review) | Scoped, non-root API key | Production automation. **Never use root credentials for autonomous agents.** Root keys bypass all policies. Create a non-root user with scoped policies instead. See [Agentic Wallets](/solutions/company-wallets/agentic-wallets) and the `provisioning-agent` skill. | +| Setup | Credential type | When to use | +| :----------------------------------------------------- | :---------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Interactive assistant** (human approves each action) | Root API key (with extreme caution) or a scoped, non-root API key | Organization administration, testing, and exploration. Human should review every action before it executes. | +| **Autonomous agent** (acts without human review) | Scoped, non-root API key | Production automation. **Never use root credentials for autonomous agents.** Root keys bypass all policies. Create a non-root user with scoped policies instead. See [Agentic Wallets](/solutions/company-wallets/agentic-wallets) and the `provisioning-agent` skill. | ## Available skills @@ -47,21 +48,21 @@ Skills are organized into **workflows** (guided multi-step procedures) and **pri ### Workflows -| Skill | Description | -| :--- | :--- | -| **Getting Started** | Day-0 onboarding: verify credentials, create your first wallet | +| Skill | Description | +| :--------------------- | :-------------------------------------------------------------- | +| **Getting Started** | Day-0 onboarding: verify credentials, create your first wallet | | **Provisioning Agent** | Create a scoped agent with constrained credentials and policies | -| **Managing Agent** | Debug denied transactions, rotate keys, update agent policies | +| **Managing Agent** | Debug denied transactions, rotate keys, update agent policies | ### Primitives -| Skill | Description | -| :--- | :--- | -| **Managing Wallets** | Create wallets, derive addresses, add chains, import/export | -| **Signing Transactions** | Sign and broadcast on any supported chain (EVM, Solana, Bitcoin, and more) | -| **Managing Users** | Create users, rotate API keys, manage user tags | -| **Managing Policies** | Access control, spending limits, allowlists, multi-party approval | -| **Monitoring Activities** | Activity status, consensus approvals, audit logs | +| Skill | Description | +| :------------------------ | :------------------------------------------------------------------------- | +| **Managing Wallets** | Create wallets, derive addresses, add chains, import/export | +| **Signing Transactions** | Sign and broadcast on any supported chain (EVM, Solana, Bitcoin, and more) | +| **Managing Users** | Create users, rotate API keys, manage user tags | +| **Managing Policies** | Access control, spending limits, allowlists, multi-party approval | +| **Monitoring Activities** | Activity status, consensus approvals, audit logs | ## Getting started @@ -74,9 +75,35 @@ cd turnkey-agent-skills ## Next steps -
- - - - +
+ + + +
diff --git a/get-started/backup-recovery.mdx b/get-started/backup-recovery.mdx index f17cd526..f1b47aeb 100644 --- a/get-started/backup-recovery.mdx +++ b/get-started/backup-recovery.mdx @@ -29,7 +29,7 @@ Wallets, wallet accounts, and raw private keys can all be exported securely usin With this process, users have two main options: -1. Expose the seed phrase to the user in plaintext clientside so they can record it manually. See [wallet exports](/features/wallets/export-wallets) for more detail. +1. Expose the seed phrase to the user in plaintext clientside so they can record it manually. See [wallet exports](/features/wallets/export-wallets) for more detail. 2. Encrypt the seed phrase to a user defined passphrase (using [PBKDF2](https://en.wikipedia.org/wiki/PBKDF2)). Contact Turnkey support if you’re interested in this implementation. For non-embedded wallets, [scripted exports](/solutions/embedded-wallets/integration-guide/react/using-embedded-wallets#nodejs) are also possible. diff --git a/get-started/examples.mdx b/get-started/examples.mdx index 37c5aef6..214a49af 100644 --- a/get-started/examples.mdx +++ b/get-started/examples.mdx @@ -92,26 +92,26 @@ Signers and chain-specific transaction examples. ## DeFi & Protocol Integrations -| Example | Description | -| ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | -| [`with-uniswap`](https://github.com/tkhq/sdk/tree/main/examples/with-uniswap/) | Sign and broadcast a Uniswap v3 trade using the Ethers signer | -| [`eth-usdc-swap`](https://github.com/tkhq/sdk/tree/main/examples/eth-usdc-swap) | ETH to USDC swap on Base mainnet via Uniswap Universal Router | -| [`with-0x`](/solutions/cookbooks/0x) | EVM swapping ETH for USDC using 0x Swap API | -| [`with-lifi`](/solutions/cookbooks/lifi) | EVM and SVM bridging between ETH and SOL using Li.Fi | -| [`with-aave`](/solutions/cookbooks/aave) | Aave v3 USDC deposit/withdraw with Turnkey policy engine controls | -| [`with-morpho`](/solutions/cookbooks/morpho) | Morpho Vaults USDC deposit/withdraw on Base Mainnet | -| [`with-yield-xyz`](/solutions/cookbooks/yieldxyz) | Yield.xyz vaults deposit/withdraw across 75+ networks | -| [`with-porto`](https://github.com/tkhq/sdk/tree/main/examples/with-porto) | Porto wallet upgrade and operations using API keys | -| [`with-x402`](https://github.com/tkhq/sdk/tree/main/examples/with-x402) | Coinbase x402 payment protocol with embedded wallets | -| [`with-jupiter`](/solutions/cookbooks/jupiter) | Solana token swaps using Jupiter Ultra Swap API | -| [`with-breeze`](/solutions/cookbooks/breeze) | Solana USDC staking and yield management via Breeze API | -| [`trading-runner`](https://github.com/tkhq/sdk/tree/main/examples/trading-runner/) | Multi-user Uniswap v3 trading demo with private key tags, user tags, and policies | -| [`with-gnosis`](https://github.com/tkhq/sdk/tree/main/examples/with-gnosis/) | Create new Ethereum addresses, configure a 3/3 Gnosis safe, and create \+ execute a transaction from it | +| Example | Description | +| ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | +| [`with-uniswap`](https://github.com/tkhq/sdk/tree/main/examples/with-uniswap/) | Sign and broadcast a Uniswap v3 trade using the Ethers signer | +| [`eth-usdc-swap`](https://github.com/tkhq/sdk/tree/main/examples/eth-usdc-swap) | ETH to USDC swap on Base mainnet via Uniswap Universal Router | +| [`with-0x`](/solutions/cookbooks/0x) | EVM swapping ETH for USDC using 0x Swap API | +| [`with-lifi`](/solutions/cookbooks/lifi) | EVM and SVM bridging between ETH and SOL using Li.Fi | +| [`with-aave`](/solutions/cookbooks/aave) | Aave v3 USDC deposit/withdraw with Turnkey policy engine controls | +| [`with-morpho`](/solutions/cookbooks/morpho) | Morpho Vaults USDC deposit/withdraw on Base Mainnet | +| [`with-yield-xyz`](/solutions/cookbooks/yieldxyz) | Yield.xyz vaults deposit/withdraw across 75+ networks | +| [`with-porto`](https://github.com/tkhq/sdk/tree/main/examples/with-porto) | Porto wallet upgrade and operations using API keys | +| [`with-x402`](https://github.com/tkhq/sdk/tree/main/examples/with-x402) | Coinbase x402 payment protocol with embedded wallets | +| [`with-jupiter`](/solutions/cookbooks/jupiter) | Solana token swaps using Jupiter Ultra Swap API | +| [`with-breeze`](/solutions/cookbooks/breeze) | Solana USDC staking and yield management via Breeze API | +| [`trading-runner`](https://github.com/tkhq/sdk/tree/main/examples/trading-runner/) | Multi-user Uniswap v3 trading demo with private key tags, user tags, and policies | +| [`with-gnosis`](https://github.com/tkhq/sdk/tree/main/examples/with-gnosis/) | Create new Ethereum addresses, configure a 3/3 Gnosis safe, and create \+ execute a transaction from it | | [`with-walletconnect-pay`](/solutions/cookbooks/wallet-connect-pay-integration) | React Native wallet that authenticates users via email OTP and signs EIP-712 payment authorizations for WalletConnect Pay | -| [`brale`](/solutions/cookbooks/brale) | Stablecoin issuance and transfers with Turnkey wallets and the Brale API | -| [`relay`](/solutions/cookbooks/relay) | Cross-chain bridging and same-chain token swaps via the Relay protocol | -| [`polymarket-builders`](/solutions/cookbooks/polymarket-builders) | Polymarket prediction market trading with builder attribution, Gnosis Safe, and CLOB order placement | -| [`base-builder-codes`](/solutions/cookbooks/base-builder-codes) | ERC-8021 Base Builder Code attribution appended to Turnkey-signed transactions | +| [`brale`](/solutions/cookbooks/brale) | Stablecoin issuance and transfers with Turnkey wallets and the Brale API | +| [`relay`](/solutions/cookbooks/relay) | Cross-chain bridging and same-chain token swaps via the Relay protocol | +| [`polymarket-builders`](/solutions/cookbooks/polymarket-builders) | Polymarket prediction market trading with builder attribution, Gnosis Safe, and CLOB order placement | +| [`base-builder-codes`](/solutions/cookbooks/base-builder-codes) | ERC-8021 Base Builder Code attribution appended to Turnkey-signed transactions | ## Policies & Access Control @@ -156,10 +156,12 @@ features such as: - ![demo embedded wallet login view](/images/getting-started/demo-embedded-wallet.png) + ![demo embedded wallet login + view](/images/getting-started/demo-embedded-wallet.png) - ![demo embedded wallet dashboard view](/images/getting-started/demo-embedded-wallet-ui.png) + ![demo embedded wallet dashboard + view](/images/getting-started/demo-embedded-wallet-ui.png) diff --git a/get-started/production-checklist.mdx b/get-started/production-checklist.mdx index dbbf9007..f0ca20c0 100644 --- a/get-started/production-checklist.mdx +++ b/get-started/production-checklist.mdx @@ -11,8 +11,9 @@ description: "This checklist contains recommendations and steps specifically for Double check our [resource limits](/reference/resource-limits) and [rate - limits](/reference/faq#do-you-have-any-rate-limits-in-place-in-your-public-api) to - ensure your implementation will not trigger these limits at production scale. + limits](/reference/faq#do-you-have-any-rate-limits-in-place-in-your-public-api) + to ensure your implementation will not trigger these limits at production + scale. ## Security diff --git a/get-started/quickstart.mdx b/get-started/quickstart.mdx index 25e66f9a..699041b1 100644 --- a/get-started/quickstart.mdx +++ b/get-started/quickstart.mdx @@ -4,7 +4,7 @@ description: "Before diving into the code, let's set up your organization and co sidebarTitle: "Account setup" --- -import { FeatureCard } from '/snippets/feature-card.mdx' +import { FeatureCard } from "/snippets/feature-card.mdx"; ## Create an account @@ -33,25 +33,26 @@ The API keypair is used to authenticate requests to Turnkey. We'll create one no - - - - - - - - For this guide, we'll use the in-browser method. - - - - Optionally, you may also generate keys using the [Turnkey CLI](/sdks/introduction). - - - - - - - + + + + + + + + For this guide, we'll use the in-browser method. + + + + Optionally, you may also generate keys using the [Turnkey + CLI](/sdks/introduction). + + + + + + + You'll be prompted to authenticate with the authenticator setup during account creation. Save the private key in a secure location — **it won't be visible after this step**. @@ -75,7 +76,23 @@ The API keypair is used to authenticate requests to Turnkey. We'll create one no Now that you've created an organization and API keypair, you're ready to start developing with Turnkey! -
- - +
+ +
diff --git a/hero-animation.js b/hero-animation.js index bba1ef44..282ef5bb 100644 --- a/hero-animation.js +++ b/hero-animation.js @@ -1,32 +1,37 @@ (function () { function inlineHero() { - document.querySelectorAll('img[data-hero-inline-src]:not([data-hero-inlined])').forEach(function (img) { - var src = img.getAttribute('data-hero-inline-src'); - if (!src) return; + document + .querySelectorAll("img[data-hero-inline-src]:not([data-hero-inlined])") + .forEach(function (img) { + var src = img.getAttribute("data-hero-inline-src"); + if (!src) return; - fetch(src) - .then(function (res) { - return res.text(); - }) - .then(function (markup) { - if (img.getAttribute('data-hero-inlined')) return; + fetch(src) + .then(function (res) { + return res.text(); + }) + .then(function (markup) { + if (img.getAttribute("data-hero-inlined")) return; - var el = document.createElement('div'); - el.className = img.className; - el.setAttribute('role', 'img'); - el.setAttribute('aria-label', img.getAttribute('alt') || 'Turnkey hero illustration'); - el.innerHTML = markup; - img.setAttribute('data-hero-inlined', 'true'); - img.replaceWith(el); - }) - .catch(function () { - /* Keep fallback */ - }); - }); + var el = document.createElement("div"); + el.className = img.className; + el.setAttribute("role", "img"); + el.setAttribute( + "aria-label", + img.getAttribute("alt") || "Turnkey hero illustration", + ); + el.innerHTML = markup; + img.setAttribute("data-hero-inlined", "true"); + img.replaceWith(el); + }) + .catch(function () { + /* Keep fallback */ + }); + }); } - if (document.readyState === 'loading') { - document.addEventListener('DOMContentLoaded', inlineHero); + if (document.readyState === "loading") { + document.addEventListener("DOMContentLoaded", inlineHero); } else { inlineHero(); } diff --git a/reference/faq.mdx b/reference/faq.mdx index 2dc81e47..082c3774 100644 --- a/reference/faq.mdx +++ b/reference/faq.mdx @@ -13,6 +13,7 @@ title: "FAQ" - Turnkey _cannot_ leak your API private keys, even if compromised, because Turnkey only knows your API public keys. - Your API private key stays on the server you generated it for. This means there's a lower risk of key exfiltration compared to other methods where an API key, or API credentials in general, are generated in one place (web browser, company server), transported via a second (copy/paste, email, PDF document) and used in a third place (your server). + Signing the whole payload is a way for Turnkey to know: @@ -27,11 +28,13 @@ title: "FAQ" 3. **That the request is legitimate**: this is achieved by parsing the serialized request to make sure the intent is correct. This happens all the way down in our [Secure Enclaves](/security/secure-enclaves). For example, when you send a request to create a new Private Key, our policy engine parses your original request to independently derive the type of request, the payload to sign, etc. This guards against man-in-the-middle attacks. Turnkey would not be able to have its enclaves verify signatures and check the request intent if we didn't have your signature on the whole payload. + A Turnkey API key is simply a way to authenticate requests to Turnkey. Crypto assets are not tied to it in any way. Think about Turnkey API keys as an access-gating mechanism to Turnkey functionality. They're flexible in what they can do (you get to decide this with [Policies](/features/policies/overview)!), and revocable if they are lost or compromised. + Losing your Turnkey API key doesn't mean you'll lose your crypto: @@ -40,11 +43,13 @@ title: "FAQ" - If you've changed policies so that your API key is allowed to unilaterally move funds, you may be at risk. Leverage the Turnkey UI to revoke your API key as soon as possible. Talk to our team ([hello@turnkey.com](mailto:hello@turnkey.com)) if you want to get in touch and talk more in-depth. + We require a recent timestamp in the `timestampMs` field for each new activity submission. Our secure enclaves have their own, independent, secure source of time. We currently require request timestamps to be **less than an hour old**, and **up to 5 minutes in the future**. + You can, but it doesn't mean you should. If you use your existing crypto private key as a turnkey API key, you are coupling Turnkey access with your crypto wallet. In essence, the risk profile of this key goes up. It's a bit like re-using passwords across many sites. Turnkey highly recommends creating a fresh public/private key pair if you need programmatic Turnkey access. @@ -56,6 +61,7 @@ title: "FAQ" - If the day-to-day key is leaked, then you can use one of the secure, additional keys to remove it from all impacted sub-orgs via `ACTIVITY_TYPE_DELETE_API_KEYS`. Reach out to our team ([hello@turnkey.com](mailto:hello@turnkey.com)) for additional guidance. + @@ -88,6 +94,7 @@ title: "FAQ" In addition, the **broadcast transaction endpoints** (`ethSendTransaction` and `solSendTransaction`) and the `getWalletAddressBalances` query endpoint are subject to a separate global limit of **10 RPS**, applied uniformly across all plans. Please get in touch with us ([help@turnkey.com](mailto:help@turnkey.com)) if you need this limit adjusted for your use-case. + @@ -112,9 +119,10 @@ title: "FAQ" We have deeper support for [Ethereum](networks/ethereum), [Solana](networks/solana), and [Bitcoin](networks/bitcoin). If there are specific ecosystems or chains you'd like to see us offer deeper support for, please let us know by contacting us at [hello@turnkey.com](mailto:hello@turnkey.com), on [X](https://x.com/turnkeyhq/), or [on Slack](https://join.slack.com/t/clubturnkey/shared_invite/zt-3aemp2g38-zIh4V~3vNpbX5PsSmkKxcQ). + - Turnkey's [Transaction Management](/features/transaction-management) supports gas sponsorship, transaction construction, broadcast, nonce management and monitoring capabilities, down to just a few API calls.  + Turnkey's [Transaction Management](/features/transaction-management) supports gas sponsorship, transaction construction, broadcast, nonce management and monitoring capabilities, down to just a few API calls. We handle gassing and our battle-tested broadcast logic ensures inclusion even under adverse network conditions. You and your users never touch gas tokens or deal with stuck transactions. @@ -123,16 +131,19 @@ title: "FAQ" This functionality is currently supported for EVM chains (Base, Polygon, Ethereum, Arbitrum) and Solana. We're actively expanding coverage — reach out if you need a specific chain. For more detail visit the [Transaction Management](/features/transaction-management) overview page. Gas sponsorship is available on Pro (up to \$50/day) and Enterprise (unlimited and configurable). Pay-as-you-go customers can access transaction construction, signing, and broadcast. See [Transaction Management](/features/transaction-management) for details. + In the ECDSA context, messages are hashed before signing. Turnkey can perform this hashing for you, as we support two hash functions: `HASH_FUNCTION_KECCAK256` and `HASH_FUNCTION_SHA256` (for Ethereum and Bitcoin ecosystems respectively). If your message had already been hashed, you should use the `HASH_FUNCTION_NO_OP` option to sign the raw hash, in which case Turnkey will sign the payload as is. `HASH_FUNCTION_NO_OP` also has privacy implications: if a raw hashed message is passed in, Turnkey has no knowledge of the underlying pre-image. As an example, in our Viem package, the message is [hashed](https://github.com/tkhq/sdk/blob/673442f025990fde6a37436bed987b42e694a64d/packages/viem/src/index.ts#L201) before [signing](https://github.com/tkhq/sdk/blob/673442f025990fde6a37436bed987b42e694a64d/packages/viem/src/index.ts#L348). + Unlike ECDSA, in which a message is hashed as a separate step _before_ signing, when using Ed25519, hashing is performed _during_ signature computation, and thus cannot be skipped (for more details on the standard, see [RFC 8032](https://datatracker.ietf.org/doc/html/rfc8032#section-5.1): `“Ed25519 is EdDSA instantiated with: …H(x) = SHA-512"`). As a result, we have a special `HASH_FUNCTION_NOT_APPLICABLE` option for when you use ed25519/EdDSA. An example for this case can be found in our [Solana signer](https://github.com/tkhq/sdk/blob/d9ed2aefc92d298826a40e821f959b019ea1936f/packages/solana/src/index.ts#L64). + @@ -148,11 +159,13 @@ title: "FAQ" To do this you can use email aliases: if `firstname@domain.com` is your email, you can sign up for a new Turnkey organization with `firstname+test@domain.com` to have a test playground. If you need many test organizations or if you have specific questions, our team is happy to help you get set up. + Turnkey is priced per signature, i.e. any transaction or raw payload successfully signed by a private key created on Turnkey. Turnkey offers 25 free signatures each month. To execute more than 25 transactions in a given month, you are required to have a credit card on file or active enterprise plan on your account. To upgrade your plan, navigate to Account Settings from the menu in the top right-hand corner in the Turnkey dashboard and follow the instructions. For more information about pricing and billing, check out the [pricing page](https://www.turnkey.com/pricing). + Join our slack community [here](https://join.slack.com/t/clubturnkey/shared_invite/zt-3aemp2g38-zIh4V~3vNpbX5PsSmkKxcQ) to get support with your integration, share product feedback, and connect with other crypto builders. Or, reach out directly to [help@turnkey.com.](mailto:help@turnkey.com.) Teams that are looking for more in-depth integration support can upgrade to an Enterprise plan via [hello@turnkey.com](mailto:hello@turnkey.com). @@ -166,4 +179,4 @@ title: "FAQ" Check out our whitepaper, available at [whitepaper.turnkey.com](https://whitepaper.turnkey.com)! It covers our foundations and architecture in great detail. - \ No newline at end of file + diff --git a/reference/migration-guide.mdx b/reference/migration-guide.mdx index 0d6fc661..a6d39515 100644 --- a/reference/migration-guide.mdx +++ b/reference/migration-guide.mdx @@ -17,7 +17,6 @@ In most circumstances user assets remain exactly as they were onchain, belonging **Security note:** be mindful that there are no guarantees a previous provider destroys their copy of exported keys, or that it wasn't logged somewhere. It can be worth considering creating a new wallet and transferring assets to it anyway. - ## Non-custodial wallets Migrating a non-custodial (user-owned) wallet to Turnkey follows the pattern described earlier. Within your application, we want to invoke the outgoing provider's user facing export method, and prompt the user to copy over the key or seed to Turnkey's importer iframe. @@ -27,10 +26,11 @@ This can be done **"just in time,"** creating the Turnkey user information (like ### Export from existing provider This export typically takes the form of an export modal which displays the private key or seed phrase in plaintext to the user. The specifics depend on your provider, but popular choices typically have methods designed for the user to copy their key/seed to clipboard. -* [Privy - `exportWallet`](https://docs.privy.io/wallets/wallets/export#react) (React) -* [Dynamic - `exportPrivateKey`](https://www.dynamic.xyz/docs/global-wallets/export) (React) -* [Fireblocks - `full key takeover`](https://ncw-developers.fireblocks.com/docs/full-key-takeover) -* Other - some services like Para or web3auth lack embeddable key export functionality and may require users to export keys using the service dashboard + +- [Privy - `exportWallet`](https://docs.privy.io/wallets/wallets/export#react) (React) +- [Dynamic - `exportPrivateKey`](https://www.dynamic.xyz/docs/global-wallets/export) (React) +- [Fireblocks - `full key takeover`](https://ncw-developers.fireblocks.com/docs/full-key-takeover) +- Other - some services like Para or web3auth lack embeddable key export functionality and may require users to export keys using the service dashboard ### Import to Turnkey @@ -48,18 +48,19 @@ If instead you manage your users' wallets, the export/import pattern will be sim The specifics will depend on the provider, but popular choices typically offer multiple programmatic wallet export options. The mnemonic key, or the private key + its format is all that is required to create a wallet bundle and import the account. -* Privy: [Node](https://docs.privy.io/wallets/wallets/export#nodejs) and [API](https://docs.privy.io/wallets/wallets/export#rest-api) -* Dfns: [API](https://docs.dfns.co/d/api-docs/keys/advanced-keys-apis/export-key) -* Other - Database (e.g. Firebase): accessing private keys on a db instance may require special permission, but tend to be simple and efficient to fetch in large numbers -* Other - Hosted platform: some services may require user auth on key export, check available documentation +- Privy: [Node](https://docs.privy.io/wallets/wallets/export#nodejs) and [API](https://docs.privy.io/wallets/wallets/export#rest-api) +- Dfns: [API](https://docs.dfns.co/d/api-docs/keys/advanced-keys-apis/export-key) +- Other - Database (e.g. Firebase): accessing private keys on a db instance may require special permission, but tend to be simple and efficient to fetch in large numbers +- Other - Hosted platform: some services may require user auth on key export, check available documentation It is preferable for this migration script to not directly write/save these exported keys to the local filesystem, and instead directly pass them to the below import methods as keys are retrieved. ### Import to Turnkey There are two options for importing wallets to Turnkey programmatically: -* [Node](/solutions/embedded-wallets/integration-guide/react/using-embedded-wallets#nodejs) (`@turnkey/sdk-server`) -* [Turnkey CLI ](/solutions/embedded-wallets/integration-guide/react/using-embedded-wallets#cli)(`tkcli`) -Please visit these linked resources for implementation-specific guides and code samples. +- [Node](/solutions/embedded-wallets/integration-guide/react/using-embedded-wallets#nodejs) (`@turnkey/sdk-server`) +- [Turnkey CLI ](/solutions/embedded-wallets/integration-guide/react/using-embedded-wallets#cli)(`tkcli`) + +Please visit these linked resources for implementation-specific guides and code samples. diff --git a/reference/resource-limits.mdx b/reference/resource-limits.mdx index bc650474..ba7295e6 100644 --- a/reference/resource-limits.mdx +++ b/reference/resource-limits.mdx @@ -12,22 +12,22 @@ Currently, the resource limits within a single organization are as follows: | Resource | Maximum parent org allowance | Maximum sub-org allowance | | :----------------------------- | :--------------------------: | :-----------------------: | -| Sub-Organizations | unlimited | 0 | -| HD Wallet Accounts | unlimited | unlimited | -| HD Wallets | 100 | 100 | -| Private keys | 1,000 | 1,000 | -| Users | 100 | 100 | -| Policies | 100 | 100 | -| Invitations | 100 | 100 | -| Tags | 100 | 10 | -| Authenticators per user | 10 | 10 | -| API keys per user (long-lived) | 10 | 10 | -| API keys per user (expiring) | 10 | 10 | -| OAuth providers per user | 10 | 10 | +| Sub-Organizations | unlimited | 0 | +| HD Wallet Accounts | unlimited | unlimited | +| HD Wallets | 100 | 100 | +| Private keys | 1,000 | 1,000 | +| Users | 100 | 100 | +| Policies | 100 | 100 | +| Invitations | 100 | 100 | +| Tags | 100 | 10 | +| Authenticators per user | 10 | 10 | +| API keys per user (long-lived) | 10 | 10 | +| API keys per user (expiring) | 10 | 10 | +| OAuth providers per user | 10 | 10 | Note that if you create an expiring API key that would exceed the limit above, Turnkey automatically deletes one of your existing keys using the following priority: 1. Expired API keys are deleted first 2. If no expired keys exist, the oldest unexpired key is deleted -If you are approaching any of these limits in your implementation and require support, reach out to the Turnkey team ([help@turnkey.com](mailto:help@turnkey.com)). \ No newline at end of file +If you are approaching any of these limits in your implementation and require support, reach out to the Turnkey team ([help@turnkey.com](mailto:help@turnkey.com)). diff --git a/scripts/openapi-gen/README.md b/scripts/openapi-gen/README.md index e6a94902..9c58ec56 100644 --- a/scripts/openapi-gen/README.md +++ b/scripts/openapi-gen/README.md @@ -29,6 +29,7 @@ The auth proxy is generated as part of `make gen` — no separate command needed This converts `proxy_api.swagger.json` → `scripts/openapi-gen/proxy_api_openapi.json`, then generates MDX files under `api-reference/auth-proxy/` and updates the `Auth Proxy` group in `docs.json`. Key differences from the main API generation: + - `--auth-proxy`: uses the auth-proxy generator (flat output, hardcoded base URL and auth header, v1 endpoint deduplication) - `--nav-group`: targets the `Auth Proxy` group in `docs.json` instead of Activities/Queries @@ -51,7 +52,7 @@ scripts/openapi-gen/ │ └── generator.ts # Generates MDX files per endpoint ├── package.json # Dependencies for CLI (commander, ts-node) └── tsconfig.json # TypeScript configuration -``` +``` ## Generated Outputs diff --git a/scripts/openapi-gen/openapi-gen-plan.md b/scripts/openapi-gen/openapi-gen-plan.md index 7d4bc137..88c4e09e 100644 --- a/scripts/openapi-gen/openapi-gen-plan.md +++ b/scripts/openapi-gen/openapi-gen-plan.md @@ -60,7 +60,7 @@ program .option("--path ", "JSON path to specific element to output") .option( "-o, --output ", - "Output file path (stdout if not specified)" + "Output file path (stdout if not specified)", ) .parse(process.argv); ``` @@ -76,7 +76,7 @@ program ```typescript function outputResults( data: any, - options: { outputFile?: string; jsonPath?: string } + options: { outputFile?: string; jsonPath?: string }, ) { // Get the data to output (full spec or filtered by JSON path) const outputData = options.jsonPath diff --git a/scripts/openapi-gen/openapi-gen.ts b/scripts/openapi-gen/openapi-gen.ts index 0e247b0c..c0a16992 100644 --- a/scripts/openapi-gen/openapi-gen.ts +++ b/scripts/openapi-gen/openapi-gen.ts @@ -16,7 +16,10 @@ import { formatApiEndpoints, ApiEndpointParserResult, } from "./utils/endpoint-parser"; -import { generateMdxFile, generateAuthProxyMdxFile } from "./utils/mdx-generator"; +import { + generateMdxFile, + generateAuthProxyMdxFile, +} from "./utils/mdx-generator"; import path from "path"; import fs from "fs"; @@ -48,15 +51,19 @@ async function main() { // Helper to kebab-case strings and remove '?' const kebabCase = (str: string) => - str.replace(/\?/g, '').trim().toLowerCase() - .replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, ''); + str + .replace(/\?/g, "") + .trim() + .toLowerCase() + .replace(/[^a-z0-9]+/g, "-") + .replace(/^-+|-+$/g, ""); // Build raw list with name, id, type, tags - const rawList = endpointResult.endpoints.map(ep => { - const name = ep.title.replace(/\?/g, '').trim(); + const rawList = endpointResult.endpoints.map((ep) => { + const name = ep.title.replace(/\?/g, "").trim(); const id = kebabCase(name); const type = ep.type; - const tags = (ep.tags || []).map(t => ({ + const tags = (ep.tags || []).map((t) => ({ id: kebabCase(t), label: t, })); @@ -64,10 +71,15 @@ async function main() { }); // Deduplicate by id + tag ids - const uniqueList: { name: string; id: string; type: string; tags: { id: string; label: string }[] }[] = []; + const uniqueList: { + name: string; + id: string; + type: string; + tags: { id: string; label: string }[]; + }[] = []; const seen = new Set(); for (const item of rawList) { - const key = `${item.id}|${item.tags.map(t => t.id).join(',')}`; + const key = `${item.id}|${item.tags.map((t) => t.id).join(",")}`; if (!seen.has(key)) { seen.add(key); uniqueList.push(item); @@ -79,7 +91,7 @@ async function main() { // First sort by type: activities before queries if (a.type === "activity" && b.type === "query") return -1; if (a.type === "query" && b.type === "activity") return 1; - + // If same type, sort alphabetically by name return a.name.localeCompare(b.name); }); @@ -93,11 +105,11 @@ async function main() { const endpointsStr = JSON.stringify(uniqueList, null, 2); // Collect unique tags const tagMap = new Map(); - uniqueList.forEach(item => - item.tags.forEach(tag => tagMap.set(tag.id, tag.label)) + uniqueList.forEach((item) => + item.tags.forEach((tag) => tagMap.set(tag.id, tag.label)), ); const uniqueTagsArray = Array.from(tagMap.entries()).map( - ([id, label]) => ({ id, label }) + ([id, label]) => ({ id, label }), ); const tagsStr = JSON.stringify(uniqueTagsArray, null, 2); // Construct MDX content with endpoints and tags @@ -119,7 +131,7 @@ export const tags = ${tagsStr};`; // --- MDX Generation Mode --- if (!endpointResult) { throw new Error( - "Endpoint data is required for MDX generation (--endpoints flag might be needed)." + "Endpoint data is required for MDX generation (--endpoints flag might be needed).", ); } console.log(`--- Starting MDX Generation ---`); @@ -132,7 +144,7 @@ export const tags = ${tagsStr};`; const absoluteMdxOutputDir = path.resolve(projectRoot, mdxOutputDirName); const relativeMdxBaseDir = path.relative( projectRoot, - absoluteMdxOutputDir + absoluteMdxOutputDir, ); console.log(`Output directory: ${absoluteMdxOutputDir}`); @@ -163,7 +175,11 @@ export const tags = ${tagsStr};`; if (skipEndpointPaths.has(endpoint.path)) continue; // Use the auth-proxy generator when --auth-proxy is set, main generator otherwise const generatedPath = options.authProxy - ? generateAuthProxyMdxFile(endpoint, absoluteMdxOutputDir, options.mdxAddOnly) + ? generateAuthProxyMdxFile( + endpoint, + absoluteMdxOutputDir, + options.mdxAddOnly, + ) : generateMdxFile(endpoint, absoluteMdxOutputDir, options.mdxAddOnly); if (generatedPath) { @@ -203,31 +219,34 @@ export const tags = ${tagsStr};`; // Check if docsConfig.navigation is an array before proceeding if (!docsConfig || !docsConfig.navigation) { console.error( - `Error: Expected 'docs.json' to have a top-level 'navigation' array.` + `Error: Expected 'docs.json' to have a top-level 'navigation' array.`, ); throw new Error("'docs.json' structure is not as expected."); } // Find the API & SDK reference tab const apiRefTab = docsConfig.navigation.tabs.find( - (item: any) => item.tab === "API & SDK reference" + (item: any) => item.tab === "API & SDK reference", ); // Activities and Queries live inside the "REST API" group within the tab const restApiGroup = apiRefTab?.pages?.find( - (item: any) => typeof item === "object" && item.group === "REST API" + (item: any) => typeof item === "object" && item.group === "REST API", ); if (restApiGroup && Array.isArray(restApiGroup.pages)) { if (options.authProxy && options.navGroup) { // Auth-proxy mode: find or create the named nav group and set its pages let navGroup = restApiGroup.pages.find( - (item: any) => typeof item === "object" && item.group === options.navGroup + (item: any) => + typeof item === "object" && item.group === options.navGroup, ); if (!navGroup) { navGroup = { group: options.navGroup, pages: [] }; restApiGroup.pages.push(navGroup); - console.log(`Created new nav group '${options.navGroup}' in docs.json`); + console.log( + `Created new nav group '${options.navGroup}' in docs.json`, + ); } navGroup.pages = uniqueAuthProxyPaths; console.log(`Updated '${options.navGroup}' paths in docs.json`); @@ -235,7 +254,7 @@ export const tags = ${tagsStr};`; // Standard mode: update Activities and Queries groups const activitiesGroup = restApiGroup.pages.find( (item: any) => - typeof item === "object" && item.group === "Activities" + typeof item === "object" && item.group === "Activities", ); if (activitiesGroup) { activitiesGroup.pages = [ @@ -245,12 +264,13 @@ export const tags = ${tagsStr};`; console.log(`Updated Activities paths in docs.json`); } else { console.warn( - `Could not find 'Activities' group in docs.json under 'REST API'` + `Could not find 'Activities' group in docs.json under 'REST API'`, ); } const queriesGroup = restApiGroup.pages.find( - (item: any) => typeof item === "object" && item.group === "Queries" + (item: any) => + typeof item === "object" && item.group === "Queries", ); if (queriesGroup) { queriesGroup.pages = [ @@ -260,25 +280,25 @@ export const tags = ${tagsStr};`; console.log(`Updated Queries paths in docs.json`); } else { console.warn( - `Could not find 'Queries' group in docs.json under 'REST API'` + `Could not find 'Queries' group in docs.json under 'REST API'`, ); } } } else { console.warn( - `Could not find 'REST API' group in 'API & SDK reference' tab in docs.json navigation` + `Could not find 'REST API' group in 'API & SDK reference' tab in docs.json navigation`, ); } // Write updated config back to docs.json fs.writeFileSync( docsJsonPath, - JSON.stringify(docsConfig, null, 2) + "\n" + JSON.stringify(docsConfig, null, 2) + "\n", ); console.log(`Successfully updated ${docsJsonPath}`); } catch (error: any) { console.error( - `Error processing or updating docs.json: ${error.message}` + `Error processing or updating docs.json: ${error.message}`, ); } console.log(`--- Finished updating docs.json ---`); @@ -288,10 +308,10 @@ export const tags = ${tagsStr};`; if (options.output) { const absoluteFormattedOutputPath = path.resolve( projectRoot, - options.output + options.output, ); console.log( - `Additionally writing formatted endpoints to ${absoluteFormattedOutputPath}` + `Additionally writing formatted endpoints to ${absoluteFormattedOutputPath}`, ); const endpointFormat = options.format === "yaml" ? "json" : options.format; // Default to json if yaml requested @@ -332,7 +352,7 @@ export const tags = ${tagsStr};`; // --- Raw OpenAPI Spec Mode (JSON/YAML) --- if (options.format === "typescript") { throw new Error( - "TypeScript format is only supported when using the --endpoints or --generate-mdx flags." + "TypeScript format is only supported when using the --endpoints or --generate-mdx flags.", ); } // Resolve output path relative to project root if specified diff --git a/scripts/openapi-gen/openapi-to-api-endpoints.md b/scripts/openapi-gen/openapi-to-api-endpoints.md index 9d2d16f7..52180615 100644 --- a/scripts/openapi-gen/openapi-to-api-endpoints.md +++ b/scripts/openapi-gen/openapi-to-api-endpoints.md @@ -60,12 +60,10 @@ For each path in the OpenAPI spec, we will: ### Required Utility Functions 1. **String transformations:** - - `snakeToCamel`: Convert snake_case to camelCase - `snakeToScreaming`: Convert snake_case to SCREAMING_SNAKE_CASE 2. **Schema processing:** - - `schemaToApiField`: Convert OpenAPI schema to ApiField - `findVersionedComponents`: Find all versions of a component by prefix - `extractEndpointName`: Extract the endpoint name from a path diff --git a/scripts/openapi-gen/output.json b/scripts/openapi-gen/output.json index 34ea5733..2d52aae8 100644 --- a/scripts/openapi-gen/output.json +++ b/scripts/openapi-gen/output.json @@ -17503,4 +17503,4 @@ ] } } -] \ No newline at end of file +] diff --git a/scripts/openapi-gen/swagger-to-openapi.ts b/scripts/openapi-gen/swagger-to-openapi.ts index 3183711a..5ba137b0 100644 --- a/scripts/openapi-gen/swagger-to-openapi.ts +++ b/scripts/openapi-gen/swagger-to-openapi.ts @@ -9,23 +9,37 @@ const isAuthProxy = service === "auth-proxy"; const SWAGGER_PATH = path.resolve( __dirname, - isAuthProxy ? "../../proxy_api.swagger.json" : "../../public_api.swagger.json" + isAuthProxy + ? "../../proxy_api.swagger.json" + : "../../public_api.swagger.json", ); const OUTPUT_PATH = path.resolve( __dirname, - isAuthProxy ? "proxy_api_openapi.json" : "openapi.json" + isAuthProxy ? "proxy_api_openapi.json" : "openapi.json", ); // Doing some custom key ordering to match the old openapi.json and minimize diffs in initial change const KEY_ORDERS: Record = { root: [ - "openapi", "info", "servers", "security", "tags", - "paths", "components", "x-tagGroups", "x-original-swagger-version", + "openapi", + "info", + "servers", + "security", + "tags", + "paths", + "components", + "x-tagGroups", + "x-original-swagger-version", ], info: ["title", "description", "contact", "version"], operation: [ - "tags", "summary", "description", "operationId", - "requestBody", "responses", "x-codegen-request-body-name", + "tags", + "summary", + "description", + "operationId", + "requestBody", + "responses", + "x-codegen-request-body-name", ], }; @@ -84,7 +98,9 @@ async function main() { ); fs.writeFileSync(OUTPUT_PATH, JSON.stringify(ordered, null, 2)); - console.log(`Converted Swagger 2.0 → OpenAPI 3.0.1 and wrote to ${OUTPUT_PATH}`); + console.log( + `Converted Swagger 2.0 → OpenAPI 3.0.1 and wrote to ${OUTPUT_PATH}`, + ); } main().catch((err) => { diff --git a/scripts/openapi-gen/test-endpoints.json b/scripts/openapi-gen/test-endpoints.json index 9067f8d4..aff693e7 100644 --- a/scripts/openapi-gen/test-endpoints.json +++ b/scripts/openapi-gen/test-endpoints.json @@ -17503,4 +17503,4 @@ ] } } -] \ No newline at end of file +] diff --git a/scripts/openapi-gen/types.ts b/scripts/openapi-gen/types.ts index c351d150..5d7b60cd 100644 --- a/scripts/openapi-gen/types.ts +++ b/scripts/openapi-gen/types.ts @@ -19,5 +19,5 @@ export interface OutputOptions { /** Optional JSON path to filter the output */ jsonPath?: string; /** Output format (json or yaml) */ - format?: 'json' | 'yaml'; + format?: "json" | "yaml"; } diff --git a/scripts/openapi-gen/utils/cli.ts b/scripts/openapi-gen/utils/cli.ts index a17668be..a1efbd99 100644 --- a/scripts/openapi-gen/utils/cli.ts +++ b/scripts/openapi-gen/utils/cli.ts @@ -43,7 +43,7 @@ export function configureCLI(): Command { .option("--path ", "JSON path to specific element to output") .option( "-o, --output ", - "Output file path (stdout if not specified)" + "Output file path (stdout if not specified)", ) .option( "--format ", @@ -51,45 +51,42 @@ export function configureCLI(): Command { (value) => { if (value !== "json" && value !== "yaml" && value !== "typescript") { throw new Error( - 'Format must be either "json", "yaml", or "typescript"' + 'Format must be either "json", "yaml", or "typescript"', ); } return value; }, - "json" + "json", ) .option( "--endpoints", - "Generate API Endpoint objects instead of raw OpenAPI spec" + "Generate API Endpoint objects instead of raw OpenAPI spec", ) .option( "--list-endpoints-tags ", - "Output a JSON list of endpoint names and tags to the given file" + "Output a JSON list of endpoint names and tags to the given file", ) .option( "--required-only", "Include only required properties in the generated API Endpoint objects", - true + true, ) .option("--generate-mdx", "Generate MDX files for each API endpoint") .option( "--mdx-output-dir ", "Base directory for generated MDX files", - "api-reference" + "api-reference", ) .option( "--mdx-add-only", "Only add new MDX files, do not overwrite existing ones", - false - ) - .option( - "--nav-group ", - "Navigation group name in docs.json" + false, ) + .option("--nav-group ", "Navigation group name in docs.json") .option( "--auth-proxy", "Use the auth-proxy generator (flat output, custom URL/auth header, version deduplication)", - false + false, ); return program; diff --git a/scripts/openapi-gen/utils/endpoint-parser/formatter.ts b/scripts/openapi-gen/utils/endpoint-parser/formatter.ts index 209f0864..14f0f335 100644 --- a/scripts/openapi-gen/utils/endpoint-parser/formatter.ts +++ b/scripts/openapi-gen/utils/endpoint-parser/formatter.ts @@ -38,7 +38,7 @@ const DEFAULT_OPTIONS: ApiEndpointFormatterOptions = { */ export function formatApiEndpoints( result: ApiEndpointParserResult, - options: ApiEndpointFormatterOptions = DEFAULT_OPTIONS + options: ApiEndpointFormatterOptions = DEFAULT_OPTIONS, ): string { let output: string; @@ -85,7 +85,7 @@ import { ApiEndpoint } from '../types'; export const API_ENDPOINTS: ApiEndpoint[] = ${JSON.stringify( endpoints, null, - 2 + 2, )}; /** diff --git a/scripts/openapi-gen/utils/endpoint-parser/parser.ts b/scripts/openapi-gen/utils/endpoint-parser/parser.ts index 1dc3904a..a26ffa65 100644 --- a/scripts/openapi-gen/utils/endpoint-parser/parser.ts +++ b/scripts/openapi-gen/utils/endpoint-parser/parser.ts @@ -41,7 +41,7 @@ const DEFAULT_OPTIONS: ApiEndpointParserOptions = { */ export function parseApiEndpoints( openApiSpec: any, - options: ApiEndpointParserOptions = DEFAULT_OPTIONS + options: ApiEndpointParserOptions = DEFAULT_OPTIONS, ): ApiEndpointParserResult { const endpoints: ApiEndpoint[] = []; @@ -53,7 +53,7 @@ export function parseApiEndpoints( for (const [path, pathItem] of Object.entries(paths)) { // Process each HTTP method for this path for (const [method, operationObj] of Object.entries( - pathItem as Record + pathItem as Record, )) { // Skip if not a valid HTTP method if (!isHttpMethod(method)) continue; @@ -120,17 +120,17 @@ export function parseApiEndpoints( const intents = findVersionedComponents( openApiSpec, "intent", - intentBaseName + intentBaseName, ); const results = findVersionedComponents( openApiSpec, "result", - resultBaseName + resultBaseName, ); const versionedComponents = matchVersionedComponents( typeEnum, intents, - results + results, ); // Create ApiEndpoint for each matched version @@ -138,12 +138,12 @@ export function parseApiEndpoints( const intentSchema = getComponentSchema( openApiSpec, "Intent", - component.intentName + component.intentName, ); const resultSchema = getComponentSchema( openApiSpec, "Result", - component.resultName + component.resultName, ); // Create basic endpoint structure for this version @@ -172,20 +172,24 @@ export function parseApiEndpoints( name: "id", type: "string", required: true, - description: "Unique identifier for a given Activity object.", + description: + "Unique identifier for a given Activity object.", }, { name: "organizationId", type: "string", required: true, - description: "Unique identifier for a given Organization.", + description: + "Unique identifier for a given Organization.", }, { name: "status", type: "string", required: true, - description: baseEndpointInfo.path.includes("reject_activity") - ? "ACTIVITY_STATUS_REJECTED" + description: baseEndpointInfo.path.includes( + "reject_activity", + ) + ? "ACTIVITY_STATUS_REJECTED" : "The activity status", }, { @@ -217,22 +221,24 @@ export function parseApiEndpoints( required: true, description: "The result of the activity", childFields: resultSchema - ? [ - { - name: component.resultName, - type: "object", - required: true, - description: `The ${component.resultName} object`, - childFields: parseSchemaProperties(resultSchema), - }, - ] - : [], + ? [ + { + name: component.resultName, + type: "object", + required: true, + description: `The ${component.resultName} object`, + childFields: + parseSchemaProperties(resultSchema), + }, + ] + : [], }, { name: "votes", type: "array", required: true, - description: "A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata.", + description: + "A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata.", }, { name: "fingerprint", @@ -305,7 +311,7 @@ function parameterToApiParameter(param: any): any { function getComponentSchema( openApiSpec: any, componentType: string, - componentName: string + componentName: string, ): any | null { try { const schema = openApiSpec.components?.schemas?.[componentType]; @@ -385,16 +391,18 @@ function createEnumOptions(enumValues: string[]): EnumOption[] { function schemaToApiField( name: string, schema: any, - required: boolean + required: boolean, ): ApiField { const dataType = mapOpenApiTypeToDataType(schema.type); // Provide better default descriptions for common fields let defaultDescription: string; if (name === "parameters") { - defaultDescription = "The parameters object containing the specific intent data for this activity."; + defaultDescription = + "The parameters object containing the specific intent data for this activity."; } else if (name === "generateAppProofs") { - defaultDescription = "Enable to have your activity generate and return App Proofs, enabling verifiability."; + defaultDescription = + "Enable to have your activity generate and return App Proofs, enabling verifiability."; } else { defaultDescription = `${name} field`; } @@ -471,7 +479,7 @@ function mapOpenApiTypeToDataType(openApiType: string): DataType { */ function isHttpMethod(method: string): method is HttpMethod { return ["get", "post", "put", "patch", "delete"].includes( - method.toLowerCase() + method.toLowerCase(), ); } @@ -480,7 +488,7 @@ function isHttpMethod(method: string): method is HttpMethod { */ function findActivityTypeEnum( openApiSpec: any, - activityTypeBase: string + activityTypeBase: string, ): string[] { const activityTypes: string[] = []; @@ -492,8 +500,8 @@ function findActivityTypeEnum( // Filter enum values that start with the activity type base activityTypes.push( ...activityTypeSchema.enum.filter((type: string) => - startsWith(type, activityTypeBase) - ) + startsWith(type, activityTypeBase), + ), ); } } catch (error) { @@ -510,7 +518,7 @@ function findActivityTypeEnum( function findVersionedComponents( openApiSpec: any, componentType: "intent" | "result", - baseName: string + baseName: string, ): string[] { const components: string[] = []; @@ -523,8 +531,8 @@ function findVersionedComponents( // Filter properties that start with the base name components.push( ...Object.keys(schema.properties).filter((property) => - startsWith(property, baseName) - ) + startsWith(property, baseName), + ), ); } } catch (error) { @@ -551,7 +559,7 @@ interface VersionedComponent { function matchVersionedComponents( activityTypes: string[], intents: string[], - results: string[] + results: string[], ): VersionedComponent[] { const components: VersionedComponent[] = []; @@ -564,18 +572,18 @@ function matchVersionedComponents( if (latestActivityType && latestIntent) { const activityTypeVersion = extractVersionFromComponent(latestActivityType); const intentVersion = extractVersionFromComponent(latestIntent); - + // Use the higher version number for the component version const componentVersion = Math.max( parseInt(activityTypeVersion || "1"), - parseInt(intentVersion || "1") + parseInt(intentVersion || "1"), ).toString(); components.push({ version: componentVersion, activityType: latestActivityType, intentName: latestIntent, - resultName: latestResult || latestIntent.replace('Intent', 'Result'), // Use latest result or fallback + resultName: latestResult || latestIntent.replace("Intent", "Result"), // Use latest result or fallback }); } @@ -590,7 +598,7 @@ function matchVersionedComponents( */ function findLatestVersion(components: string[]): string | null { if (components.length === 0) return null; - + let latest = components[0]; let latestVersion = parseInt(extractVersionFromComponent(latest) || "1"); @@ -615,7 +623,7 @@ function parseResponsesFromOperation(operationResponses: any): ApiResponse[] { } for (const [statusCodeStr, responseObj] of Object.entries( - operationResponses + operationResponses, )) { const statusCode = parseInt(statusCodeStr, 10); if (isNaN(statusCode)) continue; // Skip if status code is not a number (like 'default') diff --git a/scripts/openapi-gen/utils/endpoint-parser/types.ts b/scripts/openapi-gen/utils/endpoint-parser/types.ts index 0faa5a69..f0eb6aff 100644 --- a/scripts/openapi-gen/utils/endpoint-parser/types.ts +++ b/scripts/openapi-gen/utils/endpoint-parser/types.ts @@ -175,7 +175,7 @@ export interface ApiEndpoint { */ requestBody?: ApiRequestBody; - /** + /** * Operation ID from the OpenAPI spec (used for SDK method naming) */ operationId?: string; diff --git a/scripts/openapi-gen/utils/mdx-generator/auth-proxy-generator.ts b/scripts/openapi-gen/utils/mdx-generator/auth-proxy-generator.ts index 3b4be9ee..d0c62cd5 100644 --- a/scripts/openapi-gen/utils/mdx-generator/auth-proxy-generator.ts +++ b/scripts/openapi-gen/utils/mdx-generator/auth-proxy-generator.ts @@ -19,12 +19,12 @@ function generateRequestExample(endpoint: ApiEndpoint): string { const dataPayloadString = JSON.stringify( dataPayloadObject, (_key, value) => (typeof value === "bigint" ? value.toString() : value), - 4 + 4, ); const escapedDataPayloadString = dataPayloadString.replace(/'/g, "'\\''"); const curlCommand = - "```bash title=\"cURL\"\n" + + '```bash title="cURL"\n' + "curl --request POST \\\n" + ` --url ${url} \\\n` + " --header 'Accept: application/json' \\\n" + @@ -39,14 +39,14 @@ function generateRequestExample(endpoint: ApiEndpoint): string { // --- Helper: Generate response example --- function generateResponseExample(endpoint: ApiEndpoint): string { const successResponse = endpoint.responses?.find( - (res) => res.statusCode === 200 + (res) => res.statusCode === 200, ); let resultPayload: Record; if (successResponse?.fields) { resultPayload = generateJsonPayloadRecursive( successResponse.fields, - endpoint.path + endpoint.path, ); } else { resultPayload = { "": "" }; @@ -55,7 +55,7 @@ function generateResponseExample(endpoint: ApiEndpoint): string { const responseJsonString = JSON.stringify( resultPayload, (_key, value) => (typeof value === "bigint" ? value.toString() : value), - 2 + 2, ); return `\n\n\`\`\`json 200\n${responseJsonString}\n\`\`\`\n\n`; @@ -98,7 +98,7 @@ import { NestedParam } from "/snippets/nested-param.mdx"; // Response fields const successResponse = endpoint.responses?.find( - (res) => res.statusCode === 200 + (res) => res.statusCode === 200, ); if (successResponse?.fields && successResponse.fields.length > 0) { mdxContent += `\n\n`; @@ -123,17 +123,18 @@ import { NestedParam } from "/snippets/nested-param.mdx"; export function generateAuthProxyMdxFile( endpoint: ApiEndpoint, baseOutputDir: string, - addOnly: boolean = false + addOnly: boolean = false, ): string | null { if (!endpoint.title || !endpoint.path) { console.warn( - `Skipping MDX generation for endpoint (Title: ${endpoint.title}, Path: ${endpoint.path}) due to missing title or path.` + `Skipping MDX generation for endpoint (Title: ${endpoint.title}, Path: ${endpoint.path}) due to missing title or path.`, ); return null; } - const slug = (endpoint.path.split("/").filter(Boolean).pop() || endpoint.title) - .replace(/_v\d+$/, ""); // strip version suffix + const slug = ( + endpoint.path.split("/").filter(Boolean).pop() || endpoint.title + ).replace(/_v\d+$/, ""); // strip version suffix const kebabCaseSlug = slug .toLowerCase() @@ -161,7 +162,7 @@ export function generateAuthProxyMdxFile( return kebabCaseSlug; } catch (error: any) { console.error( - `Error generating auth proxy MDX file for endpoint "${endpoint.title}": ${error.message}` + `Error generating auth proxy MDX file for endpoint "${endpoint.title}": ${error.message}`, ); if (error.stack) console.error(error.stack); return null; diff --git a/scripts/openapi-gen/utils/mdx-generator/generator.ts b/scripts/openapi-gen/utils/mdx-generator/generator.ts index f25b9ec9..5304e397 100644 --- a/scripts/openapi-gen/utils/mdx-generator/generator.ts +++ b/scripts/openapi-gen/utils/mdx-generator/generator.ts @@ -60,7 +60,7 @@ export function generateEnumOptionsMdx(options: EnumOption[]): string { export function generateParamMdxRecursive( fieldName: string, field: ApiField, - parentPath: string + parentPath: string, ): string { let mdx = ""; const fieldRequired = field.required ?? false; @@ -116,7 +116,7 @@ export function generateParamMdxRecursive( nestedMdx += generateParamMdxRecursive( nestedField.name, nestedField, - childParentPath // Pass the *same* parent path for array items + childParentPath, // Pass the *same* parent path for array items ); } } @@ -126,7 +126,7 @@ export function generateParamMdxRecursive( nestedMdx += generateParamMdxRecursive( nestedField.name, nestedField, - childParentPath // Pass the *current* path as parent for object properties + childParentPath, // Pass the *current* path as parent for object properties ); } } @@ -171,7 +171,7 @@ export function generateParamMdxRecursive( // Uses built-in for top-level, imported for nested. export function generateResponseFieldMdxRecursive( field: ApiField, - parentKey: string = "" + parentKey: string = "", ): string { let mdx = ""; const fieldName = field.name; @@ -243,7 +243,7 @@ export function generateResponseFieldMdxRecursive( export function generateJsonPayloadRecursive( fields: ApiField[] | undefined, endpointPath?: string, - parentPath: string = "" + parentPath: string = "", ): Record { if (!fields) { return {}; @@ -256,7 +256,11 @@ export function generateJsonPayloadRecursive( const currentPath = parentPath ? `${parentPath}.${field.name}` : field.name; // Special handling for ApproveActivity result field - if (endpointPath?.includes("approve_activity") && field.name === "result" && field.childFields?.length === 0) { + if ( + endpointPath?.includes("approve_activity") && + field.name === "result" && + field.childFields?.length === 0 + ) { value = " (approved activity result, if completed)"; } else if (field.type === "object" && field.childFields) { // Special handling for get-activity: only include the first intent in the response example @@ -266,10 +270,18 @@ export function generateJsonPayloadRecursive( field.childFields.length > 0 ) { // Only include the first intent child - value = generateJsonPayloadRecursive([field.childFields[0]], endpointPath, currentPath); + value = generateJsonPayloadRecursive( + [field.childFields[0]], + endpointPath, + currentPath, + ); } else { // Recursive call for nested objects - value = generateJsonPayloadRecursive(field.childFields, endpointPath, currentPath); + value = generateJsonPayloadRecursive( + field.childFields, + endpointPath, + currentPath, + ); } } else if ( field.type === "array" && @@ -307,7 +319,11 @@ export function generateJsonPayloadRecursive( } else { // Items are objects: recursively generate structure using all childFields // Pass the *whole* childFields array, representing the structure of ONE item. - itemValue = generateJsonPayloadRecursive(field.childFields, endpointPath, currentPath); + itemValue = generateJsonPayloadRecursive( + field.childFields, + endpointPath, + currentPath, + ); } value = [itemValue]; // Create an array with one example element } else { @@ -321,7 +337,8 @@ export function generateJsonPayloadRecursive( // Current behavior: for enum types, we grab the first (which defaults to CREDENTIAL_TYPE_WEBAUTHN_AUTHENTICATOR). // However, for `get_api_key` and `get_api_keys` endpoints, we want to use CREDENTIAL_TYPE_API_KEY_P256. if ( - (endpointPath?.includes("get_api_key") || endpointPath?.includes("get_api_keys")) && + (endpointPath?.includes("get_api_key") || + endpointPath?.includes("get_api_keys")) && field.name === "type" && enumValue === "" ) { @@ -354,7 +371,6 @@ export function generateJsonPayloadRecursive( // --- Helper: Map endpoint path to SDK method name --- function getSdkMethodName(endpoint: ApiEndpoint): string { - // Prefer operationId if present if (endpoint.operationId && endpoint.operationId.trim() !== "") { const op = endpoint.operationId.trim(); @@ -374,7 +390,10 @@ function getSdkMethodName(endpoint: ApiEndpoint): string { } // --- Helper: Generate SDK parameter value for a field --- -function generateSdkParameterValue(field: ApiField, indent: number = 2): string { +function generateSdkParameterValue( + field: ApiField, + indent: number = 2, +): string { const indentStr = " ".repeat(indent); const fieldName = field.name; const fieldType = field.type; @@ -388,7 +407,7 @@ function generateSdkParameterValue(field: ApiField, indent: number = 2): string const firstOption = options[0].value; return `${indentStr}${fieldName}: "<${firstOption}>"${description}`; } else if (fieldType === "string") { - return `${indentStr}${fieldName}: "${field.description ? ` (${field.description})` : ''}"`; + return `${indentStr}${fieldName}: "${field.description ? ` (${field.description})` : ""}"`; } else if (fieldType === "number") { return `${indentStr}${fieldName}: 0${description}`; } else if (fieldType === "boolean") { @@ -398,7 +417,8 @@ function generateSdkParameterValue(field: ApiField, indent: number = 2): string // If the array is of objects (multiple fields, or first child is an object) if ( field.childFields.length > 1 || - (field.childFields.length === 1 && field.childFields[0].type === "object") + (field.childFields.length === 1 && + field.childFields[0].type === "object") ) { const lines = [`${indentStr}${fieldName}: [{${description}`]; for (const child of field.childFields) { @@ -447,7 +467,10 @@ function generateSdkParameters(endpoint: ApiEndpoint): string { const parametersWrapper = fields.find((f) => f.name === "parameters"); if (parametersWrapper) { - if (parametersWrapper.childFields && parametersWrapper.childFields.length > 0) { + if ( + parametersWrapper.childFields && + parametersWrapper.childFields.length > 0 + ) { // For activity endpoints, extract parameters from the parameters wrapper only const paramLines: string[] = []; for (const field of parametersWrapper.childFields) { @@ -461,7 +484,9 @@ function generateSdkParameters(endpoint: ApiEndpoint): string { } else { // For query endpoints, use all top-level fields (excluding only type and timestampMs) const commonFields = ["type", "timestampMs"]; // organizationId should be included for queries - const endpointSpecificFields = fields.filter(f => !commonFields.includes(f.name)); + const endpointSpecificFields = fields.filter( + (f) => !commonFields.includes(f.name), + ); if (endpointSpecificFields.length === 0) { return ""; // No endpoint-specific parameters @@ -481,7 +506,7 @@ function generateRequestExample(endpoint: ApiEndpoint): string { // Find the 'type' field, often indicates the specific activity type const typeField = endpoint.requestBody?.fields?.find( - (f) => f.name === "type" + (f) => f.name === "type", ); const typeFieldDetails = typeField ? getEnumDetails(typeField) @@ -499,7 +524,7 @@ function generateRequestExample(endpoint: ApiEndpoint): string { // activity-style endpoint const parametersObject = generateJsonPayloadRecursive( parametersWrapper.childFields, - endpoint.path + endpoint.path, ); dataPayloadObject = { type: activityType, @@ -516,14 +541,14 @@ function generateRequestExample(endpoint: ApiEndpoint): string { const dataPayloadString = JSON.stringify( dataPayloadObject, (_key, value) => (typeof value === "bigint" ? value.toString() : value), - 4 + 4, ); // Pretty print with 4 spaces // Escape single quotes for bash compatibility within single-quoted string const escapedDataPayloadString = dataPayloadString.replace(/'/g, "'\\''"); const curlCommand = - "```bash title=\"cURL\"\n" + + '```bash title="cURL"\n' + "curl --request POST \\\n" + ` --url ${url} \\\n` + " --header 'Accept: application/json' \\\n" + @@ -535,14 +560,17 @@ function generateRequestExample(endpoint: ApiEndpoint): string { // Generate JavaScript SDK example const sdkMethodName = getSdkMethodName(endpoint); const sdkParameters = generateSdkParameters(endpoint); - const jsParams = sdkParameters.trim() === "" ? "{}" : `{ + const jsParams = + sdkParameters.trim() === "" + ? "{}" + : `{ ${sdkParameters} }`; const javascriptExample = - "```javascript title=\"JavaScript\"\n" + - "import { Turnkey } from \"@turnkey/sdk-server\";\n\n" + + '```javascript title="JavaScript"\n' + + 'import { Turnkey } from "@turnkey/sdk-server";\n\n' + "const turnkeyClient = new Turnkey({\n" + - " apiBaseUrl: \"https://api.turnkey.com\",\n" + + ' apiBaseUrl: "https://api.turnkey.com",\n' + " apiPublicKey: process.env.API_PUBLIC_KEY!,\n" + " apiPrivateKey: process.env.API_PRIVATE_KEY!,\n" + " defaultOrganizationId: process.env.ORGANIZATION_ID!,\n" + @@ -557,7 +585,7 @@ ${sdkParameters} function generateResponseExample(endpoint: ApiEndpoint): string { // Find the 'type' field from the request to potentially echo in response (common pattern) const reqTypeField = endpoint.requestBody?.fields?.find( - (f) => f.name === "type" + (f) => f.name === "type", ); const reqTypeDetails = reqTypeField ? getEnumDetails(reqTypeField) @@ -569,7 +597,7 @@ function generateResponseExample(endpoint: ApiEndpoint): string { // Attempt to find the 200 OK response schema const successResponse = endpoint.responses?.find( - (res) => res.statusCode === 200 + (res) => res.statusCode === 200, ); // Generate payload based on response schema if available, otherwise fallback @@ -577,7 +605,7 @@ function generateResponseExample(endpoint: ApiEndpoint): string { if (successResponse?.fields) { resultPayload = generateJsonPayloadRecursive( successResponse.fields, - endpoint.path + endpoint.path, ); } else { resultPayload = { "": "" }; @@ -599,14 +627,14 @@ function generateResponseExample(endpoint: ApiEndpoint): string { responseJsonString = JSON.stringify( responsePayloadObject, (_key, value) => (typeof value === "bigint" ? value.toString() : value), - 2 + 2, ); // 2-space indent } else { // Query endpoints: just the result object responseJsonString = JSON.stringify( resultPayload, (_key, value) => (typeof value === "bigint" ? value.toString() : value), - 2 + 2, ); } @@ -632,11 +660,11 @@ function determineSubdirectory(endpointPath: string): string { export function generateMdxFile( endpoint: ApiEndpoint, baseOutputDir: string, - addOnly: boolean = false + addOnly: boolean = false, ): string | null { if (!endpoint.title || !endpoint.path) { console.warn( - `Skipping MDX generation for endpoint (Title: ${endpoint.title}, Path: ${endpoint.path}) due to missing title or path.` + `Skipping MDX generation for endpoint (Title: ${endpoint.title}, Path: ${endpoint.path}) due to missing title or path.`, ); return null; } @@ -680,7 +708,7 @@ export function generateMdxFile( return relativeOutputPathWithoutExt; // Return the relative path for index generation } catch (error: any) { console.error( - `Error generating MDX file for endpoint "${endpoint.title}": ${error.message}` + `Error generating MDX file for endpoint "${endpoint.title}": ${error.message}`, ); if (error.stack) console.error(error.stack); return null; // Indicate failure @@ -723,7 +751,7 @@ import { EndpointPath } from "/snippets/api/endpoint.mdx"; // 3. Response Body Parameters Section (Assuming 200 OK) const successResponse = endpoint.responses?.find( - (res) => res.statusCode === 200 + (res) => res.statusCode === 200, ); if (successResponse?.fields && successResponse.fields.length > 0) { diff --git a/scripts/openapi-gen/utils/mdx-generator/index.ts b/scripts/openapi-gen/utils/mdx-generator/index.ts index eff5e850..947709a8 100644 --- a/scripts/openapi-gen/utils/mdx-generator/index.ts +++ b/scripts/openapi-gen/utils/mdx-generator/index.ts @@ -1,5 +1,5 @@ /** * MDX Generator module exports */ -export * from './generator'; -export * from './auth-proxy-generator'; +export * from "./generator"; +export * from "./auth-proxy-generator"; diff --git a/scripts/openapi-gen/utils/parser.ts b/scripts/openapi-gen/utils/parser.ts index 312576f0..704b1973 100644 --- a/scripts/openapi-gen/utils/parser.ts +++ b/scripts/openapi-gen/utils/parser.ts @@ -24,7 +24,7 @@ export function validateFile(filePath: string): string { * Parse and dereference an OpenAPI specification */ export async function parseOpenAPI( - options: OpenAPIParserOptions + options: OpenAPIParserOptions, ): Promise { try { // Validate file exists before attempting to parse @@ -39,7 +39,7 @@ export async function parseOpenAPI( // Dereference the parsed JSON const api = await OpenAPIParser.default.dereference(jsonContent); - console.log('api', api); + console.log("api", api); return api; } catch (error: any) { diff --git a/sdks/advanced/api-key-stamper.mdx b/sdks/advanced/api-key-stamper.mdx index ab892d55..dda07753 100644 --- a/sdks/advanced/api-key-stamper.mdx +++ b/sdks/advanced/api-key-stamper.mdx @@ -23,6 +23,7 @@ pnpm i @turnkey/api-key-stamper ```bash yarn yarn add @turnkey/api-key-stamper ``` + ## Initializing @@ -38,6 +39,7 @@ The `ApiKeyStamper` class implements the `TStamper` interface used by the [Turnk > An object containing configuration settings for the stamper. + Your Turnkey API private key. + Your Turnkey API public key. + ### Types @@ -117,6 +121,7 @@ Creates a digital stamp which includes the public key, signature scheme, and a s > The payload that needs to be stamped. + #### Types diff --git a/sdks/advanced/client-side-signing.mdx b/sdks/advanced/client-side-signing.mdx index 481ccedd..490d3c75 100644 --- a/sdks/advanced/client-side-signing.mdx +++ b/sdks/advanced/client-side-signing.mdx @@ -126,7 +126,7 @@ import { Turnkey } from "@turnkey/sdk-server"; export default async function handler( req: NextApiRequest, - res: NextApiResponse + res: NextApiResponse, ) { const { walletAccountAddress, targetPublicKey } = req.body; @@ -158,7 +158,7 @@ import axios from "axios"; async function exportKeyToIframe( iframeStamper: IframeStamper, walletAccountAddress: string, - organizationId: string + organizationId: string, ) { // Step 3a: Get or initialize the embedded key let embeddedKey = await iframeStamper.getEmbeddedPublicKey(); @@ -178,7 +178,7 @@ async function exportKeyToIframe( response.data.exportBundle, organizationId, KeyFormat.Hexadecimal, // or KeyFormat.Solana for Solana-formatted keys - walletAccountAddress // Required for multi-key support + walletAccountAddress, // Required for multi-key support ); if (!injected) { @@ -198,14 +198,14 @@ import { MessageType } from "@turnkey/iframe-stamper"; async function signMessage( iframeStamper: IframeStamper, message: string, - walletAccountAddress: string + walletAccountAddress: string, ): Promise { const signature = await iframeStamper.signMessage( { message, type: MessageType.Solana, }, - walletAccountAddress // Required when multiple keys are loaded + walletAccountAddress, // Required when multiple keys are loaded ); return signature; // Returns hex-encoded signature @@ -220,14 +220,14 @@ import { TransactionType } from "@turnkey/iframe-stamper"; async function signTransaction( iframeStamper: IframeStamper, serializedTransaction: string, // Hex-encoded transaction bytes - walletAccountAddress: string + walletAccountAddress: string, ): Promise { const signedTransaction = await iframeStamper.signTransaction( { transaction: serializedTransaction, type: TransactionType.Solana, }, - walletAccountAddress + walletAccountAddress, ); return signedTransaction; // Returns hex-encoded signed transaction @@ -246,7 +246,7 @@ Since the embedded key persists across bundle injections, you can export multipl async function loadMultipleKeys( iframeStamper: IframeStamper, addresses: string[], - organizationId: string + organizationId: string, ) { // Get or initialize the embedded key once let embeddedKey = await iframeStamper.getEmbeddedPublicKey(); @@ -264,7 +264,7 @@ async function loadMultipleKeys( response.data.exportBundle, organizationId, KeyFormat.Hexadecimal, - address // Each key is stored by its address + address, // Each key is stored by its address ); } } @@ -276,13 +276,13 @@ async function loadMultipleKeys( // Sign with the first address const sig1 = await iframeStamper.signMessage( { message: "Hello", type: MessageType.Solana }, - "address1..." + "address1...", ); // Sign with the second address const sig2 = await iframeStamper.signMessage( { message: "World", type: MessageType.Solana }, - "address2..." + "address2...", ); ``` @@ -321,13 +321,13 @@ Understanding the key lifecycle is important for building reliable applications. async function ensureKeyLoaded( iframeStamper: IframeStamper, address: string, - organizationId: string + organizationId: string, ) { try { // Attempt to sign a test message await iframeStamper.signMessage( { message: "test", type: MessageType.Solana }, - address + address, ); } catch (error) { // Key not found or expired - re-export diff --git a/sdks/advanced/iframe-stamper.mdx b/sdks/advanced/iframe-stamper.mdx index 9421ca48..2be72210 100644 --- a/sdks/advanced/iframe-stamper.mdx +++ b/sdks/advanced/iframe-stamper.mdx @@ -27,6 +27,7 @@ pnpm i @turnkey/iframe-stamper ```bash yarn yarn add @turnkey/iframe-stamper ``` + ## Initializing @@ -44,6 +45,7 @@ The IframeStamper class, part of the @turnkey/iframe-stamper package, is designe > An object containing configuration settings for the iframe stamper. + The URL of the iframe to be used. + The ID to assign to the iframe element. + The container element in which the iframe will be inserted. + #### Types @@ -124,6 +129,7 @@ Injects a new credential bundle into the iframe, a process used in email authent > The encrypted credential bundle that needs to be injected into the iframe. This bundle should be encrypted with the iframe's initial public key using HPKE ([RFC 9180](https://www.rfc-editor.org/rfc/rfc9180.html)). + #### Example @@ -150,6 +156,7 @@ Injects an export bundle into the iframe. This method is used during key export > The encrypted export bundle that needs to be injected into the iframe. This bundle should be encrypted with the iframe's initial public key using HPKE ([RFC 9180](https://www.rfc-editor.org/rfc/rfc9180.html)). + #### Example @@ -176,6 +183,7 @@ Injects a wallet export bundle into the iframe. This method is typically used du > The encrypted wallet export bundle to be injected into the iframe. This bundle must be encrypted using the iframe's initial public key according to HPKE (RFC 9180) standards. + #### Example diff --git a/sdks/advanced/overview.mdx b/sdks/advanced/overview.mdx index 1cd958d1..e8b656c6 100644 --- a/sdks/advanced/overview.mdx +++ b/sdks/advanced/overview.mdx @@ -4,14 +4,55 @@ description: "Use Turnkey's low-level http libraries directly" sidebarTitle: "Overview" --- -import { FeatureCard } from '/snippets/feature-card.mdx' +import { FeatureCard } from "/snippets/feature-card.mdx"; -
- - - - - - - +
+ + + + + + +
diff --git a/sdks/advanced/turnkey-client.mdx b/sdks/advanced/turnkey-client.mdx index 0f2eeb78..e790b8a4 100644 --- a/sdks/advanced/turnkey-client.mdx +++ b/sdks/advanced/turnkey-client.mdx @@ -22,6 +22,7 @@ pnpm i @turnkey/http ```bash yarn yarn add @turnkey/http ``` + ## Initializing @@ -39,6 +40,7 @@ You can initialize a new **`TurnkeyClient`** using the **`TurnkeyClient`** const > An object containing configuration settings for the client. + The base URL for the Turnkey API. Note: An error `Missing base URL. Please verify env vars.` will be thrown if a value is not provided. + An instance of a stamper class (e.g. [**`ApiKeyStamper`**](/sdks/advanced/api-key-stamper)) used to create signatures for authenticating API requests. + Currently Turnkey provides 3 stampers: -* applications signing requests with Passkeys or webauthn devices should use [`@turnkey/webauthn-stamper`](/sdks/advanced/webauthn-stamper) -* applications signing requests with API keys should use [`@turnkey/api-key-stamper`](/sdks/advanced/api-key-stamper) -* applications that need to sign requests within an iframe, particularly when handling sensitive operations like Auth, or Key or Wallet Export, should use the [`@turnkey/iframe-stamper`](/sdks/advanced/iframe-stamper). +- applications signing requests with Passkeys or webauthn devices should use [`@turnkey/webauthn-stamper`](/sdks/advanced/webauthn-stamper) +- applications signing requests with API keys should use [`@turnkey/api-key-stamper`](/sdks/advanced/api-key-stamper) +- applications that need to sign requests within an iframe, particularly when handling sensitive operations like Auth, or Key or Wallet Export, should use the [`@turnkey/iframe-stamper`](/sdks/advanced/iframe-stamper). You can also implement the TStamper interface yourself. For more information on implementing a custom stamper checkout the [API Design](/api-reference/overview/intro) docs. diff --git a/sdks/advanced/wallet-stamper.mdx b/sdks/advanced/wallet-stamper.mdx index 649e1d6a..ba11978f 100644 --- a/sdks/advanced/wallet-stamper.mdx +++ b/sdks/advanced/wallet-stamper.mdx @@ -23,6 +23,7 @@ pnpm i @turnkey/wallet-stamper ```bash yarn yarn add @turnkey/wallet-stamper ``` + ## Initializing @@ -39,6 +40,7 @@ The `WalletStamper` class implements the `TStamper` interface used by the [Turnk > An object representing your wallet, either a Solana or EVM wallet. + The type of wallet, either `solana` or `evm`. + A function that signs a message using your wallet's private key. + A function that recovers the public key from the signed message (required for EVM wallets). + #### Types @@ -109,6 +114,7 @@ Signs the payload using the wallet's private key and returns the stamp to be use > The payload that to be stamped. This is the stringified JSON request body that you want to send to Turnkey's API. + #### Types diff --git a/sdks/advanced/webauthn-stamper.mdx b/sdks/advanced/webauthn-stamper.mdx index de84d53a..5abef177 100644 --- a/sdks/advanced/webauthn-stamper.mdx +++ b/sdks/advanced/webauthn-stamper.mdx @@ -25,6 +25,7 @@ pnpm i @turnkey/webauthn-stamper ```bash yarn yarn add @turnkey/webauthn-stamper ``` + ## Initializing @@ -42,6 +43,7 @@ The `WebauthnStamper` class is a utility designed to facilitate the process of c > An object containing configuration settings for the stamper. + The RPID ("Relying Party ID") for your origin. For an origin named `https://www.example.com`, the RPID is typically `example.com`. If you're testing on localhost, the RPID should be `localhost`. + The time in milliseconds before the stamp request times out. Defaults to 300000 milliseconds (5 minutes) if not specified. + Specifies the user verification requirements. Can be set to values like `required`, `preferred`, or `discouraged`. Defaults to `preferred` if not provided. + An array of credential descriptors specifying the credentials to be allowed during authentication. This is optional and defaults to an empty array. + #### Types @@ -138,6 +144,7 @@ Creates a digital stamp, which includes the public key, signature scheme, and a > The Turnkey activity request, or query to be sent to Turnkey's API. + #### Types diff --git a/sdks/foundry.mdx b/sdks/foundry.mdx index 139828b8..9401ed2d 100644 --- a/sdks/foundry.mdx +++ b/sdks/foundry.mdx @@ -3,5 +3,3 @@ title: "Foundry" description: "[Foundry](https://getfoundry.sh/introduction/overview) offers native support for deploying smart contracts from Turnkey wallets. See [https://github.com/tkhq/sdk/tree/main/examples/foundry](https://github.com/tkhq/sdk/tree/main/examples/foundry) for a code example, including `.env` setup." mode: wide --- - - diff --git a/sdks/introduction.mdx b/sdks/introduction.mdx index 38b02e55..ddb54f66 100644 --- a/sdks/introduction.mdx +++ b/sdks/introduction.mdx @@ -11,32 +11,31 @@ A checkmark in the table indicates that the SDK provides either a complete imple Turnkey also has several [wrappers for popular web3 libraries](/sdks/web3/overview) to streamline integration into existing dApps. ## Client side SDKs -| | [TypeScript](/solutions/embedded-wallets/integration-guide/typescript/index) | [React](/solutions/embedded-wallets/integration-guide/react/index) | [React Native](/solutions/embedded-wallets/integration-guide/react-native/overview) | [Flutter](/solutions/embedded-wallets/integration-guide/flutter/index) | [Swift](/solutions/embedded-wallets/integration-guide/swift/overview) | [Kotlin](/solutions/embedded-wallets/integration-guide/kotlin/overview) | -|-------------------------------|-----------------------------------------------|-----------------------------------------------|-----------------------------------------------|-----------------------------------------------|-----------------------------------------------| ----------------------------------------------| -| **Authentication** | | | | | | -| Email | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| SMS | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| Passkey | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| Google | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| Facebook | ✓ | ✓ | ✓ | | | | -| Apple | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| Discord | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| X (Twitter) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| Web3 Wallets | ✓ | ✓ | | | | -| **Embedded Wallets** | | | | | | -| Wallet Creation | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| Signing | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| Import | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| Export | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | -| **Arbitrary Request Signing** | | | | | | -| Stamping | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| | [TypeScript](/solutions/embedded-wallets/integration-guide/typescript/index) | [React](/solutions/embedded-wallets/integration-guide/react/index) | [React Native](/solutions/embedded-wallets/integration-guide/react-native/overview) | [Flutter](/solutions/embedded-wallets/integration-guide/flutter/index) | [Swift](/solutions/embedded-wallets/integration-guide/swift/overview) | [Kotlin](/solutions/embedded-wallets/integration-guide/kotlin/overview) | +| ----------------------------- | ---------------------------------------------------------------------------- | ------------------------------------------------------------------ | ----------------------------------------------------------------------------------- | ---------------------------------------------------------------------- | --------------------------------------------------------------------- | ----------------------------------------------------------------------- | +| **Authentication** | | | | | | +| Email | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| SMS | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| Passkey | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| Google | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| Facebook | ✓ | ✓ | ✓ | | | | +| Apple | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| Discord | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| X (Twitter) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| Web3 Wallets | ✓ | ✓ | | | | +| **Embedded Wallets** | | | | | | +| Wallet Creation | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| Signing | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| Import | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| Export | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| **Arbitrary Request Signing** | | | | | | +| Stamping | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ## Server side SDKs -| | [TypeScript](/solutions/company-wallets/integration-guide/javascript-server) | [Go](/solutions/company-wallets/integration-guide/golang) | [Ruby](/solutions/company-wallets/integration-guide/ruby) | [Rust](/solutions/company-wallets/integration-guide/rust) | [Python](/solutions/company-wallets/integration-guide/python) | -|---------------------|---------------------------------------|--------------------|--------------------|--------------------|-----------------------| -| **Authentication** | ✓ | ✓ | ✓ | ✓ | ✓ | -| **Wallet Management** | ✓ | ✓ | ✓ | | | -| **Policy Management** | ✓ | ✓ | ✓ | | | - +| | [TypeScript](/solutions/company-wallets/integration-guide/javascript-server) | [Go](/solutions/company-wallets/integration-guide/golang) | [Ruby](/solutions/company-wallets/integration-guide/ruby) | [Rust](/solutions/company-wallets/integration-guide/rust) | [Python](/solutions/company-wallets/integration-guide/python) | +| --------------------- | ---------------------------------------------------------------------------- | --------------------------------------------------------- | --------------------------------------------------------- | --------------------------------------------------------- | ------------------------------------------------------------- | +| **Authentication** | ✓ | ✓ | ✓ | ✓ | ✓ | +| **Wallet Management** | ✓ | ✓ | ✓ | | | +| **Policy Management** | ✓ | ✓ | ✓ | | | diff --git a/sdks/swift/proxy-middleware.mdx b/sdks/swift/proxy-middleware.mdx index b08c9005..a72a527e 100644 --- a/sdks/swift/proxy-middleware.mdx +++ b/sdks/swift/proxy-middleware.mdx @@ -22,9 +22,9 @@ This initializer configures the `TurnkeyClient` to route all requests through th This setup is especially useful for operations like: -* Email [authentication](/features/authentication/email) -* Wallet [import](/features/wallets/import-wallets) & [export](/features/wallets/export-wallets) -* [Sub-organization creation](/features/sub-organizations#creating-sub-organizations) +- Email [authentication](/features/authentication/email) +- Wallet [import](/features/wallets/import-wallets) & [export](/features/wallets/export-wallets) +- [Sub-organization creation](/features/sub-organizations#creating-sub-organizations) ## Request header diff --git a/sdks/web3/gas-station.mdx b/sdks/web3/gas-station.mdx index c53abccd..ba1388cd 100644 --- a/sdks/web3/gas-station.mdx +++ b/sdks/web3/gas-station.mdx @@ -5,7 +5,10 @@ mode: wide --- - Looking for a turnkey solution? If you don't want to build your own paymaster, Turnkey's native Transaction Management handles gas sponsorship for both EVM and Solana out of the box. See the [Transaction Management](/features/transaction-management) overview to get started. + Looking for a turnkey solution? If you don't want to build your own paymaster, + Turnkey's native Transaction Management handles gas sponsorship for both EVM + and Solana out of the box. See the [Transaction + Management](/features/transaction-management) overview to get started. The Gas Station SDK enables you to implement gasless transactions using EIP-7702 delegation and EIP-712 signed intents. This SDK is designed to work with Turnkey-managed paymaster wallets within your organization, allowing you to sponsor transactions for your users so they can execute transactions without needing ETH for gas fees. diff --git a/sdks/web3/overview.mdx b/sdks/web3/overview.mdx index 1c1b1790..40730917 100644 --- a/sdks/web3/overview.mdx +++ b/sdks/web3/overview.mdx @@ -5,14 +5,55 @@ mode: wide sidebarTitle: "Overview" --- -import { FeatureCard } from '/snippets/feature-card.mdx' +import { FeatureCard } from "/snippets/feature-card.mdx"; -
- - - - - - - +
+ + + + + + +
diff --git a/sdks/web3/viem.mdx b/sdks/web3/viem.mdx index 471c5e0f..982d27e6 100644 --- a/sdks/web3/viem.mdx +++ b/sdks/web3/viem.mdx @@ -4,4 +4,4 @@ description: "[`@turnkey/viem`](https://www.npmjs.com/package/@turnkey/viem) pro mode: wide --- -See the [`with-viem`](https://github.com/tkhq/sdk/tree/main/examples/with-viem) example. \ No newline at end of file +See the [`with-viem`](https://github.com/tkhq/sdk/tree/main/examples/with-viem) example. diff --git a/sdks/web3/wagmi.mdx b/sdks/web3/wagmi.mdx index f9e394e4..97ed031b 100644 --- a/sdks/web3/wagmi.mdx +++ b/sdks/web3/wagmi.mdx @@ -1,6 +1,5 @@ --- title: Integrating an embedded wallet with Wagmi - --- Turnkey wallets are embedded, web-based wallets that differ from injected wallets (like MetaMask). @@ -175,7 +174,7 @@ export function AuthButton() { const { accounts, chainId } = await authenticateWithTurnkey(); window.opener?.postMessage( { type: "ETH_ACCOUNTS", accounts, chainId }, - "*" + "*", ); window.close(); } finally { @@ -254,7 +253,7 @@ window.opener?.postMessage( accounts, // e.g. ["0xAbc…"] chainId, // e.g. 17000 (Holesky) }, - "*" + "*", ); // Optionally close the popup or show a success screen ``` @@ -295,10 +294,10 @@ export function createEIP1193Provider(): EIP1193Provider { top = window.screenY + (window.outerHeight - h) / 2; popup = window.open( `http://localhost:3001?request=${encodeURIComponent( - JSON.stringify({ method, params }) + JSON.stringify({ method, params }), )}`, "Berakin Wallet", - `width=${w},height=${h},left=${left},top=${top}` + `width=${w},height=${h},left=${left},top=${top}`, ); if (!popup) reject(new Error("Popup blocked")); }); @@ -388,7 +387,7 @@ export function SignTransaction({ transaction, organizationId }: Props) { const txHash = await signAndSend(transaction, organizationId); window.opener?.postMessage( { type: "RPC_RESPONSE", method: "eth_signTransaction", result: txHash }, - "*" + "*", ); window.close(); } catch (err: unknown) { @@ -451,7 +450,7 @@ export function SignMessage({ }); window.opener?.postMessage( { type: "RPC_RESPONSE", method, result: signature }, - "*" + "*", ); window.close(); } catch (err: unknown) { @@ -485,7 +484,7 @@ export function SignMessage({ export async function signAndSend( tx: unknown, - organizationId: string + organizationId: string, ): Promise { /* 1. Stamp the transaction with Turnkey. diff --git a/security/overview.mdx b/security/overview.mdx index 849399e8..c0eab627 100644 --- a/security/overview.mdx +++ b/security/overview.mdx @@ -4,7 +4,7 @@ sidebarTitle: Overview description: "Learn how Turnkey achieves innovative, cloud scale, no single point of failure security." --- -import { FeatureCard } from '/snippets/feature-card.mdx' +import { FeatureCard } from "/snippets/feature-card.mdx"; Turnkey is the first verifiable key management system of its kind, securing millions of wallets and private keys for a wide variety of use cases. Turnkey's security architecture ensures that raw private keys are never exposed to Turnkey, your software, or your team. @@ -14,17 +14,83 @@ minimizes attack surface and enables reproducible, auditable deployments. From h every layer of Turnkey's architecture is designed to be secure, verifiable, and developer-friendly by default. Our whitepaper covers our holistic security model in-depth, and speaks to our vision for building verifiable key management infrastructure. Learn more about our approach to security here. -
- - - - - - - - - - - - +
+ + + + + + + + + + + +
diff --git a/security/reporting-a-vulnerability.mdx b/security/reporting-a-vulnerability.mdx index f91331ee..f7840777 100644 --- a/security/reporting-a-vulnerability.mdx +++ b/security/reporting-a-vulnerability.mdx @@ -2,7 +2,7 @@ title: "Reporting a vulnerability" --- -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 below, which is our preferred path for vulnerability reports. Alternatively, you may email us at [security@turnkey.com](mailto:security@turnkey.com). When submitting a report, please provide a thorough description of the vulnerability, including steps to reproduce it and its potential impact. +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 below, which is our preferred path for vulnerability reports. Alternatively, you may email us at [security@turnkey.com](mailto:security@turnkey.com). When submitting a report, please provide a thorough description of the vulnerability, including steps to reproduce it and its potential impact. 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.txt diff --git a/security/shared-responsibility-model.mdx b/security/shared-responsibility-model.mdx index 4022336e..815f9147 100644 --- a/security/shared-responsibility-model.mdx +++ b/security/shared-responsibility-model.mdx @@ -2,16 +2,18 @@ title: "Turnkey shared responsibility model" --- -When integrating your product with Turnkey, it is critical to understand which security tasks are Turnkey’s responsibility, and which tasks are your responsibility. +When integrating your product with Turnkey, it is critical to understand which security tasks are Turnkey’s responsibility, and which tasks are your responsibility. Turnkey provides secure, scalable, and programmable crypto infrastructure. Flexibility is at the core of our product, which means you have the freedom to integrate Turnkey in ways that may or may not fully meet your product’s security requirements. As detailed below, you are responsible for securing both your Turnkey organization, and your integration with Turnkey. ## Turnkey’s responsibility: security of the platform -Turnkey is responsible for securing the infrastructure that runs the services offered by Turnkey. + +Turnkey is responsible for securing the infrastructure that runs the services offered by Turnkey. This includes the security of all Turnkey-authored code, from the code running within our enclaves to our SDKs, and everything in between. -Turnkey commits to securing the Confidentiality, Integrity, and Availability of the Turnkey platform. Turnkey’s responsibilities therefore include: +Turnkey commits to securing the Confidentiality, Integrity, and Availability of the Turnkey platform. Turnkey’s responsibilities therefore include: + - Maintaining the confidentiality of secret materials stored with Turnkey, in particular but not limited to cryptocurrency private keys; - Ensuring the integrity of all end user requests that are made to Turnkey’s system and all data associated with those requests; and - Providing constant [availability](https://www.turnkey-status.com) of Turnkey’s services. @@ -19,7 +21,8 @@ Turnkey commits to securing the Confidentiality, Integrity, and Availability of Turnkey also offers multiple options for various components of Turnkey’s product in order to accommodate customers with varying security and user experience profiles. This allows each Turnkey customer to choose a security approach tailored to their specific needs. ## Customer’s responsibility: security using the platform -Customers are responsible for the decisions they make when using Turnkey. Each customer’s unique product and threat model play a critical role in determining the appropriate configurations and integration patterns, including choices that could impact security. + +Customers are responsible for the decisions they make when using Turnkey. Each customer’s unique product and threat model play a critical role in determining the appropriate configurations and integration patterns, including choices that could impact security. Customers are responsible for securely integrating their product with Turnkey. Turnkey provides extensive [documentation and examples](https://docs.turnkey.com/home) for building multiple products, including guidance on authentication flows, appropriate feature selection, credential management, and more. Each customer’s implementation choices differ significantly based on the unique integration of Turnkey, and therefore the ultimate responsibility remains with the customer to select the right approach. @@ -28,16 +31,21 @@ In addition, customers are responsible for securing their Turnkey organizations. ## Illustrations of the shared responsibility model ### Authentication and authorization -- Turnkey is responsible for ensuring authentication correctness and that any action taken within an authenticated context is unable to exceed previously granted permissions. + +- Turnkey is responsible for ensuring authentication correctness and that any action taken within an authenticated context is unable to exceed previously granted permissions. - Customers are responsible for ensuring that authorization permissions are appropriately configured for each user and that user authentication credentials are securely managed. -### Policies -Turnkey has built and maintains a [policy engine](https://docs.turnkey.com/concepts/policies/overview), which is the foundation for granular controls and permissions when using Turnkey. Customers are able to use the policy engine to define key- and wallet-use policies specific to their needs. -- Turnkey is responsible for ensuring that policies are always evaluated correctly, reflecting the policy as authored by the customer. +### Policies + +Turnkey has built and maintains a [policy engine](https://docs.turnkey.com/concepts/policies/overview), which is the foundation for granular controls and permissions when using Turnkey. Customers are able to use the policy engine to define key- and wallet-use policies specific to their needs. + +- Turnkey is responsible for ensuring that policies are always evaluated correctly, reflecting the policy as authored by the customer. - Customers are responsible for authoring valid policies that address their specific key and wallet permissions and usage requirements. ## Additional guidance on applying the shared responsibility model + Turnkey provides comprehensive documentation to help customers effectively manage their responsibilities within the shared responsibility model: + - [Evaluating the security of your root quorum configuration](https://docs.turnkey.com/concepts/users/root-quorum?share_chat=1ef47f7f-e895-4195-9590-af958441dedc) - [Understanding Turnkey authentication](https://docs.turnkey.com/authentication/passkeys/introduction) -- [Turnkey Whitepaper: Understanding Turnkey’s architecture and security model](https://whitepaper.turnkey.com) \ No newline at end of file +- [Turnkey Whitepaper: Understanding Turnkey’s architecture and security model](https://whitepaper.turnkey.com) diff --git a/security/turnkey-verified.mdx b/security/turnkey-verified.mdx index 2b84abe1..258117c3 100644 --- a/security/turnkey-verified.mdx +++ b/security/turnkey-verified.mdx @@ -11,8 +11,9 @@ For the first time we're exposing proofs produced by our TEEs to the outside wor ### Boot Proofs A Boot Proof is a proof that a particular AWS Nitro Enclave has booted with a particular configuration. A Boot Proof contains: -* An AWS attestation document, which contains AWS-level information: [PCR measurements](https://docs.aws.amazon.com/enclaves/latest/user/set-up-attestation.html#where), certificate chain, public key, and user data. -* A signed [QOS manifest](https://github.com/tkhq/qos/blob/f773bb8fbe0b84c93c585f1ab10882fb570d8005/src/qos_core/src/protocol/services/boot.rs#L310-L327) which contains information about the application running in this particular enclave: binary hash and arguments, operator public keys, quorum public key, and more. + +- An AWS attestation document, which contains AWS-level information: [PCR measurements](https://docs.aws.amazon.com/enclaves/latest/user/set-up-attestation.html#where), certificate chain, public key, and user data. +- A signed [QOS manifest](https://github.com/tkhq/qos/blob/f773bb8fbe0b84c93c585f1ab10882fb570d8005/src/qos_core/src/protocol/services/boot.rs#L310-L327) which contains information about the application running in this particular enclave: binary hash and arguments, operator public keys, quorum public key, and more. ### App Proofs @@ -24,25 +25,26 @@ We envision enclave applications will need to prove many different types of fact To summarize: App Proofs contain JSON payloads, serialized and signed by enclave Ephemeral Keys. - ### Claims and verification Boot Proofs are application-agnostic. They prove 3 claims: -* **A particular machine is a legitimate AWS Nitro Enclave**. This can be verified by checking the signature of the attestation and the associated certificate bundle: it contains a chain of certificates going up to the root certificate for the commercial AWS partitions (can be downloaded from https://aws-nitro-enclaves.amazonaws.com/AWS_NitroEnclaves_Root-G1.zip). -* **A particular machine is running within Turnkey's AWS account**. This can be verified by looking at the `PCR3` measurement inside of the AWS attestation document. It should be `b798abfdbd591d5e1b7db6485a6de9e65100f5796d9e3a2bd7c179989cd663338b567162974974fbcc45d03847e70d8b` (this is the sha384 digest of the parent instance role: `arn:aws:iam::705331783682:role/talos-worker`. The role is `talos-worker` because Turnkey uses a [Talos](https://www.talos.dev/)-based Kubernetes cluster to deploy all software, including enclave software). -* **A particular machine runs the correct, expected software**. This can be verified in a few steps: - * Verify that `PCR0`, `PCR1`, and `PCR2` values are correct and match a known QOS version. You can [reproduce these hashes yourself](https://github.com/tkhq/qos?tab=readme-ov-file#reproducing-builds) or look at our [`tkhq/core-enclaves`](https://github.com/tkhq/core-enclaves) repository for known good values. - * Verify that the AWS attestation document's `user_data` is the digest of the QOS manifest, to ensure you are looking at the correct QOS manifest. - * Parse the QOS manifest and inspect it to find the digest of the application. - * Verify this digest against known good digests published in our [`tkhq/core-enclaves`](https://github.com/tkhq/core-enclaves) repository. + +- **A particular machine is a legitimate AWS Nitro Enclave**. This can be verified by checking the signature of the attestation and the associated certificate bundle: it contains a chain of certificates going up to the root certificate for the commercial AWS partitions (can be downloaded from https://aws-nitro-enclaves.amazonaws.com/AWS_NitroEnclaves_Root-G1.zip). +- **A particular machine is running within Turnkey's AWS account**. This can be verified by looking at the `PCR3` measurement inside of the AWS attestation document. It should be `b798abfdbd591d5e1b7db6485a6de9e65100f5796d9e3a2bd7c179989cd663338b567162974974fbcc45d03847e70d8b` (this is the sha384 digest of the parent instance role: `arn:aws:iam::705331783682:role/talos-worker`. The role is `talos-worker` because Turnkey uses a [Talos](https://www.talos.dev/)-based Kubernetes cluster to deploy all software, including enclave software). +- **A particular machine runs the correct, expected software**. This can be verified in a few steps: + - Verify that `PCR0`, `PCR1`, and `PCR2` values are correct and match a known QOS version. You can [reproduce these hashes yourself](https://github.com/tkhq/qos?tab=readme-ov-file#reproducing-builds) or look at our [`tkhq/core-enclaves`](https://github.com/tkhq/core-enclaves) repository for known good values. + - Verify that the AWS attestation document's `user_data` is the digest of the QOS manifest, to ensure you are looking at the correct QOS manifest. + - Parse the QOS manifest and inspect it to find the digest of the application. + - Verify this digest against known good digests published in our [`tkhq/core-enclaves`](https://github.com/tkhq/core-enclaves) repository. App Proofs and Boot Proofs are linked together by the `public_key` field of the AWS attestation document. So, in addition to proving the key claims outlined above, a Boot Proof proves the validity of all App Proofs signed by the Ephemeral Key it references. In other words, a Boot Proof attests to the fact that the public key referenced in its `public_key` field is indeed the Ephemeral Key of a particular enclave, provisioned with a very specific configuration, operating system, and application. Verifying an App Proof thus involves 3 simple steps: -* Verify that the App Proof public key matches the `public_key` field of a **valid** Boot Proof. -* Verify the App Proof signature validity (standard P-256 signature verification) -* Parse the content of the App Proof payload (JSON) and use the data within it to verify claimed facts (see below for an example). + +- Verify that the App Proof public key matches the `public_key` field of a **valid** Boot Proof. +- Verify the App Proof signature validity (standard P-256 signature verification) +- Parse the content of the App Proof payload (JSON) and use the data within it to verify claimed facts (see below for an example). ## Use cases @@ -53,6 +55,7 @@ You can enable App Proofs for any [activity](/api-reference/activities/overview) Address derivation proofs verify that a crypto address was correctly derived by Turnkey's **signer application**. These proofs are generated when new wallets are created. Turnkey verified will automatically fetch and verify proofs for you when new wallets are created through Turnkey's [Embedded Wallet Kit](/solutions/embedded-wallets/integration-guide/react/getting-started) or via Turnkey's [dashboard](https://app.turnkey.com). The payload: + ```json { "type": "APP_PROOF_TYPE_ADDRESS_DERIVATION", @@ -71,6 +74,7 @@ The payload: Policy outcome proofs verify that policy decisions for your activity requests were properly evaluated against your org's policies by Turnkey's **policy engine application** in a secure enclave. These proofs can be generated for all activities. The payload: + ```json { "type": "APP_PROOF_TYPE_POLICY_OUTCOME", @@ -96,20 +100,21 @@ All App Proofs share a common structure. Enclave applications sign the above JSO // Fake Ephemeral Public Key used for demonstration purposes "publicKey": "04dc8333ff552b2ffa91d410c10ad0ae36055a9232f176e07f115db460aafbb959057834d367d1724b699b56bd2fd5ca30d3ee755f93c68c24a67e8e60bf37c7dd045417fb43faadacd8471cfbbf3733f4b4ea5602b9d84d3731d581fe7a69b7de42a025e5f63b8580bdb38c76b8ac3c2ae17ed047993c19835eca0491753de52f01", // Serialized payload matching the example from above - "proofPayload":"{\"type\":\"APP_PROOF_TYPE_ADDRESS_DERIVATION\",\"timestampMs\":\"1758909116\",\"addressDerivationProof\":{\"organizationId\":\"your-organization-id\",\"walletId\":\"your-wallet-id\",\"derivationPath\":\"m/44'/60'/0'/0/0\",\"address\":\"0x61f4Ec0630DD50F1393cbDB60e5ccA1ed98f5100\"}}", + "proofPayload": "{\"type\":\"APP_PROOF_TYPE_ADDRESS_DERIVATION\",\"timestampMs\":\"1758909116\",\"addressDerivationProof\":{\"organizationId\":\"your-organization-id\",\"walletId\":\"your-wallet-id\",\"derivationPath\":\"m/44'/60'/0'/0/0\",\"address\":\"0x61f4Ec0630DD50F1393cbDB60e5ccA1ed98f5100\"}}", // P-256 signature by the Ephemeral Key over the proofPayload (JSON) bytes - "signature":"ecdff31d3543cd65cc9c9f8e4e758be226243b212d44426a8f9e8fefe7ba2a95410a661818560b43e92404a2ec6e6dcbe2bb79e329be0b4df441ba715d6fce44" + "signature": "ecdff31d3543cd65cc9c9f8e4e758be226243b212d44426a8f9e8fefe7ba2a95410a661818560b43e92404a2ec6e6dcbe2bb79e329be0b4df441ba715d6fce44" } ``` #### Verification guarantees By combining App Proof and Boot Proof verification, Turnkey Verified guarantees that the operation was performed: -* in the context of your Turnkey organization -* within a secure Turnkey enclave application -* inside of a legitimate and precise version of [QuorumOS](https://github.com/tkhq/qos) -* inside of a legitimate [AWS Nitro Enclave](https://docs.aws.amazon.com/enclaves/latest/user/nitro-enclave.html) -* inside Turnkey's canonical AWS production account + +- in the context of your Turnkey organization +- within a secure Turnkey enclave application +- inside of a legitimate and precise version of [QuorumOS](https://github.com/tkhq/qos) +- inside of a legitimate [AWS Nitro Enclave](https://docs.aws.amazon.com/enclaves/latest/user/nitro-enclave.html) +- inside Turnkey's canonical AWS production account ### Open-source tooling diff --git a/snippets/api/authorizations.mdx b/snippets/api/authorizations.mdx index a79b7e38..cf14d5d0 100644 --- a/snippets/api/authorizations.mdx +++ b/snippets/api/authorizations.mdx @@ -21,5 +21,6 @@ export const Authorizations = () => {
- ); + +); }; diff --git a/snippets/data/endpoint-tags.mdx b/snippets/data/endpoint-tags.mdx index 7dbf9b94..37344419 100644 --- a/snippets/data/endpoint-tags.mdx +++ b/snippets/data/endpoint-tags.mdx @@ -1,1602 +1,1602 @@ export const endpoints = [ { - "name": "Approve activity", - "id": "approve-activity", - "type": "activity", - "tags": [ + name: "Approve activity", + id: "approve-activity", + type: "activity", + tags: [ { - "id": "consensus", - "label": "Consensus" - } - ] + id: "consensus", + label: "Consensus", + }, + ], }, { - "name": "Broadcast EVM transaction", - "id": "broadcast-evm-transaction", - "type": "activity", - "tags": [ + name: "Broadcast EVM transaction", + id: "broadcast-evm-transaction", + type: "activity", + tags: [ { - "id": "broadcasting", - "label": "Broadcasting" - } - ] + id: "broadcasting", + label: "Broadcasting", + }, + ], }, { - "name": "Broadcast SVM transaction", - "id": "broadcast-svm-transaction", - "type": "activity", - "tags": [ + name: "Broadcast SVM transaction", + id: "broadcast-svm-transaction", + type: "activity", + tags: [ { - "id": "broadcasting", - "label": "Broadcasting" - } - ] + id: "broadcasting", + label: "Broadcasting", + }, + ], }, { - "name": "Claim Spark transfer", - "id": "claim-spark-transfer", - "type": "activity", - "tags": [ + name: "Claim Spark transfer", + id: "claim-spark-transfer", + type: "activity", + tags: [ { - "id": "signing", - "label": "Signing" - } - ] + id: "signing", + label: "Signing", + }, + ], }, { - "name": "Create a Fiat On Ramp Credential", - "id": "create-a-fiat-on-ramp-credential", - "type": "activity", - "tags": [ + name: "Create a Fiat On Ramp Credential", + id: "create-a-fiat-on-ramp-credential", + type: "activity", + tags: [ { - "id": "on-ramp", - "label": "On Ramp" - } - ] + id: "on-ramp", + label: "On Ramp", + }, + ], }, { - "name": "Create a TVC App", - "id": "create-a-tvc-app", - "type": "activity", - "tags": [ + name: "Create a TVC App", + id: "create-a-tvc-app", + type: "activity", + tags: [ { - "id": "tvc", - "label": "TVC" - } - ] + id: "tvc", + label: "TVC", + }, + ], }, { - "name": "Create a TVC Deployment", - "id": "create-a-tvc-deployment", - "type": "activity", - "tags": [ + name: "Create a TVC Deployment", + id: "create-a-tvc-deployment", + type: "activity", + tags: [ { - "id": "tvc", - "label": "TVC" - } - ] + id: "tvc", + label: "TVC", + }, + ], }, { - "name": "Create an OAuth 2.0 Credential", - "id": "create-an-oauth-2-0-credential", - "type": "activity", - "tags": [ + name: "Create an OAuth 2.0 Credential", + id: "create-an-oauth-2-0-credential", + type: "activity", + tags: [ { - "id": "user-auth", - "label": "User Auth" - } - ] + id: "user-auth", + label: "User Auth", + }, + ], }, { - "name": "Create API keys", - "id": "create-api-keys", - "type": "activity", - "tags": [ + name: "Create API keys", + id: "create-api-keys", + type: "activity", + tags: [ { - "id": "api-keys", - "label": "API Keys" - } - ] + id: "api-keys", + label: "API Keys", + }, + ], }, { - "name": "Create authenticators", - "id": "create-authenticators", - "type": "activity", - "tags": [ + name: "Create authenticators", + id: "create-authenticators", + type: "activity", + tags: [ { - "id": "authenticators", - "label": "Authenticators" - } - ] + id: "authenticators", + label: "Authenticators", + }, + ], }, { - "name": "Create invitations", - "id": "create-invitations", - "type": "activity", - "tags": [ + name: "Create invitations", + id: "create-invitations", + type: "activity", + tags: [ { - "id": "invitations", - "label": "Invitations" - } - ] + id: "invitations", + label: "Invitations", + }, + ], }, { - "name": "Create Oauth providers", - "id": "create-oauth-providers", - "type": "activity", - "tags": [ + name: "Create Oauth providers", + id: "create-oauth-providers", + type: "activity", + tags: [ { - "id": "user-auth", - "label": "User Auth" - } - ] + id: "user-auth", + label: "User Auth", + }, + ], }, { - "name": "Create policies", - "id": "create-policies", - "type": "activity", - "tags": [ + name: "Create policies", + id: "create-policies", + type: "activity", + tags: [ { - "id": "policies", - "label": "Policies" - } - ] + id: "policies", + label: "Policies", + }, + ], }, { - "name": "Create policy", - "id": "create-policy", - "type": "activity", - "tags": [ + name: "Create policy", + id: "create-policy", + type: "activity", + tags: [ { - "id": "policies", - "label": "Policies" - } - ] + id: "policies", + label: "Policies", + }, + ], }, { - "name": "Create private key tag", - "id": "create-private-key-tag", - "type": "activity", - "tags": [ + name: "Create private key tag", + id: "create-private-key-tag", + type: "activity", + tags: [ { - "id": "private-key-tags", - "label": "Private Key Tags" - } - ] + id: "private-key-tags", + label: "Private Key Tags", + }, + ], }, { - "name": "Create private keys", - "id": "create-private-keys", - "type": "activity", - "tags": [ + name: "Create private keys", + id: "create-private-keys", + type: "activity", + tags: [ { - "id": "private-keys", - "label": "Private Keys" - } - ] + id: "private-keys", + label: "Private Keys", + }, + ], }, { - "name": "Create read only session", - "id": "create-read-only-session", - "type": "activity", - "tags": [ + name: "Create read only session", + id: "create-read-only-session", + type: "activity", + tags: [ { - "id": "sessions", - "label": "Sessions" - } - ] + id: "sessions", + label: "Sessions", + }, + ], }, { - "name": "Create read write session", - "id": "create-read-write-session", - "type": "activity", - "tags": [ + name: "Create read write session", + id: "create-read-write-session", + type: "activity", + tags: [ { - "id": "sessions", - "label": "Sessions" - } - ] + id: "sessions", + label: "Sessions", + }, + ], }, { - "name": "Create smart contract interface", - "id": "create-smart-contract-interface", - "type": "activity", - "tags": [ + name: "Create smart contract interface", + id: "create-smart-contract-interface", + type: "activity", + tags: [ { - "id": "policies", - "label": "Policies" - } - ] + id: "policies", + label: "Policies", + }, + ], }, { - "name": "Create sub-organization", - "id": "create-sub-organization", - "type": "activity", - "tags": [ + name: "Create sub-organization", + id: "create-sub-organization", + type: "activity", + tags: [ { - "id": "organizations", - "label": "Organizations" - } - ] + id: "organizations", + label: "Organizations", + }, + ], }, { - "name": "Create TVC Manifest Approvals", - "id": "create-tvc-manifest-approvals", - "type": "activity", - "tags": [ + name: "Create TVC Manifest Approvals", + id: "create-tvc-manifest-approvals", + type: "activity", + tags: [ { - "id": "tvc", - "label": "TVC" - } - ] + id: "tvc", + label: "TVC", + }, + ], }, { - "name": "Create user tag", - "id": "create-user-tag", - "type": "activity", - "tags": [ + name: "Create user tag", + id: "create-user-tag", + type: "activity", + tags: [ { - "id": "user-tags", - "label": "User Tags" - } - ] + id: "user-tags", + label: "User Tags", + }, + ], }, { - "name": "Create users", - "id": "create-users", - "type": "activity", - "tags": [ + name: "Create users", + id: "create-users", + type: "activity", + tags: [ { - "id": "users", - "label": "Users" - } - ] + id: "users", + label: "Users", + }, + ], }, { - "name": "Create wallet", - "id": "create-wallet", - "type": "activity", - "tags": [ + name: "Create wallet", + id: "create-wallet", + type: "activity", + tags: [ { - "id": "wallets", - "label": "Wallets" - } - ] + id: "wallets", + label: "Wallets", + }, + ], }, { - "name": "Create wallet accounts", - "id": "create-wallet-accounts", - "type": "activity", - "tags": [ + name: "Create wallet accounts", + id: "create-wallet-accounts", + type: "activity", + tags: [ { - "id": "wallets", - "label": "Wallets" - } - ] + id: "wallets", + label: "Wallets", + }, + ], }, { - "name": "Create webhook endpoint", - "id": "create-webhook-endpoint", - "type": "activity", - "tags": [ + name: "Create webhook endpoint", + id: "create-webhook-endpoint", + type: "activity", + tags: [ { - "id": "organizations", - "label": "Organizations" - } - ] + id: "organizations", + label: "Organizations", + }, + ], }, { - "name": "Delete a Fiat On Ramp Credential", - "id": "delete-a-fiat-on-ramp-credential", - "type": "activity", - "tags": [ + name: "Delete a Fiat On Ramp Credential", + id: "delete-a-fiat-on-ramp-credential", + type: "activity", + tags: [ { - "id": "on-ramp", - "label": "On Ramp" - } - ] + id: "on-ramp", + label: "On Ramp", + }, + ], }, { - "name": "Delete a TVC App and all of its deployments", - "id": "delete-a-tvc-app-and-all-of-its-deployments", - "type": "activity", - "tags": [ + name: "Delete a TVC App and all of its deployments", + id: "delete-a-tvc-app-and-all-of-its-deployments", + type: "activity", + tags: [ { - "id": "tvc", - "label": "TVC" - } - ] + id: "tvc", + label: "TVC", + }, + ], }, { - "name": "Delete a TVC Deployment", - "id": "delete-a-tvc-deployment", - "type": "activity", - "tags": [ + name: "Delete a TVC Deployment", + id: "delete-a-tvc-deployment", + type: "activity", + tags: [ { - "id": "tvc", - "label": "TVC" - } - ] + id: "tvc", + label: "TVC", + }, + ], }, { - "name": "Delete an OAuth 2.0 Credential", - "id": "delete-an-oauth-2-0-credential", - "type": "activity", - "tags": [ + name: "Delete an OAuth 2.0 Credential", + id: "delete-an-oauth-2-0-credential", + type: "activity", + tags: [ { - "id": "user-auth", - "label": "User Auth" - } - ] + id: "user-auth", + label: "User Auth", + }, + ], }, { - "name": "Delete API keys", - "id": "delete-api-keys", - "type": "activity", - "tags": [ + name: "Delete API keys", + id: "delete-api-keys", + type: "activity", + tags: [ { - "id": "api-keys", - "label": "API Keys" - } - ] + id: "api-keys", + label: "API Keys", + }, + ], }, { - "name": "Delete authenticators", - "id": "delete-authenticators", - "type": "activity", - "tags": [ + name: "Delete authenticators", + id: "delete-authenticators", + type: "activity", + tags: [ { - "id": "authenticators", - "label": "Authenticators" - } - ] + id: "authenticators", + label: "Authenticators", + }, + ], }, { - "name": "Delete invitation", - "id": "delete-invitation", - "type": "activity", - "tags": [ + name: "Delete invitation", + id: "delete-invitation", + type: "activity", + tags: [ { - "id": "invitations", - "label": "Invitations" - } - ] + id: "invitations", + label: "Invitations", + }, + ], }, { - "name": "Delete Oauth providers", - "id": "delete-oauth-providers", - "type": "activity", - "tags": [ + name: "Delete Oauth providers", + id: "delete-oauth-providers", + type: "activity", + tags: [ { - "id": "user-auth", - "label": "User Auth" - } - ] + id: "user-auth", + label: "User Auth", + }, + ], }, { - "name": "Delete policies", - "id": "delete-policies", - "type": "activity", - "tags": [ + name: "Delete policies", + id: "delete-policies", + type: "activity", + tags: [ { - "id": "policies", - "label": "Policies" - } - ] + id: "policies", + label: "Policies", + }, + ], }, { - "name": "Delete policy", - "id": "delete-policy", - "type": "activity", - "tags": [ + name: "Delete policy", + id: "delete-policy", + type: "activity", + tags: [ { - "id": "policies", - "label": "Policies" - } - ] + id: "policies", + label: "Policies", + }, + ], }, { - "name": "Delete private key tags", - "id": "delete-private-key-tags", - "type": "activity", - "tags": [ + name: "Delete private key tags", + id: "delete-private-key-tags", + type: "activity", + tags: [ { - "id": "private-key-tags", - "label": "Private Key Tags" - } - ] + id: "private-key-tags", + label: "Private Key Tags", + }, + ], }, { - "name": "Delete private keys", - "id": "delete-private-keys", - "type": "activity", - "tags": [ + name: "Delete private keys", + id: "delete-private-keys", + type: "activity", + tags: [ { - "id": "private-keys", - "label": "Private Keys" - } - ] + id: "private-keys", + label: "Private Keys", + }, + ], }, { - "name": "Delete smart contract interface", - "id": "delete-smart-contract-interface", - "type": "activity", - "tags": [ + name: "Delete smart contract interface", + id: "delete-smart-contract-interface", + type: "activity", + tags: [ { - "id": "policies", - "label": "Policies" - } - ] + id: "policies", + label: "Policies", + }, + ], }, { - "name": "Delete sub-organization", - "id": "delete-sub-organization", - "type": "activity", - "tags": [ + name: "Delete sub-organization", + id: "delete-sub-organization", + type: "activity", + tags: [ { - "id": "organizations", - "label": "Organizations" - } - ] + id: "organizations", + label: "Organizations", + }, + ], }, { - "name": "Delete user tags", - "id": "delete-user-tags", - "type": "activity", - "tags": [ + name: "Delete user tags", + id: "delete-user-tags", + type: "activity", + tags: [ { - "id": "user-tags", - "label": "User Tags" - } - ] + id: "user-tags", + label: "User Tags", + }, + ], }, { - "name": "Delete users", - "id": "delete-users", - "type": "activity", - "tags": [ + name: "Delete users", + id: "delete-users", + type: "activity", + tags: [ { - "id": "users", - "label": "Users" - } - ] + id: "users", + label: "Users", + }, + ], }, { - "name": "Delete wallet accounts", - "id": "delete-wallet-accounts", - "type": "activity", - "tags": [ + name: "Delete wallet accounts", + id: "delete-wallet-accounts", + type: "activity", + tags: [ { - "id": "wallets", - "label": "Wallets" - } - ] + id: "wallets", + label: "Wallets", + }, + ], }, { - "name": "Delete wallets", - "id": "delete-wallets", - "type": "activity", - "tags": [ + name: "Delete wallets", + id: "delete-wallets", + type: "activity", + tags: [ { - "id": "wallets", - "label": "Wallets" - } - ] + id: "wallets", + label: "Wallets", + }, + ], }, { - "name": "Delete webhook endpoint", - "id": "delete-webhook-endpoint", - "type": "activity", - "tags": [ + name: "Delete webhook endpoint", + id: "delete-webhook-endpoint", + type: "activity", + tags: [ { - "id": "organizations", - "label": "Organizations" - } - ] + id: "organizations", + label: "Organizations", + }, + ], }, { - "name": "Export private key", - "id": "export-private-key", - "type": "activity", - "tags": [ + name: "Export private key", + id: "export-private-key", + type: "activity", + tags: [ { - "id": "private-keys", - "label": "Private Keys" - } - ] + id: "private-keys", + label: "Private Keys", + }, + ], }, { - "name": "Export wallet", - "id": "export-wallet", - "type": "activity", - "tags": [ + name: "Export wallet", + id: "export-wallet", + type: "activity", + tags: [ { - "id": "wallets", - "label": "Wallets" - } - ] + id: "wallets", + label: "Wallets", + }, + ], }, { - "name": "Export wallet account", - "id": "export-wallet-account", - "type": "activity", - "tags": [ + name: "Export wallet account", + id: "export-wallet-account", + type: "activity", + tags: [ { - "id": "wallets", - "label": "Wallets" - } - ] + id: "wallets", + label: "Wallets", + }, + ], }, { - "name": "Import private key", - "id": "import-private-key", - "type": "activity", - "tags": [ + name: "Import private key", + id: "import-private-key", + type: "activity", + tags: [ { - "id": "private-keys", - "label": "Private Keys" - } - ] + id: "private-keys", + label: "Private Keys", + }, + ], }, { - "name": "Import wallet", - "id": "import-wallet", - "type": "activity", - "tags": [ + name: "Import wallet", + id: "import-wallet", + type: "activity", + tags: [ { - "id": "wallets", - "label": "Wallets" - } - ] + id: "wallets", + label: "Wallets", + }, + ], }, { - "name": "Init email recovery", - "id": "init-email-recovery", - "type": "activity", - "tags": [ + name: "Init email recovery", + id: "init-email-recovery", + type: "activity", + tags: [ { - "id": "user-recovery", - "label": "User Recovery" - } - ] + id: "user-recovery", + label: "User Recovery", + }, + ], }, { - "name": "Init fiat on ramp", - "id": "init-fiat-on-ramp", - "type": "activity", - "tags": [ + name: "Init fiat on ramp", + id: "init-fiat-on-ramp", + type: "activity", + tags: [ { - "id": "on-ramp", - "label": "On Ramp" - } - ] + id: "on-ramp", + label: "On Ramp", + }, + ], }, { - "name": "Init generic OTP", - "id": "init-generic-otp", - "type": "activity", - "tags": [ + name: "Init generic OTP", + id: "init-generic-otp", + type: "activity", + tags: [ { - "id": "user-verification", - "label": "User Verification" - } - ] + id: "user-verification", + label: "User Verification", + }, + ], }, { - "name": "Init import private key", - "id": "init-import-private-key", - "type": "activity", - "tags": [ + name: "Init import private key", + id: "init-import-private-key", + type: "activity", + tags: [ { - "id": "private-keys", - "label": "Private Keys" - } - ] + id: "private-keys", + label: "Private Keys", + }, + ], }, { - "name": "Init import wallet", - "id": "init-import-wallet", - "type": "activity", - "tags": [ + name: "Init import wallet", + id: "init-import-wallet", + type: "activity", + tags: [ { - "id": "wallets", - "label": "Wallets" - } - ] + id: "wallets", + label: "Wallets", + }, + ], }, { - "name": "Init OTP auth", - "id": "init-otp-auth", - "type": "activity", - "tags": [ + name: "Init OTP auth", + id: "init-otp-auth", + type: "activity", + tags: [ { - "id": "user-auth", - "label": "User Auth" - } - ] + id: "user-auth", + label: "User Auth", + }, + ], }, { - "name": "Login with a stamp", - "id": "login-with-a-stamp", - "type": "activity", - "tags": [ + name: "Login with a stamp", + id: "login-with-a-stamp", + type: "activity", + tags: [ { - "id": "sessions", - "label": "Sessions" - } - ] + id: "sessions", + label: "Sessions", + }, + ], }, { - "name": "Login with Oauth", - "id": "login-with-oauth", - "type": "activity", - "tags": [ + name: "Login with Oauth", + id: "login-with-oauth", + type: "activity", + tags: [ { - "id": "sessions", - "label": "Sessions" - } - ] + id: "sessions", + label: "Sessions", + }, + ], }, { - "name": "Login with OTP", - "id": "login-with-otp", - "type": "activity", - "tags": [ + name: "Login with OTP", + id: "login-with-otp", + type: "activity", + tags: [ { - "id": "sessions", - "label": "Sessions" - } - ] + id: "sessions", + label: "Sessions", + }, + ], }, { - "name": "Oauth", - "id": "oauth", - "type": "activity", - "tags": [ + name: "Oauth", + id: "oauth", + type: "activity", + tags: [ { - "id": "user-auth", - "label": "User Auth" - } - ] + id: "user-auth", + label: "User Auth", + }, + ], }, { - "name": "OAuth 2.0 authentication", - "id": "oauth-2-0-authentication", - "type": "activity", - "tags": [ + name: "OAuth 2.0 authentication", + id: "oauth-2-0-authentication", + type: "activity", + tags: [ { - "id": "user-auth", - "label": "User Auth" - } - ] + id: "user-auth", + label: "User Auth", + }, + ], }, { - "name": "OTP auth", - "id": "otp-auth", - "type": "activity", - "tags": [ + name: "OTP auth", + id: "otp-auth", + type: "activity", + tags: [ { - "id": "user-auth", - "label": "User Auth" - } - ] + id: "user-auth", + label: "User Auth", + }, + ], }, { - "name": "Perform email auth", - "id": "perform-email-auth", - "type": "activity", - "tags": [ + name: "Perform email auth", + id: "perform-email-auth", + type: "activity", + tags: [ { - "id": "user-auth", - "label": "User Auth" - } - ] + id: "user-auth", + label: "User Auth", + }, + ], }, { - "name": "Prepare Spark transfer", - "id": "prepare-spark-transfer", - "type": "activity", - "tags": [ + name: "Prepare Spark transfer", + id: "prepare-spark-transfer", + type: "activity", + tags: [ { - "id": "signing", - "label": "Signing" - } - ] + id: "signing", + label: "Signing", + }, + ], }, { - "name": "Recover a user", - "id": "recover-a-user", - "type": "activity", - "tags": [ + name: "Recover a user", + id: "recover-a-user", + type: "activity", + tags: [ { - "id": "user-recovery", - "label": "User Recovery" - } - ] + id: "user-recovery", + label: "User Recovery", + }, + ], }, { - "name": "Reject activity", - "id": "reject-activity", - "type": "activity", - "tags": [ + name: "Reject activity", + id: "reject-activity", + type: "activity", + tags: [ { - "id": "consensus", - "label": "Consensus" - } - ] + id: "consensus", + label: "Consensus", + }, + ], }, { - "name": "Remove IP Allowlist", - "id": "remove-ip-allowlist", - "type": "activity", - "tags": [ + name: "Remove IP Allowlist", + id: "remove-ip-allowlist", + type: "activity", + tags: [ { - "id": "ip-allowlist", - "label": "IP Allowlist" - } - ] + id: "ip-allowlist", + label: "IP Allowlist", + }, + ], }, { - "name": "Remove organization feature", - "id": "remove-organization-feature", - "type": "activity", - "tags": [ + name: "Remove organization feature", + id: "remove-organization-feature", + type: "activity", + tags: [ { - "id": "features", - "label": "Features" - } - ] + id: "features", + label: "Features", + }, + ], }, { - "name": "Restore a TVC Deployment", - "id": "restore-a-tvc-deployment", - "type": "activity", - "tags": [ + name: "Restore a TVC Deployment", + id: "restore-a-tvc-deployment", + type: "activity", + tags: [ { - "id": "tvc", - "label": "TVC" - } - ] + id: "tvc", + label: "TVC", + }, + ], }, { - "name": "Set IP Allowlist", - "id": "set-ip-allowlist", - "type": "activity", - "tags": [ + name: "Set IP Allowlist", + id: "set-ip-allowlist", + type: "activity", + tags: [ { - "id": "ip-allowlist", - "label": "IP Allowlist" - } - ] + id: "ip-allowlist", + label: "IP Allowlist", + }, + ], }, { - "name": "Set organization feature", - "id": "set-organization-feature", - "type": "activity", - "tags": [ + name: "Set organization feature", + id: "set-organization-feature", + type: "activity", + tags: [ { - "id": "features", - "label": "Features" - } - ] + id: "features", + label: "Features", + }, + ], }, { - "name": "Sign Frost Spark", - "id": "sign-frost-spark", - "type": "activity", - "tags": [ + name: "Sign Frost Spark", + id: "sign-frost-spark", + type: "activity", + tags: [ { - "id": "signing", - "label": "Signing" - } - ] + id: "signing", + label: "Signing", + }, + ], }, { - "name": "Sign raw payload", - "id": "sign-raw-payload", - "type": "activity", - "tags": [ + name: "Sign raw payload", + id: "sign-raw-payload", + type: "activity", + tags: [ { - "id": "signing", - "label": "Signing" - } - ] + id: "signing", + label: "Signing", + }, + ], }, { - "name": "Sign raw payloads", - "id": "sign-raw-payloads", - "type": "activity", - "tags": [ + name: "Sign raw payloads", + id: "sign-raw-payloads", + type: "activity", + tags: [ { - "id": "signing", - "label": "Signing" - } - ] + id: "signing", + label: "Signing", + }, + ], }, { - "name": "Sign transaction", - "id": "sign-transaction", - "type": "activity", - "tags": [ + name: "Sign transaction", + id: "sign-transaction", + type: "activity", + tags: [ { - "id": "signing", - "label": "Signing" - } - ] + id: "signing", + label: "Signing", + }, + ], }, { - "name": "Spark prepare Lightning receive", - "id": "spark-prepare-lightning-receive", - "type": "activity", - "tags": [ + name: "Spark prepare Lightning receive", + id: "spark-prepare-lightning-receive", + type: "activity", + tags: [ { - "id": "signing", - "label": "Signing" - } - ] + id: "signing", + label: "Signing", + }, + ], }, { - "name": "Update a Fiat On Ramp Credential", - "id": "update-a-fiat-on-ramp-credential", - "type": "activity", - "tags": [ + name: "Update a Fiat On Ramp Credential", + id: "update-a-fiat-on-ramp-credential", + type: "activity", + tags: [ { - "id": "on-ramp", - "label": "On Ramp" - } - ] + id: "on-ramp", + label: "On Ramp", + }, + ], }, { - "name": "Update an OAuth 2.0 Credential", - "id": "update-an-oauth-2-0-credential", - "type": "activity", - "tags": [ + name: "Update an OAuth 2.0 Credential", + id: "update-an-oauth-2-0-credential", + type: "activity", + tags: [ { - "id": "user-auth", - "label": "User Auth" - } - ] + id: "user-auth", + label: "User Auth", + }, + ], }, { - "name": "Update organization name", - "id": "update-organization-name", - "type": "activity", - "tags": [ + name: "Update organization name", + id: "update-organization-name", + type: "activity", + tags: [ { - "id": "organizations", - "label": "Organizations" - } - ] + id: "organizations", + label: "Organizations", + }, + ], }, { - "name": "Update policy", - "id": "update-policy", - "type": "activity", - "tags": [ + name: "Update policy", + id: "update-policy", + type: "activity", + tags: [ { - "id": "policies", - "label": "Policies" - } - ] + id: "policies", + label: "Policies", + }, + ], }, { - "name": "Update private key tag", - "id": "update-private-key-tag", - "type": "activity", - "tags": [ + name: "Update private key tag", + id: "update-private-key-tag", + type: "activity", + tags: [ { - "id": "private-key-tags", - "label": "Private Key Tags" - } - ] + id: "private-key-tags", + label: "Private Key Tags", + }, + ], }, { - "name": "Update root quorum", - "id": "update-root-quorum", - "type": "activity", - "tags": [ + name: "Update root quorum", + id: "update-root-quorum", + type: "activity", + tags: [ { - "id": "organizations", - "label": "Organizations" - } - ] + id: "organizations", + label: "Organizations", + }, + ], }, { - "name": "Update user", - "id": "update-user", - "type": "activity", - "tags": [ + name: "Update user", + id: "update-user", + type: "activity", + tags: [ { - "id": "users", - "label": "Users" - } - ] + id: "users", + label: "Users", + }, + ], }, { - "name": "Update user tag", - "id": "update-user-tag", - "type": "activity", - "tags": [ + name: "Update user tag", + id: "update-user-tag", + type: "activity", + tags: [ { - "id": "user-tags", - "label": "User Tags" - } - ] + id: "user-tags", + label: "User Tags", + }, + ], }, { - "name": "Update user's email", - "id": "update-user-s-email", - "type": "activity", - "tags": [ + name: "Update user's email", + id: "update-user-s-email", + type: "activity", + tags: [ { - "id": "users", - "label": "Users" - } - ] + id: "users", + label: "Users", + }, + ], }, { - "name": "Update user's name", - "id": "update-user-s-name", - "type": "activity", - "tags": [ + name: "Update user's name", + id: "update-user-s-name", + type: "activity", + tags: [ { - "id": "users", - "label": "Users" - } - ] + id: "users", + label: "Users", + }, + ], }, { - "name": "Update user's phone number", - "id": "update-user-s-phone-number", - "type": "activity", - "tags": [ + name: "Update user's phone number", + id: "update-user-s-phone-number", + type: "activity", + tags: [ { - "id": "users", - "label": "Users" - } - ] + id: "users", + label: "Users", + }, + ], }, { - "name": "Update wallet", - "id": "update-wallet", - "type": "activity", - "tags": [ + name: "Update wallet", + id: "update-wallet", + type: "activity", + tags: [ { - "id": "wallets", - "label": "Wallets" - } - ] + id: "wallets", + label: "Wallets", + }, + ], }, { - "name": "Update webhook endpoint", - "id": "update-webhook-endpoint", - "type": "activity", - "tags": [ + name: "Update webhook endpoint", + id: "update-webhook-endpoint", + type: "activity", + tags: [ { - "id": "organizations", - "label": "Organizations" - } - ] + id: "organizations", + label: "Organizations", + }, + ], }, { - "name": "Verify generic OTP", - "id": "verify-generic-otp", - "type": "activity", - "tags": [ + name: "Verify generic OTP", + id: "verify-generic-otp", + type: "activity", + tags: [ { - "id": "user-verification", - "label": "User Verification" - } - ] + id: "user-verification", + label: "User Verification", + }, + ], }, { - "name": "", - "id": "", - "type": "query", - "tags": [] + name: "", + id: "", + type: "query", + tags: [], }, { - "name": "Get a specific boot proof", - "id": "get-a-specific-boot-proof", - "type": "query", - "tags": [ + name: "Get a specific boot proof", + id: "get-a-specific-boot-proof", + type: "query", + tags: [ { - "id": "boot-proof", - "label": "Boot Proof" - } - ] + id: "boot-proof", + label: "Boot Proof", + }, + ], }, { - "name": "Get activity", - "id": "get-activity", - "type": "query", - "tags": [ + name: "Get activity", + id: "get-activity", + type: "query", + tags: [ { - "id": "activities", - "label": "Activities" - } - ] + id: "activities", + label: "Activities", + }, + ], }, { - "name": "Get API key", - "id": "get-api-key", - "type": "query", - "tags": [ + name: "Get API key", + id: "get-api-key", + type: "query", + tags: [ { - "id": "api-keys", - "label": "API keys" - } - ] + id: "api-keys", + label: "API keys", + }, + ], }, { - "name": "Get API keys", - "id": "get-api-keys", - "type": "query", - "tags": [ + name: "Get API keys", + id: "get-api-keys", + type: "query", + tags: [ { - "id": "api-keys", - "label": "API keys" - } - ] + id: "api-keys", + label: "API keys", + }, + ], }, { - "name": "Get authenticator", - "id": "get-authenticator", - "type": "query", - "tags": [ + name: "Get authenticator", + id: "get-authenticator", + type: "query", + tags: [ { - "id": "authenticators", - "label": "Authenticators" - } - ] + id: "authenticators", + label: "Authenticators", + }, + ], }, { - "name": "Get authenticators", - "id": "get-authenticators", - "type": "query", - "tags": [ + name: "Get authenticators", + id: "get-authenticators", + type: "query", + tags: [ { - "id": "authenticators", - "label": "Authenticators" - } - ] + id: "authenticators", + label: "Authenticators", + }, + ], }, { - "name": "Get balances", - "id": "get-balances", - "type": "query", - "tags": [ + name: "Get balances", + id: "get-balances", + type: "query", + tags: [ { - "id": "wallets", - "label": "Wallets" - } - ] + id: "wallets", + label: "Wallets", + }, + ], }, { - "name": "Get configs", - "id": "get-configs", - "type": "query", - "tags": [ + name: "Get configs", + id: "get-configs", + type: "query", + tags: [ { - "id": "organizations", - "label": "Organizations" - } - ] + id: "organizations", + label: "Organizations", + }, + ], }, { - "name": "Get gas usage", - "id": "get-gas-usage", - "type": "query", - "tags": [ + name: "Get gas usage", + id: "get-gas-usage", + type: "query", + tags: [ { - "id": "broadcasting", - "label": "Broadcasting" - } - ] + id: "broadcasting", + label: "Broadcasting", + }, + ], }, { - "name": "Get IP Allowlist", - "id": "get-ip-allowlist", - "type": "query", - "tags": [ + name: "Get IP Allowlist", + id: "get-ip-allowlist", + type: "query", + tags: [ { - "id": "ip-allowlist", - "label": "IP Allowlist" - } - ] + id: "ip-allowlist", + label: "IP Allowlist", + }, + ], }, { - "name": "Get nonces", - "id": "get-nonces", - "type": "query", - "tags": [ + name: "Get nonces", + id: "get-nonces", + type: "query", + tags: [ { - "id": "broadcasting", - "label": "Broadcasting" - } - ] + id: "broadcasting", + label: "Broadcasting", + }, + ], }, { - "name": "Get OAuth 2.0 credential", - "id": "get-oauth-2-0-credential", - "type": "query", - "tags": [] + name: "Get OAuth 2.0 credential", + id: "get-oauth-2-0-credential", + type: "query", + tags: [], }, { - "name": "Get Oauth providers", - "id": "get-oauth-providers", - "type": "query", - "tags": [ + name: "Get Oauth providers", + id: "get-oauth-providers", + type: "query", + tags: [ { - "id": "user-auth", - "label": "User Auth" - } - ] + id: "user-auth", + label: "User Auth", + }, + ], }, { - "name": "Get On Ramp transaction status", - "id": "get-on-ramp-transaction-status", - "type": "query", - "tags": [ + name: "Get On Ramp transaction status", + id: "get-on-ramp-transaction-status", + type: "query", + tags: [ { - "id": "on-ramp", - "label": "On Ramp" - } - ] + id: "on-ramp", + label: "On Ramp", + }, + ], }, { - "name": "Get policy", - "id": "get-policy", - "type": "query", - "tags": [ + name: "Get policy", + id: "get-policy", + type: "query", + tags: [ { - "id": "policies", - "label": "Policies" - } - ] + id: "policies", + label: "Policies", + }, + ], }, { - "name": "Get policy evaluations", - "id": "get-policy-evaluations", - "type": "query", - "tags": [ + name: "Get policy evaluations", + id: "get-policy-evaluations", + type: "query", + tags: [ { - "id": "activities", - "label": "Activities" - } - ] + id: "activities", + label: "Activities", + }, + ], }, { - "name": "Get private key", - "id": "get-private-key", - "type": "query", - "tags": [ + name: "Get private key", + id: "get-private-key", + type: "query", + tags: [ { - "id": "private-keys", - "label": "Private Keys" - } - ] + id: "private-keys", + label: "Private Keys", + }, + ], }, { - "name": "Get send transaction status", - "id": "get-send-transaction-status", - "type": "query", - "tags": [ + name: "Get send transaction status", + id: "get-send-transaction-status", + type: "query", + tags: [ { - "id": "send-transactions", - "label": "Send Transactions" - } - ] + id: "send-transactions", + label: "Send Transactions", + }, + ], }, { - "name": "Get smart contract interface", - "id": "get-smart-contract-interface", - "type": "query", - "tags": [ + name: "Get smart contract interface", + id: "get-smart-contract-interface", + type: "query", + tags: [ { - "id": "policies", - "label": "Policies" - } - ] + id: "policies", + label: "Policies", + }, + ], }, { - "name": "Get sub-organizations", - "id": "get-sub-organizations", - "type": "query", - "tags": [ + name: "Get sub-organizations", + id: "get-sub-organizations", + type: "query", + tags: [ { - "id": "organizations", - "label": "Organizations" - } - ] + id: "organizations", + label: "Organizations", + }, + ], }, { - "name": "Get the latest boot proof for an app", - "id": "get-the-latest-boot-proof-for-an-app", - "type": "query", - "tags": [ + name: "Get the latest boot proof for an app", + id: "get-the-latest-boot-proof-for-an-app", + type: "query", + tags: [ { - "id": "boot-proof", - "label": "Boot Proof" - } - ] + id: "boot-proof", + label: "Boot Proof", + }, + ], }, { - "name": "Get TVC App", - "id": "get-tvc-app", - "type": "query", - "tags": [ + name: "Get TVC App", + id: "get-tvc-app", + type: "query", + tags: [ { - "id": "tvc", - "label": "TVC" - } - ] + id: "tvc", + label: "TVC", + }, + ], }, { - "name": "Get TVC App status", - "id": "get-tvc-app-status", - "type": "query", - "tags": [ + name: "Get TVC App status", + id: "get-tvc-app-status", + type: "query", + tags: [ { - "id": "tvc", - "label": "TVC" - } - ] + id: "tvc", + label: "TVC", + }, + ], }, { - "name": "Get TVC Deployment", - "id": "get-tvc-deployment", - "type": "query", - "tags": [ + name: "Get TVC Deployment", + id: "get-tvc-deployment", + type: "query", + tags: [ { - "id": "tvc", - "label": "TVC" - } - ] + id: "tvc", + label: "TVC", + }, + ], }, { - "name": "Get user", - "id": "get-user", - "type": "query", - "tags": [ + name: "Get user", + id: "get-user", + type: "query", + tags: [ { - "id": "users", - "label": "Users" - } - ] + id: "users", + label: "Users", + }, + ], }, { - "name": "Get verified sub-organizations", - "id": "get-verified-sub-organizations", - "type": "query", - "tags": [ + name: "Get verified sub-organizations", + id: "get-verified-sub-organizations", + type: "query", + tags: [ { - "id": "organizations", - "label": "Organizations" - } - ] + id: "organizations", + label: "Organizations", + }, + ], }, { - "name": "Get wallet", - "id": "get-wallet", - "type": "query", - "tags": [ + name: "Get wallet", + id: "get-wallet", + type: "query", + tags: [ { - "id": "wallets", - "label": "Wallets" - } - ] + id: "wallets", + label: "Wallets", + }, + ], }, { - "name": "Get wallet account", - "id": "get-wallet-account", - "type": "query", - "tags": [ + name: "Get wallet account", + id: "get-wallet-account", + type: "query", + tags: [ { - "id": "wallets", - "label": "Wallets" - } - ] + id: "wallets", + label: "Wallets", + }, + ], }, { - "name": "List activities", - "id": "list-activities", - "type": "query", - "tags": [ + name: "List activities", + id: "list-activities", + type: "query", + tags: [ { - "id": "activities", - "label": "Activities" - } - ] + id: "activities", + label: "Activities", + }, + ], }, { - "name": "List App Proofs for an activity", - "id": "list-app-proofs-for-an-activity", - "type": "query", - "tags": [ + name: "List App Proofs for an activity", + id: "list-app-proofs-for-an-activity", + type: "query", + tags: [ { - "id": "app-proof", - "label": "App Proof" - } - ] + id: "app-proof", + label: "App Proof", + }, + ], }, { - "name": "List Fiat On Ramp Credentials", - "id": "list-fiat-on-ramp-credentials", - "type": "query", - "tags": [ + name: "List Fiat On Ramp Credentials", + id: "list-fiat-on-ramp-credentials", + type: "query", + tags: [ { - "id": "on-ramp", - "label": "On Ramp" - } - ] + id: "on-ramp", + label: "On Ramp", + }, + ], }, { - "name": "List OAuth 2.0 Credentials", - "id": "list-oauth-2-0-credentials", - "type": "query", - "tags": [ + name: "List OAuth 2.0 Credentials", + id: "list-oauth-2-0-credentials", + type: "query", + tags: [ { - "id": "user-auth", - "label": "User Auth" - } - ] + id: "user-auth", + label: "User Auth", + }, + ], }, { - "name": "List policies", - "id": "list-policies", - "type": "query", - "tags": [ + name: "List policies", + id: "list-policies", + type: "query", + tags: [ { - "id": "policies", - "label": "Policies" - } - ] + id: "policies", + label: "Policies", + }, + ], }, { - "name": "List private key tags", - "id": "list-private-key-tags", - "type": "query", - "tags": [ + name: "List private key tags", + id: "list-private-key-tags", + type: "query", + tags: [ { - "id": "private-key-tags", - "label": "Private Key Tags" - } - ] + id: "private-key-tags", + label: "Private Key Tags", + }, + ], }, { - "name": "List private keys", - "id": "list-private-keys", - "type": "query", - "tags": [ + name: "List private keys", + id: "list-private-keys", + type: "query", + tags: [ { - "id": "private-keys", - "label": "Private Keys" - } - ] + id: "private-keys", + label: "Private Keys", + }, + ], }, { - "name": "List smart contract interfaces", - "id": "list-smart-contract-interfaces", - "type": "query", - "tags": [ + name: "List smart contract interfaces", + id: "list-smart-contract-interfaces", + type: "query", + tags: [ { - "id": "policies", - "label": "Policies" - } - ] + id: "policies", + label: "Policies", + }, + ], }, { - "name": "List supported assets", - "id": "list-supported-assets", - "type": "query", - "tags": [ + name: "List supported assets", + id: "list-supported-assets", + type: "query", + tags: [ { - "id": "wallets", - "label": "Wallets" - } - ] + id: "wallets", + label: "Wallets", + }, + ], }, { - "name": "List TVC Apps", - "id": "list-tvc-apps", - "type": "query", - "tags": [ + name: "List TVC Apps", + id: "list-tvc-apps", + type: "query", + tags: [ { - "id": "tvc", - "label": "TVC" - } - ] + id: "tvc", + label: "TVC", + }, + ], }, { - "name": "List TVC Deployments", - "id": "list-tvc-deployments", - "type": "query", - "tags": [ + name: "List TVC Deployments", + id: "list-tvc-deployments", + type: "query", + tags: [ { - "id": "tvc", - "label": "TVC" - } - ] + id: "tvc", + label: "TVC", + }, + ], }, { - "name": "List user tags", - "id": "list-user-tags", - "type": "query", - "tags": [ + name: "List user tags", + id: "list-user-tags", + type: "query", + tags: [ { - "id": "user-tags", - "label": "User Tags" - } - ] + id: "user-tags", + label: "User Tags", + }, + ], }, { - "name": "List users", - "id": "list-users", - "type": "query", - "tags": [ + name: "List users", + id: "list-users", + type: "query", + tags: [ { - "id": "users", - "label": "Users" - } - ] + id: "users", + label: "Users", + }, + ], }, { - "name": "List wallets", - "id": "list-wallets", - "type": "query", - "tags": [ + name: "List wallets", + id: "list-wallets", + type: "query", + tags: [ { - "id": "wallets", - "label": "Wallets" - } - ] + id: "wallets", + label: "Wallets", + }, + ], }, { - "name": "List wallets accounts", - "id": "list-wallets-accounts", - "type": "query", - "tags": [ + name: "List wallets accounts", + id: "list-wallets-accounts", + type: "query", + tags: [ { - "id": "wallets", - "label": "Wallets" - } - ] + id: "wallets", + label: "Wallets", + }, + ], }, { - "name": "List webhook endpoints", - "id": "list-webhook-endpoints", - "type": "query", - "tags": [ + name: "List webhook endpoints", + id: "list-webhook-endpoints", + type: "query", + tags: [ { - "id": "organizations", - "label": "Organizations" - } - ] + id: "organizations", + label: "Organizations", + }, + ], }, { - "name": "Validate Container Image for TVC", - "id": "validate-container-image-for-tvc", - "type": "query", - "tags": [ + name: "Validate Container Image for TVC", + id: "validate-container-image-for-tvc", + type: "query", + tags: [ { - "id": "tvc", - "label": "TVC" - } - ] + id: "tvc", + label: "TVC", + }, + ], }, { - "name": "Who am I", - "id": "who-am-i", - "type": "query", - "tags": [ + name: "Who am I", + id: "who-am-i", + type: "query", + tags: [ { - "id": "sessions", - "label": "Sessions" - } - ] - } + id: "sessions", + label: "Sessions", + }, + ], + }, ]; export const tags = [ { - "id": "consensus", - "label": "Consensus" + id: "consensus", + label: "Consensus", }, { - "id": "broadcasting", - "label": "Broadcasting" + id: "broadcasting", + label: "Broadcasting", }, { - "id": "signing", - "label": "Signing" + id: "signing", + label: "Signing", }, { - "id": "on-ramp", - "label": "On Ramp" + id: "on-ramp", + label: "On Ramp", }, { - "id": "tvc", - "label": "TVC" + id: "tvc", + label: "TVC", }, { - "id": "user-auth", - "label": "User Auth" + id: "user-auth", + label: "User Auth", }, { - "id": "api-keys", - "label": "API keys" + id: "api-keys", + label: "API keys", }, { - "id": "authenticators", - "label": "Authenticators" + id: "authenticators", + label: "Authenticators", }, { - "id": "invitations", - "label": "Invitations" + id: "invitations", + label: "Invitations", }, { - "id": "policies", - "label": "Policies" + id: "policies", + label: "Policies", }, { - "id": "private-key-tags", - "label": "Private Key Tags" + id: "private-key-tags", + label: "Private Key Tags", }, { - "id": "private-keys", - "label": "Private Keys" + id: "private-keys", + label: "Private Keys", }, { - "id": "sessions", - "label": "Sessions" + id: "sessions", + label: "Sessions", }, { - "id": "organizations", - "label": "Organizations" + id: "organizations", + label: "Organizations", }, { - "id": "user-tags", - "label": "User Tags" + id: "user-tags", + label: "User Tags", }, { - "id": "users", - "label": "Users" + id: "users", + label: "Users", }, { - "id": "wallets", - "label": "Wallets" + id: "wallets", + label: "Wallets", }, { - "id": "user-recovery", - "label": "User Recovery" + id: "user-recovery", + label: "User Recovery", }, { - "id": "user-verification", - "label": "User Verification" + id: "user-verification", + label: "User Verification", }, { - "id": "ip-allowlist", - "label": "IP Allowlist" + id: "ip-allowlist", + label: "IP Allowlist", }, { - "id": "features", - "label": "Features" + id: "features", + label: "Features", }, { - "id": "boot-proof", - "label": "Boot Proof" + id: "boot-proof", + label: "Boot Proof", }, { - "id": "activities", - "label": "Activities" + id: "activities", + label: "Activities", }, { - "id": "send-transactions", - "label": "Send Transactions" + id: "send-transactions", + label: "Send Transactions", }, { - "id": "app-proof", - "label": "App Proof" - } -]; \ No newline at end of file + id: "app-proof", + label: "App Proof", + }, +]; diff --git a/snippets/divider.mdx b/snippets/divider.mdx index b9a5fc4f..864e83bc 100644 --- a/snippets/divider.mdx +++ b/snippets/divider.mdx @@ -1,5 +1,5 @@ export const Divider = ({ label }) => ( -
-
-
-) +
+
+
+); diff --git a/snippets/logo.mdx b/snippets/logo.mdx index 595be136..06bd80f1 100644 --- a/snippets/logo.mdx +++ b/snippets/logo.mdx @@ -155,93 +155,90 @@ if (id === "rest-api") { ); } - if (id === 'typescript') { - return ( - - - - - - ); - } - if (id === "go") { - return ( - - Go Logo - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ); - } - if (id === "rust") { - return ( - + + + + +); +} +if (id === "go") { +return ( + +Go Logo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +); +} +if (id === "rust") { +return ( + - +className={className} +{...props} > + @@ -279,29 +276,29 @@ width="300" height="200" viewBox="0 0 300 200" fill="none" ); - } - if (id === "python") { - return ( - - Python Logo - +Python Logo + - - - + - - - - + + + - - - - - - ); - } + + + + + +); +} - if (id === 'ruby') { - return ( - - - +if (id === 'ruby') { +return ( + + + ) - } - return null; + +} +return null; }; export const Card = ({ title, children, className = "", href }) => { diff --git a/snippets/shared/balance-concepts.mdx b/snippets/shared/balance-concepts.mdx index db07c838..6f897b4c 100644 --- a/snippets/shared/balance-concepts.mdx +++ b/snippets/shared/balance-concepts.mdx @@ -21,13 +21,14 @@ Each balance entry includes the asset metadata (symbol, name, decimals, and CAIP the current amount held at the address. - See the [with-balances](https://github.com/tkhq/sdk/tree/main/examples/with-balances) SDK example - for a working integration. + See the + [with-balances](https://github.com/tkhq/sdk/tree/main/examples/with-balances) + SDK example for a working integration. - The address must belong to a wallet account in your organization. Private key addresses are not - supported. + The address must belong to a wallet account in your organization. Private key + addresses are not supported. #### Supported chains @@ -116,18 +117,18 @@ Balance webhooks are currently supported on: The `balances:finalized` webhook fires once the block containing a transaction has reached a chain-specific number of confirmations. The table below lists the confirmation threshold Turnkey uses for each supported network: -| Network | CAIP-2 Identifier | Confirmations | -| :------------------ | :----------------------------------------- | ------------: | -| Ethereum Mainnet | `eip155:1` | 32 | -| Ethereum Sepolia | `eip155:11155111` | 12 | -| Base Mainnet | `eip155:8453` | 10 | -| Base Sepolia | `eip155:84532` | 5 | -| Polygon Mainnet | `eip155:137` | 30 | -| Polygon Amoy | `eip155:80002` | 12 | -| Arbitrum Mainnet | `eip155:42161` | 10 | -| Arbitrum Sepolia | `eip155:421614` | 5 | -| Solana mainnet | `solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp` | 32 | -| Solana devnet | `solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1` | 32 | +| Network | CAIP-2 Identifier | Confirmations | +| :--------------- | :---------------------------------------- | ------------: | +| Ethereum Mainnet | `eip155:1` | 32 | +| Ethereum Sepolia | `eip155:11155111` | 12 | +| Base Mainnet | `eip155:8453` | 10 | +| Base Sepolia | `eip155:84532` | 5 | +| Polygon Mainnet | `eip155:137` | 30 | +| Polygon Amoy | `eip155:80002` | 12 | +| Arbitrum Mainnet | `eip155:42161` | 10 | +| Arbitrum Sepolia | `eip155:421614` | 5 | +| Solana mainnet | `solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp` | 32 | +| Solana devnet | `solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1` | 32 | #### Delivery payload @@ -165,6 +166,7 @@ may produce multiple webhook deliveries — each with its own `idempotencyKey`. ``` ##### Example payload (`balances:finalized`) + ```json { "type": "balances:finalized", @@ -192,23 +194,24 @@ may produce multiple webhook deliveries — each with its own `idempotencyKey`. } ``` -| **Field** | **Description** | -| :--------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Field** | **Description** | +| :--------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `type` | `"balances:confirmed"` for when a balance change is first seen onchain, or `"balances:finalized"` when the associated block has reached the finalization threshold. | -| `organizationId` | Organization that owns the address. | -| `parentOrganizationId` | Billing/parent organization that owns webhook configuration and delivery. | -| `msg` | Object containing the balance change details. | -| `msg.operation` | Either `"deposit"` (incoming) or `"withdraw"` (outgoing). | -| `msg.caip2` | The chain identifier where the event occurred. | -| `msg.txHash` | The transaction hash that triggered the balance change. | -| `msg.address` | The address whose balance changed. | -| `msg.idempotencyKey` | A stable, unique key for this event. Use this to safely deduplicate webhook deliveries. | -| `msg.asset` | Asset metadata: symbol, name, decimals, CAIP-19 identifier, and the amount transferred (in the asset's decimals). Webhooks are emitted only for supported assets. | -| `msg.block` | Block number, hash, and timestamp of the block in which the transaction was first seen. | +| `organizationId` | Organization that owns the address. | +| `parentOrganizationId` | Billing/parent organization that owns webhook configuration and delivery. | +| `msg` | Object containing the balance change details. | +| `msg.operation` | Either `"deposit"` (incoming) or `"withdraw"` (outgoing). | +| `msg.caip2` | The chain identifier where the event occurred. | +| `msg.txHash` | The transaction hash that triggered the balance change. | +| `msg.address` | The address whose balance changed. | +| `msg.idempotencyKey` | A stable, unique key for this event. Use this to safely deduplicate webhook deliveries. | +| `msg.asset` | Asset metadata: symbol, name, decimals, CAIP-19 identifier, and the amount transferred (in the asset's decimals). Webhooks are emitted only for supported assets. | +| `msg.block` | Block number, hash, and timestamp of the block in which the transaction was first seen. | - See the [with-tx-webhooks](https://github.com/tkhq/sdk/tree/main/examples/with-tx-webhooks) SDK - example for a working integration. + See the + [with-tx-webhooks](https://github.com/tkhq/sdk/tree/main/examples/with-tx-webhooks) + SDK example for a working integration. #### Limitations diff --git a/snippets/shared/export-wallets.mdx b/snippets/shared/export-wallets.mdx index dedc06b7..1339c1de 100644 --- a/snippets/shared/export-wallets.mdx +++ b/snippets/shared/export-wallets.mdx @@ -14,9 +14,10 @@ ensure key material cannot be compromised on its way to you: - Initialize the wallet or private key export activity. In this activity, specify the wallet or - private key ID being exported, plus a target encryption key (TEK). A Turnkey enclave encrypts - the exported key to the target public key, and returns the bundle. + Initialize the wallet or private key export activity. In this activity, + specify the wallet or private key ID being exported, plus a target + encryption key (TEK). A Turnkey enclave encrypts the exported key to the + target public key, and returns the bundle. Decrypt the resulting bundle to reveal the wallet or private key. diff --git a/snippets/shared/import-wallets.mdx b/snippets/shared/import-wallets.mdx index 3b98408e..2284ea3a 100644 --- a/snippets/shared/import-wallets.mdx +++ b/snippets/shared/import-wallets.mdx @@ -14,13 +14,15 @@ which together ensure key material cannot be compromised on its way to Turnkey: - Initialize the import process. Turnkey creates and returns a secure bundle, which includes a - target encryption key (TEK). + Initialize the import process. Turnkey creates and returns a secure bundle, + which includes a target encryption key (TEK). - Encrypt the wallet or private key to the TEK from the previous step. - Send the resulting bundle to Turnkey. Turnkey decrypts the bundle in secure enclave where the - wallet or private key will reside long-term. + Encrypt the wallet or private key to the TEK from the previous step. + + + Send the resulting bundle to Turnkey. Turnkey decrypts the bundle in secure + enclave where the wallet or private key will reside long-term. diff --git a/snippets/shared/networks-links.mdx b/snippets/shared/networks-links.mdx index a9e5c6f5..de01dae1 100644 --- a/snippets/shared/networks-links.mdx +++ b/snippets/shared/networks-links.mdx @@ -31,25 +31,24 @@ export const NetworkLinks = () => { ); - return ( -
- - - - - - - - - - - - - - -
- ); +return ( +
+ + + + + + + + + + + + + + +
+); }; diff --git a/snippets/shared/policy-engine.mdx b/snippets/shared/policy-engine.mdx index c113b2b3..3a95dfba 100644 --- a/snippets/shared/policy-engine.mdx +++ b/snippets/shared/policy-engine.mdx @@ -30,7 +30,8 @@ All policies defined within an Organization are evaluated on each request. The i `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 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 diff --git a/snippets/shared/send-solana-tx-sdk-overview.mdx b/snippets/shared/send-solana-tx-sdk-overview.mdx index 204df866..69f46257 100644 --- a/snippets/shared/send-solana-tx-sdk-overview.mdx +++ b/snippets/shared/send-solana-tx-sdk-overview.mdx @@ -24,9 +24,9 @@ You can sign and broadcast Solana transactions in two primary ways: This page walks you through the React flow with full code examples. For using `@turnkey/core` directly, see [Sending Sponsored Transactions](/features/transaction-management/broadcasting). - Before sponsoring Solana transactions, review - [Solana Rent Sponsorship](/features/networks/solana-rent-refunds). Rent sponsorship is + Before sponsoring Solana transactions, review [Solana Rent + Sponsorship](/features/networks/solana-rent-refunds). Rent sponsorship is opt-in, disabled by default, and must be enabled in the dashboard first. This is especially important if you sponsor transactions from swap providers or other third-party builders that may create and close accounts. - \ No newline at end of file + diff --git a/snippets/shared/send-tx-concepts.mdx b/snippets/shared/send-tx-concepts.mdx index 6b969785..446f5465 100644 --- a/snippets/shared/send-tx-concepts.mdx +++ b/snippets/shared/send-tx-concepts.mdx @@ -31,7 +31,9 @@ Turnkey reduces this to a couple of API calls. We handle fees and our battle-tes > Interested in another chain? Reach out to us! - To access sponsored transactions, ensure that Gas Sponsorship is first enabled within your Turnkey dashboard. Then set `sponsor: true` and update the `caip2` parameter with the corresponding chain identifier. + To access sponsored transactions, ensure that Gas Sponsorship is first enabled + within your Turnkey dashboard. Then set `sponsor: true` and update the `caip2` + parameter with the corresponding chain identifier. ## Construction and Broadcast @@ -64,12 +66,13 @@ A successful Solana transaction requires: Turnkey handles all of this for you via `solSendTransaction`. Whether or not you use sponsorship, you pass through a minimal payload and we manage the rest. - On Solana, fee sponsorship and rent sponsorship are separate. `Sponsor Solana Rent` is disabled by - default and must be enabled in the dashboard before Turnkey will pre-fund rent for account - creation. If created accounts are later closed, refunded rent can go back to the signer rather - than the sponsor. See [Solana Rent Sponsorship](/features/networks/solana-rent-refunds). For payer - behavior, static-key requirements, and account-creation caveats in sponsored flows, see [Solana - transaction construction for sponsored + On Solana, fee sponsorship and rent sponsorship are separate. `Sponsor Solana + Rent` is disabled by default and must be enabled in the dashboard before + Turnkey will pre-fund rent for account creation. If created accounts are later + closed, refunded rent can go back to the signer rather than the sponsor. See + [Solana Rent Sponsorship](/features/networks/solana-rent-refunds). For payer + behavior, static-key requirements, and account-creation caveats in sponsored + flows, see [Solana transaction construction for sponsored flows](/features/networks/solana-transaction-construction). @@ -84,10 +87,11 @@ Either way, Turnkey handles construction, signing, broadcast, and status monitor Gas Sponsorship is available on **Pro** and **Enterprise** plans. - - **Pro:** Up to \$50/day across your organization. Sub-organization spending limits can be configured freely up to the \$50/day ceiling. - - **Enterprise:** Unlimited spend, with configurable time windows +- **Pro:** Up to \$50/day across your organization. Sub-organization spending limits can be configured freely up to the \$50/day ceiling. +- **Enterprise:** Unlimited spend, with configurable time windows + +Pay-as-you-go customers can still access transaction construction, signing, and broadcast. If you'd like to leverage gas sponsorship, please reach out! - Pay-as-you-go customers can still access transaction construction, signing, and broadcast. If you'd like to leverage gas sponsorship, please reach out! ### Spend limits @@ -99,16 +103,19 @@ Turnkey gives you USD-denominated controls over gas sponsorship spend at two lev What you can configure depends on your plan: -| | Pro | Enterprise | -|---|---|---| -| Organization-wide limit | Up to \$50/day | Fully configurable, no limits | -| Interval | Daily only | Minutes, hours, daily, weekly, or monthly | -| Sub-organization limits | Configurable up to the \$50/day org limit | Fully configurable, no limits | +| | Pro | Enterprise | +| ----------------------- | ----------------------------------------- | ----------------------------------------- | +| Organization-wide limit | Up to \$50/day | Fully configurable, no limits | +| Interval | Daily only | Minutes, hours, daily, weekly, or monthly | +| Sub-organization limits | Configurable up to the \$50/day org limit | Fully configurable, no limits | You can set limit values and time intervals through the dashboard. You can also query current usage against the active limit via the [`get_gas_usage`](https://docs.turnkey.com/api-reference/queries/get-gas-usage) endpoint. - Turnkey provides fee sponsorship and transaction broadcasting services only. In high-fee or congested network conditions, delays or non-inclusion may occur. It is the developer's responsibility to ensure appropriate spend limits are in place. + Turnkey provides fee sponsorship and transaction broadcasting services only. + In high-fee or congested network conditions, delays or non-inclusion may + occur. It is the developer's responsibility to ensure appropriate spend limits + are in place. ### Policy engine @@ -144,4 +151,4 @@ By default, our SDKs include a special gas station nonce for sponsored transacti ### RPCs -Turnkey's send transaction and transaction status endpoints eliminate the need for third-party RPC providers. You save costs and reduce latency because we holistically incorporate internal data and minimize external calls. \ No newline at end of file +Turnkey's send transaction and transaction status endpoints eliminate the need for third-party RPC providers. You save costs and reduce latency because we holistically incorporate internal data and minimize external calls. diff --git a/snippets/shared/send-tx-core.mdx b/snippets/shared/send-tx-core.mdx index 291bfc9e..32b75de8 100644 --- a/snippets/shared/send-tx-core.mdx +++ b/snippets/shared/send-tx-core.mdx @@ -5,12 +5,15 @@ For custom frameworks or full manual control (client-side). You will call: ### `ethSendTransaction(params)` + → returns `{ sendTransactionStatusId }` ### `solSendTransaction(params)` + → returns `{ sendTransactionStatusId }` ### `pollTransactionStatus(params)` + → returns chain-specific status (`eth.txHash` or `sol.signature`) ### Step 1 — Create a client @@ -137,9 +140,10 @@ and decode common revert reasons — giving you actionable error messages instea | CUSTOM | The transaction reverted due to a contract-defined custom error declared using Solidity's `error` keyword. | - These error types describe how an EVM smart contract reverted during onchain execution or - pre-flight simulation. Turnkey application-level errors (e.g. signing failures, policy rejections) - are not classified here and are instead surfaced via `Error.Message`. + These error types describe how an EVM smart contract reverted during onchain + execution or pre-flight simulation. Turnkey application-level errors (e.g. + signing failures, policy rejections) are not classified here and are instead + surfaced via `Error.Message`. ### Querying via API @@ -260,6 +264,7 @@ present in `msg` depend on the status: ``` - See the [with-tx-webhooks](https://github.com/tkhq/sdk/tree/main/examples/with-tx-webhooks) SDK - example for a working integration. + See the + [with-tx-webhooks](https://github.com/tkhq/sdk/tree/main/examples/with-tx-webhooks) + SDK example for a working integration. diff --git a/snippets/shared/send-tx-gas-usage.mdx b/snippets/shared/send-tx-gas-usage.mdx index 181688d4..779e7ebb 100644 --- a/snippets/shared/send-tx-gas-usage.mdx +++ b/snippets/shared/send-tx-gas-usage.mdx @@ -5,9 +5,10 @@ You can configure gas limits for both sub-orgs and all orgs. We recommend checki You may also want to monitor your all org gas usage regularly to see if you are approaching your gas limit. ```ts -const resp = await httpClient?.getGasUsage({}) -if (resp?.usageUsd! > resp?.windowLimitUsd!) { // you can also configure this to be a threshold +const resp = await httpClient?.getGasUsage({}); +if (resp?.usageUsd! > resp?.windowLimitUsd!) { + // you can also configure this to be a threshold console.error("Gas usage limit exceeded for sponsored transactions"); - return + return; } ``` diff --git a/snippets/shared/send-tx-react.mdx b/snippets/shared/send-tx-react.mdx index ef0f35e8..cf910159 100644 --- a/snippets/shared/send-tx-react.mdx +++ b/snippets/shared/send-tx-react.mdx @@ -71,6 +71,7 @@ await handleSendTransaction({ - Full React handler implementation [here](https://github.com/tkhq/sdk/blob/e5a153efa90c325d4f5ecfe65d8d2bff8573c64f/packages/react-wallet-kit/src/providers/client/Provider.tsx#L5536) This automatically: + - opens Turnkey modal - shows chain logo - polls until INCLUDED diff --git a/snippets/sms-price-data.mdx b/snippets/sms-price-data.mdx index fd482d68..86ae9139 100644 --- a/snippets/sms-price-data.mdx +++ b/snippets/sms-price-data.mdx @@ -21,7 +21,7 @@ export const priceDataJson = { Brazil: 2.297, "British Virgin Islands": 18.022, Brunei: 1.289, - Bulgaria: 13.600, + Bulgaria: 13.6, Cameroon: 12.333, Canada: 0.581, "Cape Verde": 13.74, @@ -144,7 +144,7 @@ export const priceDataJson = { Tunisia: 25.684, Turkey: 0.318, "United Arab Emirates": 10.809, - "United Kingdom": 4.500, + "United Kingdom": 4.5, "United States": 0.581, Uruguay: 7.317, Uzbekistan: 36.803, diff --git a/snippets/solution-card.mdx b/snippets/solution-card.mdx index 48c6920d..a66a3419 100644 --- a/snippets/solution-card.mdx +++ b/snippets/solution-card.mdx @@ -4,7 +4,7 @@ export const SolutionCard = ({ title, description, icon, href }) => { href={href} className="not-prose font-normal group ring-0 ring-transparent cursor-pointer block rounded-lg border border-zinc-950/10 dark:border-white/10 bg-white dark:bg-transparent p-5 no-underline hover:border-primary/40 transition-colors" > -
+
- The [agent provisioning skill](/get-started/ai-skills) can run this entire workflow for you through an AI assistant. Use the steps below if you prefer to implement it manually. + The [agent provisioning skill](/get-started/ai-skills) can run this entire + workflow for you through an AI assistant. Use the steps below if you prefer to + implement it manually. - This guide assumes you've completed the [Quickstart](/solutions/company-wallets/quickstart) and have a Turnkey client initialized with your root credentials. The agent will get its own separate credentials. + This guide assumes you've completed the + [Quickstart](/solutions/company-wallets/quickstart) and have a Turnkey client + initialized with your root credentials. The agent will get its own separate + credentials. @@ -65,7 +70,10 @@ Create a dedicated wallet scoped to the agent's needs. Always check for existing ```ts const { wallets } = await turnkeyClient.apiClient().getWallets(); -console.log("Existing wallets:", wallets.map((w) => `${w.walletName} (${w.walletId})`)); +console.log( + "Existing wallets:", + wallets.map((w) => `${w.walletName} (${w.walletId})`), +); const { walletId, addresses } = await turnkeyClient.apiClient().createWallet({ walletName: "Trading Agent Wallet", @@ -98,23 +106,29 @@ const pubJwk = keyPair.publicKey.export({ format: "jwk" }); const privJwk = keyPair.privateKey.export({ format: "jwk" }); // SEC1-compressed P-256 public key (33 bytes, 66 hex chars) -const xHex = Buffer.from(pubJwk.x!, "base64url").toString("hex").padStart(64, "0"); +const xHex = Buffer.from(pubJwk.x!, "base64url") + .toString("hex") + .padStart(64, "0"); const yBuf = Buffer.from( Buffer.from(pubJwk.y!, "base64url").toString("hex").padStart(64, "0"), - "hex" + "hex", ); const prefix = (yBuf[yBuf.length - 1] & 1) === 0 ? "02" : "03"; const agentPublicKey = prefix + xHex; -const agentPrivateKey = Buffer.from(privJwk.d!, "base64url").toString("hex").padStart(64, "0"); +const agentPrivateKey = Buffer.from(privJwk.d!, "base64url") + .toString("hex") + .padStart(64, "0"); ``` Then create a user tag and the agent user. `userTags` takes tag IDs (UUIDs), not string labels, so create the tag first: ```ts -const { userTagId: agentTagId } = await turnkeyClient.apiClient().createUserTag({ - userTagName: "agent", - userIds: [], -}); +const { userTagId: agentTagId } = await turnkeyClient + .apiClient() + .createUserTag({ + userTagName: "agent", + userIds: [], + }); const { userIds } = await turnkeyClient.apiClient().createUsers({ users: [ @@ -138,7 +152,8 @@ const agentUserId = userIds[0]; ``` - Never create agents as root users. Root users bypass the policy engine entirely. Always use non-root users with explicit ALLOW policies. + Never create agents as root users. Root users bypass the policy engine + entirely. Always use non-root users with explicit ALLOW policies. @@ -220,7 +235,8 @@ SIGN_WITH= ``` - Never output or log root credentials alongside agent credentials. The agent should only ever have its own key pair. + Never output or log root credentials alongside agent credentials. The agent + should only ever have its own key pair. @@ -228,9 +244,35 @@ SIGN_WITH= ## Next steps -
- - - - +
+ + + +
diff --git a/solutions/company-wallets/integration-guide/golang.mdx b/solutions/company-wallets/integration-guide/golang.mdx index 64792fe8..251e86f0 100644 --- a/solutions/company-wallets/integration-guide/golang.mdx +++ b/solutions/company-wallets/integration-guide/golang.mdx @@ -3,4 +3,3 @@ title: "Golang" description: "Turnkey offers native tooling for interacting with the API using Golang. See [https://github.com/tkhq/go-sdk](https://github.com/tkhq/go-sdk) for more details." mode: wide --- - diff --git a/solutions/company-wallets/integration-guide/javascript-server.mdx b/solutions/company-wallets/integration-guide/javascript-server.mdx index d988ffee..62bf91bf 100644 --- a/solutions/company-wallets/integration-guide/javascript-server.mdx +++ b/solutions/company-wallets/integration-guide/javascript-server.mdx @@ -195,7 +195,8 @@ if (initAuthResponse?.otpId) { #### Parameters - An object containing the parameters to initiate an `EMAIL` or `SMS` OTP authentication flow. + An object containing the parameters to initiate an `EMAIL` or `SMS` OTP + authentication flow. @@ -289,7 +290,8 @@ if (verifyResponse?.verificationToken) { - Optional. The session lifetime in seconds. Defaults to 900 seconds (15 minutes). + Optional. The session lifetime in seconds. Defaults to 900 seconds (15 + minutes). ### `createOauthSession()` @@ -388,11 +390,13 @@ const sendCredentialResponse = await server.sendCredential({ - IP Address, iframePublicKey, or other unique identifier used for rate limiting. + IP Address, iframePublicKey, or other unique identifier used for rate + limiting. - Specify the length of the session in seconds. Defaults to 900 seconds or 15 minutes. + Specify the length of the session in seconds. Defaults to 900 seconds or 15 + minutes. diff --git a/solutions/company-wallets/integration-guide/overview.mdx b/solutions/company-wallets/integration-guide/overview.mdx index dab40e6d..8f59fa98 100644 --- a/solutions/company-wallets/integration-guide/overview.mdx +++ b/solutions/company-wallets/integration-guide/overview.mdx @@ -1,7 +1,6 @@ --- title: "Server SDKs" -description: - "Language and framework options for integrating Company Wallets from a backend service." +description: "Language and framework options for integrating Company Wallets from a backend service." sidebarTitle: "Overview" --- @@ -12,22 +11,53 @@ choosing the right SDK for your stack. ## Choose your SDK - + Our most complete SDK. Recommended if your backend can run Node.js. - + Native Go SDK. - + turnkey_client gem for Ruby and Rails projects. - + Native Rust SDK. - - Pydantic type definitions, an HTTP-client for easy direct requests, and API-key stamper. + + Pydantic type definitions, an HTTP-client for easy direct requests, and + API-key stamper. - + Call the Turnkey REST API directly from any language. diff --git a/solutions/company-wallets/integration-guide/rust.mdx b/solutions/company-wallets/integration-guide/rust.mdx index e5a2fa62..17f0c78d 100644 --- a/solutions/company-wallets/integration-guide/rust.mdx +++ b/solutions/company-wallets/integration-guide/rust.mdx @@ -3,5 +3,3 @@ title: "Rust" description: "Turnkey offers native tooling for interacting with the API using Rust. See [https://github.com/tkhq/rust-sdk](https://github.com/tkhq/rust-sdk) for more details." mode: wide --- - - diff --git a/solutions/company-wallets/overview.mdx b/solutions/company-wallets/overview.mdx index 860fd21f..9107df4c 100644 --- a/solutions/company-wallets/overview.mdx +++ b/solutions/company-wallets/overview.mdx @@ -2,7 +2,7 @@ title: "Overview" --- -import { SolutionCard } from '/snippets/solution-card.mdx'; +import { SolutionCard } from "/snippets/solution-card.mdx"; ## What are company wallets? @@ -62,7 +62,13 @@ See the [Company Wallets Quickstart](/solutions/company-wallets/quickstart) to g Company wallets serve different needs depending on what you're building. Choose the pattern that matches your operations. -
+
- This guide assumes you've completed the [Quickstart](/solutions/company-wallets/quickstart) and have a Turnkey client initialized. If not, start there first. + This guide assumes you've completed the + [Quickstart](/solutions/company-wallets/quickstart) and have a Turnkey client + initialized. If not, start there first. @@ -81,7 +83,7 @@ Then generate fresh deposit addresses on demand: ```ts async function createDepositAddresses( turnkeyClient: Turnkey, - walletId: string + walletId: string, ): Promise { const addresses = await turnkeyClient.apiClient().createWalletAccounts({ walletId, @@ -126,17 +128,19 @@ Turnkey's Policy Engine is default-deny: you only specify the exact conditions t Normally you'd need to fund every deposit address with gas before sweeping. Sponsored transactions bypass this entirely: ```ts -const sendTransactionStatusId = await turnkeyClient.apiClient().ethSendTransaction({ - transaction: { - from: depositAddress, - to: "OMNIBUS_ADDRESS", - caip2: "eip155:8453", - sponsor: true, - value: "0", - data: "0x", - nonce: "0", - }, -}); +const sendTransactionStatusId = await turnkeyClient + .apiClient() + .ethSendTransaction({ + transaction: { + from: depositAddress, + to: "OMNIBUS_ADDRESS", + caip2: "eip155:8453", + sponsor: true, + value: "0", + data: "0x", + nonce: "0", + }, + }); ``` See the [gas sponsorship guide](/features/transaction-management/broadcasting) for more details. @@ -165,8 +169,29 @@ For token transfers, the policy above parses the ERC-20 `transfer` function sign ## Next steps -
- - - +
+ + +
diff --git a/solutions/company-wallets/quickstart.mdx b/solutions/company-wallets/quickstart.mdx index bd807e3f..d1ea9d53 100644 --- a/solutions/company-wallets/quickstart.mdx +++ b/solutions/company-wallets/quickstart.mdx @@ -4,8 +4,8 @@ description: "Get from zero to a signed transaction with Turnkey's Company Walle sidebarTitle: "Quickstart" --- -import { FeatureCard } from '/snippets/feature-card.mdx' -import { SolutionCard } from '/snippets/solution-card.mdx' +import { FeatureCard } from "/snippets/feature-card.mdx"; +import { SolutionCard } from "/snippets/solution-card.mdx"; ## Prerequisites @@ -28,7 +28,12 @@ npm install @turnkey/sdk-server @turnkey/ethers ethers - This quickstart uses Ethereum, but Turnkey supports all EVM and SVM chains, along with Bitcoin, Tron, and [more](/features/networks/overview). To sign Solana transactions, derive a Solana address using `ADDRESS_FORMAT_SOLANA` with `CURVE_ED25519` and use [`@turnkey/solana`](https://www.npmjs.com/package/@turnkey/solana) or the server SDK's [`solSendTransaction`](/features/networks/solana) method. + This quickstart uses Ethereum, but Turnkey supports all EVM and SVM chains, + along with Bitcoin, Tron, and [more](/features/networks/overview). To sign + Solana transactions, derive a Solana address using `ADDRESS_FORMAT_SOLANA` + with `CURVE_ED25519` and use + [`@turnkey/solana`](https://www.npmjs.com/package/@turnkey/solana) or the + server SDK's [`solSendTransaction`](/features/networks/solana) method. ## Sign your first transaction @@ -90,17 +95,18 @@ import { createWalletClient, http } from "viem"; import { mainnet } from "viem/chains"; const turnkeyAccount = await createAccount({ - client: turnkeyClient.apiClient(), - organizationId: process.env.TURNKEY_ORGANIZATION_ID!, - signWith: ethereumAddress, +client: turnkeyClient.apiClient(), +organizationId: process.env.TURNKEY_ORGANIZATION_ID!, +signWith: ethereumAddress, }); const walletClient = createWalletClient({ - account: turnkeyAccount, - chain: mainnet, - transport: http(), +account: turnkeyAccount, +chain: mainnet, +transport: http(), }); -``` + +```` ```ts @@ -114,7 +120,8 @@ const turnkeySigner = new TurnkeySigner({ signWith: ethereumAddress, }); const connectedSigner = turnkeySigner.connect(provider); -``` +```` + @@ -127,11 +134,12 @@ const connectedSigner = turnkeySigner.connect(provider); import { parseEther } from "viem"; const txHash = await walletClient.sendTransaction({ - to: "", - value: parseEther(""), +to: "", +value: parseEther(""), }); console.log("Transaction hash:", txHash); -``` + +```` ```ts @@ -141,7 +149,8 @@ const txHash = await connectedSigner.sendTransaction({ type: 2, }); console.log("Transaction hash:", txHash.hash); -``` +```` + @@ -150,9 +159,35 @@ console.log("Transaction hash:", txHash.hash); ## Next steps -
- - - - +
+ + + +
diff --git a/solutions/company-wallets/smart-contract-management.mdx b/solutions/company-wallets/smart-contract-management.mdx index d4c9b0dd..eee9f667 100644 --- a/solutions/company-wallets/smart-contract-management.mdx +++ b/solutions/company-wallets/smart-contract-management.mdx @@ -4,8 +4,8 @@ description: "Secure the full smart contract lifecycle with policy-enforced depl mode: wide --- -import { FeatureCard } from '/snippets/feature-card.mdx' -import { SolutionCard } from '/snippets/solution-card.mdx' +import { FeatureCard } from "/snippets/feature-card.mdx"; +import { SolutionCard } from "/snippets/solution-card.mdx"; This guide covers the key implementation decisions for securing smart contract operations, then walks through the contract lifecycle end-to-end: permissioned deployment, function-level interaction policies, and minimizing risk during upgrades. For basic signing, start with the [Quickstart](/solutions/company-wallets/quickstart). @@ -20,32 +20,34 @@ Turnkey also fits **existing** contract deployments. You don't need to redeploy ## Key implementation decisions -| Decision | What to consider | -| :--- | :--- | -| Role isolation | Separate wallets for deployer, operator, and upgrade owner so each role has its own keys and scoped policies | -| Deployment permissions | Policy scoping the deployer to a specific wallet and network | +| Decision | What to consider | +| :---------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Role isolation | Separate wallets for deployer, operator, and upgrade owner so each role has its own keys and scoped policies | +| Deployment permissions | Policy scoping the deployer to a specific wallet and network | | Function-level controls | Policies targeting specific contract addresses and function signatures, or [upload the ABI](/features/policies/smart-contract-interfaces) for full parsing | -| Value thresholds | Automated approval for routine operations (small mints), multi-party consensus for large ones | -| Upgrade controls | Grant upgrade permissions only when needed via temporary policies, then revoke immediately after | +| Value thresholds | Automated approval for routine operations (small mints), multi-party consensus for large ones | +| Upgrade controls | Grant upgrade permissions only when needed via temporary policies, then revoke immediately after | ## Example: stablecoins and RWAs Stablecoins and tokenized Real-World Assets often secure billions of dollars in value. These contracts typically involve minting, burning, pausing, and upgrades, each requiring different levels of authorization. -| Need | How Turnkey solves it | -| :--- | :--- | -| Minting must be constrained to approved limits | Policies can bound mint amounts and require multi-party approval above a threshold via [smart contract interfaces](/features/policies/smart-contract-interfaces) | -| Only authorized addresses can receive new supply | Policies target specific contract addresses and function arguments, restricting who the `mint` recipient can be | -| Must support emergency pause | A dedicated pause operator wallet with a scoped policy for the `pause` function, separate from day-to-day minting | -| Upgrades must not introduce unreviewed logic | Temporary upgrade policies with multi-party consensus, revoked immediately after execution | -| Full audit trail of every operation | Every signing action is an activity in Turnkey with a complete audit log of who approved what and when | +| Need | How Turnkey solves it | +| :----------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Minting must be constrained to approved limits | Policies can bound mint amounts and require multi-party approval above a threshold via [smart contract interfaces](/features/policies/smart-contract-interfaces) | +| Only authorized addresses can receive new supply | Policies target specific contract addresses and function arguments, restricting who the `mint` recipient can be | +| Must support emergency pause | A dedicated pause operator wallet with a scoped policy for the `pause` function, separate from day-to-day minting | +| Upgrades must not introduce unreviewed logic | Temporary upgrade policies with multi-party consensus, revoked immediately after execution | +| Full audit trail of every operation | Every signing action is an activity in Turnkey with a complete audit log of who approved what and when | ![rbac](/assets/files/rbac.png) ### Implementation steps - This guide assumes you've completed the [Quickstart](/solutions/company-wallets/quickstart) and have a Turnkey client initialized. If not, start there first. + This guide assumes you've completed the + [Quickstart](/solutions/company-wallets/quickstart) and have a Turnkey client + initialized. If not, start there first. @@ -111,14 +113,42 @@ The `0x3659cfe6` selector matches `upgradeTo(address)`. After the upgrade comple - This lifecycle is further explored in the [Smart Contract Management demo](https://github.com/tkhq/solutions/tree/main/smart-contract-mgmt) on GitHub. + This lifecycle is further explored in the [Smart Contract Management + demo](https://github.com/tkhq/solutions/tree/main/smart-contract-mgmt) on + GitHub. ## Next steps -
- - - - +
+ + + +
diff --git a/solutions/cookbooks/0x.mdx b/solutions/cookbooks/0x.mdx index 3f312034..a8eaed41 100644 --- a/solutions/cookbooks/0x.mdx +++ b/solutions/cookbooks/0x.mdx @@ -1,5 +1,5 @@ --- -title: 'Use Turnkey wallets with 0x' +title: "Use Turnkey wallets with 0x" sidebarTitle: "0x integration" --- @@ -16,7 +16,7 @@ We'll demonstrate this using the [`with-0x`](https://github.com/tkhq/sdk/tree/ma Before you begin, make sure you’ve followed the [Turnkey Quickstart guide](/get-started/quickstart). You should have: -- A Turnkey **organization** and **Auth Proxy Config ID** +- A Turnkey **organization** and **Auth Proxy Config ID** - Once you generate an account with the example, the account funded with **ETH** You’ll also need your **0X API key** (see the [Breeze Developer Portal](https://dashboard.0x.org/)). @@ -41,7 +41,9 @@ import { createAccount } from "@turnkey/viem"; export default function SwapPage() { const { httpClient, session, fetchWalletAccounts, wallets } = useTurnkey(); - const [viemWalletClient, setViemWalletClient] = useState(undefined); + const [viemWalletClient, setViemWalletClient] = useState< + WalletClient | undefined + >(undefined); // obtain a users turnkey wallets const walletAccountResponse = await fetchWalletAccounts({ @@ -60,7 +62,7 @@ export default function SwapPage() { account: turnkeyAccount as Account, chain: mainnet, transport: http(MAINNET_RPC_PROVIDER), - }) + }); // Render your login/logout and account selector UI here } ``` @@ -177,11 +179,12 @@ This code snippet shows how to check and set the allowance for an address for US import { createPublicClient, erc20Abi, maxUint256, parseUnits } from "viem"; import { mainnet } from "viem/chains"; -const USDC_MAINNET_TOKEN_ADDRESS = "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"; // ETH MAINNET USDC token contract address -const MAINNET_0X_ALLOWANCE_HOLDER_ADDRESS = "0x0000000000001fF3684f28c67538d4D072C22734"; // 0x Allowance Holder contract address +const USDC_MAINNET_TOKEN_ADDRESS = "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"; // ETH MAINNET USDC token contract address +const MAINNET_0X_ALLOWANCE_HOLDER_ADDRESS = + "0x0000000000001fF3684f28c67538d4D072C22734"; // 0x Allowance Holder contract address const address = ""; // this should be the address sending the USDC to swap -const fromAmount = "" // 1 == 1 USDC +const fromAmount = ""; // 1 == 1 USDC const viemPublicClient = createPublicClient({ chain: mainnet, @@ -213,7 +216,6 @@ if (currentAllowance < parseUnits(fromAmount, 6)) { hash: approveAllowanceHash!, }); } - ``` ## Summary @@ -224,4 +226,4 @@ You’ve now learned how to: - Set allowances on ERC-20 tokens -- Interact with 0x to retrieve quotes and swap EVM tokens \ No newline at end of file +- Interact with 0x to retrieve quotes and swap EVM tokens diff --git a/solutions/cookbooks/aave.mdx b/solutions/cookbooks/aave.mdx index fd51d9ae..41abc114 100644 --- a/solutions/cookbooks/aave.mdx +++ b/solutions/cookbooks/aave.mdx @@ -1,5 +1,5 @@ --- -title: 'Use Turnkey wallets with Aave' +title: "Use Turnkey wallets with Aave" sidebarTitle: "Aave integration" --- @@ -33,31 +33,31 @@ import { Turnkey } from "@turnkey/sdk-server"; import { AaveV3Base } from "@bgd-labs/aave-address-book"; const turnkeyClient = new Turnkey({ - apiBaseUrl: "https://api.turnkey.com", - apiPrivateKey: process.env.TURNKEY_API_PRIVATE_KEY!, - apiPublicKey: process.env.TURNKEY_API_PUBLIC_KEY!, - defaultOrganizationId: process.env.TURNKEY_ORGANIZATION_ID!, + apiBaseUrl: "https://api.turnkey.com", + apiPrivateKey: process.env.TURNKEY_API_PRIVATE_KEY!, + apiPublicKey: process.env.TURNKEY_API_PUBLIC_KEY!, + defaultOrganizationId: process.env.TURNKEY_ORGANIZATION_ID!, }).apiClient(); -const userId = ""; +const userId = + ""; // Pull addresses from Aave Address Book (Base) const USDC_ADDRESS = AaveV3Base.ASSETS.USDC.UNDERLYING; const AAVE_POOL = AaveV3Base.POOL; -const policyName = - "Allow API key user to only sign txs to Aave Pool and USDC"; - const effect = "EFFECT_ALLOW"; - const consensus = `approvers.any(user, user.id == '${userId}')`; - const condition = `eth.tx.to in ['${USDC_ADDRESS}', '${AAVE_POOL}']`; - const notes = ""; +const policyName = "Allow API key user to only sign txs to Aave Pool and USDC"; +const effect = "EFFECT_ALLOW"; +const consensus = `approvers.any(user, user.id == '${userId}')`; +const condition = `eth.tx.to in ['${USDC_ADDRESS}', '${AAVE_POOL}']`; +const notes = ""; const { policyId } = await turnkeyClient.createPolicy({ - policyName, - condition, - consensus, - effect, - notes, + policyName, + condition, + consensus, + effect, + notes, }); ``` @@ -70,42 +70,42 @@ import { base } from "viem/chains"; import { createAccount } from "@turnkey/viem"; import { Turnkey as TurnkeyServerSDK } from "@turnkey/sdk-server"; import { - parseAbi, - erc20Abi, - parseUnits, - createWalletClient, - http, - createPublicClient, - type Account, + parseAbi, + erc20Abi, + parseUnits, + createWalletClient, + http, + createPublicClient, + type Account, } from "viem"; const turnkeyClient = new TurnkeyServerSDK({ - apiBaseUrl: process.env.TURNKEY_BASE_URL!, - apiPrivateKey: process.env.NONROOT_API_PRIVATE_KEY!, - apiPublicKey: process.env.NONROOT_API_PUBLIC_KEY!, - defaultOrganizationId: process.env.TURNKEY_ORGANIZATION_ID!, + apiBaseUrl: process.env.TURNKEY_BASE_URL!, + apiPrivateKey: process.env.NONROOT_API_PRIVATE_KEY!, + apiPublicKey: process.env.NONROOT_API_PUBLIC_KEY!, + defaultOrganizationId: process.env.TURNKEY_ORGANIZATION_ID!, }); const turnkeyAccount = await createAccount({ - client: turnkeyClient.apiClient(), - organizationId: process.env.TURNKEY_ORGANIZATION_ID!, - signWith: process.env.SIGN_WITH!, + client: turnkeyClient.apiClient(), + organizationId: process.env.TURNKEY_ORGANIZATION_ID!, + signWith: process.env.SIGN_WITH!, }); const client = createWalletClient({ - account: turnkeyAccount as Account, - chain: base, - transport: http( - `https://base-mainnet.infura.io/v3/${process.env.INFURA_API_KEY!}`, - ), + account: turnkeyAccount as Account, + chain: base, + transport: http( + `https://base-mainnet.infura.io/v3/${process.env.INFURA_API_KEY!}`, + ), }); // Use the standard viem client for non-signing operations const publicClient = createPublicClient({ - transport: http( - `https://base-mainnet.infura.io/v3/${process.env.INFURA_API_KEY!}`, - ), - chain: base, + transport: http( + `https://base-mainnet.infura.io/v3/${process.env.INFURA_API_KEY!}`, + ), + chain: base, }); ``` @@ -120,19 +120,23 @@ const AAVE_POOL = AaveV3Base.POOL; // Approve Pool to spend 10 USDC const { request: approveReq } = await publicClient.simulateContract({ - address: USDC_ADDRESS as `0x${string}`, - abi: erc20Abi, - functionName: "approve", - args: [AAVE_POOL as `0x${string}`, parseUnits("10", 6)], // USDC has 6 decimals - account: walletClient.account, + address: USDC_ADDRESS as `0x${string}`, + abi: erc20Abi, + functionName: "approve", + args: [AAVE_POOL as `0x${string}`, parseUnits("10", 6)], // USDC has 6 decimals + account: walletClient.account, }); const approveHash = await walletClient.writeContract(approveReq); const receiptApprove = await publicClient.waitForTransactionReceipt({ - hash: approveHash, + hash: approveHash, }); -console.log("Approve transaction:", `https://basescan.org/tx/${approveHash}`, receiptApprove.status); +console.log( + "Approve transaction:", + `https://basescan.org/tx/${approveHash}`, + receiptApprove.status, +); ``` ## Deposit USDC into Aave Pool @@ -140,51 +144,54 @@ console.log("Approve transaction:", `https://basescan.org/tx/${approveHash}`, re ```tsx // Supply 0.5 USDC const poolAbi = parseAbi([ - "function supply(address asset,uint256 amount,address onBehalfOf,uint16 referralCode)", + "function supply(address asset,uint256 amount,address onBehalfOf,uint16 referralCode)", ]); const { request: supplyReq } = await publicClient.simulateContract({ - address: AAVE_POOL as `0x${string}`, - abi: poolAbi, - functionName: "supply", - args: [ - USDC_ADDRESS, - parseUnits("0.5", 6), - (walletClient.account as Account).address, - 0, - ], - account: walletClient.account as Account, + address: AAVE_POOL as `0x${string}`, + abi: poolAbi, + functionName: "supply", + args: [ + USDC_ADDRESS, + parseUnits("0.5", 6), + (walletClient.account as Account).address, + 0, + ], + account: walletClient.account as Account, }); // The USDC transfer path & proxy layers sometimes make estimateGas under-shoot // Adding a buffer to avoid occasional out-of-gas errors const gas = await publicClient.estimateContractGas({ - address: AAVE_POOL as `0x${string}`, - abi: poolAbi, - functionName: "supply", - args: [ - USDC_ADDRESS, - parseUnits("0.5", 6), - (walletClient.account as Account).address, - 0, - ], - account: walletClient.account as Account, + address: AAVE_POOL as `0x${string}`, + abi: poolAbi, + functionName: "supply", + args: [ + USDC_ADDRESS, + parseUnits("0.5", 6), + (walletClient.account as Account).address, + 0, + ], + account: walletClient.account as Account, }); const gasWithBuffer = (gas * 130n) / 100n; const supplyHash = await walletClient.writeContract({ - ...supplyReq, - gas: gasWithBuffer, + ...supplyReq, + gas: gasWithBuffer, }); const receiptSupply = await publicClient.waitForTransactionReceipt({ - hash: supplyHash, + hash: supplyHash, }); -console.log("Supply transaction:", `https://basescan.org/tx/${supplyHash}`, receiptSupply.status); +console.log( + "Supply transaction:", + `https://basescan.org/tx/${supplyHash}`, + receiptSupply.status, +); ``` - ## Read the aUSDC balance When you supply USDC into Aave, you receive aUSDC (an ERC-20 “receipt” token), aUSDC.balanceOf(user) already shows your live underlying balance (principal + interest), because it’s auto-scaled by Aave’s liquidity index. @@ -195,22 +202,22 @@ const aUSDC = AaveV3Base.ASSETS.USDC.A_TOKEN; // Read aUSDC balance which tracks your supplied principal + interest const erc20ReadAbi = parseAbi([ - "function balanceOf(address) view returns (uint256)", - "function decimals() view returns (uint8)", + "function balanceOf(address) view returns (uint256)", + "function decimals() view returns (uint8)", ]); const [decimals, rawBal] = await Promise.all([ - publicClient.readContract({ - address: aUSDC as `0x${string}`, - abi: erc20ReadAbi, - functionName: "decimals", -}), - publicClient.readContract({ - address: aUSDC as `0x${string}`, - abi: erc20ReadAbi, - functionName: "balanceOf", - args: [(walletClient.account as Account).address], - }), + publicClient.readContract({ + address: aUSDC as `0x${string}`, + abi: erc20ReadAbi, + functionName: "decimals", + }), + publicClient.readContract({ + address: aUSDC as `0x${string}`, + abi: erc20ReadAbi, + functionName: "balanceOf", + args: [(walletClient.account as Account).address], + }), ]); console.log("aUSDC balance:", formatUnits(rawBal, Number(decimals))); @@ -226,45 +233,49 @@ const USDC_ADDRESS = AaveV3Base.ASSETS.USDC.UNDERLYING; const AAVE_POOL = AaveV3Base.POOL; const poolReadWriteAbi = parseAbi([ - "function withdraw(address asset,uint256 amount,address to) returns (uint256)", + "function withdraw(address asset,uint256 amount,address to) returns (uint256)", ]); // withdraw 0.1 USDC const { request: withdrawReq } = await publicClient.simulateContract({ - address: AAVE_POOL as `0x${string}`, - abi: poolReadWriteAbi, - functionName: "withdraw", - args: [ - USDC_ADDRESS, - parseUnits("0.1", 6), - (walletClient.account as Account).address, - ], - account: walletClient.account as Account, + address: AAVE_POOL as `0x${string}`, + abi: poolReadWriteAbi, + functionName: "withdraw", + args: [ + USDC_ADDRESS, + parseUnits("0.1", 6), + (walletClient.account as Account).address, + ], + account: walletClient.account as Account, }); // the USDC transfer path & proxy layers sometimes make estimateGas under-shoot // adding a buffer to avoid occasional out-of-gas errors const gas = await publicClient.estimateContractGas({ - address: AAVE_POOL as `0x${string}`, - abi: poolReadWriteAbi, - functionName: "withdraw", - args: [ - USDC_ADDRESS, - parseUnits("0.1", 6), - (walletClient.account as Account).address, - ], - account: walletClient.account as Account, + address: AAVE_POOL as `0x${string}`, + abi: poolReadWriteAbi, + functionName: "withdraw", + args: [ + USDC_ADDRESS, + parseUnits("0.1", 6), + (walletClient.account as Account).address, + ], + account: walletClient.account as Account, }); const gasWithBuffer = (gas * 130n) / 100n; const withdrawHash = await walletClient.writeContract({ - ...withdrawReq, - gas: gasWithBuffer, + ...withdrawReq, + gas: gasWithBuffer, }); const receiptWithdraw = await publicClient.waitForTransactionReceipt({ - hash: withdrawHash, + hash: withdrawHash, }); -console.log("Withdraw transaction:", `https://basescan.org/tx/${withdrawHash}`, receiptWithdraw.status); -``` \ No newline at end of file +console.log( + "Withdraw transaction:", + `https://basescan.org/tx/${withdrawHash}`, + receiptWithdraw.status, +); +``` diff --git a/solutions/cookbooks/base-builder-codes.mdx b/solutions/cookbooks/base-builder-codes.mdx index 7fde64b9..fca95e72 100644 --- a/solutions/cookbooks/base-builder-codes.mdx +++ b/solutions/cookbooks/base-builder-codes.mdx @@ -5,7 +5,7 @@ sidebarTitle: "Base builders" ## Overview -[Builder Codes (ERC-8021)](https://www.erc8021.com/) allow app developers to attribute onchain activity to their application. This guide explains how to integrate Builder Code attribution on Base with Turnkey-signed transactions using viem's `dataSuffix` option. +[Builder Codes (ERC-8021)](https://www.erc8021.com/) allow app developers to attribute onchain activity to their application. This guide explains how to integrate Builder Code attribution on Base with Turnkey-signed transactions using viem's `dataSuffix` option. By appending an encoded Builder Code to transaction data, you can track usage analytics on [base.dev](https://base.dev) and qualify for potential future rewards. diff --git a/solutions/cookbooks/brale.mdx b/solutions/cookbooks/brale.mdx index 8802a694..b629f9df 100644 --- a/solutions/cookbooks/brale.mdx +++ b/solutions/cookbooks/brale.mdx @@ -104,7 +104,12 @@ console.log("Created policy", policyId); import { createAccount } from "@turnkey/viem"; import { Turnkey as TurnkeyServerSDK } from "@turnkey/sdk-server"; import { base } from "viem/chains"; -import { createPublicClient, createWalletClient, http, type Account } from "viem"; +import { + createPublicClient, + createWalletClient, + http, + type Account, +} from "viem"; const nonRootClient = new TurnkeyServerSDK({ apiBaseUrl: process.env.TURNKEY_BASE_URL!, diff --git a/solutions/cookbooks/breeze.mdx b/solutions/cookbooks/breeze.mdx index e50e18c2..dc2279ae 100644 --- a/solutions/cookbooks/breeze.mdx +++ b/solutions/cookbooks/breeze.mdx @@ -1,12 +1,12 @@ --- -title: 'Use Turnkey wallets with Breeze' +title: "Use Turnkey wallets with Breeze" sidebarTitle: "Breeze integration" --- ## Overview [Breeze](https://breeze.baby) is a Solana-based yield platform that allows users to deposit and withdraw assets from managed yield funds via smart contracts and APIs. -In this guide, we’ll walk through how to use **Turnkey** wallets to sign transactions that interact with Breeze funds, including deposits, withdrawals, and balance queries. +In this guide, we’ll walk through how to use **Turnkey** wallets to sign transactions that interact with Breeze funds, including deposits, withdrawals, and balance queries. We'll demonstrate this using the [`with-breeze`](https://github.com/tkhq/sdk/tree/main/examples/with-breeze) example, which integrates **Turnkey**, **Solana**, and **Breeze** for staking deposits/withdrawals. --- @@ -16,7 +16,7 @@ We'll demonstrate this using the [`with-breeze`](https://github.com/tkhq/sdk/tre Before you begin, make sure you’ve followed the [Turnkey Quickstart guide](/get-started/quickstart). You should have -- A Turnkey **organization** and **Auth Proxy Config ID** +- A Turnkey **organization** and **Auth Proxy Config ID** - An account funded with **USDC** on **SOL** You’ll also need your **Breeze API key** (see the [Breeze Developer Portal](https://docs.breeze.baby)) and your fund ID. @@ -40,11 +40,15 @@ import { useTurnkey, WalletAccount } from "@turnkey/react-wallet-kit"; import { TurnkeySigner } from "@turnkey/solana"; import { VersionedTransaction, PublicKey, Connection } from "@solana/web3.js"; -const connection = new Connection("https://solana-rpc.publicnode.com", "confirmed"); +const connection = new Connection( + "https://solana-rpc.publicnode.com", + "confirmed", +); export default function BreezePage() { const { wallets, httpClient, handleLogin, logout, session } = useTurnkey(); - const [activeWalletAccount, setActiveWalletAccount] = useState(null); + const [activeWalletAccount, setActiveWalletAccount] = + useState(null); const signer = activeWalletAccount ? new TurnkeySigner({ @@ -135,7 +139,10 @@ import { TurnkeySigner } from "@turnkey/solana"; import { Connection, VersionedTransaction, PublicKey } from "@solana/web3.js"; import { createDepositTx } from "../actions/breeze"; -const connection = new Connection("https://solana-rpc.publicnode.com", "confirmed"); +const connection = new Connection( + "https://solana-rpc.publicnode.com", + "confirmed", +); export default function DepositButton({ fundId, @@ -147,7 +154,8 @@ export default function DepositButton({ amount: number; }) { const { httpClient, wallets } = useTurnkey(); - const [activeWalletAccount, setActiveWalletAccount] = useState(null); + const [activeWalletAccount, setActiveWalletAccount] = + useState(null); const signer = activeWalletAccount ? new TurnkeySigner({ @@ -178,7 +186,10 @@ export default function DepositButton({ } return ( - ); @@ -212,6 +223,7 @@ async function handleWithdraw() { ``` ## Checking balances and yield info + ```tsx import { getUserData } from "../actions/breeze"; diff --git a/solutions/cookbooks/jupiter.mdx b/solutions/cookbooks/jupiter.mdx index 04b219e1..676e7f45 100644 --- a/solutions/cookbooks/jupiter.mdx +++ b/solutions/cookbooks/jupiter.mdx @@ -1,5 +1,5 @@ --- -title: 'Use Turnkey wallets with Jupiter' +title: "Use Turnkey wallets with Jupiter" sidebarTitle: "Jupiter integration" --- @@ -17,10 +17,11 @@ You’ll learn how to authenticate with Turnkey, load a wallet, and use it to cr Before you begin, make sure you’ve followed the [Turnkey Quickstart guide](/get-started/quickstart). You should have: -- A Turnkey **organization** and **Auth Proxy Config ID** +- A Turnkey **organization** and **Auth Proxy Config ID** - An account funded with **SOL** and optionally **USDC** You’ll also need: + - Access to the **Jupiter API** (Ultra API) - Access to a Solana RPC Provider (e.g., `https://solana-rpc.publicnode.com`) @@ -44,7 +45,10 @@ import { useTurnkey, WalletAccount } from "@turnkey/react-wallet-kit"; import { TurnkeySigner } from "@turnkey/solana"; import { Connection, PublicKey, VersionedTransaction } from "@solana/web3.js"; -const connection = new Connection("https://solana-rpc.publicnode.com", "confirmed"); +const connection = new Connection( + "https://solana-rpc.publicnode.com", + "confirmed", +); const USDC_MINT = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"; const SOL_MINT = "So11111111111111111111111111111111111111112"; @@ -73,7 +77,8 @@ function LogoutButton({ onClick }: { onClick: () => void }) { export default function JupiterSwapPage() { const { wallets, httpClient, handleLogin, logout } = useTurnkey(); - const [activeWalletAccount, setActiveWalletAccount] = useState(null); + const [activeWalletAccount, setActiveWalletAccount] = + useState(null); const [status, setStatus] = useState(""); const signer = activeWalletAccount @@ -190,16 +195,24 @@ import { useEffect, useState } from "react"; import { useTurnkey, WalletAccount } from "@turnkey/react-wallet-kit"; import { TurnkeySigner } from "@turnkey/solana"; import { Connection, VersionedTransaction } from "@solana/web3.js"; -import { createUltraOrder, executeUltraOrder, getUltraQuote } from "../actions/jupiter"; +import { + createUltraOrder, + executeUltraOrder, + getUltraQuote, +} from "../actions/jupiter"; -const connection = new Connection("https://solana-rpc.publicnode.com", "confirmed"); +const connection = new Connection( + "https://solana-rpc.publicnode.com", + "confirmed", +); const USDC_MINT = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"; const SOL_MINT = "So11111111111111111111111111111111111111112"; export default function JupiterSwap() { const { wallets, httpClient, handleLogin, logout } = useTurnkey(); - const [activeWalletAccount, setActiveWalletAccount] = useState(null); + const [activeWalletAccount, setActiveWalletAccount] = + useState(null); const [status, setStatus] = useState(""); const signer = activeWalletAccount @@ -274,4 +287,4 @@ You’ve now learned how to: - Interact with Jupiter Ultra API for token swaps -- Retrieve balances and verify swap transactions on Solscan \ No newline at end of file +- Retrieve balances and verify swap transactions on Solscan diff --git a/solutions/cookbooks/landing.mdx b/solutions/cookbooks/landing.mdx index 7ad7383f..371ab017 100644 --- a/solutions/cookbooks/landing.mdx +++ b/solutions/cookbooks/landing.mdx @@ -5,9 +5,15 @@ sidebarTitle: "Overview" slug: "cookbook/landing" --- -import { FeatureCard } from '/snippets/feature-card.mdx'; +import { FeatureCard } from "/snippets/feature-card.mdx"; -
+
(undefined); + const [viemWalletClient, setViemWalletClient] = useState< + WalletClient | undefined + >(undefined); // obtain a users turnkey wallets const walletAccountResponse = await fetchWalletAccounts({ @@ -67,7 +69,7 @@ export default function SwapPage() { account: turnkeyAccount as Account, chain: mainnet, transport: http(MAINNET_RPC_PROVIDER), - }) + }); // create a solana signer to sign SOL transactions const turnkeySolSigner = new TurnkeySigner({ @@ -149,25 +151,25 @@ import { mainnet } from "viem/chains"; async function handleEVMSwap() { const quoteParams: QuoteParams = { - fromChain: "ETH", // view the full list of chains here: https://docs.li.fi/introduction/chains - toChain: "SOL", - fromToken: "ETH", // view all available tokens for a chain here: https://docs.li.fi/api-reference/fetch-all-known-tokens - toToken: "SOL", - fromAmount: parseEther(value).toString(), // where value is a human-readable amount of ETH 1.0 == 1 ETH - fromAddress: ethAddress, // the sending ETH address - toAddress: solAddress, // the SOL address where the bridged SOL should be sent to - }; - - const getPriceResponse = await getQuote(quoteParams); - - // build, sign, and broadcast the transaction - const sendTransactionResponse = await viemWalletClient?.sendTransaction({ - to: getPriceResponse.transactionRequest.to, - value: getPriceResponse.transactionRequest.value, - data: getPriceResponse.transactionRequest.data, - chain: mainnet, - account: turnkeyViemAccount!, - }); + fromChain: "ETH", // view the full list of chains here: https://docs.li.fi/introduction/chains + toChain: "SOL", + fromToken: "ETH", // view all available tokens for a chain here: https://docs.li.fi/api-reference/fetch-all-known-tokens + toToken: "SOL", + fromAmount: parseEther(value).toString(), // where value is a human-readable amount of ETH 1.0 == 1 ETH + fromAddress: ethAddress, // the sending ETH address + toAddress: solAddress, // the SOL address where the bridged SOL should be sent to + }; + + const getPriceResponse = await getQuote(quoteParams); + + // build, sign, and broadcast the transaction + const sendTransactionResponse = await viemWalletClient?.sendTransaction({ + to: getPriceResponse.transactionRequest.to, + value: getPriceResponse.transactionRequest.value, + data: getPriceResponse.transactionRequest.data, + chain: mainnet, + account: turnkeyViemAccount!, + }); } ``` @@ -176,7 +178,11 @@ async function handleEVMSwap() { ```tsx "use client"; -import { Connection, LAMPORTS_PER_SOL, VersionedTransaction } from "@solana/web3.js"; +import { + Connection, + LAMPORTS_PER_SOL, + VersionedTransaction, +} from "@solana/web3.js"; function solToLamports(sol: string | number): number { return Math.floor(Number(sol) * LAMPORTS_PER_SOL); @@ -197,7 +203,10 @@ async function handleSVMSwap() { const getPriceResponse = await getQuote(quoteParams); // construct the SOL transaction to send for the bridge - const txBuffer = Buffer.from(getPriceResponse.transactionRequest.data, "base64"); + const txBuffer = Buffer.from( + getPriceResponse.transactionRequest.data, + "base64", + ); const hexTransaction = VersionedTransaction.deserialize( new Uint8Array(txBuffer), ); @@ -219,7 +228,11 @@ After a transaction has been sent to create a bridge transaction you can check t ```tsx "use client"; -import { Connection, LAMPORTS_PER_SOL, VersionedTransaction } from "@solana/web3.js"; +import { + Connection, + LAMPORTS_PER_SOL, + VersionedTransaction, +} from "@solana/web3.js"; async function getStatus() { let statusParams: StatusParams = { @@ -233,9 +246,13 @@ async function getStatus() { // check if the status us "DONE" if (getStatusResponse.status == "DONE") { if (fromToken === "ETH") { - console.log("SOL Receiving Transaction:" + getStatusResponse.receiving.txHash); + console.log( + "SOL Receiving Transaction:" + getStatusResponse.receiving.txHash, + ); } else if (fromToken === "SOL") { - console.log("ETH Receiving Transaction:" + getStatusResponse.receiving.txHash); + console.log( + "ETH Receiving Transaction:" + getStatusResponse.receiving.txHash, + ); } break; } diff --git a/solutions/cookbooks/morpho.mdx b/solutions/cookbooks/morpho.mdx index 46f79449..92039dc9 100644 --- a/solutions/cookbooks/morpho.mdx +++ b/solutions/cookbooks/morpho.mdx @@ -1,5 +1,5 @@ --- -title: 'Use Turnkey wallets with Morpho' +title: "Use Turnkey wallets with Morpho" sidebarTitle: "Morpho integration" --- @@ -18,7 +18,7 @@ The first step is to set up your Turnkey organization and account. By following - A root user with a public/private API key pair within the Turnkey parent organization - An organization ID -The next step is to create another user within the organization with a different API key and remove it from the root quorum. You can do this from the Turnkey [dashboard](https://app.turnkey.com/dashboard/security/updateRootQuorum) or [API](https://docs.turnkey.com/api-reference/activities/update-root-quorum). +The next step is to create another user within the organization with a different API key and remove it from the root quorum. You can do this from the Turnkey [dashboard](https://app.turnkey.com/dashboard/security/updateRootQuorum) or [API](https://docs.turnkey.com/api-reference/activities/update-root-quorum). Here's a simple [script](https://github.com/tkhq/sdk/blob/main/examples/kitchen-sink/src/sdk-server/updateRootQuorum.ts) that shows how to update the root quorum using @turnkey/sdk-server. Finally, make sure you have a wallet with an Ethereum account created within this organization and have it funded with some ETH and USDC on Base Mainnet. @@ -65,56 +65,56 @@ import { base } from "viem/chains"; import { createAccount } from "@turnkey/viem"; import { Turnkey as TurnkeyServerSDK } from "@turnkey/sdk-server"; import { - createWalletClient, - http, - type Account, - erc20Abi, - createPublicClient, - parseAbi, - parseUnits, + createWalletClient, + http, + type Account, + erc20Abi, + createPublicClient, + parseAbi, + parseUnits, } from "viem"; - const turnkeyClient = new TurnkeyServerSDK({ - apiBaseUrl: process.env.TURNKEY_BASE_URL!, - apiPrivateKey: process.env.NONROOT_API_PRIVATE_KEY!, - apiPublicKey: process.env.NONROOT_API_PUBLIC_KEY!, - defaultOrganizationId: process.env.TURNKEY_ORGANIZATION_ID!, +const turnkeyClient = new TurnkeyServerSDK({ + apiBaseUrl: process.env.TURNKEY_BASE_URL!, + apiPrivateKey: process.env.NONROOT_API_PRIVATE_KEY!, + apiPublicKey: process.env.NONROOT_API_PUBLIC_KEY!, + defaultOrganizationId: process.env.TURNKEY_ORGANIZATION_ID!, }); const turnkeyAccount = await createAccount({ - client: turnkeyClient.apiClient(), - organizationId: process.env.TURNKEY_ORGANIZATION_ID!, - signWith: process.env.SIGN_WITH!, + client: turnkeyClient.apiClient(), + organizationId: process.env.TURNKEY_ORGANIZATION_ID!, + signWith: process.env.SIGN_WITH!, }); const client = createWalletClient({ - account: turnkeyAccount as Account, - chain: base, - transport: http( - `https://base-mainnet.infura.io/v3/${process.env.INFURA_API_KEY!}`, - ), + account: turnkeyAccount as Account, + chain: base, + transport: http( + `https://base-mainnet.infura.io/v3/${process.env.INFURA_API_KEY!}`, + ), }); // Use the standard viem client for non-signing operations const publicClient = createPublicClient({ - transport: http( - `https://base-mainnet.infura.io/v3/${process.env.INFURA_API_KEY!}`, - ), - chain: base, + transport: http( + `https://base-mainnet.infura.io/v3/${process.env.INFURA_API_KEY!}`, + ), + chain: base, }); ``` ## Approve the vault to spend USDC and deposit USDC into the vault ```tsx - // Approve the vault to spend for 10 USDC, use maxUint256 if you want the max token approval +// Approve the vault to spend for 10 USDC, use maxUint256 if you want the max token approval const { request: approveReq } = await publicClient.simulateContract({ - abi: erc20Abi, - address: USDC_ADDRESS as `0x${string}`, - functionName: "approve", - chain: base, - args: [MORPHO_VAULT_ADDRESS as `0x${string}`, parseUnits("10", 6)], - account: client.account, + abi: erc20Abi, + address: USDC_ADDRESS as `0x${string}`, + functionName: "approve", + chain: base, + args: [MORPHO_VAULT_ADDRESS as `0x${string}`, parseUnits("10", 6)], + account: client.account, }); const approveHash = await client.writeContract(approveReq); @@ -123,15 +123,15 @@ console.log("Approve transaction:", `https://basescan.org/tx/${approveHash}`); // Deposit USDC into vault const vaultAbi = parseAbi([ - "function deposit(uint256 assets, address receiver) external returns (uint256 shares)", + "function deposit(uint256 assets, address receiver) external returns (uint256 shares)", ]); const { request: depositReq } = await publicClient.simulateContract({ - abi: vaultAbi, - address: MORPHO_VAULT_ADDRESS as `0x${string}`, - functionName: "deposit", - args: [parseUnits("0.5", 6), (turnkeyAccount as Account).address], - account: turnkeyAccount as Account, + abi: vaultAbi, + address: MORPHO_VAULT_ADDRESS as `0x${string}`, + functionName: "deposit", + args: [parseUnits("0.5", 6), (turnkeyAccount as Account).address], + account: turnkeyAccount as Account, }); const depositHash = await client.writeContract(depositReq); @@ -143,22 +143,22 @@ console.log("Deposit transaction:", `https://basescan.org/tx/${depositHash}`); In order to see how much the user can withdraw we can call the `balanceOf` function if the Vault contract. ```tsx - const balanceAbi = parseAbi([ - "function balanceOf(address account) external view returns (uint256)", - "function decimals() external view returns (uint8)", +const balanceAbi = parseAbi([ + "function balanceOf(address account) external view returns (uint256)", + "function decimals() external view returns (uint8)", ]); const decimals = await publicClient.readContract({ - address: MORPHO_VAULT_ADDRESS as `0x${string}`, - abi: balanceAbi, - functionName: "decimals", + address: MORPHO_VAULT_ADDRESS as `0x${string}`, + abi: balanceAbi, + functionName: "decimals", }); const rawBalance = await publicClient.readContract({ - address: MORPHO_VAULT_ADDRESS as `0x${string}`, - abi: balanceAbi, - functionName: "balanceOf", - args: [turnkeyAccount.address], + address: MORPHO_VAULT_ADDRESS as `0x${string}`, + abi: balanceAbi, + functionName: "balanceOf", + args: [turnkeyAccount.address], }); // Format to human-readable @@ -187,9 +187,9 @@ const query = ` `; const response = await fetch("https://api.morpho.org/graphql", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ query }), + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ query }), }); const json = await response.json(); @@ -202,19 +202,19 @@ console.log("Vault data:", JSON.stringify(json.data, null, 2)); Call the `withdraw` function if you want a specific amount: ```tsx - const withdrawAbi = parseAbi([ - "function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares)", +const withdrawAbi = parseAbi([ + "function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares)", ]); const { request: withdrawReq } = await publicClient.simulateContract({ - abi: withdrawAbi, - address: MORPHO_VAULT_ADDRESS as `0x${string}`, - functionName: "withdraw", - args: [ - parseUnits("0.1", 6), - (turnkeyAccount as Account).address, - (turnkeyAccount as Account).address, - ], - account: turnkeyAccount as Account, + abi: withdrawAbi, + address: MORPHO_VAULT_ADDRESS as `0x${string}`, + functionName: "withdraw", + args: [ + parseUnits("0.1", 6), + (turnkeyAccount as Account).address, + (turnkeyAccount as Account).address, + ], + account: turnkeyAccount as Account, }); const withdrawHash = await client.writeContract(withdrawReq); @@ -225,32 +225,32 @@ Or `redeem` for the full shares amount: ```tsx const balanceAbi = parseAbi([ - "function balanceOf(address account) external view returns (uint256)", + "function balanceOf(address account) external view returns (uint256)", ]); const rawBalance = await publicClient.readContract({ - address: MORPHO_VAULT_ADDRESS as `0x${string}`, - abi: balanceAbi, - functionName: "balanceOf", - args: [turnkeyAccount.address], + address: MORPHO_VAULT_ADDRESS as `0x${string}`, + abi: balanceAbi, + functionName: "balanceOf", + args: [turnkeyAccount.address], }); // Redeem all user shares const redeemAbi = parseAbi([ - "function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets)", + "function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets)", ]); const { request: redeemReq } = await publicClient.simulateContract({ - abi: redeemAbi, - address: MORPHO_VAULT_ADDRESS as `0x${string}`, - functionName: "redeem", - args: [ - rawBalance, - (turnkeyAccount as Account).address, - (turnkeyAccount as Account).address, - ], - account: turnkeyAccount as Account, + abi: redeemAbi, + address: MORPHO_VAULT_ADDRESS as `0x${string}`, + functionName: "redeem", + args: [ + rawBalance, + (turnkeyAccount as Account).address, + (turnkeyAccount as Account).address, + ], + account: turnkeyAccount as Account, }); const redeemHash = await client.writeContract(redeemReq); console.log("redeem tx:", `https://basescan.org/tx/${redeemHash}`); -``` \ No newline at end of file +``` diff --git a/solutions/cookbooks/polymarket-builders.mdx b/solutions/cookbooks/polymarket-builders.mdx index c2698ce6..457831d9 100644 --- a/solutions/cookbooks/polymarket-builders.mdx +++ b/solutions/cookbooks/polymarket-builders.mdx @@ -1,5 +1,5 @@ --- -title: 'Polymarket builders with Turnkey' +title: "Polymarket builders with Turnkey" sidebarTitle: "Polymarket builders" --- @@ -9,17 +9,18 @@ Polymarket's Builders program allows apps and order routers to generate and shar Learn more about the program [here](https://docs.polymarket.com/developers/builders/builder-intro). ## What does the Turnkey Safe builder example do? + [This open-source demo](https://github.com/Polymarket/turnkey-safe-builder-example) allows users to log-in and make wallets, then use -Polymarket's [CLOB](https://github.com/Polymarket/clob-client) and +Polymarket's [CLOB](https://github.com/Polymarket/clob-client) and [Builder Relayer](https://github.com/Polymarket/builder-relayer-client) clients for gasless trading with Builder-program order attribution. -* Authenticate users via Turnkey email login for web2-style onboarding -* Provision an EOA wallet automatically via Turnkey's embedded wallets -* Deploy a Gnosis Safe Proxy Wallet using the builder-relayer-client -* Obtain User API Credentials from the CLOB client -* Set token approvals for CTF Contract, CTF Exchange, Neg Risk Exchange, and Neg Risk Adapter -* Place orders via CLOB client with builder attribution using remote signing +- Authenticate users via Turnkey email login for web2-style onboarding +- Provision an EOA wallet automatically via Turnkey's embedded wallets +- Deploy a Gnosis Safe Proxy Wallet using the builder-relayer-client +- Obtain User API Credentials from the CLOB client +- Set token approvals for CTF Contract, CTF Exchange, Neg Risk Exchange, and Neg Risk Adapter +- Place orders via CLOB client with builder attribution using remote signing ## Getting started @@ -119,6 +120,7 @@ const walletClient = createWalletClient({ transport: http(POLYGON_RPC_URL), }); ``` + ## Builder config with remote signing File `app/api/polymarket/sign/route.ts` @@ -153,7 +155,7 @@ export async function POST(request: NextRequest) { parseInt(sigTimestamp), method, path, - body + body, ); return NextResponse.json({ @@ -204,6 +206,7 @@ Files: `hooks/useTokenApprovals.ts`, `utils/approvals.ts` Before trading, the Safe must approve **multiple contracts** to spend USDC.e and manage outcome tokens. This involves setting approvals for both **ERC-20 (USDC.e)** and **ERC-1155 (outcome tokens)**. **Key Points:** + - Uses **batch execution** via `relayClient.execute()` for gas efficiency - Sets **unlimited approvals** (MaxUint256) for ERC-20 tokens - Sets **operator approvals** for ERC-1155 outcome tokens @@ -245,7 +248,7 @@ if (approvalStatus.allApproved) { // Step 3: Execute all approvals in a single batch const response = await relayClient.execute( approvalTxs, - "Set all token approvals for trading" + "Set all token approvals for trading", ); await response.wait(); @@ -350,7 +353,7 @@ const order = { const response = await clobClient.createAndPostOrder( order, { negRisk: false }, // Market-specific flag - OrderType.GTC + OrderType.GTC, ); console.log("Order ID:", response.orderID); @@ -366,9 +369,9 @@ await clobClient.cancelOrder({ orderID: "order_id_here" }); With this integration you can: -* Onboard users easily, with a variety of sign-in methods. -* Scale with ease. -* Create and manage Polymarket orders with order attribution +- Onboard users easily, with a variety of sign-in methods. +- Scale with ease. +- Create and manage Polymarket orders with order attribution Be sure to see the even more detailed [README](https://github.com/Polymarket/turnkey-safe-builder-example/blob/main/README.md) for more implementation details. diff --git a/solutions/cookbooks/relay.mdx b/solutions/cookbooks/relay.mdx index a1154ec9..89afdf25 100644 --- a/solutions/cookbooks/relay.mdx +++ b/solutions/cookbooks/relay.mdx @@ -1,5 +1,5 @@ --- -title: 'Use Turnkey wallets with Relay' +title: "Use Turnkey wallets with Relay" sidebarTitle: "Relay integration" --- @@ -15,8 +15,8 @@ The [`relay turnkey example`](https://github.com/relayprotocol/relay-wallet-prov Complete the Turnkey Quickstart first. You'll need: -* A Turnkey organization and Auth Proxy Config ID -* (Optional) A [Relay API key](https://docs.relay.link/references/api/api-keys) for higher rate limits +- A Turnkey organization and Auth Proxy Config ID +- (Optional) A [Relay API key](https://docs.relay.link/references/api/api-keys) for higher rate limits --- @@ -51,7 +51,11 @@ export function useTurnkeyWallet() { }); function makeWalletClient(chain: Chain) { - return createWalletClient({ account: turnkeyAccount, chain, transport: http() }); + return createWalletClient({ + account: turnkeyAccount, + chain, + transport: http(), + }); } function makePublicClient(chain: Chain) { @@ -108,7 +112,13 @@ A Relay quote contains an array of steps, each of kind `"transaction"` or `"sign ```tsx "use client"; -export async function executeQuote({ quote, account, chains, makeWalletClient, makePublicClient }) { +export async function executeQuote({ + quote, + account, + chains, + makeWalletClient, + makePublicClient, +}) { for (const step of quote.steps) { for (const item of step.items) { if (item.status === "complete") continue; @@ -118,8 +128,11 @@ export async function executeQuote({ quote, account, chains, makeWalletClient, m if (step.kind === "signature") { const client = makeWalletClient(chain); const signature = await signItem(client, item); - await submitSignature(item.data.post.endpoint, signature, item.data.post.body); - + await submitSignature( + item.data.post.endpoint, + signature, + item.data.post.body, + ); } else if (step.kind === "transaction") { const client = makeWalletClient(chain); const publicClient = makePublicClient(chain); @@ -168,7 +181,10 @@ Some Relay steps (particularly for swaps) require offchain signatures before the import { type WalletClient, type Hex } from "viem"; -async function signItem(walletClient: WalletClient, item: StepItem): Promise { +async function signItem( + walletClient: WalletClient, + item: StepItem, +): Promise { const sign = item.data.sign!; if (sign.signatureKind === "eip191") { @@ -195,11 +211,11 @@ async function signItem(walletClient: WalletClient, item: StepItem): Promise { const { method, params } = action.walletRpc; const parsedParams = JSON.parse(params); @@ -206,9 +206,19 @@ async function signWcPayAction( throw new Error(`Unsupported RPC method: ${method}`); } -function assembleSignature(result: { r: string; s: string; v: string }): string { - const r = (result.r.startsWith("0x") ? result.r.slice(2) : result.r).padStart(64, "0"); - const s = (result.s.startsWith("0x") ? result.s.slice(2) : result.s).padStart(64, "0"); +function assembleSignature(result: { + r: string; + s: string; + v: string; +}): string { + const r = (result.r.startsWith("0x") ? result.r.slice(2) : result.r).padStart( + 64, + "0", + ); + const s = (result.s.startsWith("0x") ? result.s.slice(2) : result.s).padStart( + 64, + "0", + ); if (!result.v) throw new Error("Turnkey returned empty v value in signature"); let v = parseInt(result.v, 10); if (v < 27) v += 27; @@ -217,7 +227,10 @@ function assembleSignature(result: { r: string; s: string; v: string }): string ``` -The `signMessage` parameter names must be `encoding` and `hashFunction` — not `encodingOverride` or `hashFunctionOverride`. Using the wrong names will silently fall back to default encoding, producing a valid but incorrect signature. + The `signMessage` parameter names must be `encoding` and `hashFunction` — not + `encodingOverride` or `hashFunctionOverride`. Using the wrong names will + silently fall back to default encoding, producing a valid but incorrect + signature. ## Handling identity verification @@ -362,4 +375,4 @@ You've now learned how to: - Handle Travel Rule identity verification via WebView - Confirm payments through WalletConnect Pay, which handles gas sponsorship and on-chain broadcast -For the full working example, see the [`with-walletconnect-pay`](https://github.com/tkhq/sdk/tree/main/examples/with-walletconnect-pay) repository. \ No newline at end of file +For the full working example, see the [`with-walletconnect-pay`](https://github.com/tkhq/sdk/tree/main/examples/with-walletconnect-pay) repository. diff --git a/solutions/cookbooks/yieldxyz.mdx b/solutions/cookbooks/yieldxyz.mdx index 29eb793b..7b574c47 100644 --- a/solutions/cookbooks/yieldxyz.mdx +++ b/solutions/cookbooks/yieldxyz.mdx @@ -1,5 +1,5 @@ --- -title: 'Building on Yield.xyz with Turnkey' +title: "Building on Yield.xyz with Turnkey" sidebarTitle: "Yield.xyz integration" --- @@ -17,11 +17,11 @@ Yield.xyz’s API is self-custodial by design: it constructs ready-to-sign tran - **Pre-configured OAVs** – instantly offer access to 10–20 standardized and pre-configured Optimized Allocator Vaults (“grab-off-the-shelf”) across popular assets. - **Custom OAVs** – request dedicated OAVs for specific strategies or branded products. - **Monetization** – ability to layer on additional user-level fees per OAV as well as revenue sharing from validators on all staking integrations - - *Note: Yield.xyz enforces a minimum 10% fee* - - *Note: the validator revenue share is applicable only to PVN members (>30 of the largest validator service providers)* + - _Note: Yield.xyz enforces a minimum 10% fee_ + - _Note: the validator revenue share is applicable only to PVN members (>30 of the largest validator service providers)_ - **Security & control** – Turnkey enforces transaction policies so client keys can only interact with the exact vaults/tokens you allow. -By combining Yield.xyz and Turnkey, you deliver a production-ready yield experience in your app with minimal effort: your users can discover, deposit, track, manage, and withdraw – all signed securely with Turnkey. +By combining Yield.xyz and Turnkey, you deliver a production-ready yield experience in your app with minimal effort: your users can discover, deposit, track, manage, and withdraw – all signed securely with Turnkey. The working example can be found [here](https://github.com/tkhq/sdk/tree/main/examples/with-yield-xyz). @@ -55,7 +55,7 @@ Once configured, you’ll be able to: ## Setting up the policies for the non-root user -Now, we want to use the non-root user for signing transactions to Yield.xyz and restrict it to only be able to interact with the USDC and Yield vault smart contracts. We'll define a new API client that uses the organization’s root user to create the required policies. +Now, we want to use the non-root user for signing transactions to Yield.xyz and restrict it to only be able to interact with the USDC and Yield vault smart contracts. We'll define a new API client that uses the organization’s root user to create the required policies. Each policy uses the `eth.tx.data` field to identify which smart contract function is being called. The first four bytes of this field represent the function selector. For the `approve` function, the selector is `0x095ea7b3`; for `deposit` it is `0x6e553f65`; and for `withdraw`, it’s `0xba087652`. This allows the policies to precisely restrict the non-root user to only those permitted contract calls. ```tsx @@ -165,15 +165,15 @@ main().catch((error) => { Discovery is just a read to the Yield.xyz API — Turnkey doesn’t change this step. You’ll typically do it server-side (to keep your Yield API key secret), then surface the results to your app where you’ll later enter using your Turnkey signer. -**Example: USDC yields on Base** +**Example: USDC yields on Base** ```tsx const res = await fetch( - 'https://api.yield.xyz/v1/yields?network=base&token=USDC&limit=10', - { headers: { 'X-API-KEY': process.env.YIELD_API_KEY! } } + "https://api.yield.xyz/v1/yields?network=base&token=USDC&limit=10", + { headers: { "X-API-KEY": process.env.YIELD_API_KEY! } }, ); -const result = (await res.json()) as any; -const items = result.items +const result = (await res.json()) as any; +const items = result.items; // pick one yield const selected = items[0]; @@ -201,22 +201,22 @@ The Stablecoin/DeFi yields provided here are wrapped using **Optimized Allocato - Asset wrapping (where applicable) - Fee charging (performance, management, deposit) -This makes OAVs unique: they **enable fee capture for partners while simultaneously simplifying the user experience**, ensuring yield products feel as seamless as mainstream fintech offerings. +This makes OAVs unique: they **enable fee capture for partners while simultaneously simplifying the user experience**, ensuring yield products feel as seamless as mainstream fintech offerings. We’ve deployed two sets of OAVs with pre-configured fees — available via API Keys: - 10% fee OAVs: `4bea9274-7cef-4e43-995b-f35147469ede` - 20% fee OAVs: `e35de2d4-93e2-4cf8-b016-b0838fec1f20` -For reference, the expanded list of yields most popular among existing clients (already wrapped into OAVs) can be found **[here](https://docs.yield.xyz/docs/off-the-shelf-oavs#/).** +For reference, the expanded list of yields most popular among existing clients (already wrapped into OAVs) can be found **[here](https://docs.yield.xyz/docs/off-the-shelf-oavs#/).** -| Yield ID | Yield Name | Protocol | Monetization | -| --- | --- | --- | --- | -| arbitrum-usdc-gtusdcc-0x7e97fa6893871A2751B5fE961978DCCb2c201E65-4626-vault | Gauntlet USDC Core | Morpho | Available deposit, performance, management fees | -| ethereum-usds-susds-0xa3931d71877c0e7a3148cb7eb4463524fec27fbd-4626-vault | USDS Sky Savings Rate | Sky | Available deposit, performance, management fees | -| ethereum-usdc-fusdc-0x9Fb7b4477576Fe5B32be4C1843aFB1e55F251B33-4626-vault | Fluid USDC Vault | Fluid | Available deposit, performance, management fees | -| base-usdc-smusdc-0x616a4e1db48e22028f6bbf20444cd3b8e3273738-4626-vault | Seamless USDC Vault | Morpho | Available deposit, performance, management fees | -| base-usdc-aave-v3-lending | USDC Aave Lending | Aave | Available deposit, performance, management fees | +| Yield ID | Yield Name | Protocol | Monetization | +| --------------------------------------------------------------------------- | --------------------- | -------- | ----------------------------------------------- | +| arbitrum-usdc-gtusdcc-0x7e97fa6893871A2751B5fE961978DCCb2c201E65-4626-vault | Gauntlet USDC Core | Morpho | Available deposit, performance, management fees | +| ethereum-usds-susds-0xa3931d71877c0e7a3148cb7eb4463524fec27fbd-4626-vault | USDS Sky Savings Rate | Sky | Available deposit, performance, management fees | +| ethereum-usdc-fusdc-0x9Fb7b4477576Fe5B32be4C1843aFB1e55F251B33-4626-vault | Fluid USDC Vault | Fluid | Available deposit, performance, management fees | +| base-usdc-smusdc-0x616a4e1db48e22028f6bbf20444cd3b8e3273738-4626-vault | Seamless USDC Vault | Morpho | Available deposit, performance, management fees | +| base-usdc-aave-v3-lending | USDC Aave Lending | Aave | Available deposit, performance, management fees | **Staking Yields** @@ -226,15 +226,15 @@ These staking yields are accessible via Yield.xyz, which: - Supports **validator revenue sharing** (50–85% of validator fees) with preferred validators - Standardizes interactions across networks (undelegation, cooldowns, reward tracking) -| Yield ID | Network | Exemplary Validator | Validator Address | Monetization | -| --- | --- | --- | --- | --- | -| solana-sol-native-multivalidator-staking | Solana | Meria | H2tJNyMHnRF6ahCQLQ1sSycM4FGchymuzyYzUqKEuydk | Deposit fees and revenue share | -| tron-trx-native-staking | Tron | Luganodes | TGyrSc9ZmTdbYziuk1SKEmdtCdETafewJ9 | Revenue share | -| bsc-bnb-native-staking | Binance | Figment | 0x477cB5d87144b2a6d93f72e32f5E01a459260D68 | Revenue share | -| ethereum-eth-everstake-staking | Ethereum | Everstake | N/A | Revenue share | -| ethereum-eth-figment-staking | Ethereum | Figment | N/A | Revenue share | -| hyperevm-hype-native-staking | Hyperliquid | Meria | 0x950f8dd5e5030e1fa6ad2cdc4295809d185925d0 | Revenue share | -| cosmos-atom-native-staking | Cosmos | Chorus One | cosmosvaloper15urq2dtp9qce4fyc85m6upwm9xul3049e02707 | Deposit fees and revenue share | +| Yield ID | Network | Exemplary Validator | Validator Address | Monetization | +| ---------------------------------------- | ----------- | ------------------- | ---------------------------------------------------- | ------------------------------ | +| solana-sol-native-multivalidator-staking | Solana | Meria | H2tJNyMHnRF6ahCQLQ1sSycM4FGchymuzyYzUqKEuydk | Deposit fees and revenue share | +| tron-trx-native-staking | Tron | Luganodes | TGyrSc9ZmTdbYziuk1SKEmdtCdETafewJ9 | Revenue share | +| bsc-bnb-native-staking | Binance | Figment | 0x477cB5d87144b2a6d93f72e32f5E01a459260D68 | Revenue share | +| ethereum-eth-everstake-staking | Ethereum | Everstake | N/A | Revenue share | +| ethereum-eth-figment-staking | Ethereum | Figment | N/A | Revenue share | +| hyperevm-hype-native-staking | Hyperliquid | Meria | 0x950f8dd5e5030e1fa6ad2cdc4295809d185925d0 | Revenue share | +| cosmos-atom-native-staking | Cosmos | Chorus One | cosmosvaloper15urq2dtp9qce4fyc85m6upwm9xul3049e02707 | Deposit fees and revenue share | The full list of staking yields can be found [in the Yield.xyz docs](https://docs.yield.xyz/docs/staking-yields#/). @@ -338,7 +338,7 @@ const balanceRes = await fetch( "x-api-key": process.env.YIELD_API_KEY!, }, body: JSON.stringify({ address: turnkeyAccount.address }), - } + }, ); const balances = await balanceRes.json(); console.log("Vault balances:", JSON.stringify(balances, null, 2)); @@ -352,7 +352,7 @@ Yield.xyz’s `POST /v1/actions/exit` endpoint returns the transaction data req ```tsx const exitPayload = { - yieldId: process.env.YIELD_ID! , + yieldId: process.env.YIELD_ID!, address: process.env.SIGN_WITH!, arguments: { amount: "0.1" }, }; @@ -368,13 +368,13 @@ const exitRes = await fetch("https://api.yield.xyz/v1/actions/exit", { const exitAction = await exitRes.json(); for (const tx of exitAction.transactions) { - const unsignedTx = JSON.parse(tx.unsignedTransaction); + const unsignedTx = JSON.parse(tx.unsignedTransaction); const sent = await connectedSigner.sendTransaction({ - to: unsignedTx.to, - data: unsignedTx.data, - value: unsignedTx.value ?? '0x0', - chainId: unsignedTx.chainId - }); + to: unsignedTx.to, + data: unsignedTx.data, + value: unsignedTx.value ?? "0x0", + chainId: unsignedTx.chainId, + }); console.log("Withdraw tx:", sent.hash); } ``` @@ -388,17 +388,17 @@ In the first step, we requested to withdraw 0.1 USDC. Yield.xyz returned the app Monetization of yield interactions is possible on multiple levels depending on the yield type: - **Staking.** - - **Deposit Fees**: Leverage **FeeWrapper contracts** (EVM) and **atomic fee transfer mechanisms** (non-EVM) to deduct a percentage of the deposit and transfer it to the recipient in the same transaction. - - **Revenue Share:** [Yield.xyz](http://yield.xyz/) has agreements with 30+ validator service providers, entitling clients to a portion of validator revenues (typically 50%–85%). - - [Validator revenue share overview](https://www.notion.so/2695318e934e80cea8b1ccb00ac835c0?pvs=21) + - **Deposit Fees**: Leverage **FeeWrapper contracts** (EVM) and **atomic fee transfer mechanisms** (non-EVM) to deduct a percentage of the deposit and transfer it to the recipient in the same transaction. + - **Revenue Share:** [Yield.xyz](http://yield.xyz/) has agreements with 30+ validator service providers, entitling clients to a portion of validator revenues (typically 50%–85%). + - [Validator revenue share overview](https://www.notion.so/2695318e934e80cea8b1ccb00ac835c0?pvs=21) - **DeFi.** - - **Revenue Share:** Some major protocols and curators provide revenue share on deposits via the [Yield.xyz](http://yield.xyz/) API. - - [DeFi revenue share overview](https://www.notion.so/25b5318e934e803eab5cccfc941a6ba8?pvs=21) - - **User-Facing Fees via OAVs:** - - **Optimized Allocator Vaults (OAVs)** allow deposit, performance, and management fees to be configured at the user level. - - **Performance Fees:** Charged on realized profits. - - **Management Fees:** Flat annualized rate applied on AUM. - - **Deposit Fees:** Automatically deducted at the time of deposit. + - **Revenue Share:** Some major protocols and curators provide revenue share on deposits via the [Yield.xyz](http://yield.xyz/) API. + - [DeFi revenue share overview](https://www.notion.so/25b5318e934e803eab5cccfc941a6ba8?pvs=21) + - **User-Facing Fees via OAVs:** + - **Optimized Allocator Vaults (OAVs)** allow deposit, performance, and management fees to be configured at the user level. + - **Performance Fees:** Charged on realized profits. + - **Management Fees:** Flat annualized rate applied on AUM. + - **Deposit Fees:** Automatically deducted at the time of deposit. You can identify which monetization options apply to a given yield in the yield metadata, specifically the `possibleFeeTakingMechanisms` object → [API Reference](https://docs.yield.xyz/reference/yieldscontroller_getyield#/) @@ -410,7 +410,7 @@ Beyond monetization, **OAVs deliver a Web2-grade experience for Web3 yields.** - **Automatic Wrapping/Swapping:** Complex asset flows are handled automatically, reducing friction and mirroring the simplicity of Web2 fintech apps. - **Unified UX:** End-users interact only with their deposit asset — no juggling of dozens of reward tokens, no manual reinvestments. -This makes OAVs unique: they **enable fee capture for partners while simultaneously simplifying the user experience**, ensuring yield products feel as seamless as mainstream fintech offerings.For reference, the yields most popular among existing clients (already wrapped into OAVs) can be found [**here](https://docs.google.com/spreadsheets/d/1_GphMivV3ebN4-SHlviYx9eyweceI7ple6KmpAajcMY/edit?gid=524025543#gid=524025543).** We’ve deployed two sets of OAVs with pre-configured fees — available via API Keys: +This makes OAVs unique: they **enable fee capture for partners while simultaneously simplifying the user experience**, ensuring yield products feel as seamless as mainstream fintech offerings.For reference, the yields most popular among existing clients (already wrapped into OAVs) can be found [\*\*here](https://docs.google.com/spreadsheets/d/1_GphMivV3ebN4-SHlviYx9eyweceI7ple6KmpAajcMY/edit?gid=524025543#gid=524025543).\*\* We’ve deployed two sets of OAVs with pre-configured fees — available via API Keys: - 10% fee OAVs: `4bea9274-7cef-4e43-995b-f35147469ede` - 20% fee OAVs: `e35de2d4-93e2-4cf8-b016-b0838fec1f20` diff --git a/solutions/embedded-wallets/embedded-business-wallets.mdx b/solutions/embedded-wallets/embedded-business-wallets.mdx index 6b8d2fac..ccb39790 100644 --- a/solutions/embedded-wallets/embedded-business-wallets.mdx +++ b/solutions/embedded-wallets/embedded-business-wallets.mdx @@ -3,7 +3,7 @@ title: "Embedded Business Wallets" description: "Shared wallets with role-based signing controls for teams, operators, and finance workflows." --- -import { FeatureCard } from '/snippets/feature-card.mdx' +import { FeatureCard } from "/snippets/feature-card.mdx"; With Turnkey, your application can provision wallets designed for team usage. Multiple end users operate within a single sub-organization with role-based access control governed by the policy engine. No seed phrases, no browser extensions. @@ -12,8 +12,9 @@ With Turnkey, your application can provision wallets designed for team usage. Mu Your parent organization sits at the top with read-only visibility. Each business customer gets its own sub-organization — fully isolated, with independent wallets, team members, and policy configurations. - ![Embedded Business Wallets architecture: sub-organizations with users, roles, policies, and - wallets per business](/images/embedded-wallets/embedded-business-wallets-diagram.png) + ![Embedded Business Wallets architecture: sub-organizations with users, roles, + policies, and wallets per + business](/images/embedded-wallets/embedded-business-wallets-diagram.png) ## Powered by Turnkey @@ -25,37 +26,53 @@ Your parent organization sits at the top with read-only visibility. Each busines Turnkey enables developers to build shared business wallets with role-based controls across dimensions such as organization hierarchy, access control, and custody. See the key implementation decisions below to curate the exact experience your business customers need. -| Decision | Explanation | Learn more | -| :------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **Organization hierarchy** | Create a sub-organization for each business customer. Each sub-org is a fully isolated environment with its own wallets, users, and policies. | [Sub-Organizations](/features/sub-organizations) | -| **Role-based access control** | Assign roles to users via tags (e.g. `finance-team`, `operator`, `admin`). Write policies that reference these roles to control who can sign, what they can sign, and under what conditions. | [Policies](/features/policies/overview), [Policy Language](/features/policies/language) | -| **Policies and guardrails** | With roles in place, enforce spending limits, require multi-party approval for high-value transactions, restrict payments to allowlisted addresses, or require quorum for policy changes. Optionally let business customers configure their own guardrails. | [Policies](/features/policies/overview), [Delegated Access](/features/policies/delegated-access/overview) | -| **Custody model** | Choose who can authorize the enclave to sign: the user only (non-custodial), your application (custodial), or both with scoped permissions (hybrid). Business wallets commonly use hybrid custody with policy-backed controls. | [Custody models](/solutions/embedded-wallets/overview#custody-models) | -| **Authentication methods** | Choose user auth methods: Passkeys, OAuth/email, or SMS. You can use the [Auth Proxy](/features/authentication/auth-proxy) for backend-signed OTP/OAuth/signup without your own backend, or wire auth to your app. | [Authentication Overview](/features/authentication/overview), [Auth Proxy](/features/authentication/auth-proxy) | -| **Session management** | Allow a user to take multiple, contiguous actions in a defined period of time. Actions include: Read-write or read-only. | [Sessions](/features/authentication/sessions) | -| **Gas sponsorship** | Integrate a gasless UX via sponsored transactions to cover who pays gas and how transactions are broadcast. | [Transaction Management](/features/transaction-management), [Sending sponsored transactions](/features/transaction-management/sending-sponsored-transactions) | -| **Key portability** | Determine whether users can import or export keys. | [Import wallets](/features/wallets/import-wallets), [Export wallets](/features/wallets/export-wallets) | -| **Recovery flows** | Define how users regain access if they lose their authenticator. Options include email recovery and backup passkeys. | [Email recovery](/features/authentication/email) | -| **Agent-delegated signing** | Let end users grant scoped signing authority to AI agents or automated systems from their own wallet. The user retains root control and can revoke access at any time. | [End-User Delegated Agent Signing](/features/policies/delegated-access/agentic-wallets) | +| Decision | Explanation | Learn more | +| :---------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| **Organization hierarchy** | Create a sub-organization for each business customer. Each sub-org is a fully isolated environment with its own wallets, users, and policies. | [Sub-Organizations](/features/sub-organizations) | +| **Role-based access control** | Assign roles to users via tags (e.g. `finance-team`, `operator`, `admin`). Write policies that reference these roles to control who can sign, what they can sign, and under what conditions. | [Policies](/features/policies/overview), [Policy Language](/features/policies/language) | +| **Policies and guardrails** | With roles in place, enforce spending limits, require multi-party approval for high-value transactions, restrict payments to allowlisted addresses, or require quorum for policy changes. Optionally let business customers configure their own guardrails. | [Policies](/features/policies/overview), [Delegated Access](/features/policies/delegated-access/overview) | +| **Custody model** | Choose who can authorize the enclave to sign: the user only (non-custodial), your application (custodial), or both with scoped permissions (hybrid). Business wallets commonly use hybrid custody with policy-backed controls. | [Custody models](/solutions/embedded-wallets/overview#custody-models) | +| **Authentication methods** | Choose user auth methods: Passkeys, OAuth/email, or SMS. You can use the [Auth Proxy](/features/authentication/auth-proxy) for backend-signed OTP/OAuth/signup without your own backend, or wire auth to your app. | [Authentication Overview](/features/authentication/overview), [Auth Proxy](/features/authentication/auth-proxy) | +| **Session management** | Allow a user to take multiple, contiguous actions in a defined period of time. Actions include: Read-write or read-only. | [Sessions](/features/authentication/sessions) | +| **Gas sponsorship** | Integrate a gasless UX via sponsored transactions to cover who pays gas and how transactions are broadcast. | [Transaction Management](/features/transaction-management), [Sending sponsored transactions](/features/transaction-management/sending-sponsored-transactions) | +| **Key portability** | Determine whether users can import or export keys. | [Import wallets](/features/wallets/import-wallets), [Export wallets](/features/wallets/export-wallets) | +| **Recovery flows** | Define how users regain access if they lose their authenticator. Options include email recovery and backup passkeys. | [Email recovery](/features/authentication/email) | +| **Agent-delegated signing** | Let end users grant scoped signing authority to AI agents or automated systems from their own wallet. The user retains root control and can revoke access at any time. | [End-User Delegated Agent Signing](/features/policies/delegated-access/agentic-wallets) | ## Example: Payments platform with role-based controls Typical requirements and how Turnkey addresses them: -| Requirement | Turnkey capability | -| :-------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Multi-user team access | One [sub-organization](/features/sub-organizations) per business customer with isolated wallets, users, and [role-based policies](/features/policies/overview) | -| Non-custodial with oversight | Hybrid custody with [policy engine](/features/policies/overview) controls. See [Custody models](/solutions/embedded-wallets/overview#custody-models) | -| Multi-party approval | [Policies](/features/policies/language) requiring 2+ approvers for high-value transactions or policy changes | -| Vendor and recipient controls | Allowlisted addresses and spending limits via [policy language](/features/policies/language) | -| Familiar auth for non-crypto users | Passkey and email authentication with [email recovery](/features/authentication/email). No seed phrases | -| Cross-border payments | Chain-agnostic derivation and signing. See [Networks](/features/networks/overview) and [Wallets Concept](/features/wallets) | -| Gasless UX | [Sponsored transactions](/features/transaction-management) and [sending sponsored transactions](/features/transaction-management/sending-sponsored-transactions) | -| Fast integration | Use the [Embedded Wallet Kit](/solutions/embedded-wallets/integration-guide/react/index) for built-in auth and wallet UI components. See [Quickstart](/solutions/embedded-wallets/quickstart) | +| Requirement | Turnkey capability | +| :--------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Multi-user team access | One [sub-organization](/features/sub-organizations) per business customer with isolated wallets, users, and [role-based policies](/features/policies/overview) | +| Non-custodial with oversight | Hybrid custody with [policy engine](/features/policies/overview) controls. See [Custody models](/solutions/embedded-wallets/overview#custody-models) | +| Multi-party approval | [Policies](/features/policies/language) requiring 2+ approvers for high-value transactions or policy changes | +| Vendor and recipient controls | Allowlisted addresses and spending limits via [policy language](/features/policies/language) | +| Familiar auth for non-crypto users | Passkey and email authentication with [email recovery](/features/authentication/email). No seed phrases | +| Cross-border payments | Chain-agnostic derivation and signing. See [Networks](/features/networks/overview) and [Wallets Concept](/features/wallets) | +| Gasless UX | [Sponsored transactions](/features/transaction-management) and [sending sponsored transactions](/features/transaction-management/sending-sponsored-transactions) | +| Fast integration | Use the [Embedded Wallet Kit](/solutions/embedded-wallets/integration-guide/react/index) for built-in auth and wallet UI components. See [Quickstart](/solutions/embedded-wallets/quickstart) | ## Next steps -
- - +
+ +
diff --git a/solutions/embedded-wallets/embedded-consumer-wallet.mdx b/solutions/embedded-wallets/embedded-consumer-wallet.mdx index e9c1554b..5ef814c4 100644 --- a/solutions/embedded-wallets/embedded-consumer-wallet.mdx +++ b/solutions/embedded-wallets/embedded-consumer-wallet.mdx @@ -3,7 +3,7 @@ title: "Embedded Consumer Wallet" description: "Give every user of your application their own wallet, provisioned automatically at signup." --- -import { FeatureCard } from '/snippets/feature-card.mdx'; +import { FeatureCard } from "/snippets/feature-card.mdx"; With Turnkey, you can provision a dedicated wallet for every user as part of your application's signup flow, at any scale. Users authenticate with familiar methods like passkeys, email, or social login. They never manage keys or install extensions. @@ -19,36 +19,42 @@ Turnkey enables developers to tailor non-custodial, embedded user wallets across custody model, authentication, and more. See the key implementation decisions below to curate the exact user experience you need. -| Decision | Explanation | Learn more | -| :------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **Custody model** | Choose who can authorize the enclave to sign: the user only (non-custodial), your application (custodial), or both with scoped permissions (hybrid). | [Custody models](/solutions/embedded-wallets/overview#custody-models) | -| **Authentication methods** | Choose user auth methods: Passkeys, OAuth/email, or SMS. You can use the [Auth Proxy](/features/authentication/auth-proxy) for backend-signed OTP/OAuth/signup without your own backend, or wire auth to your app. | [Authentication Overview](/features/authentication/overview), [Auth Proxy](/features/authentication/auth-proxy) | -| **Policies and guardrails** | Set guardrails for what your end users can do, such as spending limits, allowed destinations, or multi-party approval. Optionally let users configure their own guardrails within your app. | [Policies](/features/policies/overview), [Delegated Access](/features/policies/delegated-access/overview) | -| **Session management** | Allow a user to take multiple, contiguous actions in a defined period of time. Actions include: Read-write or read-only. | [Sessions](/features/authentication/sessions) | -| **Wallet architecture** | Choose between key-based (HD) or smart contract wallets for your users. Turnkey supports both. | [Wallets Concept](/features/wallets), [Transaction Management](/features/transaction-management) | -| **Gas sponsorship** | Integrate a gasless UX via sponsored transactions to cover who pays gas and how transactions are broadcast. | [Transaction Management](/features/transaction-management), [Sending sponsored transactions](/features/transaction-management/sending-sponsored-transactions) | -| **Key portability** | Determine whether users can import or export keys. | [Import wallets](/features/wallets/import-wallets), [Export wallets](/features/wallets/export-wallets) | -| **Recovery flows** | Define how users regain access if they lose their authenticator. Options include email recovery and backup passkeys. | [Email recovery](/features/authentication/email) | -| **Agent-delegated signing** | Let end users grant scoped signing authority to AI agents or automated systems from their own wallet. The user retains root control and can revoke access at any time. | [End-User Delegated Agent Signing](/features/policies/delegated-access/agentic-wallets) | +| Decision | Explanation | Learn more | +| :-------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| **Custody model** | Choose who can authorize the enclave to sign: the user only (non-custodial), your application (custodial), or both with scoped permissions (hybrid). | [Custody models](/solutions/embedded-wallets/overview#custody-models) | +| **Authentication methods** | Choose user auth methods: Passkeys, OAuth/email, or SMS. You can use the [Auth Proxy](/features/authentication/auth-proxy) for backend-signed OTP/OAuth/signup without your own backend, or wire auth to your app. | [Authentication Overview](/features/authentication/overview), [Auth Proxy](/features/authentication/auth-proxy) | +| **Policies and guardrails** | Set guardrails for what your end users can do, such as spending limits, allowed destinations, or multi-party approval. Optionally let users configure their own guardrails within your app. | [Policies](/features/policies/overview), [Delegated Access](/features/policies/delegated-access/overview) | +| **Session management** | Allow a user to take multiple, contiguous actions in a defined period of time. Actions include: Read-write or read-only. | [Sessions](/features/authentication/sessions) | +| **Wallet architecture** | Choose between key-based (HD) or smart contract wallets for your users. Turnkey supports both. | [Wallets Concept](/features/wallets), [Transaction Management](/features/transaction-management) | +| **Gas sponsorship** | Integrate a gasless UX via sponsored transactions to cover who pays gas and how transactions are broadcast. | [Transaction Management](/features/transaction-management), [Sending sponsored transactions](/features/transaction-management/sending-sponsored-transactions) | +| **Key portability** | Determine whether users can import or export keys. | [Import wallets](/features/wallets/import-wallets), [Export wallets](/features/wallets/export-wallets) | +| **Recovery flows** | Define how users regain access if they lose their authenticator. Options include email recovery and backup passkeys. | [Email recovery](/features/authentication/email) | +| **Agent-delegated signing** | Let end users grant scoped signing authority to AI agents or automated systems from their own wallet. The user retains root control and can revoke access at any time. | [End-User Delegated Agent Signing](/features/policies/delegated-access/agentic-wallets) | ## Example: Neobank-style embedded consumer wallet Typical requirements and how Turnkey addresses them: -| Requirement | Turnkey capability | -| :-------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Requirement | Turnkey capability | +| :-------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Seamless onboarding | Passkey registration and automated wallet provisioning. See [Quickstart](/solutions/embedded-wallets/quickstart) or [Integration Guide](/solutions/embedded-wallets/integration-guide/overview) | -| User custody without key exposure | Keys remain in [secure enclaves](/security/secure-enclaves); only signatures are returned. See [Security](/security/our-approach) | -| Gasless UX | [Sponsored transactions](/features/transaction-management) and [sending sponsored transactions](/features/transaction-management/sending-sponsored-transactions) | -| Email-based auth and recovery | [Sub-organization recovery](/features/authentication/email) | -| Send without wallet setup | [Claim links](/features/wallets/claim-links#claim-links): send via URL; recipient claims with email | -| Backend automation | [Delegated access](/features/policies/delegated-access/overview) and scoped signing policies | -| Multichain support | Chain-agnostic derivation and signing. See [Networks](/features/networks/overview) and [Wallets Concept](/features/wallets) | -| Fast integration | Use the [Embedded Wallet Kit](/solutions/embedded-wallets/integration-guide/react/index) for built-in auth and wallet UI components. See [Quickstart](/solutions/embedded-wallets/quickstart) | +| User custody without key exposure | Keys remain in [secure enclaves](/security/secure-enclaves); only signatures are returned. See [Security](/security/our-approach) | +| Gasless UX | [Sponsored transactions](/features/transaction-management) and [sending sponsored transactions](/features/transaction-management/sending-sponsored-transactions) | +| Email-based auth and recovery | [Sub-organization recovery](/features/authentication/email) | +| Send without wallet setup | [Claim links](/features/wallets/claim-links#claim-links): send via URL; recipient claims with email | +| Backend automation | [Delegated access](/features/policies/delegated-access/overview) and scoped signing policies | +| Multichain support | Chain-agnostic derivation and signing. See [Networks](/features/networks/overview) and [Wallets Concept](/features/wallets) | +| Fast integration | Use the [Embedded Wallet Kit](/solutions/embedded-wallets/integration-guide/react/index) for built-in auth and wallet UI components. See [Quickstart](/solutions/embedded-wallets/quickstart) | ## Next steps -
+
- - +
+ +
diff --git a/solutions/embedded-wallets/integration-guide/flutter/advanced-api-requests.mdx b/solutions/embedded-wallets/integration-guide/flutter/advanced-api-requests.mdx index 1edd40cd..2bb738ed 100644 --- a/solutions/embedded-wallets/integration-guide/flutter/advanced-api-requests.mdx +++ b/solutions/embedded-wallets/integration-guide/flutter/advanced-api-requests.mdx @@ -1,5 +1,4 @@ --- - title: "Advanced API requests" description: "Learn how to make advanced API requests to Turnkey's infrastructure." sidebarTitle: "Advanced API requests" @@ -93,20 +92,18 @@ if (activity != null) { } ``` - ## Stamping with a passkey -You can create a client that uses a passkey for stamping instead of using securely stored api keys. Use the `createPasskeyClient` method from the `TurnkeyProvider` to create a new client instance configured for passkey stamping. +You can create a client that uses a passkey for stamping instead of using securely stored api keys. Use the `createPasskeyClient` method from the `TurnkeyProvider` to create a new client instance configured for passkey stamping. An `rpId` is required to use passkey stamping; you can either pass it directly when creating the client or set it in the `TurnkeyProvider` config. ```dart final passkeyClient = await tk.createPasskeyClient( passkeyStamperConfig: PasskeyStamperConfig( // You can pass this into the TurnkeyProvider config instead - rpId: 'example.com', + rpId: 'example.com', ), ); ``` To learn more about using passkeys in your Flutter app, check out the [Passkey Authentication](/solutions/embedded-wallets/integration-guide/flutter/authentication/passkey) guide. - diff --git a/solutions/embedded-wallets/integration-guide/flutter/authentication/email-sms.mdx b/solutions/embedded-wallets/integration-guide/flutter/authentication/email-sms.mdx index 47779fd0..4da9284a 100644 --- a/solutions/embedded-wallets/integration-guide/flutter/authentication/email-sms.mdx +++ b/solutions/embedded-wallets/integration-guide/flutter/authentication/email-sms.mdx @@ -1,5 +1,4 @@ --- - title: "Email and SMS OTP authentication" description: "Set up and implement email or SMS OTP authentication using Turnkey's Flutter SDK." sidebarTitle: "Email & SMS" @@ -11,8 +10,8 @@ This guide shows how to implement OTP authentication using `turnkey_sdk_flutter` Before you begin: -* Complete the provider setup from **Getting Started** and enable **Auth Proxy** with **Email OTP** and/or **SMS OTP** in the Turnkey Dashboard. -* Ensure your `TurnkeyConfig` is pointing at the correct `authProxyConfigId` (OTP settings are controlled in the dashboard). +- Complete the provider setup from **Getting Started** and enable **Auth Proxy** with **Email OTP** and/or **SMS OTP** in the Turnkey Dashboard. +- Ensure your `TurnkeyConfig` is pointing at the correct `authProxyConfigId` (OTP settings are controlled in the dashboard). ## Request an OTP (email) @@ -167,6 +166,6 @@ class _OTPScreenState extends State { ### Notes -* The default OTP length is **6**; if you customized OTP settings in the dashboard, validate accordingly. -* To resend a code, call `initOtp` again with the same contact. -* For SMS, replace `OtpType.Email` with `OtpType.Sms` and pass a phone number in `contact`. +- The default OTP length is **6**; if you customized OTP settings in the dashboard, validate accordingly. +- To resend a code, call `initOtp` again with the same contact. +- For SMS, replace `OtpType.Email` with `OtpType.Sms` and pass a phone number in `contact`. diff --git a/solutions/embedded-wallets/integration-guide/flutter/authentication/overview.mdx b/solutions/embedded-wallets/integration-guide/flutter/authentication/overview.mdx index 3c37298c..eb439274 100644 --- a/solutions/embedded-wallets/integration-guide/flutter/authentication/overview.mdx +++ b/solutions/embedded-wallets/integration-guide/flutter/authentication/overview.mdx @@ -4,7 +4,7 @@ description: "Learn how to set up, log in, or sign up easily in your Flutter app sidebarTitle: "Overview" --- -import { FeatureCard } from '/snippets/feature-card.mdx' +import { FeatureCard } from "/snippets/feature-card.mdx"; Turnkey's Flutter SDK makes authentication simple. You can call specific login and signup functions (email/SMS OTP, passkeys, or social logins) to build your own UI and auth flow. @@ -13,6 +13,7 @@ Turnkey's Flutter SDK makes authentication simple. You can call specific login a To check if a user is authenticated, you can use the `authState` variable from the `TurnkeyProvider`. `authState` can be one of the following: + - `AuthState.authenticated`: The user has a stored session. - `AuthState.unauthenticated`: The user does not have a stored session. - `AuthState.loading`: The provider is initializing. Turnkey is checking for any existing stored sessions or restoring state. UI should show a splash or progress indicator. @@ -128,9 +129,9 @@ class DashboardScreenState extends State { > **Tips** > -> * Use `addListener/removeListener` for one-off reactions to state changes. -> * Use `Consumer`, `Selector`, or `context.select` when you want automatic rebuilds based on specific slices of provider state. -> * Avoid calling `setState` inside your listener after the widget is disposed — always guard with `if (!mounted) return;` or `if (!context.mounted) return;`. +> - Use `addListener/removeListener` for one-off reactions to state changes. +> - Use `Consumer`, `Selector`, or `context.select` when you want automatic rebuilds based on specific slices of provider state. +> - Avoid calling `setState` inside your listener after the widget is disposed — always guard with `if (!mounted) return;` or `if (!context.mounted) return;`. ## Customize sub-organization creation @@ -138,8 +139,29 @@ Need to configure default user names, passkey names, wallet creations or anythin Follow the guides below to learn how to set up email and SMS authentication, passkey authentication, and social logins in your Flutter app. -
- - - -
\ No newline at end of file +
+ + + +
diff --git a/solutions/embedded-wallets/integration-guide/flutter/authentication/passkey.mdx b/solutions/embedded-wallets/integration-guide/flutter/authentication/passkey.mdx index a1cddf3c..a83d60e5 100644 --- a/solutions/embedded-wallets/integration-guide/flutter/authentication/passkey.mdx +++ b/solutions/embedded-wallets/integration-guide/flutter/authentication/passkey.mdx @@ -1,5 +1,4 @@ --- - title: "Passkey authentication" description: "Set up and implement passkey authentication using Turnkey's Flutter SDK." sidebarTitle: "Passkeys" @@ -17,9 +16,8 @@ Passkeys require an **Relying Party ID (rpId)** that matches a domain you contro ### iOS — associated domains 1. **Enable the entitlement** in Xcode for your iOS target: - - * Select your app target → **Signing & Capabilities** → **+ Capability** → **Associated Domains**. - * Add an entry: `webcredentials:yourdomain.com` (replace with your domain). + - Select your app target → **Signing & Capabilities** → **+ Capability** → **Associated Domains**. + - Add an entry: `webcredentials:yourdomain.com` (replace with your domain). 2. **Entitlements file** (if editing manually): `ios/Runner/Runner.entitlements` @@ -51,9 +49,7 @@ Passkeys require an **Relying Party ID (rpId)** that matches a domain you contro ```json title=public/.well-known/assetlinks.json [ { - "relation": [ - "delegate_permission/common.get_login_creds" - ], + "relation": ["delegate_permission/common.get_login_creds"], "target": { "namespace": "android_app", "package_name": "com.example.myapp", @@ -148,7 +144,7 @@ class LoginScreen extends StatelessWidget { ## Tips -* `rpId` **must** match the domain configured in your platform setup, otherwise passkey operations will fail. -* iOS: confirm your build includes **Associated Domains** and the AASA file is reachable. -* Android: confirm `assetlinks.json` is valid and your app's package name + signing certificate fingerprint are correct. -* Consider setting a dynamic display name for passkeys on sign-up so users can identify authenticators later. +- `rpId` **must** match the domain configured in your platform setup, otherwise passkey operations will fail. +- iOS: confirm your build includes **Associated Domains** and the AASA file is reachable. +- Android: confirm `assetlinks.json` is valid and your app's package name + signing certificate fingerprint are correct. +- Consider setting a dynamic display name for passkeys on sign-up so users can identify authenticators later. diff --git a/solutions/embedded-wallets/integration-guide/flutter/authentication/social-logins.mdx b/solutions/embedded-wallets/integration-guide/flutter/authentication/social-logins.mdx index fe3fc6f1..b08610e7 100644 --- a/solutions/embedded-wallets/integration-guide/flutter/authentication/social-logins.mdx +++ b/solutions/embedded-wallets/integration-guide/flutter/authentication/social-logins.mdx @@ -1,5 +1,4 @@ --- - title: "Social logins" description: "Configure and implement social logins in your Flutter app using `turnkey_sdk_flutter`." sidebarTitle: "Social logins" @@ -13,26 +12,39 @@ Using OAuth requires configuration in the Turnkey Dashboard and in your app. Navigate to the **Wallet Kit** section in the [Turnkey Dashboard](https://app.turnkey.com/dashboard/walletKit) and enable **OAuth**. If you have not enabled the Auth Proxy, enable it first. See [Getting Started](/solutions/embedded-wallets/integration-guide/flutter/getting-started) for details. -OAuth providers configuration +OAuth providers configuration ### Configuring OAuth providers Enable the providers you want to use under **Social logins**. -OAuth client IDs configuration +OAuth client IDs configuration #### Client IDs You can enter client IDs for each provider and the redirect URL directly in the dashboard: -OAuth client IDs configuration +OAuth client IDs configuration -OAuth redirect URL configuration +OAuth redirect URL configuration Or provide client IDs and the redirect URI through your app configuration and pass them to the `TurnkeyProvider`. - For OAuth 2.0 providers, you will need to upload the client ID and secret in the dashboard. See the **OAuth 2.0 providers** section below for details. + For OAuth 2.0 providers, you will need to upload the client ID and secret in + the dashboard. See the **OAuth 2.0 providers** section below for details. #### Client configuration @@ -158,8 +170,8 @@ class SocialLoginButtons extends StatelessWidget { Requirements: -* Dashboard: enable Google in Wallet Kit → Authentication. -* Client ID: Web client ID from the Google developer console, set in the Dashboard or via `OAuthConfig`. +- Dashboard: enable Google in Wallet Kit → Authentication. +- Client ID: Web client ID from the Google developer console, set in the Dashboard or via `OAuthConfig`. Usage: @@ -171,9 +183,9 @@ await context.read().handleGoogleOauth(); Requirements: -* Dashboard: enable Apple. -* Client ID: Apple Services ID, set in the Dashboard or via `OAuthConfig`. -* Redirect URI must match your configured value (e.g., `myapp://`). +- Dashboard: enable Apple. +- Client ID: Apple Services ID, set in the Dashboard or via `OAuthConfig`. +- Redirect URI must match your configured value (e.g., `myapp://`). Usage: @@ -185,9 +197,9 @@ await context.read().handleAppleOauth(); Requirements: -* Dashboard: enable Facebook. -* Client ID: set in the Dashboard or via `OAuthConfig`. -* Redirect URI must match your configured value (e.g., `myapp://`). +- Dashboard: enable Facebook. +- Client ID: set in the Dashboard or via `OAuthConfig`. +- Redirect URI must match your configured value (e.g., `myapp://`). Usage: @@ -201,15 +213,24 @@ For providers that use OAuth 2.0 (e.g., X, Discord), configure additional settin In **Wallet Kit → Socials**, click **Add provider**. -OAuth2.0 providers configuration +OAuth2.0 providers configuration Select the provider and fill in the required fields from the provider console. Secrets are encrypted on upload. -Adding an OAuth2.0 provider +Adding an OAuth2.0 provider Then go to **Authentication** and enable the provider under **SDK Configuration**. -Enabling an OAuth2.0 provider +Enabling an OAuth2.0 provider Click **Select** to choose your newly added client ID, then **Save Settings**. Alternatively, enter the client ID through `OAuthConfig`. @@ -217,9 +238,9 @@ Click **Select** to choose your newly added client ID, then **Save Settings**. A Requirements: -* Dashboard: enable Discord (OAuth 2.0). -* Client ID: set in Dashboard or via `OAuthConfig`. -* Redirect URI must match your configured value (e.g., `myapp://`). +- Dashboard: enable Discord (OAuth 2.0). +- Client ID: set in Dashboard or via `OAuthConfig`. +- Redirect URI must match your configured value (e.g., `myapp://`). Usage: @@ -231,9 +252,9 @@ await context.read().handleDiscordOauth(); Requirements: -* Dashboard: enable X (OAuth 2.0). -* Client ID: set in Dashboard or via `OAuthConfig`. -* Redirect URI must match your configured value (e.g., `myapp://`). +- Dashboard: enable X (OAuth 2.0). +- Client ID: set in Dashboard or via `OAuthConfig`. +- Redirect URI must match your configured value (e.g., `myapp://`). Usage: diff --git a/solutions/embedded-wallets/integration-guide/flutter/getting-started.mdx b/solutions/embedded-wallets/integration-guide/flutter/getting-started.mdx index b036b12b..ffec16da 100644 --- a/solutions/embedded-wallets/integration-guide/flutter/getting-started.mdx +++ b/solutions/embedded-wallets/integration-guide/flutter/getting-started.mdx @@ -15,18 +15,15 @@ For this setup, we will be using Turnkey's Auth Proxy to handle authentication. Navigate to the **Wallet Kit** section in the Turnkey Dashboard and enable the **Auth Proxy**. - Auth Proxy toggle - - You can choose which auth methods to enable and customize various options from this screen. For this quickstart, let's enable **email OTP** and **passkeys**. When you're done, click **Save**. Wallet kit options - - Once you're finished with the auth proxy setup, you can copy the **auth proxy config ID** @@ -86,12 +80,10 @@ flutter pub add turnkey_sdk_flutter provider flutter_inappwebview - ## Provider Wrap your app with `ChangeNotifierProvider` and configure `TurnkeyProvider`. - ```dart lib/main.dart import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -118,7 +110,7 @@ void main() async { final turnkeyProvider = TurnkeyProvider( config: TurnkeyConfig( - authProxyConfigId: "", + authProxyConfigId: "", organizationId: "", // Optional: attach some callbacks @@ -164,15 +156,11 @@ turnkeyProvider.ready.then((_) { }); ``` - ## Demo app You can check out a complete demo app that uses Turnkey's Flutter SDK on [GitHub](https://github.com/tkhq/dart-sdk/tree/main/examples/flutter-demo-app). Feel free to clone and modify it to get started quickly! - - + ## Next steps diff --git a/solutions/embedded-wallets/integration-guide/flutter/index.mdx b/solutions/embedded-wallets/integration-guide/flutter/index.mdx index f11b53c8..78675df0 100644 --- a/solutions/embedded-wallets/integration-guide/flutter/index.mdx +++ b/solutions/embedded-wallets/integration-guide/flutter/index.mdx @@ -4,14 +4,45 @@ description: "Turnkey's Flutter SDK [`(turnkey_sdk_flutter)`](https://pub.dev/pa sidebarTitle: "Overview" --- -import { FeatureCard } from '/snippets/feature-card.mdx' +import { FeatureCard } from "/snippets/feature-card.mdx"; Find `turnkey_sdk_flutter` on [pub.dev](https://pub.dev/packages/turnkey_sdk_flutter) or view the source code on [GitHub](https://github.com/tkhq/dart-sdk)! For a working reference implementation covering auth, wallet creation, export, and signing, see the [flutter-demo-app](https://github.com/tkhq/dart-sdk/tree/main/examples/flutter-demo-app) example app. -
- - - - - -
\ No newline at end of file +
+ + + + + +
diff --git a/solutions/embedded-wallets/integration-guide/flutter/signing.mdx b/solutions/embedded-wallets/integration-guide/flutter/signing.mdx index 49f5f6e8..fce4d510 100644 --- a/solutions/embedded-wallets/integration-guide/flutter/signing.mdx +++ b/solutions/embedded-wallets/integration-guide/flutter/signing.mdx @@ -1,5 +1,4 @@ --- - title: "Signing" description: "Learn how to sign messages and transactions in your Flutter app using Turnkey's Embedded Wallets." sidebarTitle: "Signing" @@ -9,7 +8,6 @@ sidebarTitle: "Signing" Turnkey's Flutter SDK makes it simple to sign messages and transactions using embedded wallets managed by the `TurnkeyProvider`. - ## Signing messages To sign a message, select a wallet account and call `signMessage` from the `TurnkeyProvider`. You can optionally pass in the payload's `encoding` and `hashFunction` if needed. diff --git a/solutions/embedded-wallets/integration-guide/flutter/sub-organization-customization.mdx b/solutions/embedded-wallets/integration-guide/flutter/sub-organization-customization.mdx index b5da0e38..d0298567 100644 --- a/solutions/embedded-wallets/integration-guide/flutter/sub-organization-customization.mdx +++ b/solutions/embedded-wallets/integration-guide/flutter/sub-organization-customization.mdx @@ -1,5 +1,4 @@ --- - title: "Sub-organization customization" description: "Learn how to customize the sub-organization creation process in your Flutter app." sidebarTitle: "Sub-organization customization" diff --git a/solutions/embedded-wallets/integration-guide/flutter/using-embedded-wallets.mdx b/solutions/embedded-wallets/integration-guide/flutter/using-embedded-wallets.mdx index 703f227e..032a96ee 100644 --- a/solutions/embedded-wallets/integration-guide/flutter/using-embedded-wallets.mdx +++ b/solutions/embedded-wallets/integration-guide/flutter/using-embedded-wallets.mdx @@ -251,6 +251,3 @@ class ExportWalletButton extends StatelessWidget { ## Next steps Continue to **[Signing](/solutions/embedded-wallets/integration-guide/flutter/signing)** to learn how to sign messages and transactions with your embedded wallets. - - - diff --git a/solutions/embedded-wallets/integration-guide/kotlin/advanced-api-requests.mdx b/solutions/embedded-wallets/integration-guide/kotlin/advanced-api-requests.mdx index 21bf545d..38cf0d2e 100644 --- a/solutions/embedded-wallets/integration-guide/kotlin/advanced-api-requests.mdx +++ b/solutions/embedded-wallets/integration-guide/kotlin/advanced-api-requests.mdx @@ -34,7 +34,7 @@ class MainActivity : AppCompatActivity() { setContentView(R.layout.activity_main) val button = findViewById; } export default function Home() { - return ( - - ); + return ; } ``` @@ -133,7 +131,7 @@ You can choose to enter your client IDs for each OAuth provider and the redirect alt="OAuth client IDs configuration" /> -Or, you can provide the client IDs and redirect URI through environment variables and pass them in the `TurnkeyProvider`'s config. This is useful if you want to use different OAuth client IDs or a different redirect URL for different environments (e.g., development, staging, production). +Or, you can provide the client IDs and redirect URI through environment variables and pass them in the `TurnkeyProvider`'s config. This is useful if you want to use different OAuth client IDs or a different redirect URL for different environments (e.g., development, staging, production). Here, you can also toggle `openOauthInPage` to `true` if you want OAuth to replace the current page instead of opening a new popup. @@ -191,12 +189,11 @@ In the **Wallet Kit** section of the dashboard, head to the **Socials** tab and alt="OAuth2.0 providers configuration" /> - Select the provider you want to add from the dropdown, and fill in the required fields. You can find these values in the provider's developer console. Any secrets will automatically be encrypted before uploading to Turnkey. Adding an OAuth2.0 provider Once you've added the provider, head back to the **Authentication** tab, and enable the provider you just added under the **SDK Configuration** section. @@ -213,7 +210,6 @@ Click **Select** to choose your newly added client ID, then click **Save Setting alt="Selecting an OAuth2.0 provider" /> - ## Customize sub-organization creation Need to configure default user names, passkey names, wallet creations or anything sub-org related? You can learn more about customizing the sub-orgs you create in the [Sub-Organization Customization](/solutions/embedded-wallets/integration-guide/react/sub-organization-customization) section. diff --git a/solutions/embedded-wallets/integration-guide/react/getting-started.mdx b/solutions/embedded-wallets/integration-guide/react/getting-started.mdx index 40f64f7b..2af2f6b2 100644 --- a/solutions/embedded-wallets/integration-guide/react/getting-started.mdx +++ b/solutions/embedded-wallets/integration-guide/react/getting-started.mdx @@ -122,18 +122,21 @@ const turnkeyConfig: TurnkeyProviderConfig = { }; export function Providers({ children }: { children: React.ReactNode }) { - return console.error("Turnkey error:", error), - }} - >{children}; + return ( + console.error("Turnkey error:", error), + }} + > + {children} + + ); } ``` In case anything goes wrong, we've added an `onError` callback to the `TurnkeyProvider` to catch any errors. - Then, use the `Providers` component to wrap your app in `app/layout.tsx`. ```tsx app/layout.tsx @@ -187,9 +190,9 @@ The client performs several asynchronous operations during initialization: Calling methods before Ready can cause: -* Race conditions with session management -* Missing configuration errors -* Failed client operations +- Race conditions with session management +- Missing configuration errors +- Failed client operations ### How to check client readiness diff --git a/solutions/embedded-wallets/integration-guide/react/index.mdx b/solutions/embedded-wallets/integration-guide/react/index.mdx index 1894e9ca..7554752e 100644 --- a/solutions/embedded-wallets/integration-guide/react/index.mdx +++ b/solutions/embedded-wallets/integration-guide/react/index.mdx @@ -4,19 +4,75 @@ description: "Turnkey's Embedded Wallet Kit [`(@turnkey/react-wallet-kit)`](http sidebarTitle: "Overview" --- -import { FeatureCard } from '/snippets/feature-card.mdx' +import { FeatureCard } from "/snippets/feature-card.mdx"; Find `@turnkey/react-wallet-kit` on [npm](https://www.npmjs.com/package/@turnkey/react-wallet-kit) or view the source code on [GitHub](https://github.com/tkhq/sdk/tree/main/packages/react-wallet-kit)! For a working reference implementation covering auth, wallet management, signing, import/export, see the [react-wallet-kit](https://github.com/tkhq/sdk/tree/main/examples/react-wallet-kit) example app, or try the [live demo](https://wallets.turnkey.com). -
- - - - - - - - - - +
+ + + + + + + + + +
diff --git a/solutions/embedded-wallets/integration-guide/react/migrating-sdk-react.mdx b/solutions/embedded-wallets/integration-guide/react/migrating-sdk-react.mdx index c5483772..0d7cc24e 100644 --- a/solutions/embedded-wallets/integration-guide/react/migrating-sdk-react.mdx +++ b/solutions/embedded-wallets/integration-guide/react/migrating-sdk-react.mdx @@ -252,7 +252,7 @@ export async function initEmailAuth({ "auth", email, "email", - targetPublicKey + targetPublicKey, ); return client.initOtp({ @@ -588,7 +588,7 @@ const walletsWithAccounts = await Promise.all( }); // ...merge accounts return { ...wallet, accounts }; - }) + }), ); ``` @@ -635,7 +635,7 @@ const { walletId } = await indexedDbClient.createWallet({ // Compute a default Ethereum account at the next index to maintain derivation path ordering const newAccount = defaultEthereumAccountAtIndex( - state.selectedWallet.accounts.length + 1 + state.selectedWallet.accounts.length + 1, ); // Add a new Ethereum account to the created wallet @@ -703,7 +703,7 @@ const { turnkey, indexedDbClient } = useTurnkey(); // 1) Create export iframe client const iframeClient = await turnkey?.iframeClient({ iframeContainer: document.getElementById( - "turnkey-export-iframe-container-id" + "turnkey-export-iframe-container-id", )!, iframeUrl: "https://export.turnkey.com", }); @@ -716,7 +716,7 @@ const walletExport = await indexedDbClient?.exportWallet({ const session = await turnkey?.getSession(); await iframeClient?.injectWalletExportBundle( walletExport!.exportBundle, - session?.organizationId + session?.organizationId, ); // 2b) Export a private key (by account address) @@ -726,7 +726,7 @@ const keyExport = await indexedDbClient?.exportWalletAccount({ }); await iframeClient?.injectKeyExportBundle( keyExport!.exportBundle, - session?.organizationId + session?.organizationId, ); ``` @@ -764,7 +764,7 @@ const { turnkey, indexedDbClient } = useTurnkey(); // 1) Create import iframe client const iframeClient = await turnkey?.iframeClient({ iframeContainer: document.getElementById( - "turnkey-import-iframe-container-id" + "turnkey-import-iframe-container-id", )!, iframeUrl: "https://import.turnkey.com", }); @@ -779,7 +779,7 @@ const initWallet = await indexedDbClient?.initImportWallet({ await iframeClient?.injectImportBundle( initWallet!.importBundle, session?.organizationId, - session?.userId + session?.userId, ); // or Private Key @@ -789,7 +789,7 @@ const initKey = await indexedDbClient?.initImportPrivateKey({ await iframeClient?.injectImportBundle( initKey!.importBundle, session?.organizationId, - session?.userId + session?.userId, ); // 3) Extract encrypted bundle from iframe and submit import diff --git a/solutions/embedded-wallets/integration-guide/react/signing.mdx b/solutions/embedded-wallets/integration-guide/react/signing.mdx index d3120e33..84fa5baa 100644 --- a/solutions/embedded-wallets/integration-guide/react/signing.mdx +++ b/solutions/embedded-wallets/integration-guide/react/signing.mdx @@ -118,7 +118,7 @@ function SignMessageWithExternalWalletButton() { const doSignMessage = async () => { try { const externalWallet = wallets.find( - (wallet) => wallet.source === WalletSource.Connected + (wallet) => wallet.source === WalletSource.Connected, ); // Find an external wallet if (!externalWallet) { @@ -131,7 +131,7 @@ function SignMessageWithExternalWalletButton() { const signature = await handleSignMessage({ walletAccount, message, - addEthereumPrefix: true, // Required for connected Ethereum wallets (e.g. MetaMask) + addEthereumPrefix: true, // Required for connected Ethereum wallets (e.g. MetaMask) }); console.log("Message signed with external wallet:", signature); } catch (error) { diff --git a/solutions/embedded-wallets/integration-guide/react/troubleshooting.mdx b/solutions/embedded-wallets/integration-guide/react/troubleshooting.mdx index f86a11a6..bff1eae1 100644 --- a/solutions/embedded-wallets/integration-guide/react/troubleshooting.mdx +++ b/solutions/embedded-wallets/integration-guide/react/troubleshooting.mdx @@ -86,7 +86,7 @@ If you are using environment variables, ensure they are correctly set up in your ```tsx console.log( "Auth Proxy Config ID:", - process.env.NEXT_PUBLIC_AUTH_PROXY_CONFIG_ID + process.env.NEXT_PUBLIC_AUTH_PROXY_CONFIG_ID, ); console.log("Organization ID:", process.env.NEXT_PUBLIC_ORGANIZATION_ID); ``` @@ -412,11 +412,13 @@ function RadixDialog() { /> #### Problem + This error occurs when using Create React App (CRA) and trying to import `@turnkey/react-wallet-kit`. CRA requires that all imports include the file extension to be fully specified. Note that this can also occur in strict ESM build environments (e.g., Next.js builds in CI) where fully specified imports are required. In those cases you may see errors like: `Cannot find module '@turnkey/core/dist/__types__/enums'` and a suggestion to import `@turnkey/core/dist/__types__/enums.js`. The fix is to ensure the import is resolved with the `.js` extension (e.g., `@turnkey/core/dist/__types__/enums.js`). If you can't edit the package source directly, apply a small build-time patch that rewrites the import. #### Solution Follow these steps to resolve the issue: + Ejecting from CRA will give you full control over the Webpack configuration, allowing you to modify it to remove the need for fully specified imports. @@ -427,27 +429,29 @@ Follow these steps to resolve the issue: - After ejecting, open the `config/webpack.config.js` file and locate the `resolve` section. Add the following line to the `resolve` object under the rules for `/\.(js|mjs)$/` files: - ```js - // config/webpack.config.js +After ejecting, open the `config/webpack.config.js` file and locate the `resolve` section. Add the following line to the `resolve` object under the rules for `/\.(js|mjs)$/` files: - // ... other configurations - { - test: /\.(js|mjs)$/, // Search for this line - exclude: /@babel(?:\/|\\{1,2})runtime/, - loader: require.resolve('babel-loader'), +```js +// config/webpack.config.js - resolve: { - fullySpecified: false, // Add this line - }, +// ... other configurations +{ + test: /\.(js|mjs)$/, // Search for this line + exclude: /@babel(?:\/|\\{1,2})runtime/, + loader: require.resolve('babel-loader'), + resolve: { + fullySpecified: false, // Add this line + }, - // ... other configurations - } - ``` - This will disable the requirement for fully specified imports in your project. +// ... other configurations +} +``` + +This will disable the requirement for fully specified imports in your project. + @@ -461,13 +465,14 @@ Read more about fully specified imports in the [Webpack documentation](https://w /> #### Problem + This error occurs when you try to use Turnkey client functions before the SDK has finished initializing said client. The Turnkey SDK performs several asynchronous operations during initialization, and if you attempt to call client functions before this process is complete, you'll encounter this error. #### Solution To resolve this issue, ensure that you only call Turnkey client functions after the SDK has fully initialized. You can do this by checking the `clientState` state variable from the `useTurnkey` hook. The `clientState` variable indicates the current state of the Turnkey client. You can read up more about how to use the `clientState` variable and why its important in the [Getting Started](/solutions/embedded-wallets/integration-guide/react/getting-started#client-readiness) guide. -Example solutions to potential issues: +Example solutions to potential issues: **Calling client functions in `useEffects` or event handlers without checking client readiness:** @@ -500,4 +505,3 @@ useEffect(() => { } }, [clientState]); ``` - diff --git a/solutions/embedded-wallets/integration-guide/react/using-embedded-wallets.mdx b/solutions/embedded-wallets/integration-guide/react/using-embedded-wallets.mdx index 39f7bacb..bd4331d6 100644 --- a/solutions/embedded-wallets/integration-guide/react/using-embedded-wallets.mdx +++ b/solutions/embedded-wallets/integration-guide/react/using-embedded-wallets.mdx @@ -199,7 +199,7 @@ and this export modal when you click the "Export Wallet" button: alt="Export Wallet Modal" /> -Check out this [example](https://github.com/tkhq/sdk/tree/main/examples/import-export-with-rwk) showing how to import / export wallets, wallet accounts and private keys using `@turnkey/react-wallet-kit`. +Check out this [example](https://github.com/tkhq/sdk/tree/main/examples/import-export-with-rwk) showing how to import / export wallets, wallet accounts and private keys using `@turnkey/react-wallet-kit`. ## Next steps diff --git a/solutions/embedded-wallets/integration-guide/react/using-external-wallets/authentication.mdx b/solutions/embedded-wallets/integration-guide/react/using-external-wallets/authentication.mdx index 7485fa1b..98b9b8a5 100644 --- a/solutions/embedded-wallets/integration-guide/react/using-external-wallets/authentication.mdx +++ b/solutions/embedded-wallets/integration-guide/react/using-external-wallets/authentication.mdx @@ -5,17 +5,19 @@ sidebarTitle: "Authentication" --- > **Prerequisite:** -> If you haven’t already, check out the [External Wallets Overview](/solutions/embedded-wallets/integration-guide/react/using-external-wallets/overview) first, this guide builds on the concepts introduced there. - +> If you haven’t already, check out the [External Wallets Overview](/solutions/embedded-wallets/integration-guide/react/using-external-wallets/overview) first, this guide builds on the concepts introduced there. ## Setting up wallet authentication + The toggle to enable wallet authentication is available in the `TurnkeyProvider` configuration. Wallet authentication can also be set in the dashboard, but the `TurnkeyProvider` configuration takes precedence. You can further customize settings, such as which chains are enabled, which providers are supported, and whether WalletConnect is allowed. -> **Note:** -> - For authentication to work, you must define at least one `ethereum` or `solana` chain, either as `native` or with `walletConnectNamespaces`. +> **Note:** +> +> - For authentication to work, you must define at least one `ethereum` or `solana` chain, either as `native` or with `walletConnectNamespaces`. +> > ```tsx > walletConfig: { -> // at least one chain must be enabled (native: true) +> // at least one chain must be enabled (native: true) > // or have non-empty `walletConnectNamespaces` > chains: { > ethereum: { @@ -27,8 +29,9 @@ The toggle to enable wallet authentication is available in the `TurnkeyProvider` > walletConnectNamespaces: [], > }, > }, ->``` -> - To enable WalletConnect, you must configure both the `walletConnect` object **and** define `walletConnectNamespaces` in at least one chain (e.g., `ethereum` or `solana`). +> ``` +> +> - To enable WalletConnect, you must configure both the `walletConnect` object **and** define `walletConnectNamespaces` in at least one chain (e.g., `ethereum` or `solana`). ```tsx import { @@ -80,6 +83,7 @@ function App() { There are two paths you can take: let us handle it for you, or build it yourself. We recommend letting us do the heavy lifting using our built-in modal. ### Option 1: use the auth modal + If you want a fully styled, plug-and-play experience, use our `Auth` modal. It handles the entire authentication flow for you. ```tsx @@ -94,7 +98,7 @@ function LoginButton() { Below are screenshots of what the default UI looks like out of the box when using the built-in Auth modal: -
+
-
+
WalletConnect QR Modal
- - > **Note**: this UI is customizable. Checkout the [UI Customization](/solutions/embedded-wallets/integration-guide/react/ui-customization) guide to learn how to customize the look and feel of the Auth modal and other UI components. ### Option 2: build a custom auth flow There are a few ways to authenticate users with their wallets. We provide several abstraction functions that handle authentication, each with slightly different behavior: + 1. `loginWithWallet()` 2. `signUpWithWallet()` 3. `loginOrSignUpWithWallet()` @@ -144,27 +149,30 @@ For this guide, we'll use `loginOrSignUpWithWallet()` as the reference, since it // this represents the WalletProvider (e.g., MetaMask) and the currently selected wallet within it // this is the wallet that will be used to authenticate into the sub-org const selectedProvider = providers[0]; - ``` - - - ```tsx - import { useTurnkey } from "@turnkey/react-wallet-kit"; +```` + + + +```tsx + import { useTurnkey } from "@turnkey/react-wallet-kit"; - const { loginOrSignUpWithWallet } = useTurnkey(); + const { loginOrSignUpWithWallet } = useTurnkey(); + + const handleLoginOrSignUp = async () => { + try { + await loginOrSignupWithWallet({ walletProvider: selectedProvider }); + } catch (error) { + console.error("Error logging in or signing up:", error); + } + }; +```` - const handleLoginOrSignUp = async () => { - try { - await loginOrSignupWithWallet({ walletProvider: selectedProvider }); - } catch (error) { - console.error("Error logging in or signing up:", error); - } - }; - ``` ## How does this look structurally in a Turnkey organization? + If you're just looking to implement wallet authentication in your app, you don't need to worry about the internal structure. But if you're curious about how these flows map to Turnkey's organization model under the hood, here's a deeper look: At its core, a wallet is just a key pair. When a user signs up with a wallet, Turnkey creates a sub-org for that user and sets up the public key of the wallet as an authenticator for that sub-org. diff --git a/solutions/embedded-wallets/integration-guide/react/using-external-wallets/connecting.mdx b/solutions/embedded-wallets/integration-guide/react/using-external-wallets/connecting.mdx index 742601e4..87a4d989 100644 --- a/solutions/embedded-wallets/integration-guide/react/using-external-wallets/connecting.mdx +++ b/solutions/embedded-wallets/integration-guide/react/using-external-wallets/connecting.mdx @@ -5,16 +5,19 @@ sidebarTitle: "Connecting" --- > **Prerequisite:** -> If you haven’t already, check out the [External Wallets Overview](/solutions/embedded-wallets/integration-guide/react/using-external-wallets/overview) first, this guide builds on the concepts introduced there. +> If you haven’t already, check out the [External Wallets Overview](/solutions/embedded-wallets/integration-guide/react/using-external-wallets/overview) first, this guide builds on the concepts introduced there. ## Setting up connecting wallet support + The toggle to enable connecting external wallets is available in the `TurnkeyProvider` configuration. You can further customize settings, such as which chains are enabled, which providers are supported, and whether WalletConnect is allowed. -> **Note:** -> - For wallet connecting to work, you must define at least one `ethereum` or `solana` chain, either as `native` or with `walletConnectNamespaces`. +> **Note:** +> +> - For wallet connecting to work, you must define at least one `ethereum` or `solana` chain, either as `native` or with `walletConnectNamespaces`. +> > ```tsx > walletConfig: { -> // at least one chain must be enabled (native: true) +> // at least one chain must be enabled (native: true) > // or have non-empty `walletConnectNamespaces` > chains: { > ethereum: { @@ -26,9 +29,10 @@ The toggle to enable connecting external wallets is available in the `TurnkeyPro > walletConnectNamespaces: [], > }, > }, ->``` -> - To enable WalletConnect, you must configure both the `walletConnect` object **and** define `walletConnectNamespaces` in at least one chain (e.g., `ethereum` or `solana`). -> - For EVM chain switching on WalletConnect, all supported chain namespaces must be listed in `walletConnectNamespaces` under `ethereum`. Attempting to switch to a chain not listed here will result in an error. The first chain in the array is the default chain you will be connected to. +> ``` +> +> - To enable WalletConnect, you must configure both the `walletConnect` object **and** define `walletConnectNamespaces` in at least one chain (e.g., `ethereum` or `solana`). +> - For EVM chain switching on WalletConnect, all supported chain namespaces must be listed in `walletConnectNamespaces` under `ethereum`. Attempting to switch to a chain not listed here will result in an error. The first chain in the array is the default chain you will be connected to. ```tsx import { @@ -84,51 +88,56 @@ One thing to understand is that when a user authenticates into a Turnkey sub-org To put it simply: **logging in with a wallet automatically connects it.** That means the wallet can then be used both: + - as a stamper for Turnkey activities, and - as a connected wallet for signing messages and transactions in your app logic ### What happens after a wallet is connected? + Once a wallet is successfully connected, several things become available in your app: - The `WalletProvider` you connected to now shows in the `connectedAddresses` property of the provider. +The `WalletProvider` you connected to now shows in the `connectedAddresses` property of the provider. - ```tsx - import { useTurnkey } from "@turnkey/react-wallet-kit"; +```tsx +import { useTurnkey } from "@turnkey/react-wallet-kit"; - const { fetchWalletProviders } = useTurnkey(); +const { fetchWalletProviders } = useTurnkey(); - const providers = await fetchWalletProviders(); +const providers = await fetchWalletProviders(); - // this represents the WalletProvider (e.g., MetaMask) we just connected to - const connectedProvider = providers[0]; +// this represents the WalletProvider (e.g., MetaMask) we just connected to +const connectedProvider = providers[0]; + +// this is an array of connected wallet addresses +// it's normally just one address, unless this provider is WalletConnect +const connectedAddresses = connectedProvider.connectedAddresses; +``` - // this is an array of connected wallet addresses - // it's normally just one address, unless this provider is WalletConnect - const connectedAddresses = connectedProvider.connectedAddresses; - ``` - The wallet you just connected to will automatically be included in the `wallets` state. - ```tsx - import { useTurnkey } from "@turnkey/react-wallet-kit"; +The wallet you just connected to will automatically be included in the `wallets` state. + +```tsx +import { useTurnkey } from "@turnkey/react-wallet-kit"; + +const { wallets } = useTurnkey(); +``` - const { wallets } = useTurnkey(); - ``` +#### Understanding the connected wallet structure - #### Understanding the connected wallet structure +When a user connects to an external wallet (like a wallet in MetaMask or Phantom), Turnkey creates a `Wallet` object representing that provider. This wallet contains one or more `WalletAccount` entries, each representing a connected address on a specific chain (e.g., Ethereum or Solana). - When a user connects to an external wallet (like a wallet in MetaMask or Phantom), Turnkey creates a `Wallet` object representing that provider. This wallet contains one or more `WalletAccount` entries, each representing a connected address on a specific chain (e.g., Ethereum or Solana). +For example, if the user connects to MetaMask with an Ethereum address, a Wallet named "MetaMask" is created, and a corresponding Ethereum account is added. If the user then connects to MetaMask with a Solana address, that address appears as an additional account within the same wallet. - For example, if the user connects to MetaMask with an Ethereum address, a Wallet named "MetaMask" is created, and a corresponding Ethereum account is added. If the user then connects to MetaMask with a Solana address, that address appears as an additional account within the same wallet. +In short: - In short: - - The `Wallet` represents the external provider (e.g., "MetaMask"). - - The `WalletAccounts` represent the connected addresses, one per namespace (Ethereum, and or Solana) under that provider. +- The `Wallet` represents the external provider (e.g., "MetaMask"). +- The `WalletAccounts` represent the connected addresses, one per namespace (Ethereum, and or Solana) under that provider. ```ts @@ -163,13 +172,14 @@ Once a wallet is successfully connected, several things become available in your - Once connected, you can call high-level signing functions by passing in that wallet account just like you would with an embedded wallet. +Once connected, you can call high-level signing functions by passing in that wallet account just like you would with an embedded wallet. ```tsx - import { useTurnkey } from "@turnkey/react-wallet-kit"; +import { useTurnkey } from "@turnkey/react-wallet-kit"; + +const { signMessage, signTransaction, signAndSendTransaction } = useTurnkey(); +``` - const { signMessage, signTransaction, signAndSendTransaction } = useTurnkey(); - ``` @@ -178,17 +188,18 @@ Once a wallet is successfully connected, several things become available in your There are two paths you can take: let us handle it for you, or build it yourself. We recommend letting us do the heavy lifting using our built-in modal. #### Option 1: use our `Connect External Wallet` + If you want a fully styled, plug-and-play experience, use our Connect External Wallet modal. It handles the entire connection flow for you. ```tsx - import { useTurnkey } from "@turnkey/react-wallet-kit"; +import { useTurnkey } from "@turnkey/react-wallet-kit"; - const { handleConnectExternalWallet } = useTurnkey(); +const { handleConnectExternalWallet } = useTurnkey(); ``` Below are screenshots of what the default UI looks like out of the box when using the built-in Connect External Wallet modal: -
+
-
+
WalletConnect QR Modal
-> **Note**: this UI is customizable. Checkout the [UI Customization](/solutions/embedded-wallets/integration-guide/react/ui-customization) guide to learn how to customize the look and feel of the Connect External Wallet modal and other UI components. +> **Note**: this UI is customizable. Checkout the [UI Customization](/solutions/embedded-wallets/integration-guide/react/ui-customization) guide to learn how to customize the look and feel of the Connect External Wallet modal and other UI components. + +#### Option 2: build a custom connection flow -#### Option 2: build a custom connection flow If you prefer full control over the connection experience, you can use our low-level functions to handle the flow manually. @@ -228,23 +242,25 @@ If you prefer full control over the connection experience, you can use our low-l // this represents the WalletProvider (e.g., MetaMask) and the currently selected wallet within it // this is the wallet that will be connected to const selectedProvider = providers[0]; - ``` - - - ```tsx - import { useTurnkey } from "@turnkey/react-wallet-kit"; +```` + - const { connectWalletAccount } = useTurnkey(); + +```tsx + import { useTurnkey } from "@turnkey/react-wallet-kit"; + + const { connectWalletAccount } = useTurnkey(); + + const handleConnectWalletAccount = async () => { + try { + await connectWalletAccount(selectedProvider); + } catch (error) { + console.error("Error connecting this wallet account:", error); + } + }; +```` - const handleConnectWalletAccount = async () => { - try { - await connectWalletAccount(selectedProvider); - } catch (error) { - console.error("Error connecting this wallet account:", error); - } - }; - ``` @@ -260,8 +276,9 @@ If you prefer full control over the connection experience, you can use our low-l console.error("Error disconnecting this wallet account:", error); } }; - ``` - + +``` + ## How does this look structurally in a Turnkey organization? @@ -276,3 +293,4 @@ We included this feature because many developers want to allow users to connect ## Next steps Now that you have an external wallet connected, check out the [Signing](/solutions/embedded-wallets/integration-guide/react/signing) guide to learn how to sign transactions and messages. +``` diff --git a/solutions/embedded-wallets/integration-guide/react/using-external-wallets/overview.mdx b/solutions/embedded-wallets/integration-guide/react/using-external-wallets/overview.mdx index 90792950..00ad75e9 100644 --- a/solutions/embedded-wallets/integration-guide/react/using-external-wallets/overview.mdx +++ b/solutions/embedded-wallets/integration-guide/react/using-external-wallets/overview.mdx @@ -5,9 +5,11 @@ sidebarTitle: "Overview" --- ## Overview + The Embedded Wallet Kit provides a straightforward way to authenticate and use external wallets in your React application. The EWK offers abstractions to easily discover available wallet providers, connect to them, sign messages and transactions, switch chains, and use external wallets alongside embedded ones. This creates a seamless developer experience when switching between embedded and external wallets, with minimal changes required to your application logic. ## Different uses cases of external wallets + External wallets can be used in two primary ways within your application: @@ -24,39 +26,43 @@ External wallets can be used in two primary ways within your application: - Sign transactions using a connected wallet - Switch between EVM chains when multiple networks are supported - Disconnect a connected wallet + ## What is a WalletProvider? + Both authentication and external wallet connecting flows rely on a `WalletProvider`. A **WalletProvider** refers to an external wallet interface, such as a browser extension (e.g., MetaMask, Phantom) or a bridge like WalletConnect (if enabled). These providers act as the bridge between your app and the user's wallet for signing, authentication, and transaction purposes. You can retrieve available wallet providers by calling the `fetchWalletProviders()`, which returns an array of WalletProvider instances available in the current environment. + ```tsx - import { useTurnkey } from "@turnkey/react-wallet-kit"; +import { useTurnkey } from "@turnkey/react-wallet-kit"; + +const { fetchWalletProviders } = useTurnkey(); - const { fetchWalletProviders } = useTurnkey(); - - const providers = await fetchWalletProviders(); +const providers = await fetchWalletProviders(); ``` If a provider is already connected, it will still appear in the result of `fetchWalletProviders()`. To determine whether it's connected, you can inspect the `provider.connectedAddresses` property. This will list the currently connected addresses for that provider. -> **Note:** -> - Each `WalletProvider` can only maintain **one active connection per namespace** (e.g., one Ethereum address *and* one Solana address at a time). -> - Example: if you connect a second Ethereum address in MetaMask, it will replace the currently connected one. The same applies for Solana. +> **Note:** > -> - If a provider supports multiple namespaces (e.g., MetaMask supports both Ethereum and Solana), it will appear as **two separate providers** in the result of `fetchWalletProviders()`. -> - They may share the same display name (e.g., `"MetaMask"`), but they’ll have different `chainInfo` values and are treated independently in authentication and connection logic. -> -> - The **duration of a connection** depends on the provider’s behavior. -> - Most providers maintain a session until it is explicitly disconnected, either from your app or manually via the wallet UI (e.g., disconnecting in MetaMask). +> - Each `WalletProvider` can only maintain **one active connection per namespace** (e.g., one Ethereum address _and_ one Solana address at a time). +> - Example: if you connect a second Ethereum address in MetaMask, it will replace the currently connected one. The same applies for Solana. +> - If a provider supports multiple namespaces (e.g., MetaMask supports both Ethereum and Solana), it will appear as **two separate providers** in the result of `fetchWalletProviders()`. +> - They may share the same display name (e.g., `"MetaMask"`), but they’ll have different `chainInfo` values and are treated independently in authentication and connection logic. +> - The **duration of a connection** depends on the provider’s behavior. +> - Most providers maintain a session until it is explicitly disconnected, either from your app or manually via the wallet UI (e.g., disconnecting in MetaMask). ### What does the WalletProvider object look like? + Here’s an example of how `WalletProvider` objects are returned when both Ethereum, Solana, and WalletConnect are enabled. #### Native Ethereum provider + ```ts { interfaceType: "ethereum", @@ -76,6 +82,7 @@ Here’s an example of how `WalletProvider` objects are returned when both Ether ``` #### Native Solana provider + ```ts { interfaceType: "solana", @@ -92,6 +99,7 @@ Here’s an example of how `WalletProvider` objects are returned when both Ether ``` #### WalletConnect provider (Ethereum example) + ```ts { interfaceType: "wallet-connect", @@ -111,6 +119,7 @@ Here’s an example of how `WalletProvider` objects are returned when both Ether #### Shared attributes All providers, regardless of chain, include: + - `interfaceType` – identifies where the provider came from: - "ethereum" → native EIP-1193 Ethereum provider (e.g., MetaMask, Rabby). - "solana" → native Wallet Standard Solana provider (e.g., Phantom, Backpack). @@ -121,11 +130,11 @@ All providers, regardless of chain, include: - `connectedAddresses` – an array of currently connected addresses (populated after the user connects). #### Namespace-specific differences + - Ethereum (`namespace: "ethereum"`) - always includes a `chainId` in `chainInfo` (e.g., "0x1" for Mainnet, "0xaa36a7" for Sepolia). - Solana (`namespace: "solana"`) - never includes a `chainId`, since Solana is a single-chain ecosystem. #### Provider-specific differences + - WalletConnect (`interfaceType: "wallet_connect"`) - includes a `uri` property used for the session handshake. - Metadata (`info`) - Native Ethereum providers may expose extra fields like `uuid` and `rdns`, while Native Solana providers usually only include a `name` and `icon`. - - diff --git a/solutions/embedded-wallets/integration-guide/swift/authentication/email-sms.mdx b/solutions/embedded-wallets/integration-guide/swift/authentication/email-sms.mdx index aba08669..3015303d 100644 --- a/solutions/embedded-wallets/integration-guide/swift/authentication/email-sms.mdx +++ b/solutions/embedded-wallets/integration-guide/swift/authentication/email-sms.mdx @@ -4,7 +4,7 @@ description: "Set up and implement email and SMS OTP authentication using the Tu sidebarTitle: "Email & SMS" --- -import { FeatureCard } from '/snippets/feature-card.mdx' +import { FeatureCard } from "/snippets/feature-card.mdx"; ## Overview @@ -151,4 +151,9 @@ Tip: You can use a library like [PhoneNumberKit](https://github.com/PhoneNumberK ## Next steps - + diff --git a/solutions/embedded-wallets/integration-guide/swift/authentication/overview.mdx b/solutions/embedded-wallets/integration-guide/swift/authentication/overview.mdx index 7376765d..60c7cf5b 100644 --- a/solutions/embedded-wallets/integration-guide/swift/authentication/overview.mdx +++ b/solutions/embedded-wallets/integration-guide/swift/authentication/overview.mdx @@ -4,14 +4,13 @@ description: "Learn how to set up, log in, or sign up in your Swift app using th sidebarTitle: "Overview" --- -import { FeatureCard } from '/snippets/feature-card.mdx' +import { FeatureCard } from "/snippets/feature-card.mdx"; ## Choose your authentication path Decide whether you'll use Turnkey's managed Auth Proxy (no backend required) or route auth through your own server. - **No backend (Auth Proxy)** - - Your app talks directly to Turnkey's Auth Proxy for OTP, OAuth, and signup. - Origin validation, CORS, session lifetimes, and templates are centrally managed in the Dashboard. - Proxy keys are HPKE-encrypted and decrypted only in-memory per request inside Turnkey's enclave. @@ -106,8 +105,29 @@ For more information, see [Sub-organization customization](/solutions/embedded-w Follow the guides below to implement Email/SMS authentication, Passkey authentication, and Social Logins in your Swift app. -
- - - +
+ + +
diff --git a/solutions/embedded-wallets/integration-guide/swift/authentication/passkey.mdx b/solutions/embedded-wallets/integration-guide/swift/authentication/passkey.mdx index 4c5f5c9c..bebca462 100644 --- a/solutions/embedded-wallets/integration-guide/swift/authentication/passkey.mdx +++ b/solutions/embedded-wallets/integration-guide/swift/authentication/passkey.mdx @@ -4,7 +4,7 @@ description: "Set up and implement passkey authentication using the Turnkey Swif sidebarTitle: "Passkeys" --- -import { FeatureCard } from '/snippets/feature-card.mdx' +import { FeatureCard } from "/snippets/feature-card.mdx"; ## Overview @@ -125,4 +125,9 @@ try await turnkey.signUpWithPasskey( ## Next steps - + diff --git a/solutions/embedded-wallets/integration-guide/swift/authentication/social-logins.mdx b/solutions/embedded-wallets/integration-guide/swift/authentication/social-logins.mdx index bbca86ed..a42119c8 100644 --- a/solutions/embedded-wallets/integration-guide/swift/authentication/social-logins.mdx +++ b/solutions/embedded-wallets/integration-guide/swift/authentication/social-logins.mdx @@ -4,7 +4,7 @@ description: "Implement Google, Apple, Discord, and X OAuth using the Turnkey Sw sidebarTitle: "Social logins" --- -import { FeatureCard } from '/snippets/feature-card.mdx' +import { FeatureCard } from "/snippets/feature-card.mdx"; ## Overview @@ -212,4 +212,9 @@ For more information, refer to the [Social Logins](/features/authentication/soci ## Next steps - + diff --git a/solutions/embedded-wallets/integration-guide/swift/overview.mdx b/solutions/embedded-wallets/integration-guide/swift/overview.mdx index a5daa075..533a142f 100644 --- a/solutions/embedded-wallets/integration-guide/swift/overview.mdx +++ b/solutions/embedded-wallets/integration-guide/swift/overview.mdx @@ -13,7 +13,13 @@ Find the Turnkey Swift SDK on [GitHub](https://github.com/tkhq/swift-sdk). For a implementation covering OTP, OAuth, passkey auth, wallet creation, message signing, and transaction sending, see [swift-sdk/Examples](https://github.com/tkhq/swift-sdk/tree/main/Examples). -
+
You can choose which auth methods to enable and customize various options from - this screen. For this quickstart, let's enable **email OTP**. - When you're done, click **Save**. + this screen. For this quickstart, let's enable **email OTP**. When you're + done, click **Save**. Auth Proxy options ## React Native setup + If you're using React Native, there's some additional setup required. You can skip this section if you're using a web framework. @@ -95,36 +96,33 @@ yarn add @react-native-async-storage/async-storage react-native-keychain @turnke If you're not using Expo, you may need to install the iOS dependencies. + ```bash npx pod-install # or cd ios && pod install ``` + `@turnkey/core` requires a polyfill to work in React Native. Install the `react-native-get-random-values` package. + -```bash npm -npm install react-native-get-random-values -``` -```bash pnpm -pnpm add react-native-get-random-values -``` -```bash yarn -yarn add react-native-get-random-values -``` + ```bash npm npm install react-native-get-random-values ``` ```bash pnpm pnpm + add react-native-get-random-values ``` ```bash yarn yarn add + react-native-get-random-values ``` -Then, import it at the top of your entry file (e.g. `index.js`, `entry.js` etc.). If you don't have this file, you'll need to create one. -```ts index.js -import 'react-native-get-random-values'; -// ... other imports +Then, import it at the top of your entry file (e.g. `index.js`, `entry.js` +etc.). If you don't have this file, you'll need to create one. ```ts index.js +import 'react-native-get-random-values'; // ... other imports // You may need this line if you're using Expo Router import 'expo-router/entry'; -``` + +```` You'll need to add this file to your `package.json` under the `main` field if it's not already there. ```json package.json @@ -132,17 +130,12 @@ You'll need to add this file to your `package.json` under the `main` field if it "main": "index.js", // May be named differently in your project // ... other fields } -``` - +```` - - - - ## Client initialization Unlike `@turnkey/react-wallet-kit`, `@turnkey/core` doesn't provide a React provider or hooks — you work directly with the TurnkeyClient. @@ -179,12 +172,10 @@ const client = new TurnkeyClient({ }); ``` -All fields are optional in web environments. +All fields are optional in web environments. On React Native, `rpId` is required. We recommend following [this guide](https://github.com/f-23/react-native-passkey?tab=readme-ov-file#configuration) to set up associated domains for iOS and Android. - - ### External browser wallets ```ts diff --git a/solutions/embedded-wallets/integration-guide/typescript/index.mdx b/solutions/embedded-wallets/integration-guide/typescript/index.mdx index 84063afd..20265fd0 100644 --- a/solutions/embedded-wallets/integration-guide/typescript/index.mdx +++ b/solutions/embedded-wallets/integration-guide/typescript/index.mdx @@ -10,11 +10,37 @@ description: sidebarTitle: "Overview" --- -import { FeatureCard } from '/snippets/feature-card.mdx' +import { FeatureCard } from "/snippets/feature-card.mdx"; -
- - - - +
+ + + +
diff --git a/solutions/embedded-wallets/integration-guide/typescript/legacy.mdx b/solutions/embedded-wallets/integration-guide/typescript/legacy.mdx index d75659cb..f7ea290b 100644 --- a/solutions/embedded-wallets/integration-guide/typescript/legacy.mdx +++ b/solutions/embedded-wallets/integration-guide/typescript/legacy.mdx @@ -3,7 +3,7 @@ title: "@turnkey/sdk-browser (legacy)" sidebarTitle: "Legacy (@turnkey/sdk-browser)" --- -import { FeatureCard } from '/snippets/feature-card.mdx' +import { FeatureCard } from "/snippets/feature-card.mdx"; `@turnkey/sdk-browser` is our legacy TypeScript SDK for building embedded wallet experiences in browser applications. @@ -305,8 +305,29 @@ const result = await turnkey.serverSign("method", [param1, param2]); ## Examples -
- - - +
+ + +
diff --git a/solutions/embedded-wallets/overview.mdx b/solutions/embedded-wallets/overview.mdx index 70bc6cd4..52f3cb1b 100644 --- a/solutions/embedded-wallets/overview.mdx +++ b/solutions/embedded-wallets/overview.mdx @@ -2,7 +2,7 @@ title: "Overview" --- -import { SolutionCard } from '/snippets/solution-card.mdx'; +import { SolutionCard } from "/snippets/solution-card.mdx"; ## What are embedded wallets? @@ -31,8 +31,9 @@ another provider or with [Turnkey Transaction Management](/features/transaction-management). - ![Embedded Wallets architecture: user/service, wallets, policy engine, authenticators, - secure enclave infrastructure](/assets/files/embedded-consumer-wallet.png) + ![Embedded Wallets architecture: user/service, wallets, policy engine, + authenticators, secure enclave + infrastructure](/assets/files/embedded-consumer-wallet.png) ### Custody models @@ -68,7 +69,13 @@ See the [Integration Guide](/solutions/embedded-wallets/integration-guide/overvi Embedded wallets serve different needs depending on who holds the wallet and how it's operated. Choose the pattern that matches what you're building. -
+
- **Building with AI?** Connect your IDE or LLM to Turnkey's docs via our [MCP server and LLM - feeds](/get-started/using-llms) for contextual help while you integrate. + **Building with AI?** Connect your IDE or LLM to Turnkey's docs via our [MCP + server and LLM feeds](/get-started/using-llms) for contextual help while you + integrate. -
- - - +
+ + +
--- @@ -31,7 +53,12 @@ The fastest way to see Turnkey embedded wallets in action. Our Wallet Kit. Use it to try out authentication flows, wallet creation, transaction signing, and more, all from your browser with no setup. - + ## Clone and customize @@ -110,19 +137,44 @@ wallet UI components, a hook-based API, and requires no backend setup. For React Native, Flutter, Swift, or Kotlin, choose the guide for your platform: - + Pre-built components with minimal configuration. - + JavaScript packages for React Native. - + Dart SDK for Flutter apps. - + Native iOS integration. - + Native Android integration. diff --git a/solutions/key-management/encryption-key-storage.mdx b/solutions/key-management/encryption-key-storage.mdx index dd291190..f726d75b 100644 --- a/solutions/key-management/encryption-key-storage.mdx +++ b/solutions/key-management/encryption-key-storage.mdx @@ -3,8 +3,8 @@ title: "Encryption Key Storage" description: "Build recovery flows with risk separation between your infrastructure and Turnkey." --- -import { FeatureCard } from '/snippets/feature-card.mdx' -import { SolutionCard } from '/snippets/solution-card.mdx' +import { FeatureCard } from "/snippets/feature-card.mdx"; +import { SolutionCard } from "/snippets/solution-card.mdx"; Store and retrieve encryption keys from Turnkey's secure enclave with policy-controlled access. Your infrastructure holds encrypted data and Turnkey holds the encryption key. Neither party alone can access plaintext. For an overview of Turnkey's key management capabilities, see the [Key Management Overview](/solutions/key-management/overview). @@ -14,31 +14,35 @@ Store and retrieve encryption keys from Turnkey's secure enclave with policy-con ## Key implementation decisions -| Decision | What to consider | Learn more | -| :--- | :--- | :--- | -| **Export controls** | Gate key export through policies. Require quorum approval, restrict which users can trigger export, or scope export to specific key IDs. | [Policy Engine](/features/policies/overview), [Root Quorum](/features/users/root-quorum) | -| **Authentication method** | Choose how users authenticate to access keys: API keys, passkeys, social logins, email, or SMS OTP. Match the method to your security and UX requirements. | [Authentication Overview](/features/authentication/overview) | -| **Encrypted data storage** | Store encrypted bundles wherever you control: client-side (localStorage, IndexedDB), mobile secure enclave, your database, or object storage (S3, GCS). Turnkey only holds the encryption key. | | +| Decision | What to consider | Learn more | +| :------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------- | +| **Export controls** | Gate key export through policies. Require quorum approval, restrict which users can trigger export, or scope export to specific key IDs. | [Policy Engine](/features/policies/overview), [Root Quorum](/features/users/root-quorum) | +| **Authentication method** | Choose how users authenticate to access keys: API keys, passkeys, social logins, email, or SMS OTP. Match the method to your security and UX requirements. | [Authentication Overview](/features/authentication/overview) | +| **Encrypted data storage** | Store encrypted bundles wherever you control: client-side (localStorage, IndexedDB), mobile secure enclave, your database, or object storage (S3, GCS). Turnkey only holds the encryption key. | | ## Example: backup and recovery A common pattern for applications: encrypt recovery bundles, store them in your infrastructure, and authenticate through Turnkey to decrypt when needed. No single party holds both the encrypted data and the decryption key. - 2-of-2 security model diagram showing encrypted data in your infrastructure and encryption key in Turnkey secure enclave + 2-of-2 security model diagram showing encrypted data in your infrastructure and encryption key in Turnkey secure enclave -| Need | How Turnkey solves it | -| :--- | :--- | -| Risk separation between platforms | Turnkey never sees the encrypted data; your infrastructure never sees the encryption key. Both must be compromised. | -| Decrypt recovery bundles without managing keys directly | Encryption key lives in the enclave; authenticate to export it on demand | -| Caller retains control | Only the caller's authenticator (passkey, email, social login) can trigger key export | -| Policy-gated access for sensitive operations | Quorum approval, scoped export policies, and audit trails for every key operation | +| Need | How Turnkey solves it | +| :------------------------------------------------------ | :------------------------------------------------------------------------------------------------------------------ | +| Risk separation between platforms | Turnkey never sees the encrypted data; your infrastructure never sees the encryption key. Both must be compromised. | +| Decrypt recovery bundles without managing keys directly | Encryption key lives in the enclave; authenticate to export it on demand | +| Caller retains control | Only the caller's authenticator (passkey, email, social login) can trigger key export | +| Policy-gated access for sensitive operations | Quorum approval, scoped export policies, and audit trails for every key operation | ### Implementation steps - Explore the complete implementation in the [GitHub encryption-key-escrow example](https://github.com/tkhq/sdk/tree/main/examples/encryption-key-escrow). + Explore the complete implementation in the [GitHub encryption-key-escrow + example](https://github.com/tkhq/sdk/tree/main/examples/encryption-key-escrow). @@ -54,6 +58,7 @@ A common pattern for applications: encrypt recovery bundles, store them in your }], }); ``` + @@ -65,6 +70,7 @@ A common pattern for applications: encrypt recovery bundles, store them in your }); const publicKey = privateKey.publicKey; ``` + @@ -77,6 +83,7 @@ A common pattern for applications: encrypt recovery bundles, store them in your // Store in YOUR infrastructure await saveToYourStorage(encryptedBundle); ``` + @@ -109,6 +116,7 @@ A common pattern for applications: encrypt recovery bundles, store them in your ``` This example requires two approvers for any export of the encryption key, adding human oversight to sensitive operations. + @@ -125,14 +133,41 @@ A common pattern for applications: encrypt recovery bundles, store them in your secureWipe(decryptionKey); secureWipe(decryptedData); ``` + ## Next steps -
- - - - +
+ + + +
diff --git a/solutions/key-management/enterprise-disaster-recovery.mdx b/solutions/key-management/enterprise-disaster-recovery.mdx index 62162f2b..e3c03985 100644 --- a/solutions/key-management/enterprise-disaster-recovery.mdx +++ b/solutions/key-management/enterprise-disaster-recovery.mdx @@ -3,19 +3,19 @@ title: "Enterprise Disaster Recovery" description: "Import and recover wallets with end-to-end encryption, quorum-controlled access, and a cryptographic audit trail." --- -import { FeatureCard } from '/snippets/feature-card.mdx' -import { SolutionCard } from '/snippets/solution-card.mdx' +import { FeatureCard } from "/snippets/feature-card.mdx"; +import { SolutionCard } from "/snippets/solution-card.mdx"; Back up wallets on Turnkey and recover them when you need to for incident response, provider migration, and redundancy. All key material is encrypted directly to Turnkey's secure enclave using [HPKE](/security/enclave-secure-channels), and every recovery operation is cryptographically stamped. For an overview of Turnkey's key management capabilities, see the [Key Management Overview](/solutions/key-management/overview). ## Key implementation decisions -| Decision | What to consider | Learn more | -| :--- | :--- | :--- | -| **Organization setup** | Create dedicated recovery users with limited permissions. Distribute authenticators (passkeys, YubiKeys) across geographic locations where possible. | [Organizations](/features/organizations) | -| **Root quorum** | Require multiple approvers for sensitive operations to prevent any single credential compromise from triggering unauthorized recovery. | [Root Quorum](/features/users/root-quorum) | -| **Recovery policies** | Restrict what can be done with recovered wallets: limit fund movement to allowed addresses, require multi-party approval, scope signing by chain or value. | [Policy Engine](/features/policies/overview), [Signing Control](/features/policies/examples/signing-control) | -| **Import method** | Use the NodeJS server SDK for the full import flow including encryption and secure transport, or the React Wallet Kit for client-side import. | [Import Wallets](/features/wallets/import-wallets), [SDK Server](https://github.com/tkhq/sdk/tree/main/examples/import-in-node) | +| Decision | What to consider | Learn more | +| :--------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------ | +| **Organization setup** | Create dedicated recovery users with limited permissions. Distribute authenticators (passkeys, YubiKeys) across geographic locations where possible. | [Organizations](/features/organizations) | +| **Root quorum** | Require multiple approvers for sensitive operations to prevent any single credential compromise from triggering unauthorized recovery. | [Root Quorum](/features/users/root-quorum) | +| **Recovery policies** | Restrict what can be done with recovered wallets: limit fund movement to allowed addresses, require multi-party approval, scope signing by chain or value. | [Policy Engine](/features/policies/overview), [Signing Control](/features/policies/examples/signing-control) | +| **Import method** | Use the NodeJS server SDK for the full import flow including encryption and secure transport, or the React Wallet Kit for client-side import. | [Import Wallets](/features/wallets/import-wallets), [SDK Server](https://github.com/tkhq/sdk/tree/main/examples/import-in-node) | ## Example: treasury recovery @@ -28,18 +28,19 @@ Import wallet keys into Turnkey's secure enclave ahead of time. If a key holder /> -| Need | How Turnkey solves it | -| :--- | :--- | -| Import keys with no plaintext exposure in transit | All key material is encrypted directly to the enclave using [HPKE](/security/enclave-secure-channels). Plaintext never exists outside the enclave boundary. | -| No single person can unilaterally move recovered funds | [Quorum approval](/features/users/root-quorum) requires multiple approvers for sensitive operations | -| Restrict what can be done with recovered wallets | [Policies](/features/policies/overview) scope fund movement to allowed addresses, chains, and value thresholds | -| Cryptographic audit trail | Every recovery operation is cryptographically stamped, ensuring recoveries cannot be tampered with | -| Secondary signing path must always be available | Import backup copies of critical wallet keys so operations continue if a primary signer goes down | +| Need | How Turnkey solves it | +| :----------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Import keys with no plaintext exposure in transit | All key material is encrypted directly to the enclave using [HPKE](/security/enclave-secure-channels). Plaintext never exists outside the enclave boundary. | +| No single person can unilaterally move recovered funds | [Quorum approval](/features/users/root-quorum) requires multiple approvers for sensitive operations | +| Restrict what can be done with recovered wallets | [Policies](/features/policies/overview) scope fund movement to allowed addresses, chains, and value thresholds | +| Cryptographic audit trail | Every recovery operation is cryptographically stamped, ensuring recoveries cannot be tampered with | +| Secondary signing path must always be available | Import backup copies of critical wallet keys so operations continue if a primary signer goes down | ### Implementation steps - Explore the complete implementation in the [GitHub disaster-recovery example](https://github.com/tkhq/sdk/tree/main/examples/disaster-recovery). + Explore the complete implementation in the [GitHub disaster-recovery + example](https://github.com/tkhq/sdk/tree/main/examples/disaster-recovery). @@ -50,6 +51,7 @@ Import wallet keys into Turnkey's secure enclave ahead of time. If a key holder - Configure the [Root Quorum](/features/users/root-quorum) to require multiple approvers for sensitive operations - Distribute authenticators ([passkeys](/features/authentication/passkeys/introduction), YubiKeys) across geographic locations - Define [policies](/features/policies/examples/signing-control) that restrict what can be done with recovered wallets + @@ -70,6 +72,7 @@ Import wallet keys into Turnkey's secure enclave ahead of time. If a key holder organizationId, }); ``` + @@ -83,14 +86,41 @@ Import wallet keys into Turnkey's secure enclave ahead of time. If a key holder accounts: [], }); ``` + ## Next steps -
- - - - +
+ + + +
diff --git a/solutions/key-management/overview.mdx b/solutions/key-management/overview.mdx index f8ecba93..5c44c120 100644 --- a/solutions/key-management/overview.mdx +++ b/solutions/key-management/overview.mdx @@ -2,7 +2,7 @@ title: "Overview" --- -import { SolutionCard } from '/snippets/solution-card.mdx'; +import { SolutionCard } from "/snippets/solution-card.mdx"; ## What is key management? @@ -55,7 +55,13 @@ The [Turnkey Dashboard](https://app.turnkey.com) provides an interface for manag Key management serves different needs depending on how your application uses cryptographic keys. Choose the pattern that matches your requirements. -
+
+
+
+

- Turnkey is infrastructure for generating wallets and keys, signing transactions, and - controlling who can use them, when, and how. Private keys are secured in hardware-isolated - enclaves and never exposed — not even to Turnkey. + Turnkey is infrastructure for generating wallets and keys, signing + transactions, and controlling who can use them, when, and how. Private + keys are secured in hardware-isolated enclaves and never exposed — not + even to Turnkey.

{ if (typeof window !== "undefined") { document.dispatchEvent( - new KeyboardEvent("keydown", { key: "k", metaKey: true, bubbles: true }), + new KeyboardEvent("keydown", { + key: "k", + metaKey: true, + bubbles: true, + }), ); } }} @@ -80,9 +85,10 @@ mode: "custom"

Build with Turnkey

- Build at whichever level best meets your needs. Start with Solutions for common patterns, go - deeper with our SDKs for more control, or reach all the way down to the API for complete - flexibility. The full stack is always available. + Build at whichever level best meets your needs. Start with Solutions for + common patterns, go deeper with our SDKs for more control, or reach all + the way down to the API for complete flexibility. The full stack is always + available.

@@ -207,25 +213,41 @@ mode: "custom"
- Embedded Wallets + Embedded Wallets
- + Embedded Wallets

- Build wallets directly into your app. Users authenticate with email, passkeys, or social login. - You control the experience. + Build wallets directly into your app. Users authenticate with email, + passkeys, or social login. You control the experience.

@@ -233,25 +255,38 @@ mode: "custom"
- Company Wallets + Company Wallets
Company Wallets

- Automate your onchain operations with wallets, keys and programmable controls purpose built for - scale. + Automate your onchain operations with wallets, keys and programmable + controls purpose built for scale.

@@ -259,19 +294,26 @@ mode: "custom"
- Key Management + Key Management
Key Management

- Enterprise-grade security for your most sensitive keys — hardware-backed with programmable - access controls. + Enterprise-grade security for your most sensitive keys — hardware-backed + with programmable access controls.