From b0051606a18147a40b46060c8229d02ee165c6e3 Mon Sep 17 00:00:00 2001 From: Amir Cheikh Date: Fri, 6 Jun 2025 15:57:37 -0400 Subject: [PATCH 001/184] Init. Swap stampers by passing in enum --- examples/with-sdk-js/.env.local.example | 4 + examples/with-sdk-js/.eslintrc.json | 3 + examples/with-sdk-js/.gitignore | 35 + examples/with-sdk-js/README.md | 104 + examples/with-sdk-js/img/demo.png | Bin 0 -> 28500 bytes examples/with-sdk-js/next.config.js | 4 + examples/with-sdk-js/package.json | 44 + examples/with-sdk-js/public/favicon.svg | 10 + .../public/fonts/inter/Inter-Bold.woff2 | Bin 0 -> 106140 bytes .../public/fonts/inter/Inter-Regular.woff2 | Bin 0 -> 98868 bytes .../public/fonts/inter/Inter-SemiBold.woff2 | Bin 0 -> 105804 bytes examples/with-sdk-js/public/logo.svg | 29 + examples/with-sdk-js/src/app/index.module.css | 86 + examples/with-sdk-js/src/app/layout.tsx | 29 + examples/with-sdk-js/src/app/page.tsx | 85 + examples/with-sdk-js/tsconfig.json | 29 + packages/sdk-js/package.json | 47 + packages/sdk-js/rollup.config.mjs | 3 + packages/sdk-js/scripts/codegen.js | 550 + packages/sdk-js/src/__clients__/core.ts | 41 + .../src/__generated__/sdk-client-base.ts | 2501 +++++ .../sdk-js/src/__generated__/sdk_api_types.ts | 511 + packages/sdk-js/src/__generated__/version.ts | 1 + .../src/__inputs__/public_api.swagger.json | 9880 +++++++++++++++++ .../sdk-js/src/__inputs__/public_api.types.ts | 4714 ++++++++ packages/sdk-js/src/__polyfills__/window.ts | 25 + packages/sdk-js/src/__types__/base.ts | 167 + packages/sdk-js/src/index.ts | 105 + packages/sdk-js/src/storage.ts | 75 + packages/sdk-js/src/utils.ts | 141 + packages/sdk-js/tsconfig.json | 25 + pnpm-lock.yaml | 126 +- 32 files changed, 19372 insertions(+), 2 deletions(-) create mode 100644 examples/with-sdk-js/.env.local.example create mode 100644 examples/with-sdk-js/.eslintrc.json create mode 100644 examples/with-sdk-js/.gitignore create mode 100644 examples/with-sdk-js/README.md create mode 100644 examples/with-sdk-js/img/demo.png create mode 100644 examples/with-sdk-js/next.config.js create mode 100644 examples/with-sdk-js/package.json create mode 100644 examples/with-sdk-js/public/favicon.svg create mode 100644 examples/with-sdk-js/public/fonts/inter/Inter-Bold.woff2 create mode 100644 examples/with-sdk-js/public/fonts/inter/Inter-Regular.woff2 create mode 100644 examples/with-sdk-js/public/fonts/inter/Inter-SemiBold.woff2 create mode 100644 examples/with-sdk-js/public/logo.svg create mode 100644 examples/with-sdk-js/src/app/index.module.css create mode 100644 examples/with-sdk-js/src/app/layout.tsx create mode 100644 examples/with-sdk-js/src/app/page.tsx create mode 100644 examples/with-sdk-js/tsconfig.json create mode 100644 packages/sdk-js/package.json create mode 100644 packages/sdk-js/rollup.config.mjs create mode 100644 packages/sdk-js/scripts/codegen.js create mode 100644 packages/sdk-js/src/__clients__/core.ts create mode 100644 packages/sdk-js/src/__generated__/sdk-client-base.ts create mode 100644 packages/sdk-js/src/__generated__/sdk_api_types.ts create mode 100644 packages/sdk-js/src/__generated__/version.ts create mode 100644 packages/sdk-js/src/__inputs__/public_api.swagger.json create mode 100644 packages/sdk-js/src/__inputs__/public_api.types.ts create mode 100644 packages/sdk-js/src/__polyfills__/window.ts create mode 100644 packages/sdk-js/src/__types__/base.ts create mode 100644 packages/sdk-js/src/index.ts create mode 100644 packages/sdk-js/src/storage.ts create mode 100644 packages/sdk-js/src/utils.ts create mode 100644 packages/sdk-js/tsconfig.json diff --git a/examples/with-sdk-js/.env.local.example b/examples/with-sdk-js/.env.local.example new file mode 100644 index 000000000..0a0c162bd --- /dev/null +++ b/examples/with-sdk-js/.env.local.example @@ -0,0 +1,4 @@ +TURNKEY_API_PUBLIC_KEY="" +TURNKEY_API_PRIVATE_KEY="" +NEXT_PUBLIC_BASE_URL="https://api.turnkey.com" +NEXT_PUBLIC_ORGANIZATION_ID="" \ No newline at end of file diff --git a/examples/with-sdk-js/.eslintrc.json b/examples/with-sdk-js/.eslintrc.json new file mode 100644 index 000000000..bffb357a7 --- /dev/null +++ b/examples/with-sdk-js/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": "next/core-web-vitals" +} diff --git a/examples/with-sdk-js/.gitignore b/examples/with-sdk-js/.gitignore new file mode 100644 index 000000000..8f322f0d8 --- /dev/null +++ b/examples/with-sdk-js/.gitignore @@ -0,0 +1,35 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env*.local + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/examples/with-sdk-js/README.md b/examples/with-sdk-js/README.md new file mode 100644 index 000000000..5dfa874a8 --- /dev/null +++ b/examples/with-sdk-js/README.md @@ -0,0 +1,104 @@ +# Example: `with-indexed-db` + +This example demonstrates how to create a sub-organization, authenticate with a passkey, and persist the session using **unextractable IndexedDB storage**. This provides a secure, user-friendly authentication flow ideal for modern web apps. + +
+ +
+ +## πŸ”§ Features + +- Create and authenticate into a Turnkey sub-organization +- Store session securely using unextractable P-256 keys in IndexedDB +- Leverages `@turnkey/sdk-react` and `TurnkeyProvider` for seamless integration + +--- + +## 🏁 Getting Started + +### 1. Clone the repo + +Make sure you have Node v18+ installed. + +```bash +git clone https://github.com/tkhq/sdk +cd sdk/ +corepack enable # Install pnpm if needed +pnpm install -r # Install dependencies +pnpm run build-all # Compile the source +cd examples/with-indexed-db/ +``` + +### 2. Set up Turnkey + +Before running the app, follow the [Turnkey Quickstart](https://docs.turnkey.com/getting-started/quickstart) to: + +- Create an organization +- Generate a P-256 API key pair +- Note your organization ID + +Then: + +```bash +cp .env.local.example .env.local +``` + +Edit `.env.local` and fill in the following: + +```env +API_PUBLIC_KEY= +API_PRIVATE_KEY= # DO NOT commit this +NEXT_PUBLIC_BASE_URL=https://api.turnkey.com +NEXT_PUBLIC_ORGANIZATION_ID= +NEXT_PUBLIC_RPID=localhost +``` + +> **Note:** Your private key is used only in development and must be handled securely. Do not expose it in production builds. + +--- + +### 3. Run the example app + +```bash +pnpm run dev +``` + +Visit [http://localhost:3000](http://localhost:3000) to see the demo in action. + +--- + +## πŸ“ Project Structure + +- `app/layout.tsx` – Wraps the app in a `TurnkeyProvider` using env-based config. +- `app/page.tsx` – Implements the IndexedDB-based passkey login and session creation. +- `components/` – Includes reusable form elements and session status UI. + +--- + +## βœ… Why IndexedDB? + +This demo migrates away from iframe-based stamping in favor of IndexedDB for stronger UX and DevEx. Benefits include: + +- Persistent, unextractable key storage +- No need for third-party iframe domains +- Seamless integration with modern browsers + +--- + +## πŸ›‘οΈ Security Note + +This example is meant for development and demo purposes. In production: + +- Never expose private keys to the browser +- Use a backend proxy to handle sensitive API operations +- Ensure HTTPS is used in all environments + +--- + +## πŸ“š Learn More + +- [Turnkey Docs](https://docs.turnkey.com/) +- [Turnkey GitHub](https://github.com/tkhq/sdk) +- [Web Cryptography API: IndexedDB Storage](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey#storing_cryptokeys) + +--- diff --git a/examples/with-sdk-js/img/demo.png b/examples/with-sdk-js/img/demo.png new file mode 100644 index 0000000000000000000000000000000000000000..1ef9ea4a2662ea16174f6ef83cd28cc63e9e7647 GIT binary patch literal 28500 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 + + + + + + + + + diff --git a/examples/with-sdk-js/public/fonts/inter/Inter-Bold.woff2 b/examples/with-sdk-js/public/fonts/inter/Inter-Bold.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..2846f29cc8af8cef50f51381940bac8845c38f59 GIT binary patch literal 106140 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
)V`qXZDL!rw2D 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

B1ttL7O_Gw{HhNLeIl%?EWPJgN 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 literal 0 HcmV?d00001 diff --git a/examples/with-sdk-js/public/fonts/inter/Inter-Regular.woff2 b/examples/with-sdk-js/public/fonts/inter/Inter-Regular.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..6c2b6893d593201d7c94e52687f78b2ef28b357e GIT binary patch literal 98868 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%0D(-D;tD2U3Vy$! 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 literal 0 HcmV?d00001 diff --git a/examples/with-sdk-js/public/fonts/inter/Inter-SemiBold.woff2 b/examples/with-sdk-js/public/fonts/inter/Inter-SemiBold.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..611e90c958f1b784ada6be1c603b923d57ca88b9 GIT binary patch literal 105804 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 `>0IwGJyHK~ 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 z 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ⅇ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 + + + + + + + + + + + diff --git a/examples/with-sdk-js/src/app/index.module.css b/examples/with-sdk-js/src/app/index.module.css new file mode 100644 index 000000000..9e52fa65f --- /dev/null +++ b/examples/with-sdk-js/src/app/index.module.css @@ -0,0 +1,86 @@ +@font-face { + font-family: "Inter"; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url("../../public/fonts/inter/Inter-Regular.woff2?v=3.19") + format("woff2"); +} + +@font-face { + font-family: "Inter"; + font-style: normal; + font-weight: 600; + font-display: swap; + src: url("../../public/fonts/inter/Inter-SemiBold.woff2?v=3.19") + format("woff2"); +} + +.main { + display: flex; + flex-direction: column; + justify-content: space-between; + align-items: center; + padding: 6rem; + gap: 60px; +} + +.input { + display: block; + width: 240px; + margin: 0; + padding: 10px 16px; + border-radius: 8px; + border-width: 1px; + border-style: solid; + border-color: rgba(216, 219, 227, 1); + font-family: "Inter"; + margin: 0 auto; +} + +.input_checkbox { + display: block; + margin: 0 auto; +} + +.label { + font-family: "Inter"; + display: block; + text-align: center; +} + +.prompt { + font-family: "Inter"; +} + +.base { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} + +.button { + display: inline-flex; + align-items: center; + justify-content: center; + margin: 0; + padding: 10px 16px; + border-radius: 8px; + border-width: 1px; + border-style: solid; + cursor: pointer; + color: white; + background-color: rgba(43, 47, 51, 1); + border-color: rgba(63, 70, 75, 1); + font-family: "Inter"; +} + +.form { + display: flex; + flex-direction: column; + justify-content: space-between; + align-items: center; + gap: 20px; + min-width: 400px; +} diff --git a/examples/with-sdk-js/src/app/layout.tsx b/examples/with-sdk-js/src/app/layout.tsx new file mode 100644 index 000000000..c77d1584d --- /dev/null +++ b/examples/with-sdk-js/src/app/layout.tsx @@ -0,0 +1,29 @@ +"use client"; + +import { TurnkeyProvider } from "@turnkey/sdk-react"; + +const turnkeyConfig = { + apiBaseUrl: process.env.NEXT_PUBLIC_BASE_URL!, + defaultOrganizationId: process.env.NEXT_PUBLIC_ORGANIZATION_ID!, + rpId: process.env.NEXT_PUBLIC_RPID!, +}; + +interface RootLayoutProps { + children: React.ReactNode; +} + +function RootLayout({ children }: RootLayoutProps) { + return ( + + + A monumental leap + + + + {children} + + + ); +} + +export default RootLayout; diff --git a/examples/with-sdk-js/src/app/page.tsx b/examples/with-sdk-js/src/app/page.tsx new file mode 100644 index 000000000..cde31302f --- /dev/null +++ b/examples/with-sdk-js/src/app/page.tsx @@ -0,0 +1,85 @@ +"use client"; + +import Image from "next/image"; +import styles from "./index.module.css"; +import { StamperType, TurnkeyClient } from "@turnkey/sdk-js"; + +import { server } from "@turnkey/sdk-server"; +import { useEffect, useState } from "react"; + +export default function AuthPage() { + const [client, setClient] = useState(null); + + useEffect(() => { + const initializeClient = async () => { + const turnkeyClient = new TurnkeyClient({ + apiBaseUrl: process.env.NEXT_PUBLIC_BASE_URL!, + organizationId: process.env.NEXT_PUBLIC_ORGANIZATION_ID!, + passkeyConfig: { + rpId: process.env.NEXT_PUBLIC_RPID!, + timeout: 60000, // 60 seconds + userVerification: "preferred", + allowCredentials: [], + }, + }); + + await turnkeyClient.indexedDBStamper?.init(); + setClient(turnkeyClient); + }; + + initializeClient(); + }, []); + + const passkey = async () => { + const resp = await client?.httpClient.getWhoami({}, StamperType.Passkey); + console.log("Response from getWhoami:", resp); + }; + + const indexedDB = async () => { + const resp = await client?.httpClient.getWhoami({}); + console.log("Response from getWhoami:", resp); + }; + + return ( +

+ + Turnkey Logo + + + + + +
+ ); +} diff --git a/examples/with-sdk-js/tsconfig.json b/examples/with-sdk-js/tsconfig.json new file mode 100644 index 000000000..06f3d9aad --- /dev/null +++ b/examples/with-sdk-js/tsconfig.json @@ -0,0 +1,29 @@ +{ + "compilerOptions": { + "target": "es5", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true, + "plugins": [ + { + "name": "next" + } + ], + "paths": { + "@/*": ["./src/*"], + "react": ["./node_modules/@types/react"] + } + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], + "exclude": ["node_modules"] +} diff --git a/packages/sdk-js/package.json b/packages/sdk-js/package.json new file mode 100644 index 000000000..59310a2cb --- /dev/null +++ b/packages/sdk-js/package.json @@ -0,0 +1,47 @@ +{ + "name": "@turnkey/sdk-js", + "version": "0.1.0", + "description": "Work in progress masterpiece", + "main": "./dist/index.js", + "module": "./dist/index.mjs", + "types": "dist/index.d.ts", + "files": [ + "dist", + "README.md" + ], + "scripts": { + "version": "node -p \"'export const VERSION = ' + JSON.stringify(require('./package.json').name + '@' + require('./package.json').version) + ';'\" > src/__generated__/version.ts", + "build": "rollup -c", + "clean": "rimraf ./dist ./.cache", + "typecheck": "tsc -p tsconfig.typecheck.json", + "prepublishOnly": "pnpm run clean && pnpm run build" + }, + "keywords": [ + "turnkey" + ], + "license": "MIT", + "dependencies": { + "@turnkey/api-key-stamper": "workspace:*", + "@turnkey/crypto": "workspace:*", + "@turnkey/encoding": "workspace:*", + "@turnkey/http": "workspace:*", + "@turnkey/wallet-stamper": "workspace:*", + "@turnkey/webauthn-stamper": "workspace:*", + "@turnkey/indexed-db-stamper": "workspace:*", + "@turnkey/sdk-types": "workspace:*", + "bs58check": "3.0.1", + "buffer": "^6.0.3", + "cross-fetch": "^3.1.5", + "hpke-js": "^1.2.7" + }, + "devDependencies": { + "glob": "^8.0.3", + "typescript": "5.4.3" + }, + "engines": { + "node": ">=18.0.0" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/packages/sdk-js/rollup.config.mjs b/packages/sdk-js/rollup.config.mjs new file mode 100644 index 000000000..23fa423e6 --- /dev/null +++ b/packages/sdk-js/rollup.config.mjs @@ -0,0 +1,3 @@ +import rollup from "../../rollup.config.base.mjs"; + +export default (options) => rollup(); diff --git a/packages/sdk-js/scripts/codegen.js b/packages/sdk-js/scripts/codegen.js new file mode 100644 index 000000000..224d62f38 --- /dev/null +++ b/packages/sdk-js/scripts/codegen.js @@ -0,0 +1,550 @@ +const fs = require("fs"); +const path = require("path"); + +const SOURCE_DIRECTORY = path.resolve(__dirname, "../src"); +const PUBLIC_API_SWAGGER_PATH = path.resolve( + `${SOURCE_DIRECTORY}/__inputs__`, + "public_api.swagger.json", +); +const TARGET_API_TYPES_PATH = path.resolve( + `${SOURCE_DIRECTORY}/__generated__`, + "sdk_api_types.ts", +); +const TARGET_SDK_CLIENT_PATH = path.resolve( + `${SOURCE_DIRECTORY}/__generated__`, + "sdk-client-base.ts", +); + +const COMMENT_HEADER = "/* @generated by codegen. DO NOT EDIT BY HAND */"; + +const VERSIONED_ACTIVITY_TYPES = { + ACTIVITY_TYPE_CREATE_AUTHENTICATORS: "ACTIVITY_TYPE_CREATE_AUTHENTICATORS_V2", + ACTIVITY_TYPE_CREATE_API_KEYS: "ACTIVITY_TYPE_CREATE_API_KEYS_V2", + ACTIVITY_TYPE_CREATE_POLICY: "ACTIVITY_TYPE_CREATE_POLICY_V3", + ACTIVITY_TYPE_CREATE_PRIVATE_KEYS: "ACTIVITY_TYPE_CREATE_PRIVATE_KEYS_V2", + ACTIVITY_TYPE_CREATE_SUB_ORGANIZATION: + "ACTIVITY_TYPE_CREATE_SUB_ORGANIZATION_V7", + ACTIVITY_TYPE_CREATE_USERS: "ACTIVITY_TYPE_CREATE_USERS_V3", + ACTIVITY_TYPE_SIGN_RAW_PAYLOAD: "ACTIVITY_TYPE_SIGN_RAW_PAYLOAD_V2", + ACTIVITY_TYPE_SIGN_TRANSACTION: "ACTIVITY_TYPE_SIGN_TRANSACTION_V2", + ACTIVITY_TYPE_EMAIL_AUTH: "ACTIVITY_TYPE_EMAIL_AUTH_V2", + ACTIVITY_TYPE_CREATE_READ_WRITE_SESSION: + "ACTIVITY_TYPE_CREATE_READ_WRITE_SESSION_V2", + ACTIVITY_TYPE_UPDATE_POLICY: "ACTIVITY_TYPE_UPDATE_POLICY_V2", + ACTIVITY_TYPE_INIT_OTP_AUTH: "ACTIVITY_TYPE_INIT_OTP_AUTH_V2", +}; + +const METHODS_WITH_ONLY_OPTIONAL_PARAMETERS = [ + "getActivities", + "getApiKeys", + "getOrganization", + "getPolicies", + "getPrivateKeys", + "getSubOrgIds", + "getUsers", + "getWallets", + "getWhoami", + "listPrivateKeys", + "listUserTags", +]; + +// Helper Functions +/** + * @param {Array} input + * @returns {string} + */ +function joinPropertyList(input) { + return input.filter(Boolean).join(",\n"); +} + +/** + * @param {string} methodName + * @returns {string} + */ +function methodTypeFromMethodName(methodName) { + if (["approveActivity", "rejectActivity"].includes(methodName)) { + return "activityDecision"; + } + if (methodName.startsWith("nOOP")) { + return "noop"; + } + // TODO: filter out unnecessary client methods, whether here or from the source + if ( + methodName.startsWith("get") || + methodName.startsWith("list") || + methodName.startsWith("test") + ) { + return "query"; + } + // Rename to submit? + return "command"; +} + +// Helper that takes in swagger definitions and returns a map containing the latest version of a field. +// The intent is to consolidate a field with multiple versions (e.g. v1CreateSubOrganizationResult, v1CreateSubOrganizationResultV2...) +// in order to get just the latest (v1CreateSubOrganizationResultV4). +function extractLatestVersions(definitions) { + const latestVersions = {}; + + // Regex to separate the version prefix, base activity details, and (optional) activity version + const keyVersionRegex = /^(v\d+)([A-Z][a-z]+(?:[A-Z][a-z]+)*)(V\d+)?$/; + + Object.keys(definitions).forEach((key) => { + const match = key.match(keyVersionRegex); + if (match) { + const fullName = match[0]; + const baseName = match[2]; // Field without any version-related prefixes or suffixes + const versionSuffix = match[3]; // Version (optional) + const formattedKeyName = + baseName.charAt(0).toLowerCase() + + baseName.slice(1) + + (versionSuffix || ""); // Reconstruct the original key with version + + // Determine if this version is newer or if no version was previously stored + if ( + !latestVersions[baseName] || + versionSuffix > (latestVersions[baseName].versionSuffix || "") + ) { + latestVersions[baseName] = { + fullName, + formattedKeyName, + versionSuffix, + }; + } + } + }); + + return latestVersions; +} + +// Generators +const generateApiTypesFromSwagger = async (swaggerSpec, targetPath) => { + const namespace = swaggerSpec.tags?.find((item) => item.name != null)?.name; + + /** @type {Array} */ + const codeBuffer = []; + + /** @type {Array} */ + const imports = []; + + imports.push( + 'import type { operations, definitions } from "../__inputs__/public_api.types";', + ); + + imports.push( + 'import type { queryOverrideParams, commandOverrideParams } from "../__types__/base";', + ); + + const latestVersions = extractLatestVersions(swaggerSpec.definitions); + + for (const endpointPath in swaggerSpec.paths) { + const methodMap = swaggerSpec.paths[endpointPath]; + const operation = methodMap.post; + const operationId = operation.operationId; + + const operationNameWithoutNamespace = operationId.replace( + new RegExp(`${namespace}_`), + "", + ); + + const methodName = `${ + operationNameWithoutNamespace.charAt(0).toLowerCase() + + operationNameWithoutNamespace.slice(1) + }`; + + const methodType = methodTypeFromMethodName(methodName); + + const parameterList = operation["parameters"] ?? []; + + let responseValue = "void"; + if (methodType === "command") { + const resultKey = operationNameWithoutNamespace + "Result"; + const versionedMethodName = latestVersions[resultKey].formattedKeyName; + + responseValue = `operations["${operationId}"]["responses"]["200"]["schema"]["activity"]["result"]["${versionedMethodName}"] & definitions["v1ActivityResponse"]`; + } else if (["noop", "query"].includes(methodType)) { + responseValue = `operations["${operationId}"]["responses"]["200"]["schema"]`; + } else if (methodType === "activityDecision") { + responseValue = `operations["${operationId}"]["responses"]["200"]["schema"]["activity"]["result"] & definitions["v1ActivityResponse"]`; + } + + /** @type {TBinding} */ + const responseTypeBinding = { + name: `T${operationNameWithoutNamespace}Response`, + isBound: true, + value: operation.responses["200"] == null ? `void` : responseValue, + }; + + let bodyValue = "{}"; + if (["activityDecision", "command"].includes(methodType)) { + bodyValue = `operations["${operationId}"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams`; + } else if (methodType === "query") { + bodyValue = `Omit & queryOverrideParams`; + } + + /** @type {TBinding} */ + const bodyTypeBinding = { + name: `T${operationNameWithoutNamespace}Body`, + isBound: parameterList.find((item) => item.in === "body") != null, + value: bodyValue, + }; + + // What are these used for? + /** @type {TBinding} */ + const queryTypeBinding = { + name: `T${operationNameWithoutNamespace}Query`, + isBound: parameterList.find((item) => item.in === "query") != null, + value: `operations["${operationId}"]["parameters"]["query"]`, + }; + + /** @type {TBinding} */ + const substitutionTypeBinding = { + name: `T${operationNameWithoutNamespace}Substitution`, + isBound: parameterList.find((item) => item.in === "path") != null, + value: `operations["${operationId}"]["parameters"]["path"]`, + }; + + /** @type {TBinding} */ + const inputTypeBinding = { + name: `T${operationNameWithoutNamespace}Input`, + isBound: + bodyTypeBinding.isBound || + queryTypeBinding.isBound || + substitutionTypeBinding.isBound, + value: `{ ${joinPropertyList([ + bodyTypeBinding.isBound ? `body: ${bodyTypeBinding.name}` : null, + queryTypeBinding.isBound ? `query: ${queryTypeBinding.name}` : null, + substitutionTypeBinding.isBound + ? `substitution: ${substitutionTypeBinding.name}` + : null, + ])} }`, + }; + + // local type aliases + codeBuffer.push( + ...[queryTypeBinding, substitutionTypeBinding] + .filter((binding) => binding.isBound) + .map((binding) => `type ${binding.name} = ${binding.value};`), + ); + + // exported type aliases + codeBuffer.push( + ...[responseTypeBinding, inputTypeBinding, bodyTypeBinding] + .filter((binding) => binding.isBound) + .map((binding) => `export type ${binding.name} = ${binding.value};`), + ); + } + + await fs.promises.writeFile( + targetPath, + [COMMENT_HEADER].concat(imports).concat(codeBuffer).join("\n\n"), + ); +}; + +const generateSDKClientFromSwagger = async (swaggerSpec, targetPath) => { + const namespace = swaggerSpec.tags?.find((item) => item.name != null)?.name; + + /** @type {Array} */ + const codeBuffer = []; + + /** @type {Array} */ + const imports = []; + + imports.push( + 'import { TERMINAL_ACTIVITY_STATUSES, TActivityResponse, TActivityStatus, TSignedRequest } from "@turnkey/http";', + ); + + imports.push( + 'import type { definitions } from "../__inputs__/public_api.types";', + ); + + imports.push( + 'import { GrpcStatus, TStamper, TurnkeyRequestError, TurnkeySDKClientConfig } from "../__types__/base";', + ); + + imports.push('import { VERSION } from "../__generated__/version";'); + + imports.push('import type * as SdkApiTypes from "./sdk_api_types";'); + + imports.push('import { StorageKeys, getStorageValue } from "../storage";'); + imports.push('import { parseSession } from "../utils";'); + + imports.push('import { StamperType } from "../__types__/base";'); + + codeBuffer.push(` + export class TurnkeySDKClientBase { + config: TurnkeySDKClientConfig; + + // Current active stamper + stamper?: TStamper | undefined; + + // Store stampers + private indexedDBStamper?: TStamper | undefined; + private passkeyStamper?: TStamper | undefined; + + constructor(config: TurnkeySDKClientConfig) { + this.config = config; + if (config.stamper) { + this.stamper = config.stamper; + // Store as default IndexedDB stamper + this.indexedDBStamper = config.stamper; + } + if (config.passkeyStamper) { + this.passkeyStamper = config.passkeyStamper; + } + } + + private getStamper(stampWith?: StamperType): TStamper | undefined { + if (!stampWith) return this.stamper; + + switch (stampWith) { + case StamperType.IndexedDB: + return this.indexedDBStamper; + case StamperType.Passkey: + return this.passkeyStamper; + default: + return this.stamper; + } + } + + async request( + url: string, + body: TBodyType, + stampWith?: StamperType + ): Promise { + const fullUrl = this.config.apiBaseUrl + url; + const stringifiedBody = JSON.stringify(body); + var headers: Record = { + "X-Client-Version": VERSION + } + + // Use the specified stamper for this request + const activeStamper = this.getStamper(stampWith); + + if (activeStamper) { + const stamp = await activeStamper.stamp(stringifiedBody); + headers[stamp.stampHeaderName] = stamp.stampHeaderValue + } + + if (this.config.readOnlySession){ + headers["X-Session"] = this.config.readOnlySession + } + + const response = await fetch(fullUrl, { + method: "POST", + headers: headers, + body: stringifiedBody, + redirect: "follow" + }); + + if (!response.ok) { + let res: GrpcStatus; + try { + res = await response.json(); + } catch (_) { + throw new Error(\`\${response.status} \${response.statusText}\`); + } + + throw new TurnkeyRequestError(res); + } + + const data = await response.json(); + return data as TResponseType; + } + + async command( + url: string, + body: TBodyType, + resultKey: string, + stampWith?: StamperType + ): Promise { + const pollingDuration = this.config.activityPoller?.intervalMs ?? 1000; + const maxRetries = this.config.activityPoller?.numRetries ?? 3; + + const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms)); + + const handleResponse = (activityData: TActivityResponse): TResponseType => { + const { result, status } = activityData.activity; + + if (status === "ACTIVITY_STATUS_COMPLETED") { + return { + ...result[\`\${resultKey}\` as keyof definitions["v1Result"]], + ...activityData + } as TResponseType; + } + + return activityData as TResponseType; + }; + + let attempts = 0; + + const pollStatus = async (activityId: string): Promise => { + const pollBody = { activityId }; + // Pass the stampWith parameter to getActivity + const pollData = await this.getActivity(pollBody, stampWith) as TActivityResponse; + + if (attempts > maxRetries) { + return handleResponse(pollData); + } + + attempts += 1; + + if (!TERMINAL_ACTIVITY_STATUSES.includes(pollData.activity.status as TActivityStatus)) { + await sleep(pollingDuration); + return pollStatus(activityId); + } + + return handleResponse(pollData); + }; + + // Use the specified stamper for the initial request + const responseData = await this.request(url, body, stampWith) as TActivityResponse; + + if (!TERMINAL_ACTIVITY_STATUSES.includes(responseData.activity.status as TActivityStatus)) { + return pollStatus(responseData.activity.id); + } + + return handleResponse(responseData); + } + + async activityDecision( + url: string, + body: TBodyType, + stampWith?: StamperType + ): Promise { + // Use the specified stamper for this request + const activityData = await this.request(url, body, stampWith) as TActivityResponse; + + return { + ...activityData["activity"]["result"], + ...activityData + } as TResponseType; + }`); + const latestVersions = extractLatestVersions(swaggerSpec.definitions); + + for (const endpointPath in swaggerSpec.paths) { + const methodMap = swaggerSpec.paths[endpointPath]; + const operation = methodMap.post; + const operationId = operation.operationId; + + const operationNameWithoutNamespace = operationId.replace( + new RegExp(`${namespace}_`), + "", + ); + + if (operationNameWithoutNamespace === "NOOPCodegenAnchor") { + continue; + } + + const methodName = `${ + operationNameWithoutNamespace.charAt(0).toLowerCase() + + operationNameWithoutNamespace.slice(1) + }`; + + const methodType = methodTypeFromMethodName(methodName); + const inputType = `T${operationNameWithoutNamespace}Body`; + const responseType = `T${operationNameWithoutNamespace}Response`; + +// For query methods +if (methodType === "query") { + codeBuffer.push( + `\n\t${methodName} = async (input: SdkApiTypes.${inputType}${ + METHODS_WITH_ONLY_OPTIONAL_PARAMETERS.includes(methodName) + ? " = {}" + : "" + }, stampWith?: StamperType): Promise => { + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + return this.request("${endpointPath}", { + ...input, + organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId + }, stampWith); + }`, + ); + } else if (methodType === "command") { + // For command methods + const unversionedActivityType = `ACTIVITY_TYPE_${operationNameWithoutNamespace + .replace(/([a-z])([A-Z])/g, "$1_$2") + .toUpperCase()}`; + const versionedActivityType = + VERSIONED_ACTIVITY_TYPES[unversionedActivityType]; + + const resultKey = operationNameWithoutNamespace + "Result"; + const versionedMethodName = latestVersions[resultKey].formattedKeyName; + + codeBuffer.push( + `\n\t${methodName} = async (input: SdkApiTypes.${inputType}, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("${endpointPath}", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "${versionedActivityType ?? unversionedActivityType}" + }, "${versionedMethodName}", stampWith); + }`, + ); + } else if (methodType === "activityDecision") { + // For activityDecision methods + codeBuffer.push( + `\n\t${methodName} = async (input: SdkApiTypes.${inputType}, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + return this.activityDecision("${endpointPath}", + { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_${operationNameWithoutNamespace + .replace(/([a-z])([A-Z])/g, "$1_$2") + .toUpperCase()}" + }, stampWith); + }`, + ); + } + // generate a stamping method for each method + codeBuffer.push( + `\n\tstamp${operationNameWithoutNamespace} = async (input: SdkApiTypes.${inputType}): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "${endpointPath}"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + }`, + ); + } + + // End of the TurnkeySDKClient Class Definition + codeBuffer.push(`}`); + + await fs.promises.writeFile( + targetPath, + [COMMENT_HEADER].concat(imports).concat(codeBuffer).join("\n\n"), + ); +}; + +// Main Runner +main().catch((error) => { + console.error(error); + process.exit(1); +}); + +async function main() { + const swaggerSpecFile = await fs.promises.readFile( + PUBLIC_API_SWAGGER_PATH, + "utf-8", + ); + const swaggerSpec = JSON.parse(swaggerSpecFile); + + await generateApiTypesFromSwagger(swaggerSpec, TARGET_API_TYPES_PATH); + await generateSDKClientFromSwagger(swaggerSpec, TARGET_SDK_CLIENT_PATH); +} diff --git a/packages/sdk-js/src/__clients__/core.ts b/packages/sdk-js/src/__clients__/core.ts new file mode 100644 index 000000000..248969c25 --- /dev/null +++ b/packages/sdk-js/src/__clients__/core.ts @@ -0,0 +1,41 @@ +import { IndexedDbStamper } from "@turnkey/indexed-db-stamper"; +import { TurnkeySDKClientBase } from "../__generated__/sdk-client-base"; +import { WebauthnStamper } from "@turnkey/webauthn-stamper"; +import WindowWrapper from "@polyfills/window"; + +export class TurnkeyClient { + config: any; // Type TBD + httpClient: TurnkeySDKClientBase; + indexedDBStamper: IndexedDbStamper | undefined; + passkeyStamper: WebauthnStamper | undefined; + constructor( + config: any, + indexedDBStamper?: IndexedDbStamper, + passkeyStamper?: WebauthnStamper + ) { + this.config = config; + this.indexedDBStamper = indexedDBStamper || new IndexedDbStamper(); + this.passkeyStamper = + passkeyStamper || + new WebauthnStamper({ + rpId: config?.passkeyConfig?.rpId ?? WindowWrapper.location.hostname, + ...(config?.passkeyConfig?.timeout !== undefined && { + timeout: config?.passkeyConfig?.timeout, + }), + ...(config?.passkeyConfig?.userVerification !== undefined && { + userVerification: config?.passkeyConfig?.userVerification, + }), + ...(config?.passkeyConfig?.allowCredentials !== undefined && { + allowCredentials: config?.passkeyConfig?.allowCredentials, + }), + }); + + this.indexedDBStamper.init(); + + this.httpClient = new TurnkeySDKClientBase({ + stamper: this.indexedDBStamper, // Maybe we should rename this + passkeyStamper: this.passkeyStamper, + ...config, + }); + } +} diff --git a/packages/sdk-js/src/__generated__/sdk-client-base.ts b/packages/sdk-js/src/__generated__/sdk-client-base.ts new file mode 100644 index 000000000..5f43a6c18 --- /dev/null +++ b/packages/sdk-js/src/__generated__/sdk-client-base.ts @@ -0,0 +1,2501 @@ +/* @generated by codegen. DO NOT EDIT BY HAND */ + +import { TERMINAL_ACTIVITY_STATUSES, TActivityResponse, TActivityStatus, TSignedRequest } from "@turnkey/http"; + +import type { definitions } from "../__inputs__/public_api.types"; + +import { GrpcStatus, TStamper, TurnkeyRequestError, TurnkeySDKClientConfig } from "../__types__/base"; + +import { VERSION } from "../__generated__/version"; + +import type * as SdkApiTypes from "./sdk_api_types"; + +import { StorageKeys, getStorageValue } from "../storage"; + +import { parseSession } from "../utils"; + +import { StamperType } from "../__types__/base"; + + + export class TurnkeySDKClientBase { + config: TurnkeySDKClientConfig; + + // Current active stamper + stamper?: TStamper | undefined; + + // Store stampers + private indexedDBStamper?: TStamper | undefined; + private passkeyStamper?: TStamper | undefined; + + constructor(config: TurnkeySDKClientConfig) { + this.config = config; + if (config.stamper) { + this.stamper = config.stamper; + // Store as default IndexedDB stamper + this.indexedDBStamper = config.stamper; + } + if (config.passkeyStamper) { + this.passkeyStamper = config.passkeyStamper; + } + } + + private getStamper(stampWith?: StamperType): TStamper | undefined { + if (!stampWith) return this.stamper; + + switch (stampWith) { + case StamperType.IndexedDB: + return this.indexedDBStamper; + case StamperType.Passkey: + return this.passkeyStamper; + default: + return this.stamper; + } + } + + async request( + url: string, + body: TBodyType, + stampWith?: StamperType + ): Promise { + const fullUrl = this.config.apiBaseUrl + url; + const stringifiedBody = JSON.stringify(body); + var headers: Record = { + "X-Client-Version": VERSION + } + + // Use the specified stamper for this request + const activeStamper = this.getStamper(stampWith); + + if (activeStamper) { + const stamp = await activeStamper.stamp(stringifiedBody); + headers[stamp.stampHeaderName] = stamp.stampHeaderValue + } + + if (this.config.readOnlySession){ + headers["X-Session"] = this.config.readOnlySession + } + + const response = await fetch(fullUrl, { + method: "POST", + headers: headers, + body: stringifiedBody, + redirect: "follow" + }); + + if (!response.ok) { + let res: GrpcStatus; + try { + res = await response.json(); + } catch (_) { + throw new Error(`${response.status} ${response.statusText}`); + } + + throw new TurnkeyRequestError(res); + } + + const data = await response.json(); + return data as TResponseType; + } + + async command( + url: string, + body: TBodyType, + resultKey: string, + stampWith?: StamperType + ): Promise { + const pollingDuration = this.config.activityPoller?.intervalMs ?? 1000; + const maxRetries = this.config.activityPoller?.numRetries ?? 3; + + const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms)); + + const handleResponse = (activityData: TActivityResponse): TResponseType => { + const { result, status } = activityData.activity; + + if (status === "ACTIVITY_STATUS_COMPLETED") { + return { + ...result[`${resultKey}` as keyof definitions["v1Result"]], + ...activityData + } as TResponseType; + } + + return activityData as TResponseType; + }; + + let attempts = 0; + + const pollStatus = async (activityId: string): Promise => { + const pollBody = { activityId }; + // Pass the stampWith parameter to getActivity + const pollData = await this.getActivity(pollBody, stampWith) as TActivityResponse; + + if (attempts > maxRetries) { + return handleResponse(pollData); + } + + attempts += 1; + + if (!TERMINAL_ACTIVITY_STATUSES.includes(pollData.activity.status as TActivityStatus)) { + await sleep(pollingDuration); + return pollStatus(activityId); + } + + return handleResponse(pollData); + }; + + // Use the specified stamper for the initial request + const responseData = await this.request(url, body, stampWith) as TActivityResponse; + + if (!TERMINAL_ACTIVITY_STATUSES.includes(responseData.activity.status as TActivityStatus)) { + return pollStatus(responseData.activity.id); + } + + return handleResponse(responseData); + } + + async activityDecision( + url: string, + body: TBodyType, + stampWith?: StamperType + ): Promise { + // Use the specified stamper for this request + const activityData = await this.request(url, body, stampWith) as TActivityResponse; + + return { + ...activityData["activity"]["result"], + ...activityData + } as TResponseType; + } + + + getActivity = async (input: SdkApiTypes.TGetActivityBody, stampWith?: StamperType): Promise => { + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + return this.request("/public/v1/query/get_activity", { + ...input, + organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId + }, stampWith); + } + + + stampGetActivity = async (input: SdkApiTypes.TGetActivityBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/query/get_activity"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + getApiKey = async (input: SdkApiTypes.TGetApiKeyBody, stampWith?: StamperType): Promise => { + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + return this.request("/public/v1/query/get_api_key", { + ...input, + organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId + }, stampWith); + } + + + stampGetApiKey = async (input: SdkApiTypes.TGetApiKeyBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/query/get_api_key"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + getApiKeys = async (input: SdkApiTypes.TGetApiKeysBody = {}, stampWith?: StamperType): Promise => { + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + return this.request("/public/v1/query/get_api_keys", { + ...input, + organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId + }, stampWith); + } + + + stampGetApiKeys = async (input: SdkApiTypes.TGetApiKeysBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/query/get_api_keys"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + getAttestationDocument = async (input: SdkApiTypes.TGetAttestationDocumentBody, stampWith?: StamperType): Promise => { + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + return this.request("/public/v1/query/get_attestation", { + ...input, + organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId + }, stampWith); + } + + + stampGetAttestationDocument = async (input: SdkApiTypes.TGetAttestationDocumentBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/query/get_attestation"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + getAuthenticator = async (input: SdkApiTypes.TGetAuthenticatorBody, stampWith?: StamperType): Promise => { + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + return this.request("/public/v1/query/get_authenticator", { + ...input, + organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId + }, stampWith); + } + + + stampGetAuthenticator = async (input: SdkApiTypes.TGetAuthenticatorBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/query/get_authenticator"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + getAuthenticators = async (input: SdkApiTypes.TGetAuthenticatorsBody, stampWith?: StamperType): Promise => { + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + return this.request("/public/v1/query/get_authenticators", { + ...input, + organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId + }, stampWith); + } + + + stampGetAuthenticators = async (input: SdkApiTypes.TGetAuthenticatorsBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/query/get_authenticators"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + getOauthProviders = async (input: SdkApiTypes.TGetOauthProvidersBody, stampWith?: StamperType): Promise => { + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + return this.request("/public/v1/query/get_oauth_providers", { + ...input, + organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId + }, stampWith); + } + + + stampGetOauthProviders = async (input: SdkApiTypes.TGetOauthProvidersBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/query/get_oauth_providers"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + getOrganization = async (input: SdkApiTypes.TGetOrganizationBody = {}, stampWith?: StamperType): Promise => { + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + return this.request("/public/v1/query/get_organization", { + ...input, + organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId + }, stampWith); + } + + + stampGetOrganization = async (input: SdkApiTypes.TGetOrganizationBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/query/get_organization"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + getOrganizationConfigs = async (input: SdkApiTypes.TGetOrganizationConfigsBody, stampWith?: StamperType): Promise => { + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + return this.request("/public/v1/query/get_organization_configs", { + ...input, + organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId + }, stampWith); + } + + + stampGetOrganizationConfigs = async (input: SdkApiTypes.TGetOrganizationConfigsBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/query/get_organization_configs"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + getPolicy = async (input: SdkApiTypes.TGetPolicyBody, stampWith?: StamperType): Promise => { + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + return this.request("/public/v1/query/get_policy", { + ...input, + organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId + }, stampWith); + } + + + stampGetPolicy = async (input: SdkApiTypes.TGetPolicyBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/query/get_policy"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + getPrivateKey = async (input: SdkApiTypes.TGetPrivateKeyBody, stampWith?: StamperType): Promise => { + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + return this.request("/public/v1/query/get_private_key", { + ...input, + organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId + }, stampWith); + } + + + stampGetPrivateKey = async (input: SdkApiTypes.TGetPrivateKeyBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/query/get_private_key"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + getUser = async (input: SdkApiTypes.TGetUserBody, stampWith?: StamperType): Promise => { + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + return this.request("/public/v1/query/get_user", { + ...input, + organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId + }, stampWith); + } + + + stampGetUser = async (input: SdkApiTypes.TGetUserBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/query/get_user"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + getWallet = async (input: SdkApiTypes.TGetWalletBody, stampWith?: StamperType): Promise => { + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + return this.request("/public/v1/query/get_wallet", { + ...input, + organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId + }, stampWith); + } + + + stampGetWallet = async (input: SdkApiTypes.TGetWalletBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/query/get_wallet"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + getWalletAccount = async (input: SdkApiTypes.TGetWalletAccountBody, stampWith?: StamperType): Promise => { + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + return this.request("/public/v1/query/get_wallet_account", { + ...input, + organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId + }, stampWith); + } + + + stampGetWalletAccount = async (input: SdkApiTypes.TGetWalletAccountBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/query/get_wallet_account"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + getActivities = async (input: SdkApiTypes.TGetActivitiesBody = {}, stampWith?: StamperType): Promise => { + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + return this.request("/public/v1/query/list_activities", { + ...input, + organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId + }, stampWith); + } + + + stampGetActivities = async (input: SdkApiTypes.TGetActivitiesBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/query/list_activities"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + getPolicies = async (input: SdkApiTypes.TGetPoliciesBody = {}, stampWith?: StamperType): Promise => { + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + return this.request("/public/v1/query/list_policies", { + ...input, + organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId + }, stampWith); + } + + + stampGetPolicies = async (input: SdkApiTypes.TGetPoliciesBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/query/list_policies"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + listPrivateKeyTags = async (input: SdkApiTypes.TListPrivateKeyTagsBody, stampWith?: StamperType): Promise => { + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + return this.request("/public/v1/query/list_private_key_tags", { + ...input, + organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId + }, stampWith); + } + + + stampListPrivateKeyTags = async (input: SdkApiTypes.TListPrivateKeyTagsBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/query/list_private_key_tags"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + getPrivateKeys = async (input: SdkApiTypes.TGetPrivateKeysBody = {}, stampWith?: StamperType): Promise => { + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + return this.request("/public/v1/query/list_private_keys", { + ...input, + organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId + }, stampWith); + } + + + stampGetPrivateKeys = async (input: SdkApiTypes.TGetPrivateKeysBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/query/list_private_keys"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + getSubOrgIds = async (input: SdkApiTypes.TGetSubOrgIdsBody = {}, stampWith?: StamperType): Promise => { + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + return this.request("/public/v1/query/list_suborgs", { + ...input, + organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId + }, stampWith); + } + + + stampGetSubOrgIds = async (input: SdkApiTypes.TGetSubOrgIdsBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/query/list_suborgs"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + listUserTags = async (input: SdkApiTypes.TListUserTagsBody = {}, stampWith?: StamperType): Promise => { + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + return this.request("/public/v1/query/list_user_tags", { + ...input, + organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId + }, stampWith); + } + + + stampListUserTags = async (input: SdkApiTypes.TListUserTagsBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/query/list_user_tags"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + getUsers = async (input: SdkApiTypes.TGetUsersBody = {}, stampWith?: StamperType): Promise => { + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + return this.request("/public/v1/query/list_users", { + ...input, + organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId + }, stampWith); + } + + + stampGetUsers = async (input: SdkApiTypes.TGetUsersBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/query/list_users"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + getVerifiedSubOrgIds = async (input: SdkApiTypes.TGetVerifiedSubOrgIdsBody, stampWith?: StamperType): Promise => { + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + return this.request("/public/v1/query/list_verified_suborgs", { + ...input, + organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId + }, stampWith); + } + + + stampGetVerifiedSubOrgIds = async (input: SdkApiTypes.TGetVerifiedSubOrgIdsBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/query/list_verified_suborgs"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + getWalletAccounts = async (input: SdkApiTypes.TGetWalletAccountsBody, stampWith?: StamperType): Promise => { + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + return this.request("/public/v1/query/list_wallet_accounts", { + ...input, + organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId + }, stampWith); + } + + + stampGetWalletAccounts = async (input: SdkApiTypes.TGetWalletAccountsBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/query/list_wallet_accounts"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + getWallets = async (input: SdkApiTypes.TGetWalletsBody = {}, stampWith?: StamperType): Promise => { + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + return this.request("/public/v1/query/list_wallets", { + ...input, + organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId + }, stampWith); + } + + + stampGetWallets = async (input: SdkApiTypes.TGetWalletsBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/query/list_wallets"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + getWhoami = async (input: SdkApiTypes.TGetWhoamiBody = {}, stampWith?: StamperType): Promise => { + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + return this.request("/public/v1/query/whoami", { + ...input, + organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId + }, stampWith); + } + + + stampGetWhoami = async (input: SdkApiTypes.TGetWhoamiBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/query/whoami"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + approveActivity = async (input: SdkApiTypes.TApproveActivityBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + return this.activityDecision("/public/v1/submit/approve_activity", + { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_APPROVE_ACTIVITY" + }, stampWith); + } + + + stampApproveActivity = async (input: SdkApiTypes.TApproveActivityBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/approve_activity"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + createApiKeys = async (input: SdkApiTypes.TCreateApiKeysBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/create_api_keys", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_CREATE_API_KEYS_V2" + }, "createApiKeysResult", stampWith); + } + + + stampCreateApiKeys = async (input: SdkApiTypes.TCreateApiKeysBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/create_api_keys"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + createApiOnlyUsers = async (input: SdkApiTypes.TCreateApiOnlyUsersBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/create_api_only_users", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_CREATE_API_ONLY_USERS" + }, "createApiOnlyUsersResult", stampWith); + } + + + stampCreateApiOnlyUsers = async (input: SdkApiTypes.TCreateApiOnlyUsersBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/create_api_only_users"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + createAuthenticators = async (input: SdkApiTypes.TCreateAuthenticatorsBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/create_authenticators", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_CREATE_AUTHENTICATORS_V2" + }, "createAuthenticatorsResult", stampWith); + } + + + stampCreateAuthenticators = async (input: SdkApiTypes.TCreateAuthenticatorsBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/create_authenticators"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + createInvitations = async (input: SdkApiTypes.TCreateInvitationsBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/create_invitations", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_CREATE_INVITATIONS" + }, "createInvitationsResult", stampWith); + } + + + stampCreateInvitations = async (input: SdkApiTypes.TCreateInvitationsBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/create_invitations"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + createOauthProviders = async (input: SdkApiTypes.TCreateOauthProvidersBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/create_oauth_providers", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_CREATE_OAUTH_PROVIDERS" + }, "createOauthProvidersResult", stampWith); + } + + + stampCreateOauthProviders = async (input: SdkApiTypes.TCreateOauthProvidersBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/create_oauth_providers"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + createPolicies = async (input: SdkApiTypes.TCreatePoliciesBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/create_policies", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_CREATE_POLICIES" + }, "createPoliciesResult", stampWith); + } + + + stampCreatePolicies = async (input: SdkApiTypes.TCreatePoliciesBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/create_policies"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + createPolicy = async (input: SdkApiTypes.TCreatePolicyBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/create_policy", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_CREATE_POLICY_V3" + }, "createPolicyResult", stampWith); + } + + + stampCreatePolicy = async (input: SdkApiTypes.TCreatePolicyBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/create_policy"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + createPrivateKeyTag = async (input: SdkApiTypes.TCreatePrivateKeyTagBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/create_private_key_tag", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_CREATE_PRIVATE_KEY_TAG" + }, "createPrivateKeyTagResult", stampWith); + } + + + stampCreatePrivateKeyTag = async (input: SdkApiTypes.TCreatePrivateKeyTagBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/create_private_key_tag"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + createPrivateKeys = async (input: SdkApiTypes.TCreatePrivateKeysBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/create_private_keys", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_CREATE_PRIVATE_KEYS_V2" + }, "createPrivateKeysResultV2", stampWith); + } + + + stampCreatePrivateKeys = async (input: SdkApiTypes.TCreatePrivateKeysBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/create_private_keys"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + createReadOnlySession = async (input: SdkApiTypes.TCreateReadOnlySessionBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/create_read_only_session", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_CREATE_READ_ONLY_SESSION" + }, "createReadOnlySessionResult", stampWith); + } + + + stampCreateReadOnlySession = async (input: SdkApiTypes.TCreateReadOnlySessionBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/create_read_only_session"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + createReadWriteSession = async (input: SdkApiTypes.TCreateReadWriteSessionBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/create_read_write_session", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_CREATE_READ_WRITE_SESSION_V2" + }, "createReadWriteSessionResultV2", stampWith); + } + + + stampCreateReadWriteSession = async (input: SdkApiTypes.TCreateReadWriteSessionBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/create_read_write_session"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + createSubOrganization = async (input: SdkApiTypes.TCreateSubOrganizationBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/create_sub_organization", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_CREATE_SUB_ORGANIZATION_V7" + }, "createSubOrganizationResultV7", stampWith); + } + + + stampCreateSubOrganization = async (input: SdkApiTypes.TCreateSubOrganizationBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/create_sub_organization"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + createUserTag = async (input: SdkApiTypes.TCreateUserTagBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/create_user_tag", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_CREATE_USER_TAG" + }, "createUserTagResult", stampWith); + } + + + stampCreateUserTag = async (input: SdkApiTypes.TCreateUserTagBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/create_user_tag"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + createUsers = async (input: SdkApiTypes.TCreateUsersBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/create_users", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_CREATE_USERS_V3" + }, "createUsersResult", stampWith); + } + + + stampCreateUsers = async (input: SdkApiTypes.TCreateUsersBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/create_users"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + createWallet = async (input: SdkApiTypes.TCreateWalletBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/create_wallet", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_CREATE_WALLET" + }, "createWalletResult", stampWith); + } + + + stampCreateWallet = async (input: SdkApiTypes.TCreateWalletBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/create_wallet"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + createWalletAccounts = async (input: SdkApiTypes.TCreateWalletAccountsBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/create_wallet_accounts", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_CREATE_WALLET_ACCOUNTS" + }, "createWalletAccountsResult", stampWith); + } + + + stampCreateWalletAccounts = async (input: SdkApiTypes.TCreateWalletAccountsBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/create_wallet_accounts"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + deleteApiKeys = async (input: SdkApiTypes.TDeleteApiKeysBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/delete_api_keys", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_DELETE_API_KEYS" + }, "deleteApiKeysResult", stampWith); + } + + + stampDeleteApiKeys = async (input: SdkApiTypes.TDeleteApiKeysBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/delete_api_keys"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + deleteAuthenticators = async (input: SdkApiTypes.TDeleteAuthenticatorsBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/delete_authenticators", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_DELETE_AUTHENTICATORS" + }, "deleteAuthenticatorsResult", stampWith); + } + + + stampDeleteAuthenticators = async (input: SdkApiTypes.TDeleteAuthenticatorsBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/delete_authenticators"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + deleteInvitation = async (input: SdkApiTypes.TDeleteInvitationBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/delete_invitation", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_DELETE_INVITATION" + }, "deleteInvitationResult", stampWith); + } + + + stampDeleteInvitation = async (input: SdkApiTypes.TDeleteInvitationBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/delete_invitation"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + deleteOauthProviders = async (input: SdkApiTypes.TDeleteOauthProvidersBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/delete_oauth_providers", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_DELETE_OAUTH_PROVIDERS" + }, "deleteOauthProvidersResult", stampWith); + } + + + stampDeleteOauthProviders = async (input: SdkApiTypes.TDeleteOauthProvidersBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/delete_oauth_providers"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + deletePolicy = async (input: SdkApiTypes.TDeletePolicyBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/delete_policy", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_DELETE_POLICY" + }, "deletePolicyResult", stampWith); + } + + + stampDeletePolicy = async (input: SdkApiTypes.TDeletePolicyBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/delete_policy"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + deletePrivateKeyTags = async (input: SdkApiTypes.TDeletePrivateKeyTagsBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/delete_private_key_tags", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_DELETE_PRIVATE_KEY_TAGS" + }, "deletePrivateKeyTagsResult", stampWith); + } + + + stampDeletePrivateKeyTags = async (input: SdkApiTypes.TDeletePrivateKeyTagsBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/delete_private_key_tags"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + deletePrivateKeys = async (input: SdkApiTypes.TDeletePrivateKeysBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/delete_private_keys", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_DELETE_PRIVATE_KEYS" + }, "deletePrivateKeysResult", stampWith); + } + + + stampDeletePrivateKeys = async (input: SdkApiTypes.TDeletePrivateKeysBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/delete_private_keys"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + deleteSubOrganization = async (input: SdkApiTypes.TDeleteSubOrganizationBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/delete_sub_organization", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_DELETE_SUB_ORGANIZATION" + }, "deleteSubOrganizationResult", stampWith); + } + + + stampDeleteSubOrganization = async (input: SdkApiTypes.TDeleteSubOrganizationBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/delete_sub_organization"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + deleteUserTags = async (input: SdkApiTypes.TDeleteUserTagsBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/delete_user_tags", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_DELETE_USER_TAGS" + }, "deleteUserTagsResult", stampWith); + } + + + stampDeleteUserTags = async (input: SdkApiTypes.TDeleteUserTagsBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/delete_user_tags"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + deleteUsers = async (input: SdkApiTypes.TDeleteUsersBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/delete_users", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_DELETE_USERS" + }, "deleteUsersResult", stampWith); + } + + + stampDeleteUsers = async (input: SdkApiTypes.TDeleteUsersBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/delete_users"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + deleteWallets = async (input: SdkApiTypes.TDeleteWalletsBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/delete_wallets", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_DELETE_WALLETS" + }, "deleteWalletsResult", stampWith); + } + + + stampDeleteWallets = async (input: SdkApiTypes.TDeleteWalletsBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/delete_wallets"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + emailAuth = async (input: SdkApiTypes.TEmailAuthBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/email_auth", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_EMAIL_AUTH_V2" + }, "emailAuthResult", stampWith); + } + + + stampEmailAuth = async (input: SdkApiTypes.TEmailAuthBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/email_auth"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + exportPrivateKey = async (input: SdkApiTypes.TExportPrivateKeyBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/export_private_key", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_EXPORT_PRIVATE_KEY" + }, "exportPrivateKeyResult", stampWith); + } + + + stampExportPrivateKey = async (input: SdkApiTypes.TExportPrivateKeyBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/export_private_key"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + exportWallet = async (input: SdkApiTypes.TExportWalletBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/export_wallet", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_EXPORT_WALLET" + }, "exportWalletResult", stampWith); + } + + + stampExportWallet = async (input: SdkApiTypes.TExportWalletBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/export_wallet"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + exportWalletAccount = async (input: SdkApiTypes.TExportWalletAccountBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/export_wallet_account", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_EXPORT_WALLET_ACCOUNT" + }, "exportWalletAccountResult", stampWith); + } + + + stampExportWalletAccount = async (input: SdkApiTypes.TExportWalletAccountBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/export_wallet_account"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + importPrivateKey = async (input: SdkApiTypes.TImportPrivateKeyBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/import_private_key", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_IMPORT_PRIVATE_KEY" + }, "importPrivateKeyResult", stampWith); + } + + + stampImportPrivateKey = async (input: SdkApiTypes.TImportPrivateKeyBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/import_private_key"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + importWallet = async (input: SdkApiTypes.TImportWalletBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/import_wallet", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_IMPORT_WALLET" + }, "importWalletResult", stampWith); + } + + + stampImportWallet = async (input: SdkApiTypes.TImportWalletBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/import_wallet"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + initImportPrivateKey = async (input: SdkApiTypes.TInitImportPrivateKeyBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/init_import_private_key", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_INIT_IMPORT_PRIVATE_KEY" + }, "initImportPrivateKeyResult", stampWith); + } + + + stampInitImportPrivateKey = async (input: SdkApiTypes.TInitImportPrivateKeyBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/init_import_private_key"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + initImportWallet = async (input: SdkApiTypes.TInitImportWalletBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/init_import_wallet", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_INIT_IMPORT_WALLET" + }, "initImportWalletResult", stampWith); + } + + + stampInitImportWallet = async (input: SdkApiTypes.TInitImportWalletBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/init_import_wallet"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + initOtp = async (input: SdkApiTypes.TInitOtpBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/init_otp", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_INIT_OTP" + }, "initOtpResult", stampWith); + } + + + stampInitOtp = async (input: SdkApiTypes.TInitOtpBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/init_otp"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + initOtpAuth = async (input: SdkApiTypes.TInitOtpAuthBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/init_otp_auth", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_INIT_OTP_AUTH_V2" + }, "initOtpAuthResultV2", stampWith); + } + + + stampInitOtpAuth = async (input: SdkApiTypes.TInitOtpAuthBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/init_otp_auth"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + initUserEmailRecovery = async (input: SdkApiTypes.TInitUserEmailRecoveryBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/init_user_email_recovery", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_INIT_USER_EMAIL_RECOVERY" + }, "initUserEmailRecoveryResult", stampWith); + } + + + stampInitUserEmailRecovery = async (input: SdkApiTypes.TInitUserEmailRecoveryBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/init_user_email_recovery"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + oauth = async (input: SdkApiTypes.TOauthBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/oauth", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_OAUTH" + }, "oauthResult", stampWith); + } + + + stampOauth = async (input: SdkApiTypes.TOauthBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/oauth"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + oauthLogin = async (input: SdkApiTypes.TOauthLoginBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/oauth_login", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_OAUTH_LOGIN" + }, "oauthLoginResult", stampWith); + } + + + stampOauthLogin = async (input: SdkApiTypes.TOauthLoginBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/oauth_login"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + otpAuth = async (input: SdkApiTypes.TOtpAuthBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/otp_auth", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_OTP_AUTH" + }, "otpAuthResult", stampWith); + } + + + stampOtpAuth = async (input: SdkApiTypes.TOtpAuthBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/otp_auth"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + otpLogin = async (input: SdkApiTypes.TOtpLoginBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/otp_login", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_OTP_LOGIN" + }, "otpLoginResult", stampWith); + } + + + stampOtpLogin = async (input: SdkApiTypes.TOtpLoginBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/otp_login"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + recoverUser = async (input: SdkApiTypes.TRecoverUserBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/recover_user", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_RECOVER_USER" + }, "recoverUserResult", stampWith); + } + + + stampRecoverUser = async (input: SdkApiTypes.TRecoverUserBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/recover_user"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + rejectActivity = async (input: SdkApiTypes.TRejectActivityBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + return this.activityDecision("/public/v1/submit/reject_activity", + { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_REJECT_ACTIVITY" + }, stampWith); + } + + + stampRejectActivity = async (input: SdkApiTypes.TRejectActivityBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/reject_activity"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + removeOrganizationFeature = async (input: SdkApiTypes.TRemoveOrganizationFeatureBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/remove_organization_feature", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_REMOVE_ORGANIZATION_FEATURE" + }, "removeOrganizationFeatureResult", stampWith); + } + + + stampRemoveOrganizationFeature = async (input: SdkApiTypes.TRemoveOrganizationFeatureBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/remove_organization_feature"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + setOrganizationFeature = async (input: SdkApiTypes.TSetOrganizationFeatureBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/set_organization_feature", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_SET_ORGANIZATION_FEATURE" + }, "setOrganizationFeatureResult", stampWith); + } + + + stampSetOrganizationFeature = async (input: SdkApiTypes.TSetOrganizationFeatureBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/set_organization_feature"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + signRawPayload = async (input: SdkApiTypes.TSignRawPayloadBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/sign_raw_payload", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_SIGN_RAW_PAYLOAD_V2" + }, "signRawPayloadResult", stampWith); + } + + + stampSignRawPayload = async (input: SdkApiTypes.TSignRawPayloadBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/sign_raw_payload"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + signRawPayloads = async (input: SdkApiTypes.TSignRawPayloadsBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/sign_raw_payloads", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_SIGN_RAW_PAYLOADS" + }, "signRawPayloadsResult", stampWith); + } + + + stampSignRawPayloads = async (input: SdkApiTypes.TSignRawPayloadsBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/sign_raw_payloads"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + signTransaction = async (input: SdkApiTypes.TSignTransactionBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/sign_transaction", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_SIGN_TRANSACTION_V2" + }, "signTransactionResult", stampWith); + } + + + stampSignTransaction = async (input: SdkApiTypes.TSignTransactionBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/sign_transaction"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + stampLogin = async (input: SdkApiTypes.TStampLoginBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/stamp_login", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_STAMP_LOGIN" + }, "stampLoginResult", stampWith); + } + + + stampStampLogin = async (input: SdkApiTypes.TStampLoginBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/stamp_login"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + updatePolicy = async (input: SdkApiTypes.TUpdatePolicyBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/update_policy", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_UPDATE_POLICY_V2" + }, "updatePolicyResultV2", stampWith); + } + + + stampUpdatePolicy = async (input: SdkApiTypes.TUpdatePolicyBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/update_policy"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + updatePrivateKeyTag = async (input: SdkApiTypes.TUpdatePrivateKeyTagBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/update_private_key_tag", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_UPDATE_PRIVATE_KEY_TAG" + }, "updatePrivateKeyTagResult", stampWith); + } + + + stampUpdatePrivateKeyTag = async (input: SdkApiTypes.TUpdatePrivateKeyTagBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/update_private_key_tag"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + updateRootQuorum = async (input: SdkApiTypes.TUpdateRootQuorumBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/update_root_quorum", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_UPDATE_ROOT_QUORUM" + }, "updateRootQuorumResult", stampWith); + } + + + stampUpdateRootQuorum = async (input: SdkApiTypes.TUpdateRootQuorumBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/update_root_quorum"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + updateUser = async (input: SdkApiTypes.TUpdateUserBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/update_user", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_UPDATE_USER" + }, "updateUserResult", stampWith); + } + + + stampUpdateUser = async (input: SdkApiTypes.TUpdateUserBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/update_user"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + updateUserTag = async (input: SdkApiTypes.TUpdateUserTagBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/update_user_tag", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_UPDATE_USER_TAG" + }, "updateUserTagResult", stampWith); + } + + + stampUpdateUserTag = async (input: SdkApiTypes.TUpdateUserTagBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/update_user_tag"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + updateWallet = async (input: SdkApiTypes.TUpdateWalletBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/update_wallet", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_UPDATE_WALLET" + }, "updateWalletResult", stampWith); + } + + + stampUpdateWallet = async (input: SdkApiTypes.TUpdateWalletBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/update_wallet"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + verifyOtp = async (input: SdkApiTypes.TVerifyOtpBody, stampWith?: StamperType): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + + return this.command("/public/v1/submit/verify_otp", { + parameters: rest, + organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_VERIFY_OTP" + }, "verifyOtpResult", stampWith); + } + + + stampVerifyOtp = async (input: SdkApiTypes.TVerifyOtpBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/verify_otp"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + + + testRateLimits = async (input: SdkApiTypes.TTestRateLimitsBody, stampWith?: StamperType): Promise => { + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + return this.request("/tkhq/api/v1/test_rate_limits", { + ...input, + organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId + }, stampWith); + } + + + stampTestRateLimits = async (input: SdkApiTypes.TTestRateLimitsBody): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = this.config.apiBaseUrl + "/tkhq/api/v1/test_rate_limits"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + } + +} \ No newline at end of file diff --git a/packages/sdk-js/src/__generated__/sdk_api_types.ts b/packages/sdk-js/src/__generated__/sdk_api_types.ts new file mode 100644 index 000000000..3c56a2ba2 --- /dev/null +++ b/packages/sdk-js/src/__generated__/sdk_api_types.ts @@ -0,0 +1,511 @@ +/* @generated by codegen. DO NOT EDIT BY HAND */ + +import type { operations, definitions } from "../__inputs__/public_api.types"; + +import type { queryOverrideParams, commandOverrideParams } from "../__types__/base"; + +export type TGetActivityResponse = operations["PublicApiService_GetActivity"]["responses"]["200"]["schema"]; + +export type TGetActivityInput = { body: TGetActivityBody }; + +export type TGetActivityBody = Omit & queryOverrideParams; + +export type TGetApiKeyResponse = operations["PublicApiService_GetApiKey"]["responses"]["200"]["schema"]; + +export type TGetApiKeyInput = { body: TGetApiKeyBody }; + +export type TGetApiKeyBody = Omit & queryOverrideParams; + +export type TGetApiKeysResponse = operations["PublicApiService_GetApiKeys"]["responses"]["200"]["schema"]; + +export type TGetApiKeysInput = { body: TGetApiKeysBody }; + +export type TGetApiKeysBody = Omit & queryOverrideParams; + +export type TGetAttestationDocumentResponse = operations["PublicApiService_GetAttestationDocument"]["responses"]["200"]["schema"]; + +export type TGetAttestationDocumentInput = { body: TGetAttestationDocumentBody }; + +export type TGetAttestationDocumentBody = Omit & queryOverrideParams; + +export type TGetAuthenticatorResponse = operations["PublicApiService_GetAuthenticator"]["responses"]["200"]["schema"]; + +export type TGetAuthenticatorInput = { body: TGetAuthenticatorBody }; + +export type TGetAuthenticatorBody = Omit & queryOverrideParams; + +export type TGetAuthenticatorsResponse = operations["PublicApiService_GetAuthenticators"]["responses"]["200"]["schema"]; + +export type TGetAuthenticatorsInput = { body: TGetAuthenticatorsBody }; + +export type TGetAuthenticatorsBody = Omit & queryOverrideParams; + +export type TGetOauthProvidersResponse = operations["PublicApiService_GetOauthProviders"]["responses"]["200"]["schema"]; + +export type TGetOauthProvidersInput = { body: TGetOauthProvidersBody }; + +export type TGetOauthProvidersBody = Omit & queryOverrideParams; + +export type TGetOrganizationResponse = operations["PublicApiService_GetOrganization"]["responses"]["200"]["schema"]; + +export type TGetOrganizationInput = { body: TGetOrganizationBody }; + +export type TGetOrganizationBody = Omit & queryOverrideParams; + +export type TGetOrganizationConfigsResponse = operations["PublicApiService_GetOrganizationConfigs"]["responses"]["200"]["schema"]; + +export type TGetOrganizationConfigsInput = { body: TGetOrganizationConfigsBody }; + +export type TGetOrganizationConfigsBody = Omit & queryOverrideParams; + +export type TGetPolicyResponse = operations["PublicApiService_GetPolicy"]["responses"]["200"]["schema"]; + +export type TGetPolicyInput = { body: TGetPolicyBody }; + +export type TGetPolicyBody = Omit & queryOverrideParams; + +export type TGetPrivateKeyResponse = operations["PublicApiService_GetPrivateKey"]["responses"]["200"]["schema"]; + +export type TGetPrivateKeyInput = { body: TGetPrivateKeyBody }; + +export type TGetPrivateKeyBody = Omit & queryOverrideParams; + +export type TGetUserResponse = operations["PublicApiService_GetUser"]["responses"]["200"]["schema"]; + +export type TGetUserInput = { body: TGetUserBody }; + +export type TGetUserBody = Omit & queryOverrideParams; + +export type TGetWalletResponse = operations["PublicApiService_GetWallet"]["responses"]["200"]["schema"]; + +export type TGetWalletInput = { body: TGetWalletBody }; + +export type TGetWalletBody = Omit & queryOverrideParams; + +export type TGetWalletAccountResponse = operations["PublicApiService_GetWalletAccount"]["responses"]["200"]["schema"]; + +export type TGetWalletAccountInput = { body: TGetWalletAccountBody }; + +export type TGetWalletAccountBody = Omit & queryOverrideParams; + +export type TGetActivitiesResponse = operations["PublicApiService_GetActivities"]["responses"]["200"]["schema"]; + +export type TGetActivitiesInput = { body: TGetActivitiesBody }; + +export type TGetActivitiesBody = Omit & queryOverrideParams; + +export type TGetPoliciesResponse = operations["PublicApiService_GetPolicies"]["responses"]["200"]["schema"]; + +export type TGetPoliciesInput = { body: TGetPoliciesBody }; + +export type TGetPoliciesBody = Omit & queryOverrideParams; + +export type TListPrivateKeyTagsResponse = operations["PublicApiService_ListPrivateKeyTags"]["responses"]["200"]["schema"]; + +export type TListPrivateKeyTagsInput = { body: TListPrivateKeyTagsBody }; + +export type TListPrivateKeyTagsBody = Omit & queryOverrideParams; + +export type TGetPrivateKeysResponse = operations["PublicApiService_GetPrivateKeys"]["responses"]["200"]["schema"]; + +export type TGetPrivateKeysInput = { body: TGetPrivateKeysBody }; + +export type TGetPrivateKeysBody = Omit & queryOverrideParams; + +export type TGetSubOrgIdsResponse = operations["PublicApiService_GetSubOrgIds"]["responses"]["200"]["schema"]; + +export type TGetSubOrgIdsInput = { body: TGetSubOrgIdsBody }; + +export type TGetSubOrgIdsBody = Omit & queryOverrideParams; + +export type TListUserTagsResponse = operations["PublicApiService_ListUserTags"]["responses"]["200"]["schema"]; + +export type TListUserTagsInput = { body: TListUserTagsBody }; + +export type TListUserTagsBody = Omit & queryOverrideParams; + +export type TGetUsersResponse = operations["PublicApiService_GetUsers"]["responses"]["200"]["schema"]; + +export type TGetUsersInput = { body: TGetUsersBody }; + +export type TGetUsersBody = Omit & queryOverrideParams; + +export type TGetVerifiedSubOrgIdsResponse = operations["PublicApiService_GetVerifiedSubOrgIds"]["responses"]["200"]["schema"]; + +export type TGetVerifiedSubOrgIdsInput = { body: TGetVerifiedSubOrgIdsBody }; + +export type TGetVerifiedSubOrgIdsBody = Omit & queryOverrideParams; + +export type TGetWalletAccountsResponse = operations["PublicApiService_GetWalletAccounts"]["responses"]["200"]["schema"]; + +export type TGetWalletAccountsInput = { body: TGetWalletAccountsBody }; + +export type TGetWalletAccountsBody = Omit & queryOverrideParams; + +export type TGetWalletsResponse = operations["PublicApiService_GetWallets"]["responses"]["200"]["schema"]; + +export type TGetWalletsInput = { body: TGetWalletsBody }; + +export type TGetWalletsBody = Omit & queryOverrideParams; + +export type TGetWhoamiResponse = operations["PublicApiService_GetWhoami"]["responses"]["200"]["schema"]; + +export type TGetWhoamiInput = { body: TGetWhoamiBody }; + +export type TGetWhoamiBody = Omit & queryOverrideParams; + +export type TApproveActivityResponse = operations["PublicApiService_ApproveActivity"]["responses"]["200"]["schema"]["activity"]["result"] & definitions["v1ActivityResponse"]; + +export type TApproveActivityInput = { body: TApproveActivityBody }; + +export type TApproveActivityBody = operations["PublicApiService_ApproveActivity"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TCreateApiKeysResponse = operations["PublicApiService_CreateApiKeys"]["responses"]["200"]["schema"]["activity"]["result"]["createApiKeysResult"] & definitions["v1ActivityResponse"]; + +export type TCreateApiKeysInput = { body: TCreateApiKeysBody }; + +export type TCreateApiKeysBody = operations["PublicApiService_CreateApiKeys"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TCreateApiOnlyUsersResponse = operations["PublicApiService_CreateApiOnlyUsers"]["responses"]["200"]["schema"]["activity"]["result"]["createApiOnlyUsersResult"] & definitions["v1ActivityResponse"]; + +export type TCreateApiOnlyUsersInput = { body: TCreateApiOnlyUsersBody }; + +export type TCreateApiOnlyUsersBody = operations["PublicApiService_CreateApiOnlyUsers"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TCreateAuthenticatorsResponse = operations["PublicApiService_CreateAuthenticators"]["responses"]["200"]["schema"]["activity"]["result"]["createAuthenticatorsResult"] & definitions["v1ActivityResponse"]; + +export type TCreateAuthenticatorsInput = { body: TCreateAuthenticatorsBody }; + +export type TCreateAuthenticatorsBody = operations["PublicApiService_CreateAuthenticators"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TCreateInvitationsResponse = operations["PublicApiService_CreateInvitations"]["responses"]["200"]["schema"]["activity"]["result"]["createInvitationsResult"] & definitions["v1ActivityResponse"]; + +export type TCreateInvitationsInput = { body: TCreateInvitationsBody }; + +export type TCreateInvitationsBody = operations["PublicApiService_CreateInvitations"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TCreateOauthProvidersResponse = operations["PublicApiService_CreateOauthProviders"]["responses"]["200"]["schema"]["activity"]["result"]["createOauthProvidersResult"] & definitions["v1ActivityResponse"]; + +export type TCreateOauthProvidersInput = { body: TCreateOauthProvidersBody }; + +export type TCreateOauthProvidersBody = operations["PublicApiService_CreateOauthProviders"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TCreatePoliciesResponse = operations["PublicApiService_CreatePolicies"]["responses"]["200"]["schema"]["activity"]["result"]["createPoliciesResult"] & definitions["v1ActivityResponse"]; + +export type TCreatePoliciesInput = { body: TCreatePoliciesBody }; + +export type TCreatePoliciesBody = operations["PublicApiService_CreatePolicies"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TCreatePolicyResponse = operations["PublicApiService_CreatePolicy"]["responses"]["200"]["schema"]["activity"]["result"]["createPolicyResult"] & definitions["v1ActivityResponse"]; + +export type TCreatePolicyInput = { body: TCreatePolicyBody }; + +export type TCreatePolicyBody = operations["PublicApiService_CreatePolicy"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TCreatePrivateKeyTagResponse = operations["PublicApiService_CreatePrivateKeyTag"]["responses"]["200"]["schema"]["activity"]["result"]["createPrivateKeyTagResult"] & definitions["v1ActivityResponse"]; + +export type TCreatePrivateKeyTagInput = { body: TCreatePrivateKeyTagBody }; + +export type TCreatePrivateKeyTagBody = operations["PublicApiService_CreatePrivateKeyTag"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TCreatePrivateKeysResponse = operations["PublicApiService_CreatePrivateKeys"]["responses"]["200"]["schema"]["activity"]["result"]["createPrivateKeysResultV2"] & definitions["v1ActivityResponse"]; + +export type TCreatePrivateKeysInput = { body: TCreatePrivateKeysBody }; + +export type TCreatePrivateKeysBody = operations["PublicApiService_CreatePrivateKeys"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TCreateReadOnlySessionResponse = operations["PublicApiService_CreateReadOnlySession"]["responses"]["200"]["schema"]["activity"]["result"]["createReadOnlySessionResult"] & definitions["v1ActivityResponse"]; + +export type TCreateReadOnlySessionInput = { body: TCreateReadOnlySessionBody }; + +export type TCreateReadOnlySessionBody = operations["PublicApiService_CreateReadOnlySession"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TCreateReadWriteSessionResponse = operations["PublicApiService_CreateReadWriteSession"]["responses"]["200"]["schema"]["activity"]["result"]["createReadWriteSessionResultV2"] & definitions["v1ActivityResponse"]; + +export type TCreateReadWriteSessionInput = { body: TCreateReadWriteSessionBody }; + +export type TCreateReadWriteSessionBody = operations["PublicApiService_CreateReadWriteSession"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TCreateSubOrganizationResponse = operations["PublicApiService_CreateSubOrganization"]["responses"]["200"]["schema"]["activity"]["result"]["createSubOrganizationResultV7"] & definitions["v1ActivityResponse"]; + +export type TCreateSubOrganizationInput = { body: TCreateSubOrganizationBody }; + +export type TCreateSubOrganizationBody = operations["PublicApiService_CreateSubOrganization"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TCreateUserTagResponse = operations["PublicApiService_CreateUserTag"]["responses"]["200"]["schema"]["activity"]["result"]["createUserTagResult"] & definitions["v1ActivityResponse"]; + +export type TCreateUserTagInput = { body: TCreateUserTagBody }; + +export type TCreateUserTagBody = operations["PublicApiService_CreateUserTag"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TCreateUsersResponse = operations["PublicApiService_CreateUsers"]["responses"]["200"]["schema"]["activity"]["result"]["createUsersResult"] & definitions["v1ActivityResponse"]; + +export type TCreateUsersInput = { body: TCreateUsersBody }; + +export type TCreateUsersBody = operations["PublicApiService_CreateUsers"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TCreateWalletResponse = operations["PublicApiService_CreateWallet"]["responses"]["200"]["schema"]["activity"]["result"]["createWalletResult"] & definitions["v1ActivityResponse"]; + +export type TCreateWalletInput = { body: TCreateWalletBody }; + +export type TCreateWalletBody = operations["PublicApiService_CreateWallet"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TCreateWalletAccountsResponse = operations["PublicApiService_CreateWalletAccounts"]["responses"]["200"]["schema"]["activity"]["result"]["createWalletAccountsResult"] & definitions["v1ActivityResponse"]; + +export type TCreateWalletAccountsInput = { body: TCreateWalletAccountsBody }; + +export type TCreateWalletAccountsBody = operations["PublicApiService_CreateWalletAccounts"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TDeleteApiKeysResponse = operations["PublicApiService_DeleteApiKeys"]["responses"]["200"]["schema"]["activity"]["result"]["deleteApiKeysResult"] & definitions["v1ActivityResponse"]; + +export type TDeleteApiKeysInput = { body: TDeleteApiKeysBody }; + +export type TDeleteApiKeysBody = operations["PublicApiService_DeleteApiKeys"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TDeleteAuthenticatorsResponse = operations["PublicApiService_DeleteAuthenticators"]["responses"]["200"]["schema"]["activity"]["result"]["deleteAuthenticatorsResult"] & definitions["v1ActivityResponse"]; + +export type TDeleteAuthenticatorsInput = { body: TDeleteAuthenticatorsBody }; + +export type TDeleteAuthenticatorsBody = operations["PublicApiService_DeleteAuthenticators"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TDeleteInvitationResponse = operations["PublicApiService_DeleteInvitation"]["responses"]["200"]["schema"]["activity"]["result"]["deleteInvitationResult"] & definitions["v1ActivityResponse"]; + +export type TDeleteInvitationInput = { body: TDeleteInvitationBody }; + +export type TDeleteInvitationBody = operations["PublicApiService_DeleteInvitation"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TDeleteOauthProvidersResponse = operations["PublicApiService_DeleteOauthProviders"]["responses"]["200"]["schema"]["activity"]["result"]["deleteOauthProvidersResult"] & definitions["v1ActivityResponse"]; + +export type TDeleteOauthProvidersInput = { body: TDeleteOauthProvidersBody }; + +export type TDeleteOauthProvidersBody = operations["PublicApiService_DeleteOauthProviders"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TDeletePolicyResponse = operations["PublicApiService_DeletePolicy"]["responses"]["200"]["schema"]["activity"]["result"]["deletePolicyResult"] & definitions["v1ActivityResponse"]; + +export type TDeletePolicyInput = { body: TDeletePolicyBody }; + +export type TDeletePolicyBody = operations["PublicApiService_DeletePolicy"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TDeletePrivateKeyTagsResponse = operations["PublicApiService_DeletePrivateKeyTags"]["responses"]["200"]["schema"]["activity"]["result"]["deletePrivateKeyTagsResult"] & definitions["v1ActivityResponse"]; + +export type TDeletePrivateKeyTagsInput = { body: TDeletePrivateKeyTagsBody }; + +export type TDeletePrivateKeyTagsBody = operations["PublicApiService_DeletePrivateKeyTags"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TDeletePrivateKeysResponse = operations["PublicApiService_DeletePrivateKeys"]["responses"]["200"]["schema"]["activity"]["result"]["deletePrivateKeysResult"] & definitions["v1ActivityResponse"]; + +export type TDeletePrivateKeysInput = { body: TDeletePrivateKeysBody }; + +export type TDeletePrivateKeysBody = operations["PublicApiService_DeletePrivateKeys"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TDeleteSubOrganizationResponse = operations["PublicApiService_DeleteSubOrganization"]["responses"]["200"]["schema"]["activity"]["result"]["deleteSubOrganizationResult"] & definitions["v1ActivityResponse"]; + +export type TDeleteSubOrganizationInput = { body: TDeleteSubOrganizationBody }; + +export type TDeleteSubOrganizationBody = operations["PublicApiService_DeleteSubOrganization"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TDeleteUserTagsResponse = operations["PublicApiService_DeleteUserTags"]["responses"]["200"]["schema"]["activity"]["result"]["deleteUserTagsResult"] & definitions["v1ActivityResponse"]; + +export type TDeleteUserTagsInput = { body: TDeleteUserTagsBody }; + +export type TDeleteUserTagsBody = operations["PublicApiService_DeleteUserTags"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TDeleteUsersResponse = operations["PublicApiService_DeleteUsers"]["responses"]["200"]["schema"]["activity"]["result"]["deleteUsersResult"] & definitions["v1ActivityResponse"]; + +export type TDeleteUsersInput = { body: TDeleteUsersBody }; + +export type TDeleteUsersBody = operations["PublicApiService_DeleteUsers"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TDeleteWalletsResponse = operations["PublicApiService_DeleteWallets"]["responses"]["200"]["schema"]["activity"]["result"]["deleteWalletsResult"] & definitions["v1ActivityResponse"]; + +export type TDeleteWalletsInput = { body: TDeleteWalletsBody }; + +export type TDeleteWalletsBody = operations["PublicApiService_DeleteWallets"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TEmailAuthResponse = operations["PublicApiService_EmailAuth"]["responses"]["200"]["schema"]["activity"]["result"]["emailAuthResult"] & definitions["v1ActivityResponse"]; + +export type TEmailAuthInput = { body: TEmailAuthBody }; + +export type TEmailAuthBody = operations["PublicApiService_EmailAuth"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TExportPrivateKeyResponse = operations["PublicApiService_ExportPrivateKey"]["responses"]["200"]["schema"]["activity"]["result"]["exportPrivateKeyResult"] & definitions["v1ActivityResponse"]; + +export type TExportPrivateKeyInput = { body: TExportPrivateKeyBody }; + +export type TExportPrivateKeyBody = operations["PublicApiService_ExportPrivateKey"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TExportWalletResponse = operations["PublicApiService_ExportWallet"]["responses"]["200"]["schema"]["activity"]["result"]["exportWalletResult"] & definitions["v1ActivityResponse"]; + +export type TExportWalletInput = { body: TExportWalletBody }; + +export type TExportWalletBody = operations["PublicApiService_ExportWallet"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TExportWalletAccountResponse = operations["PublicApiService_ExportWalletAccount"]["responses"]["200"]["schema"]["activity"]["result"]["exportWalletAccountResult"] & definitions["v1ActivityResponse"]; + +export type TExportWalletAccountInput = { body: TExportWalletAccountBody }; + +export type TExportWalletAccountBody = operations["PublicApiService_ExportWalletAccount"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TImportPrivateKeyResponse = operations["PublicApiService_ImportPrivateKey"]["responses"]["200"]["schema"]["activity"]["result"]["importPrivateKeyResult"] & definitions["v1ActivityResponse"]; + +export type TImportPrivateKeyInput = { body: TImportPrivateKeyBody }; + +export type TImportPrivateKeyBody = operations["PublicApiService_ImportPrivateKey"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TImportWalletResponse = operations["PublicApiService_ImportWallet"]["responses"]["200"]["schema"]["activity"]["result"]["importWalletResult"] & definitions["v1ActivityResponse"]; + +export type TImportWalletInput = { body: TImportWalletBody }; + +export type TImportWalletBody = operations["PublicApiService_ImportWallet"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TInitImportPrivateKeyResponse = operations["PublicApiService_InitImportPrivateKey"]["responses"]["200"]["schema"]["activity"]["result"]["initImportPrivateKeyResult"] & definitions["v1ActivityResponse"]; + +export type TInitImportPrivateKeyInput = { body: TInitImportPrivateKeyBody }; + +export type TInitImportPrivateKeyBody = operations["PublicApiService_InitImportPrivateKey"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TInitImportWalletResponse = operations["PublicApiService_InitImportWallet"]["responses"]["200"]["schema"]["activity"]["result"]["initImportWalletResult"] & definitions["v1ActivityResponse"]; + +export type TInitImportWalletInput = { body: TInitImportWalletBody }; + +export type TInitImportWalletBody = operations["PublicApiService_InitImportWallet"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TInitOtpResponse = operations["PublicApiService_InitOtp"]["responses"]["200"]["schema"]["activity"]["result"]["initOtpResult"] & definitions["v1ActivityResponse"]; + +export type TInitOtpInput = { body: TInitOtpBody }; + +export type TInitOtpBody = operations["PublicApiService_InitOtp"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TInitOtpAuthResponse = operations["PublicApiService_InitOtpAuth"]["responses"]["200"]["schema"]["activity"]["result"]["initOtpAuthResultV2"] & definitions["v1ActivityResponse"]; + +export type TInitOtpAuthInput = { body: TInitOtpAuthBody }; + +export type TInitOtpAuthBody = operations["PublicApiService_InitOtpAuth"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TInitUserEmailRecoveryResponse = operations["PublicApiService_InitUserEmailRecovery"]["responses"]["200"]["schema"]["activity"]["result"]["initUserEmailRecoveryResult"] & definitions["v1ActivityResponse"]; + +export type TInitUserEmailRecoveryInput = { body: TInitUserEmailRecoveryBody }; + +export type TInitUserEmailRecoveryBody = operations["PublicApiService_InitUserEmailRecovery"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TOauthResponse = operations["PublicApiService_Oauth"]["responses"]["200"]["schema"]["activity"]["result"]["oauthResult"] & definitions["v1ActivityResponse"]; + +export type TOauthInput = { body: TOauthBody }; + +export type TOauthBody = operations["PublicApiService_Oauth"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TOauthLoginResponse = operations["PublicApiService_OauthLogin"]["responses"]["200"]["schema"]["activity"]["result"]["oauthLoginResult"] & definitions["v1ActivityResponse"]; + +export type TOauthLoginInput = { body: TOauthLoginBody }; + +export type TOauthLoginBody = operations["PublicApiService_OauthLogin"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TOtpAuthResponse = operations["PublicApiService_OtpAuth"]["responses"]["200"]["schema"]["activity"]["result"]["otpAuthResult"] & definitions["v1ActivityResponse"]; + +export type TOtpAuthInput = { body: TOtpAuthBody }; + +export type TOtpAuthBody = operations["PublicApiService_OtpAuth"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TOtpLoginResponse = operations["PublicApiService_OtpLogin"]["responses"]["200"]["schema"]["activity"]["result"]["otpLoginResult"] & definitions["v1ActivityResponse"]; + +export type TOtpLoginInput = { body: TOtpLoginBody }; + +export type TOtpLoginBody = operations["PublicApiService_OtpLogin"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TRecoverUserResponse = operations["PublicApiService_RecoverUser"]["responses"]["200"]["schema"]["activity"]["result"]["recoverUserResult"] & definitions["v1ActivityResponse"]; + +export type TRecoverUserInput = { body: TRecoverUserBody }; + +export type TRecoverUserBody = operations["PublicApiService_RecoverUser"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TRejectActivityResponse = operations["PublicApiService_RejectActivity"]["responses"]["200"]["schema"]["activity"]["result"] & definitions["v1ActivityResponse"]; + +export type TRejectActivityInput = { body: TRejectActivityBody }; + +export type TRejectActivityBody = operations["PublicApiService_RejectActivity"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TRemoveOrganizationFeatureResponse = operations["PublicApiService_RemoveOrganizationFeature"]["responses"]["200"]["schema"]["activity"]["result"]["removeOrganizationFeatureResult"] & definitions["v1ActivityResponse"]; + +export type TRemoveOrganizationFeatureInput = { body: TRemoveOrganizationFeatureBody }; + +export type TRemoveOrganizationFeatureBody = operations["PublicApiService_RemoveOrganizationFeature"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TSetOrganizationFeatureResponse = operations["PublicApiService_SetOrganizationFeature"]["responses"]["200"]["schema"]["activity"]["result"]["setOrganizationFeatureResult"] & definitions["v1ActivityResponse"]; + +export type TSetOrganizationFeatureInput = { body: TSetOrganizationFeatureBody }; + +export type TSetOrganizationFeatureBody = operations["PublicApiService_SetOrganizationFeature"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TSignRawPayloadResponse = operations["PublicApiService_SignRawPayload"]["responses"]["200"]["schema"]["activity"]["result"]["signRawPayloadResult"] & definitions["v1ActivityResponse"]; + +export type TSignRawPayloadInput = { body: TSignRawPayloadBody }; + +export type TSignRawPayloadBody = operations["PublicApiService_SignRawPayload"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TSignRawPayloadsResponse = operations["PublicApiService_SignRawPayloads"]["responses"]["200"]["schema"]["activity"]["result"]["signRawPayloadsResult"] & definitions["v1ActivityResponse"]; + +export type TSignRawPayloadsInput = { body: TSignRawPayloadsBody }; + +export type TSignRawPayloadsBody = operations["PublicApiService_SignRawPayloads"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TSignTransactionResponse = operations["PublicApiService_SignTransaction"]["responses"]["200"]["schema"]["activity"]["result"]["signTransactionResult"] & definitions["v1ActivityResponse"]; + +export type TSignTransactionInput = { body: TSignTransactionBody }; + +export type TSignTransactionBody = operations["PublicApiService_SignTransaction"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TStampLoginResponse = operations["PublicApiService_StampLogin"]["responses"]["200"]["schema"]["activity"]["result"]["stampLoginResult"] & definitions["v1ActivityResponse"]; + +export type TStampLoginInput = { body: TStampLoginBody }; + +export type TStampLoginBody = operations["PublicApiService_StampLogin"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TUpdatePolicyResponse = operations["PublicApiService_UpdatePolicy"]["responses"]["200"]["schema"]["activity"]["result"]["updatePolicyResultV2"] & definitions["v1ActivityResponse"]; + +export type TUpdatePolicyInput = { body: TUpdatePolicyBody }; + +export type TUpdatePolicyBody = operations["PublicApiService_UpdatePolicy"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TUpdatePrivateKeyTagResponse = operations["PublicApiService_UpdatePrivateKeyTag"]["responses"]["200"]["schema"]["activity"]["result"]["updatePrivateKeyTagResult"] & definitions["v1ActivityResponse"]; + +export type TUpdatePrivateKeyTagInput = { body: TUpdatePrivateKeyTagBody }; + +export type TUpdatePrivateKeyTagBody = operations["PublicApiService_UpdatePrivateKeyTag"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TUpdateRootQuorumResponse = operations["PublicApiService_UpdateRootQuorum"]["responses"]["200"]["schema"]["activity"]["result"]["updateRootQuorumResult"] & definitions["v1ActivityResponse"]; + +export type TUpdateRootQuorumInput = { body: TUpdateRootQuorumBody }; + +export type TUpdateRootQuorumBody = operations["PublicApiService_UpdateRootQuorum"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TUpdateUserResponse = operations["PublicApiService_UpdateUser"]["responses"]["200"]["schema"]["activity"]["result"]["updateUserResult"] & definitions["v1ActivityResponse"]; + +export type TUpdateUserInput = { body: TUpdateUserBody }; + +export type TUpdateUserBody = operations["PublicApiService_UpdateUser"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TUpdateUserTagResponse = operations["PublicApiService_UpdateUserTag"]["responses"]["200"]["schema"]["activity"]["result"]["updateUserTagResult"] & definitions["v1ActivityResponse"]; + +export type TUpdateUserTagInput = { body: TUpdateUserTagBody }; + +export type TUpdateUserTagBody = operations["PublicApiService_UpdateUserTag"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TUpdateWalletResponse = operations["PublicApiService_UpdateWallet"]["responses"]["200"]["schema"]["activity"]["result"]["updateWalletResult"] & definitions["v1ActivityResponse"]; + +export type TUpdateWalletInput = { body: TUpdateWalletBody }; + +export type TUpdateWalletBody = operations["PublicApiService_UpdateWallet"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TVerifyOtpResponse = operations["PublicApiService_VerifyOtp"]["responses"]["200"]["schema"]["activity"]["result"]["verifyOtpResult"] & definitions["v1ActivityResponse"]; + +export type TVerifyOtpInput = { body: TVerifyOtpBody }; + +export type TVerifyOtpBody = operations["PublicApiService_VerifyOtp"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; + +export type TNOOPCodegenAnchorResponse = operations["PublicApiService_NOOPCodegenAnchor"]["responses"]["200"]["schema"]; + +export type TTestRateLimitsResponse = operations["PublicApiService_TestRateLimits"]["responses"]["200"]["schema"]; + +export type TTestRateLimitsInput = { body: TTestRateLimitsBody }; + +export type TTestRateLimitsBody = Omit & queryOverrideParams; \ No newline at end of file diff --git a/packages/sdk-js/src/__generated__/version.ts b/packages/sdk-js/src/__generated__/version.ts new file mode 100644 index 000000000..e2c300701 --- /dev/null +++ b/packages/sdk-js/src/__generated__/version.ts @@ -0,0 +1 @@ +export const VERSION = "@turnkey/sdk-js@0.1.0"; diff --git a/packages/sdk-js/src/__inputs__/public_api.swagger.json b/packages/sdk-js/src/__inputs__/public_api.swagger.json new file mode 100644 index 000000000..b5e0170ad --- /dev/null +++ b/packages/sdk-js/src/__inputs__/public_api.swagger.json @@ -0,0 +1,9880 @@ +{ + "swagger": "2.0", + "info": { + "title": "API Reference", + "description": "Review our [API Introduction](../api-introduction) to get started.", + "version": "1.0", + "contact": {} + }, + "tags": [ + { + "name": "PublicApiService" + }, + { + "name": "Organizations", + "description": "An Organization is the highest level of hierarchy in Turnkey. It can contain many Users, Private Keys, and Policies managed by a Root Quorum. The Root Quorum consists of a set of Users with a consensus threshold. This consensus threshold must be reached by Quorum members in order for any actions to take place.\n\nSee [Root Quorum](../concepts/users/root-quorum) for more information" + }, + { + "name": "Invitations", + "description": "Invitations allow you to invite Users into your Organization via email. Alternatively, Users can be added directly without an Invitation if their ApiKey or Authenticator credentials are known ahead of time.\n\nSee [Users](./api#tag/Users) for more information" + }, + { + "name": "Policies", + "description": "Policies allow for deep customization of the security of your Organization. They can be used to grant permissions or restrict usage of Users and Private Keys. The Policy Engine analyzes all of your Policies on each request to determine whether an Activity is allowed.\n\nSee [Policy Overview](../managing-policies/overview) for more information" + }, + { + "name": "Wallets", + "description": "Wallets contain collections of deterministically generated cryptographic public / private key pairs that share a common seed. Turnkey securely holds the common seed, but only you can access it. In most cases, Wallets should be preferred over Private Keys since they can be represented by a mnemonic phrase, used across a variety of cryptographic curves, and can derive many addresses.\n\nDerived addresses can be used to create digital signatures using the corresponding underlying private key. See [Signing](./api#tag/Signing) for more information" + }, + { + "name": "Signing", + "description": "Signers allow you to create digital signatures. Signatures are used to validate the authenticity and integrity of a digital message. Turnkey makes it easy to produce signatures by allowing you to sign with an address. If Turnkey doesn't yet support an address format you need, you can generate and sign with the public key instead by using the address format `ADDRESS_FORMAT_COMPRESSED`." + }, + { + "name": "Private Keys", + "description": "Private Keys are cryptographic public / private key pairs that can be used for cryptocurrency needs or more generalized encryption. Turnkey securely holds all private key materials for you, but only you can access them.\n\nThe Private Key ID or any derived address can be used to create digital signatures. See [Signing](./api#tag/Signing) for more information" + }, + { + "name": "Private Key Tags", + "description": "Private Key Tags allow you to easily group and permission Private Keys through Policies." + }, + { + "name": "Users", + "description": "Users are responsible for any action taken within an Organization. They can have ApiKey or Auuthenticator credentials, allowing you to onboard teammates to the Organization, or create API-only Users to run as part of your infrastructure." + }, + { + "name": "User Tags", + "description": "User Key Tags allow you to easily group and permission Users through Policies." + }, + { + "name": "Authenticators", + "description": "Authenticators are WebAuthN hardware devices, such as a Macbook TouchID or Yubikey, that can be used to authenticate requests." + }, + { + "name": "API Keys", + "description": "API Keys are used to authenticate requests\n\nSee our [CLI](https://github.com/tkhq/tkcli) for instructions on generating API Keys" + }, + { + "name": "Activities", + "description": "Activities encapsulate all the possible actions that can be taken with Turnkey. Some examples include adding a new user, creating a private key, and signing a transaction.\n\nActivities that modify your Organization are processed asynchronously. To confirm processing is complete and retrieve the Activity results, these activities must be polled until that status has been updated to a finalized state: `COMPLETED` when the activity is successful or `FAILED` when the activity has failed" + }, + { + "name": "Consensus", + "description": "Policies can enforce consensus requirements for Activities. For example, adding a new user requires two admins to approve the request.\n\nActivities that have been proposed, but don't yet meet the Consesnsus requirements will have the status: `REQUIRES_CONSENSUS`. Activities in this state can be approved or rejected using the unique fingerprint generated when an Activity is created." + } + ], + "host": "api.turnkey.com", + "schemes": ["https"], + "consumes": ["application/json"], + "produces": ["application/json"], + "paths": { + "/public/v1/query/get_activity": { + "post": { + "summary": "Get Activity", + "description": "Get details about an Activity", + "operationId": "PublicApiService_GetActivity", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1GetActivityRequest" + } + } + ], + "tags": ["Activities"] + } + }, + "/public/v1/query/get_api_key": { + "post": { + "summary": "Get API key", + "description": "Get details about an API key", + "operationId": "PublicApiService_GetApiKey", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetApiKeyResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1GetApiKeyRequest" + } + } + ], + "tags": ["API keys"] + } + }, + "/public/v1/query/get_api_keys": { + "post": { + "summary": "Get API keys", + "description": "Get details about API keys for a user", + "operationId": "PublicApiService_GetApiKeys", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetApiKeysResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1GetApiKeysRequest" + } + } + ], + "tags": ["API keys"] + } + }, + "/public/v1/query/get_attestation": { + "post": { + "summary": "Attestation", + "description": "Get the attestation document corresponding to an enclave.", + "operationId": "PublicApiService_GetAttestationDocument", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetAttestationDocumentResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1GetAttestationDocumentRequest" + } + } + ], + "tags": ["Attestation"] + } + }, + "/public/v1/query/get_authenticator": { + "post": { + "summary": "Get Authenticator", + "description": "Get details about an authenticator", + "operationId": "PublicApiService_GetAuthenticator", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetAuthenticatorResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1GetAuthenticatorRequest" + } + } + ], + "tags": ["Authenticators"] + } + }, + "/public/v1/query/get_authenticators": { + "post": { + "summary": "Get Authenticators", + "description": "Get details about authenticators for a user", + "operationId": "PublicApiService_GetAuthenticators", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetAuthenticatorsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1GetAuthenticatorsRequest" + } + } + ], + "tags": ["Authenticators"] + } + }, + "/public/v1/query/get_oauth_providers": { + "post": { + "summary": "Get Oauth providers", + "description": "Get details about Oauth providers for a user", + "operationId": "PublicApiService_GetOauthProviders", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetOauthProvidersResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1GetOauthProvidersRequest" + } + } + ], + "tags": ["User Auth"] + } + }, + "/public/v1/query/get_organization": { + "post": { + "summary": "Get Organization", + "description": "Get details about an Organization", + "operationId": "PublicApiService_GetOrganization", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetOrganizationResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1GetOrganizationRequest" + } + } + ], + "tags": ["Organizations"] + } + }, + "/public/v1/query/get_organization_configs": { + "post": { + "summary": "Get Configs", + "description": "Get quorum settings and features for an organization", + "operationId": "PublicApiService_GetOrganizationConfigs", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetOrganizationConfigsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1GetOrganizationConfigsRequest" + } + } + ], + "tags": ["Organizations"] + } + }, + "/public/v1/query/get_policy": { + "post": { + "summary": "Get Policy", + "description": "Get details about a Policy", + "operationId": "PublicApiService_GetPolicy", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetPolicyResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1GetPolicyRequest" + } + } + ], + "tags": ["Policies"] + } + }, + "/public/v1/query/get_private_key": { + "post": { + "summary": "Get Private Key", + "description": "Get details about a Private Key", + "operationId": "PublicApiService_GetPrivateKey", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetPrivateKeyResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1GetPrivateKeyRequest" + } + } + ], + "tags": ["Private Keys"] + } + }, + "/public/v1/query/get_user": { + "post": { + "summary": "Get User", + "description": "Get details about a User", + "operationId": "PublicApiService_GetUser", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetUserResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1GetUserRequest" + } + } + ], + "tags": ["Users"] + } + }, + "/public/v1/query/get_wallet": { + "post": { + "summary": "Get Wallet", + "description": "Get details about a Wallet", + "operationId": "PublicApiService_GetWallet", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetWalletResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1GetWalletRequest" + } + } + ], + "tags": ["Wallets"] + } + }, + "/public/v1/query/get_wallet_account": { + "post": { + "summary": "Get Wallet Account", + "description": "Get a single wallet account", + "operationId": "PublicApiService_GetWalletAccount", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetWalletAccountResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1GetWalletAccountRequest" + } + } + ], + "tags": ["Wallets"] + } + }, + "/public/v1/query/list_activities": { + "post": { + "summary": "List Activities", + "description": "List all Activities within an Organization", + "operationId": "PublicApiService_GetActivities", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetActivitiesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1GetActivitiesRequest" + } + } + ], + "tags": ["Activities"] + } + }, + "/public/v1/query/list_policies": { + "post": { + "summary": "List Policies", + "description": "List all Policies within an Organization", + "operationId": "PublicApiService_GetPolicies", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetPoliciesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1GetPoliciesRequest" + } + } + ], + "tags": ["Policies"] + } + }, + "/public/v1/query/list_private_key_tags": { + "post": { + "summary": "List Private Key Tags", + "description": "List all Private Key Tags within an Organization", + "operationId": "PublicApiService_ListPrivateKeyTags", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ListPrivateKeyTagsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1ListPrivateKeyTagsRequest" + } + } + ], + "tags": ["Private Key Tags"] + } + }, + "/public/v1/query/list_private_keys": { + "post": { + "summary": "List Private Keys", + "description": "List all Private Keys within an Organization", + "operationId": "PublicApiService_GetPrivateKeys", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetPrivateKeysResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1GetPrivateKeysRequest" + } + } + ], + "tags": ["Private Keys"] + } + }, + "/public/v1/query/list_suborgs": { + "post": { + "summary": "Get Suborgs", + "description": "Get all suborg IDs associated given a parent org ID and an optional filter.", + "operationId": "PublicApiService_GetSubOrgIds", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetSubOrgIdsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1GetSubOrgIdsRequest" + } + } + ], + "tags": ["Organizations"] + } + }, + "/public/v1/query/list_user_tags": { + "post": { + "summary": "List User Tags", + "description": "List all User Tags within an Organization", + "operationId": "PublicApiService_ListUserTags", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ListUserTagsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1ListUserTagsRequest" + } + } + ], + "tags": ["User Tags"] + } + }, + "/public/v1/query/list_users": { + "post": { + "summary": "List Users", + "description": "List all Users within an Organization", + "operationId": "PublicApiService_GetUsers", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetUsersResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1GetUsersRequest" + } + } + ], + "tags": ["Users"] + } + }, + "/public/v1/query/list_verified_suborgs": { + "post": { + "summary": "Get Verified Suborgs", + "description": "Get all email or phone verified suborg IDs associated given a parent org ID.", + "operationId": "PublicApiService_GetVerifiedSubOrgIds", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetVerifiedSubOrgIdsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1GetVerifiedSubOrgIdsRequest" + } + } + ], + "tags": ["Organizations"] + } + }, + "/public/v1/query/list_wallet_accounts": { + "post": { + "summary": "List Wallets Accounts", + "description": "List all Accounts within a Wallet", + "operationId": "PublicApiService_GetWalletAccounts", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetWalletAccountsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1GetWalletAccountsRequest" + } + } + ], + "tags": ["Wallets"] + } + }, + "/public/v1/query/list_wallets": { + "post": { + "summary": "List Wallets", + "description": "List all Wallets within an Organization", + "operationId": "PublicApiService_GetWallets", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetWalletsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1GetWalletsRequest" + } + } + ], + "tags": ["Wallets"] + } + }, + "/public/v1/query/whoami": { + "post": { + "summary": "Who am I?", + "description": "Get basic information about your current API or WebAuthN user and their organization. Affords Sub-Organization look ups via Parent Organization for WebAuthN or API key users.", + "operationId": "PublicApiService_GetWhoami", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetWhoamiResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1GetWhoamiRequest" + } + } + ], + "tags": ["Sessions"] + } + }, + "/public/v1/submit/approve_activity": { + "post": { + "summary": "Approve Activity", + "description": "Approve an Activity", + "operationId": "PublicApiService_ApproveActivity", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1ApproveActivityRequest" + } + } + ], + "tags": ["Consensus"] + } + }, + "/public/v1/submit/create_api_keys": { + "post": { + "summary": "Create API Keys", + "description": "Add api keys to an existing User", + "operationId": "PublicApiService_CreateApiKeys", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1CreateApiKeysRequest" + } + } + ], + "tags": ["API Keys"] + } + }, + "/public/v1/submit/create_api_only_users": { + "post": { + "summary": "Create API-only Users", + "description": "Create API-only Users in an existing Organization", + "operationId": "PublicApiService_CreateApiOnlyUsers", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1CreateApiOnlyUsersRequest" + } + } + ], + "tags": ["Users"] + } + }, + "/public/v1/submit/create_authenticators": { + "post": { + "summary": "Create Authenticators", + "description": "Create Authenticators to authenticate requests to Turnkey", + "operationId": "PublicApiService_CreateAuthenticators", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1CreateAuthenticatorsRequest" + } + } + ], + "tags": ["Authenticators"] + } + }, + "/public/v1/submit/create_invitations": { + "post": { + "summary": "Create Invitations", + "description": "Create Invitations to join an existing Organization", + "operationId": "PublicApiService_CreateInvitations", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1CreateInvitationsRequest" + } + } + ], + "tags": ["Invitations"] + } + }, + "/public/v1/submit/create_oauth_providers": { + "post": { + "summary": "Create Oauth Providers", + "description": "Creates Oauth providers for a specified user - BETA", + "operationId": "PublicApiService_CreateOauthProviders", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1CreateOauthProvidersRequest" + } + } + ], + "tags": ["User Auth"] + } + }, + "/public/v1/submit/create_policies": { + "post": { + "summary": "Create Policies", + "description": "Create new Policies", + "operationId": "PublicApiService_CreatePolicies", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1CreatePoliciesRequest" + } + } + ], + "tags": ["Policies"] + } + }, + "/public/v1/submit/create_policy": { + "post": { + "summary": "Create Policy", + "description": "Create a new Policy", + "operationId": "PublicApiService_CreatePolicy", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1CreatePolicyRequest" + } + } + ], + "tags": ["Policies"] + } + }, + "/public/v1/submit/create_private_key_tag": { + "post": { + "summary": "Create Private Key Tag", + "description": "Create a private key tag and add it to private keys.", + "operationId": "PublicApiService_CreatePrivateKeyTag", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1CreatePrivateKeyTagRequest" + } + } + ], + "tags": ["Private Key Tags"] + } + }, + "/public/v1/submit/create_private_keys": { + "post": { + "summary": "Create Private Keys", + "description": "Create new Private Keys", + "operationId": "PublicApiService_CreatePrivateKeys", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1CreatePrivateKeysRequest" + } + } + ], + "tags": ["Private Keys"] + } + }, + "/public/v1/submit/create_read_only_session": { + "post": { + "summary": "Create Read Only Session", + "description": "Create a read only session for a user (valid for 1 hour)", + "operationId": "PublicApiService_CreateReadOnlySession", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1CreateReadOnlySessionRequest" + } + } + ], + "tags": ["Sessions"] + } + }, + "/public/v1/submit/create_read_write_session": { + "post": { + "summary": "Create Read Write Session", + "description": "Create a read write session for a user", + "operationId": "PublicApiService_CreateReadWriteSession", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1CreateReadWriteSessionRequest" + } + } + ], + "tags": ["Sessions"] + } + }, + "/public/v1/submit/create_sub_organization": { + "post": { + "summary": "Create Sub-Organization", + "description": "Create a new Sub-Organization", + "operationId": "PublicApiService_CreateSubOrganization", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1CreateSubOrganizationRequest" + } + } + ], + "tags": ["Organizations"] + } + }, + "/public/v1/submit/create_user_tag": { + "post": { + "summary": "Create User Tag", + "description": "Create a user tag and add it to users.", + "operationId": "PublicApiService_CreateUserTag", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1CreateUserTagRequest" + } + } + ], + "tags": ["User Tags"] + } + }, + "/public/v1/submit/create_users": { + "post": { + "summary": "Create Users", + "description": "Create Users in an existing Organization", + "operationId": "PublicApiService_CreateUsers", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1CreateUsersRequest" + } + } + ], + "tags": ["Users"] + } + }, + "/public/v1/submit/create_wallet": { + "post": { + "summary": "Create Wallet", + "description": "Create a Wallet and derive addresses", + "operationId": "PublicApiService_CreateWallet", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1CreateWalletRequest" + } + } + ], + "tags": ["Wallets"] + } + }, + "/public/v1/submit/create_wallet_accounts": { + "post": { + "summary": "Create Wallet Accounts", + "description": "Derive additional addresses using an existing wallet", + "operationId": "PublicApiService_CreateWalletAccounts", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1CreateWalletAccountsRequest" + } + } + ], + "tags": ["Wallets"] + } + }, + "/public/v1/submit/delete_api_keys": { + "post": { + "summary": "Delete API Keys", + "description": "Remove api keys from a User", + "operationId": "PublicApiService_DeleteApiKeys", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1DeleteApiKeysRequest" + } + } + ], + "tags": ["API Keys"] + } + }, + "/public/v1/submit/delete_authenticators": { + "post": { + "summary": "Delete Authenticators", + "description": "Remove authenticators from a User", + "operationId": "PublicApiService_DeleteAuthenticators", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1DeleteAuthenticatorsRequest" + } + } + ], + "tags": ["Authenticators"] + } + }, + "/public/v1/submit/delete_invitation": { + "post": { + "summary": "Delete Invitation", + "description": "Delete an existing Invitation", + "operationId": "PublicApiService_DeleteInvitation", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1DeleteInvitationRequest" + } + } + ], + "tags": ["Invitations"] + } + }, + "/public/v1/submit/delete_oauth_providers": { + "post": { + "summary": "Delete Oauth Providers", + "description": "Removes Oauth providers for a specified user - BETA", + "operationId": "PublicApiService_DeleteOauthProviders", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1DeleteOauthProvidersRequest" + } + } + ], + "tags": ["User Auth"] + } + }, + "/public/v1/submit/delete_policy": { + "post": { + "summary": "Delete Policy", + "description": "Delete an existing Policy", + "operationId": "PublicApiService_DeletePolicy", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1DeletePolicyRequest" + } + } + ], + "tags": ["Policies"] + } + }, + "/public/v1/submit/delete_private_key_tags": { + "post": { + "summary": "Delete Private Key Tags", + "description": "Delete Private Key Tags within an Organization", + "operationId": "PublicApiService_DeletePrivateKeyTags", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1DeletePrivateKeyTagsRequest" + } + } + ], + "tags": ["Private Key Tags"] + } + }, + "/public/v1/submit/delete_private_keys": { + "post": { + "summary": "Delete Private Keys", + "description": "Deletes private keys for an organization", + "operationId": "PublicApiService_DeletePrivateKeys", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1DeletePrivateKeysRequest" + } + } + ], + "tags": ["Private Keys"] + } + }, + "/public/v1/submit/delete_sub_organization": { + "post": { + "summary": "Delete Sub Organization", + "description": "Deletes a sub organization", + "operationId": "PublicApiService_DeleteSubOrganization", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1DeleteSubOrganizationRequest" + } + } + ], + "tags": ["Organizations"] + } + }, + "/public/v1/submit/delete_user_tags": { + "post": { + "summary": "Delete User Tags", + "description": "Delete User Tags within an Organization", + "operationId": "PublicApiService_DeleteUserTags", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1DeleteUserTagsRequest" + } + } + ], + "tags": ["User Tags"] + } + }, + "/public/v1/submit/delete_users": { + "post": { + "summary": "Delete Users", + "description": "Delete Users within an Organization", + "operationId": "PublicApiService_DeleteUsers", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1DeleteUsersRequest" + } + } + ], + "tags": ["Users"] + } + }, + "/public/v1/submit/delete_wallets": { + "post": { + "summary": "Delete Wallets", + "description": "Deletes wallets for an organization", + "operationId": "PublicApiService_DeleteWallets", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1DeleteWalletsRequest" + } + } + ], + "tags": ["Wallets"] + } + }, + "/public/v1/submit/email_auth": { + "post": { + "summary": "Perform Email Auth", + "description": "Authenticate a user via Email", + "operationId": "PublicApiService_EmailAuth", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1EmailAuthRequest" + } + } + ], + "tags": ["User Auth"] + } + }, + "/public/v1/submit/export_private_key": { + "post": { + "summary": "Export Private Key", + "description": "Exports a Private Key", + "operationId": "PublicApiService_ExportPrivateKey", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1ExportPrivateKeyRequest" + } + } + ], + "tags": ["Private Keys"] + } + }, + "/public/v1/submit/export_wallet": { + "post": { + "summary": "Export Wallet", + "description": "Exports a Wallet", + "operationId": "PublicApiService_ExportWallet", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1ExportWalletRequest" + } + } + ], + "tags": ["Wallets"] + } + }, + "/public/v1/submit/export_wallet_account": { + "post": { + "summary": "Export Wallet Account", + "description": "Exports a Wallet Account", + "operationId": "PublicApiService_ExportWalletAccount", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1ExportWalletAccountRequest" + } + } + ], + "tags": ["Wallets"] + } + }, + "/public/v1/submit/import_private_key": { + "post": { + "summary": "Import Private Key", + "description": "Imports a private key", + "operationId": "PublicApiService_ImportPrivateKey", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1ImportPrivateKeyRequest" + } + } + ], + "tags": ["Private Keys"] + } + }, + "/public/v1/submit/import_wallet": { + "post": { + "summary": "Import Wallet", + "description": "Imports a wallet", + "operationId": "PublicApiService_ImportWallet", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1ImportWalletRequest" + } + } + ], + "tags": ["Wallets"] + } + }, + "/public/v1/submit/init_import_private_key": { + "post": { + "summary": "Init Import Private Key", + "description": "Initializes a new private key import", + "operationId": "PublicApiService_InitImportPrivateKey", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1InitImportPrivateKeyRequest" + } + } + ], + "tags": ["Private Keys"] + } + }, + "/public/v1/submit/init_import_wallet": { + "post": { + "summary": "Init Import Wallet", + "description": "Initializes a new wallet import", + "operationId": "PublicApiService_InitImportWallet", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1InitImportWalletRequest" + } + } + ], + "tags": ["Wallets"] + } + }, + "/public/v1/submit/init_otp": { + "post": { + "summary": "Init Generic OTP", + "description": "Initiate a Generic OTP activity", + "operationId": "PublicApiService_InitOtp", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1InitOtpRequest" + } + } + ], + "tags": ["User Verification"] + } + }, + "/public/v1/submit/init_otp_auth": { + "post": { + "summary": "Init OTP auth", + "description": "Initiate an OTP auth activity", + "operationId": "PublicApiService_InitOtpAuth", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1InitOtpAuthRequest" + } + } + ], + "tags": ["User Auth"] + } + }, + "/public/v1/submit/init_user_email_recovery": { + "post": { + "summary": "Init Email Recovery", + "description": "Initializes a new email recovery", + "operationId": "PublicApiService_InitUserEmailRecovery", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1InitUserEmailRecoveryRequest" + } + } + ], + "tags": ["User Recovery"] + } + }, + "/public/v1/submit/oauth": { + "post": { + "summary": "Oauth", + "description": "Authenticate a user with an Oidc token (Oauth) - BETA", + "operationId": "PublicApiService_Oauth", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1OauthRequest" + } + } + ], + "tags": ["User Auth"] + } + }, + "/public/v1/submit/oauth_login": { + "post": { + "summary": "Login with Oauth", + "description": "Create an Oauth session for a user", + "operationId": "PublicApiService_OauthLogin", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1OauthLoginRequest" + } + } + ], + "tags": ["Sessions"] + } + }, + "/public/v1/submit/otp_auth": { + "post": { + "summary": "OTP auth", + "description": "Authenticate a user with an OTP code sent via email or SMS", + "operationId": "PublicApiService_OtpAuth", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1OtpAuthRequest" + } + } + ], + "tags": ["User Auth"] + } + }, + "/public/v1/submit/otp_login": { + "post": { + "summary": "Login with OTP", + "description": "Create an OTP session for a user", + "operationId": "PublicApiService_OtpLogin", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1OtpLoginRequest" + } + } + ], + "tags": ["Sessions"] + } + }, + "/public/v1/submit/recover_user": { + "post": { + "summary": "Recover a user", + "description": "Completes the process of recovering a user by adding an authenticator", + "operationId": "PublicApiService_RecoverUser", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1RecoverUserRequest" + } + } + ], + "tags": ["User Recovery"] + } + }, + "/public/v1/submit/reject_activity": { + "post": { + "summary": "Reject Activity", + "description": "Reject an Activity", + "operationId": "PublicApiService_RejectActivity", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1RejectActivityRequest" + } + } + ], + "tags": ["Consensus"] + } + }, + "/public/v1/submit/remove_organization_feature": { + "post": { + "summary": "Remove Organization Feature", + "description": "Removes an organization feature. This activity must be approved by the current root quorum.", + "operationId": "PublicApiService_RemoveOrganizationFeature", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1RemoveOrganizationFeatureRequest" + } + } + ], + "tags": ["Features"] + } + }, + "/public/v1/submit/set_organization_feature": { + "post": { + "summary": "Set Organization Feature", + "description": "Sets an organization feature. This activity must be approved by the current root quorum.", + "operationId": "PublicApiService_SetOrganizationFeature", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1SetOrganizationFeatureRequest" + } + } + ], + "tags": ["Features"] + } + }, + "/public/v1/submit/sign_raw_payload": { + "post": { + "summary": "Sign Raw Payload", + "description": "Sign a raw payload", + "operationId": "PublicApiService_SignRawPayload", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1SignRawPayloadRequest" + } + } + ], + "tags": ["Signing"] + } + }, + "/public/v1/submit/sign_raw_payloads": { + "post": { + "summary": "Sign Raw Payloads", + "description": "Sign multiple raw payloads with the same signing parameters", + "operationId": "PublicApiService_SignRawPayloads", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1SignRawPayloadsRequest" + } + } + ], + "tags": ["Signing"] + } + }, + "/public/v1/submit/sign_transaction": { + "post": { + "summary": "Sign Transaction", + "description": "Sign a transaction", + "operationId": "PublicApiService_SignTransaction", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1SignTransactionRequest" + } + } + ], + "tags": ["Signing"] + } + }, + "/public/v1/submit/stamp_login": { + "post": { + "summary": "Login with a Stamp", + "description": "Create a session for a user through stamping client side (api key, wallet client, or passkey client)", + "operationId": "PublicApiService_StampLogin", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1StampLoginRequest" + } + } + ], + "tags": ["Sessions"] + } + }, + "/public/v1/submit/update_policy": { + "post": { + "summary": "Update Policy", + "description": "Update an existing Policy", + "operationId": "PublicApiService_UpdatePolicy", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1UpdatePolicyRequest" + } + } + ], + "tags": ["Policies"] + } + }, + "/public/v1/submit/update_private_key_tag": { + "post": { + "summary": "Update Private Key Tag", + "description": "Update human-readable name or associated private keys. Note that this activity is atomic: all of the updates will succeed at once, or all of them will fail.", + "operationId": "PublicApiService_UpdatePrivateKeyTag", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1UpdatePrivateKeyTagRequest" + } + } + ], + "tags": ["Private Key Tags"] + } + }, + "/public/v1/submit/update_root_quorum": { + "post": { + "summary": "Update Root Quorum", + "description": "Set the threshold and members of the root quorum. This activity must be approved by the current root quorum.", + "operationId": "PublicApiService_UpdateRootQuorum", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1UpdateRootQuorumRequest" + } + } + ], + "tags": ["Organizations"] + } + }, + "/public/v1/submit/update_user": { + "post": { + "summary": "Update User", + "description": "Update a User in an existing Organization", + "operationId": "PublicApiService_UpdateUser", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1UpdateUserRequest" + } + } + ], + "tags": ["Users"] + } + }, + "/public/v1/submit/update_user_tag": { + "post": { + "summary": "Update User Tag", + "description": "Update human-readable name or associated users. Note that this activity is atomic: all of the updates will succeed at once, or all of them will fail.", + "operationId": "PublicApiService_UpdateUserTag", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1UpdateUserTagRequest" + } + } + ], + "tags": ["User Tags"] + } + }, + "/public/v1/submit/update_wallet": { + "post": { + "summary": "Update Wallet", + "description": "Update a wallet for an organization", + "operationId": "PublicApiService_UpdateWallet", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1UpdateWalletRequest" + } + } + ], + "tags": ["Wallets"] + } + }, + "/public/v1/submit/verify_otp": { + "post": { + "summary": "Verify Generic OTP", + "description": "Verify a Generic OTP", + "operationId": "PublicApiService_VerifyOtp", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1VerifyOtpRequest" + } + } + ], + "tags": ["User Verification"] + } + }, + "/tkhq/api/v1/noop-codegen-anchor": { + "post": { + "operationId": "PublicApiService_NOOPCodegenAnchor", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1NOOPCodegenAnchorResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "tags": ["PublicApiService"] + } + }, + "/tkhq/api/v1/test_rate_limits": { + "post": { + "summary": "Test Rate Limit", + "description": "Set a rate local rate limit just on the current endpoint, for purposes of testing with Vivosuite", + "operationId": "PublicApiService_TestRateLimits", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1TestRateLimitsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1TestRateLimitsRequest" + } + } + ], + "tags": ["RateLimit"] + } + } + }, + "definitions": { + "apiApiKeyParams": { + "type": "object", + "properties": { + "apiKeyName": { + "type": "string", + "description": "Human-readable name for an API Key." + }, + "publicKey": { + "type": "string", + "description": "The public component of a cryptographic key pair used to sign messages and transactions." + }, + "expirationSeconds": { + "type": "string", + "description": "Optional window (in seconds) indicating how long the API Key should last." + } + }, + "required": ["apiKeyName", "publicKey"] + }, + "billingActivateBillingTierIntent": { + "type": "object", + "properties": { + "productId": { + "type": "string", + "description": "The product that the customer wants to subscribe to." + } + }, + "required": ["productId"] + }, + "billingActivateBillingTierResult": { + "type": "object", + "properties": { + "productId": { + "type": "string", + "description": "The id of the product being subscribed to." + } + }, + "required": ["productId"] + }, + "billingDeletePaymentMethodIntent": { + "type": "object", + "properties": { + "paymentMethodId": { + "type": "string", + "description": "The payment method that the customer wants to remove." + } + }, + "required": ["paymentMethodId"] + }, + "billingDeletePaymentMethodResult": { + "type": "object", + "properties": { + "paymentMethodId": { + "type": "string", + "description": "The payment method that was removed." + } + }, + "required": ["paymentMethodId"] + }, + "billingSetPaymentMethodIntent": { + "type": "object", + "properties": { + "number": { + "type": "string", + "description": "The account number of the customer's credit card." + }, + "cvv": { + "type": "string", + "description": "The verification digits of the customer's credit card." + }, + "expiryMonth": { + "type": "string", + "description": "The month that the credit card expires." + }, + "expiryYear": { + "type": "string", + "description": "The year that the credit card expires." + }, + "cardHolderEmail": { + "type": "string", + "description": "The email that will receive invoices for the credit card." + }, + "cardHolderName": { + "type": "string", + "description": "The name associated with the credit card." + } + }, + "required": [ + "number", + "cvv", + "expiryMonth", + "expiryYear", + "cardHolderEmail", + "cardHolderName" + ] + }, + "billingSetPaymentMethodIntentV2": { + "type": "object", + "properties": { + "paymentMethodId": { + "type": "string", + "description": "The id of the payment method that was created clientside." + }, + "cardHolderEmail": { + "type": "string", + "description": "The email that will receive invoices for the credit card." + }, + "cardHolderName": { + "type": "string", + "description": "The name associated with the credit card." + } + }, + "required": ["paymentMethodId", "cardHolderEmail", "cardHolderName"] + }, + "billingSetPaymentMethodResult": { + "type": "object", + "properties": { + "lastFour": { + "type": "string", + "description": "The last four digits of the credit card added." + }, + "cardHolderName": { + "type": "string", + "description": "The name associated with the payment method." + }, + "cardHolderEmail": { + "type": "string", + "description": "The email address associated with the payment method." + } + }, + "required": ["lastFour", "cardHolderName", "cardHolderEmail"] + }, + "datav1Tag": { + "type": "object", + "properties": { + "tagId": { + "type": "string", + "description": "Unique identifier for a given Tag." + }, + "tagName": { + "type": "string", + "description": "Human-readable name for a Tag." + }, + "tagType": { + "$ref": "#/definitions/v1TagType" + }, + "createdAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + }, + "updatedAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + } + }, + "required": ["tagId", "tagName", "tagType", "createdAt", "updatedAt"] + }, + "externaldatav1Address": { + "type": "object", + "properties": { + "format": { + "$ref": "#/definitions/v1AddressFormat" + }, + "address": { + "type": "string" + } + } + }, + "externaldatav1Credential": { + "type": "object", + "properties": { + "publicKey": { + "type": "string", + "description": "The public component of a cryptographic key pair used to sign messages and transactions." + }, + "type": { + "$ref": "#/definitions/v1CredentialType" + } + }, + "required": ["publicKey", "type"] + }, + "externaldatav1Quorum": { + "type": "object", + "properties": { + "threshold": { + "type": "integer", + "format": "int32", + "description": "Count of unique approvals required to meet quorum." + }, + "userIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Unique identifiers of quorum set members." + } + }, + "required": ["threshold", "userIds"] + }, + "externaldatav1Timestamp": { + "type": "object", + "properties": { + "seconds": { + "type": "string" + }, + "nanos": { + "type": "string" + } + }, + "required": ["seconds", "nanos"] + }, + "immutableactivityv1Address": { + "type": "object", + "properties": { + "format": { + "$ref": "#/definitions/v1AddressFormat" + }, + "address": { + "type": "string" + } + } + }, + "protobufAny": { + "type": "object", + "properties": { + "@type": { + "type": "string" + } + }, + "additionalProperties": {} + }, + "rpcStatus": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/protobufAny" + } + } + } + }, + "v1AcceptInvitationIntent": { + "type": "object", + "properties": { + "invitationId": { + "type": "string", + "description": "Unique identifier for a given Invitation object." + }, + "userId": { + "type": "string", + "description": "Unique identifier for a given User." + }, + "authenticator": { + "$ref": "#/definitions/v1AuthenticatorParams", + "description": "WebAuthN hardware devices that can be used to log in to the Turnkey web app." + } + }, + "required": ["invitationId", "userId", "authenticator"] + }, + "v1AcceptInvitationIntentV2": { + "type": "object", + "properties": { + "invitationId": { + "type": "string", + "description": "Unique identifier for a given Invitation object." + }, + "userId": { + "type": "string", + "description": "Unique identifier for a given User." + }, + "authenticator": { + "$ref": "#/definitions/v1AuthenticatorParamsV2", + "description": "WebAuthN hardware devices that can be used to log in to the Turnkey web app." + } + }, + "required": ["invitationId", "userId", "authenticator"] + }, + "v1AcceptInvitationResult": { + "type": "object", + "properties": { + "invitationId": { + "type": "string", + "description": "Unique identifier for a given Invitation." + }, + "userId": { + "type": "string", + "description": "Unique identifier for a given User." + } + }, + "required": ["invitationId", "userId"] + }, + "v1AccessType": { + "type": "string", + "enum": ["ACCESS_TYPE_WEB", "ACCESS_TYPE_API", "ACCESS_TYPE_ALL"] + }, + "v1Activity": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "Unique identifier for a given Activity object." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "status": { + "$ref": "#/definitions/v1ActivityStatus", + "description": "The current processing status of a specified Activity." + }, + "type": { + "$ref": "#/definitions/v1ActivityType", + "description": "Type of Activity, such as Add User, or Sign Transaction." + }, + "intent": { + "$ref": "#/definitions/v1Intent", + "description": "Intent object crafted by Turnkey based on the user request, used to assess the permissibility of an action." + }, + "result": { + "$ref": "#/definitions/v1Result", + "description": "Result of the intended action." + }, + "votes": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1Vote" + }, + "description": "A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata." + }, + "fingerprint": { + "type": "string", + "description": "An artifact verifying a User's action." + }, + "canApprove": { + "type": "boolean" + }, + "canReject": { + "type": "boolean" + }, + "createdAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + }, + "updatedAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + }, + "failure": { + "$ref": "#/definitions/rpcStatus", + "description": "Failure reason of the intended action." + } + }, + "required": [ + "id", + "organizationId", + "status", + "type", + "intent", + "result", + "votes", + "fingerprint", + "canApprove", + "canReject", + "createdAt", + "updatedAt" + ] + }, + "v1ActivityResponse": { + "type": "object", + "properties": { + "activity": { + "$ref": "#/definitions/v1Activity", + "description": "An action that can that can be taken within the Turnkey infrastructure." + } + }, + "required": ["activity"] + }, + "v1ActivityStatus": { + "type": "string", + "enum": [ + "ACTIVITY_STATUS_CREATED", + "ACTIVITY_STATUS_PENDING", + "ACTIVITY_STATUS_COMPLETED", + "ACTIVITY_STATUS_FAILED", + "ACTIVITY_STATUS_CONSENSUS_NEEDED", + "ACTIVITY_STATUS_REJECTED" + ] + }, + "v1ActivityType": { + "type": "string", + "enum": [ + "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" + ] + }, + "v1AddressFormat": { + "type": "string", + "enum": [ + "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" + ] + }, + "v1ApiKey": { + "type": "object", + "properties": { + "credential": { + "$ref": "#/definitions/externaldatav1Credential", + "description": "A User credential that can be used to authenticate to Turnkey." + }, + "apiKeyId": { + "type": "string", + "description": "Unique identifier for a given API Key." + }, + "apiKeyName": { + "type": "string", + "description": "Human-readable name for an API Key." + }, + "createdAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + }, + "updatedAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + }, + "expirationSeconds": { + "type": "string", + "format": "uint64", + "description": "Optional window (in seconds) indicating how long the API Key should last." + } + }, + "required": [ + "credential", + "apiKeyId", + "apiKeyName", + "createdAt", + "updatedAt" + ] + }, + "v1ApiKeyCurve": { + "type": "string", + "enum": [ + "API_KEY_CURVE_P256", + "API_KEY_CURVE_SECP256K1", + "API_KEY_CURVE_ED25519" + ] + }, + "v1ApiKeyParamsV2": { + "type": "object", + "properties": { + "apiKeyName": { + "type": "string", + "description": "Human-readable name for an API Key." + }, + "publicKey": { + "type": "string", + "description": "The public component of a cryptographic key pair used to sign messages and transactions." + }, + "curveType": { + "$ref": "#/definitions/v1ApiKeyCurve", + "description": "The curve type to be used for processing API key signatures." + }, + "expirationSeconds": { + "type": "string", + "description": "Optional window (in seconds) indicating how long the API Key should last." + } + }, + "required": ["apiKeyName", "publicKey", "curveType"] + }, + "v1ApiOnlyUserParams": { + "type": "object", + "properties": { + "userName": { + "type": "string", + "description": "The name of the new API-only User." + }, + "userEmail": { + "type": "string", + "description": "The email address for this API-only User (optional)." + }, + "userTags": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of tags assigned to the new API-only User. This field, if not needed, should be an empty array in your request body." + }, + "apiKeys": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/apiApiKeyParams" + }, + "description": "A list of API Key parameters. This field, if not needed, should be an empty array in your request body." + } + }, + "required": ["userName", "userTags", "apiKeys"] + }, + "v1ApproveActivityIntent": { + "type": "object", + "properties": { + "fingerprint": { + "type": "string", + "description": "An artifact verifying a User's action." + } + }, + "required": ["fingerprint"] + }, + "v1ApproveActivityRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_APPROVE_ACTIVITY"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1ApproveActivityIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1Attestation": { + "type": "object", + "properties": { + "credentialId": { + "type": "string", + "description": "The cbor encoded then base64 url encoded id of the credential." + }, + "clientDataJson": { + "type": "string", + "description": "A base64 url encoded payload containing metadata about the signing context and the challenge." + }, + "attestationObject": { + "type": "string", + "description": "A base64 url encoded payload containing authenticator data and any attestation the webauthn provider chooses." + }, + "transports": { + "type": "array", + "items": { + "$ref": "#/definitions/v1AuthenticatorTransport" + }, + "description": "The type of authenticator transports." + } + }, + "required": [ + "credentialId", + "clientDataJson", + "attestationObject", + "transports" + ] + }, + "v1Authenticator": { + "type": "object", + "properties": { + "transports": { + "type": "array", + "items": { + "$ref": "#/definitions/v1AuthenticatorTransport" + }, + "description": "Types of transports that may be used by an Authenticator (e.g., USB, NFC, BLE)." + }, + "attestationType": { + "type": "string" + }, + "aaguid": { + "type": "string", + "description": "Identifier indicating the type of the Security Key." + }, + "credentialId": { + "type": "string", + "description": "Unique identifier for a WebAuthn credential." + }, + "model": { + "type": "string", + "description": "The type of Authenticator device." + }, + "credential": { + "$ref": "#/definitions/externaldatav1Credential", + "description": "A User credential that can be used to authenticate to Turnkey." + }, + "authenticatorId": { + "type": "string", + "description": "Unique identifier for a given Authenticator." + }, + "authenticatorName": { + "type": "string", + "description": "Human-readable name for an Authenticator." + }, + "createdAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + }, + "updatedAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + } + }, + "required": [ + "transports", + "attestationType", + "aaguid", + "credentialId", + "model", + "credential", + "authenticatorId", + "authenticatorName", + "createdAt", + "updatedAt" + ] + }, + "v1AuthenticatorAttestationResponse": { + "type": "object", + "properties": { + "clientDataJson": { + "type": "string" + }, + "attestationObject": { + "type": "string" + }, + "transports": { + "type": "array", + "items": { + "$ref": "#/definitions/v1AuthenticatorTransport" + } + }, + "authenticatorAttachment": { + "type": "string", + "enum": ["cross-platform", "platform"], + "x-nullable": true + } + }, + "required": ["clientDataJson", "attestationObject"] + }, + "v1AuthenticatorParams": { + "type": "object", + "properties": { + "authenticatorName": { + "type": "string", + "description": "Human-readable name for an Authenticator." + }, + "userId": { + "type": "string", + "description": "Unique identifier for a given User." + }, + "attestation": { + "$ref": "#/definitions/v1PublicKeyCredentialWithAttestation" + }, + "challenge": { + "type": "string", + "description": "Challenge presented for authentication purposes." + } + }, + "required": ["authenticatorName", "userId", "attestation", "challenge"] + }, + "v1AuthenticatorParamsV2": { + "type": "object", + "properties": { + "authenticatorName": { + "type": "string", + "description": "Human-readable name for an Authenticator." + }, + "challenge": { + "type": "string", + "description": "Challenge presented for authentication purposes." + }, + "attestation": { + "$ref": "#/definitions/v1Attestation", + "description": "The attestation that proves custody of the authenticator and provides metadata about it." + } + }, + "required": ["authenticatorName", "challenge", "attestation"] + }, + "v1AuthenticatorTransport": { + "type": "string", + "enum": [ + "AUTHENTICATOR_TRANSPORT_BLE", + "AUTHENTICATOR_TRANSPORT_INTERNAL", + "AUTHENTICATOR_TRANSPORT_NFC", + "AUTHENTICATOR_TRANSPORT_USB", + "AUTHENTICATOR_TRANSPORT_HYBRID" + ] + }, + "v1Config": { + "type": "object", + "properties": { + "features": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1Feature" + } + }, + "quorum": { + "$ref": "#/definitions/externaldatav1Quorum" + } + } + }, + "v1CreateApiKeysIntent": { + "type": "object", + "properties": { + "apiKeys": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/apiApiKeyParams" + }, + "description": "A list of API Keys." + }, + "userId": { + "type": "string", + "description": "Unique identifier for a given User." + } + }, + "required": ["apiKeys", "userId"] + }, + "v1CreateApiKeysIntentV2": { + "type": "object", + "properties": { + "apiKeys": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1ApiKeyParamsV2" + }, + "description": "A list of API Keys." + }, + "userId": { + "type": "string", + "description": "Unique identifier for a given User." + } + }, + "required": ["apiKeys", "userId"] + }, + "v1CreateApiKeysRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_CREATE_API_KEYS_V2"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1CreateApiKeysIntentV2" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1CreateApiKeysResult": { + "type": "object", + "properties": { + "apiKeyIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of API Key IDs." + } + }, + "required": ["apiKeyIds"] + }, + "v1CreateApiOnlyUsersIntent": { + "type": "object", + "properties": { + "apiOnlyUsers": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1ApiOnlyUserParams" + }, + "description": "A list of API-only Users to create." + } + }, + "required": ["apiOnlyUsers"] + }, + "v1CreateApiOnlyUsersRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_CREATE_API_ONLY_USERS"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1CreateApiOnlyUsersIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1CreateApiOnlyUsersResult": { + "type": "object", + "properties": { + "userIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of API-only User IDs." + } + }, + "required": ["userIds"] + }, + "v1CreateAuthenticatorsIntent": { + "type": "object", + "properties": { + "authenticators": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1AuthenticatorParams" + }, + "description": "A list of Authenticators." + }, + "userId": { + "type": "string", + "description": "Unique identifier for a given User." + } + }, + "required": ["authenticators", "userId"] + }, + "v1CreateAuthenticatorsIntentV2": { + "type": "object", + "properties": { + "authenticators": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1AuthenticatorParamsV2" + }, + "description": "A list of Authenticators." + }, + "userId": { + "type": "string", + "description": "Unique identifier for a given User." + } + }, + "required": ["authenticators", "userId"] + }, + "v1CreateAuthenticatorsRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_CREATE_AUTHENTICATORS_V2"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1CreateAuthenticatorsIntentV2" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1CreateAuthenticatorsResult": { + "type": "object", + "properties": { + "authenticatorIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of Authenticator IDs." + } + }, + "required": ["authenticatorIds"] + }, + "v1CreateInvitationsIntent": { + "type": "object", + "properties": { + "invitations": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1InvitationParams" + }, + "description": "A list of Invitations." + } + }, + "required": ["invitations"] + }, + "v1CreateInvitationsRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_CREATE_INVITATIONS"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1CreateInvitationsIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1CreateInvitationsResult": { + "type": "object", + "properties": { + "invitationIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of Invitation IDs" + } + }, + "required": ["invitationIds"] + }, + "v1CreateOauthProvidersIntent": { + "type": "object", + "properties": { + "userId": { + "type": "string", + "description": "The ID of the User to add an Oauth provider to" + }, + "oauthProviders": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1OauthProviderParams" + }, + "description": "A list of Oauth providers." + } + }, + "required": ["userId", "oauthProviders"] + }, + "v1CreateOauthProvidersRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_CREATE_OAUTH_PROVIDERS"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1CreateOauthProvidersIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1CreateOauthProvidersResult": { + "type": "object", + "properties": { + "providerIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of unique identifiers for Oauth Providers" + } + }, + "required": ["providerIds"] + }, + "v1CreateOrganizationIntent": { + "type": "object", + "properties": { + "organizationName": { + "type": "string", + "description": "Human-readable name for an Organization." + }, + "rootEmail": { + "type": "string", + "description": "The root user's email address." + }, + "rootAuthenticator": { + "$ref": "#/definitions/v1AuthenticatorParams", + "description": "The root user's Authenticator." + }, + "rootUserId": { + "type": "string", + "description": "Unique identifier for the root user object." + } + }, + "required": ["organizationName", "rootEmail", "rootAuthenticator"] + }, + "v1CreateOrganizationIntentV2": { + "type": "object", + "properties": { + "organizationName": { + "type": "string", + "description": "Human-readable name for an Organization." + }, + "rootEmail": { + "type": "string", + "description": "The root user's email address." + }, + "rootAuthenticator": { + "$ref": "#/definitions/v1AuthenticatorParamsV2", + "description": "The root user's Authenticator." + }, + "rootUserId": { + "type": "string", + "description": "Unique identifier for the root user object." + } + }, + "required": ["organizationName", "rootEmail", "rootAuthenticator"] + }, + "v1CreateOrganizationResult": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + } + }, + "required": ["organizationId"] + }, + "v1CreatePoliciesIntent": { + "type": "object", + "properties": { + "policies": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1CreatePolicyIntentV3" + }, + "description": "An array of policy intents to be created." + } + }, + "required": ["policies"] + }, + "v1CreatePoliciesRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_CREATE_POLICIES"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1CreatePoliciesIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1CreatePoliciesResult": { + "type": "object", + "properties": { + "policyIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of unique identifiers for the created policies." + } + }, + "required": ["policyIds"] + }, + "v1CreatePolicyIntent": { + "type": "object", + "properties": { + "policyName": { + "type": "string", + "description": "Human-readable name for a Policy." + }, + "selectors": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1Selector" + }, + "description": "A list of simple functions each including a subject, target and boolean. See Policy Engine Language section for additional details." + }, + "effect": { + "$ref": "#/definitions/v1Effect", + "description": "The instruction to DENY or ALLOW a particular activity following policy selector(s)." + }, + "notes": { + "type": "string" + } + }, + "required": ["policyName", "selectors", "effect"] + }, + "v1CreatePolicyIntentV2": { + "type": "object", + "properties": { + "policyName": { + "type": "string", + "description": "Human-readable name for a Policy." + }, + "selectors": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1SelectorV2" + }, + "description": "A list of simple functions each including a subject, target and boolean. See Policy Engine Language section for additional details." + }, + "effect": { + "$ref": "#/definitions/v1Effect", + "description": "Whether to ALLOW or DENY requests that match the condition and consensus requirements." + }, + "notes": { + "type": "string" + } + }, + "required": ["policyName", "selectors", "effect"] + }, + "v1CreatePolicyIntentV3": { + "type": "object", + "properties": { + "policyName": { + "type": "string", + "description": "Human-readable name for a Policy." + }, + "effect": { + "$ref": "#/definitions/v1Effect", + "description": "The instruction to DENY or ALLOW an activity." + }, + "condition": { + "type": "string", + "description": "The condition expression that triggers the Effect" + }, + "consensus": { + "type": "string", + "description": "The consensus expression that triggers the Effect" + }, + "notes": { + "type": "string" + } + }, + "required": ["policyName", "effect"] + }, + "v1CreatePolicyRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_CREATE_POLICY_V3"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1CreatePolicyIntentV3" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1CreatePolicyResult": { + "type": "object", + "properties": { + "policyId": { + "type": "string", + "description": "Unique identifier for a given Policy." + } + }, + "required": ["policyId"] + }, + "v1CreatePrivateKeyTagIntent": { + "type": "object", + "properties": { + "privateKeyTagName": { + "type": "string", + "description": "Human-readable name for a Private Key Tag." + }, + "privateKeyIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of Private Key IDs." + } + }, + "required": ["privateKeyTagName", "privateKeyIds"] + }, + "v1CreatePrivateKeyTagRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_CREATE_PRIVATE_KEY_TAG"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1CreatePrivateKeyTagIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1CreatePrivateKeyTagResult": { + "type": "object", + "properties": { + "privateKeyTagId": { + "type": "string", + "description": "Unique identifier for a given Private Key Tag." + }, + "privateKeyIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of Private Key IDs." + } + }, + "required": ["privateKeyTagId", "privateKeyIds"] + }, + "v1CreatePrivateKeysIntent": { + "type": "object", + "properties": { + "privateKeys": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1PrivateKeyParams" + }, + "description": "A list of Private Keys." + } + }, + "required": ["privateKeys"] + }, + "v1CreatePrivateKeysIntentV2": { + "type": "object", + "properties": { + "privateKeys": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1PrivateKeyParams" + }, + "description": "A list of Private Keys." + } + }, + "required": ["privateKeys"] + }, + "v1CreatePrivateKeysRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_CREATE_PRIVATE_KEYS_V2"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1CreatePrivateKeysIntentV2" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1CreatePrivateKeysResult": { + "type": "object", + "properties": { + "privateKeyIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of Private Key IDs." + } + }, + "required": ["privateKeyIds"] + }, + "v1CreatePrivateKeysResultV2": { + "type": "object", + "properties": { + "privateKeys": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1PrivateKeyResult" + }, + "description": "A list of Private Key IDs and addresses." + } + }, + "required": ["privateKeys"] + }, + "v1CreateReadOnlySessionIntent": { + "type": "object" + }, + "v1CreateReadOnlySessionRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_CREATE_READ_ONLY_SESSION"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1CreateReadOnlySessionIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1CreateReadOnlySessionResult": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization. If the request is being made by a user and their Sub-Organization ID is unknown, this can be the Parent Organization ID. However, using the Sub-Organization ID is preferred due to performance reasons." + }, + "organizationName": { + "type": "string", + "description": "Human-readable name for an Organization." + }, + "userId": { + "type": "string", + "description": "Unique identifier for a given User." + }, + "username": { + "type": "string", + "description": "Human-readable name for a User." + }, + "session": { + "type": "string", + "description": "String representing a read only session" + }, + "sessionExpiry": { + "type": "string", + "format": "uint64", + "description": "UTC timestamp in seconds representing the expiry time for the read only session." + } + }, + "required": [ + "organizationId", + "organizationName", + "userId", + "username", + "session", + "sessionExpiry" + ] + }, + "v1CreateReadWriteSessionIntent": { + "type": "object", + "properties": { + "targetPublicKey": { + "type": "string", + "description": "Client-side public key generated by the user, to which the read write session bundle (credentials) will be encrypted." + }, + "email": { + "type": "string", + "description": "Email of the user to create a read write session for" + }, + "apiKeyName": { + "type": "string", + "description": "Optional human-readable name for an API Key. If none provided, default to Read Write Session - \u003cTimestamp\u003e" + }, + "expirationSeconds": { + "type": "string", + "description": "Expiration window (in seconds) indicating how long the API key is valid for. If not provided, a default of 15 minutes will be used." + } + }, + "required": ["targetPublicKey", "email"] + }, + "v1CreateReadWriteSessionIntentV2": { + "type": "object", + "properties": { + "targetPublicKey": { + "type": "string", + "description": "Client-side public key generated by the user, to which the read write session bundle (credentials) will be encrypted." + }, + "userId": { + "type": "string", + "description": "Unique identifier for a given User." + }, + "apiKeyName": { + "type": "string", + "description": "Optional human-readable name for an API Key. If none provided, default to Read Write Session - \u003cTimestamp\u003e" + }, + "expirationSeconds": { + "type": "string", + "description": "Expiration window (in seconds) indicating how long the API key is valid for. If not provided, a default of 15 minutes will be used." + }, + "invalidateExisting": { + "type": "boolean", + "description": "Invalidate all other previously generated ReadWriteSession API keys" + } + }, + "required": ["targetPublicKey"] + }, + "v1CreateReadWriteSessionRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_CREATE_READ_WRITE_SESSION_V2"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1CreateReadWriteSessionIntentV2" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1CreateReadWriteSessionResult": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization. If the request is being made by a user and their Sub-Organization ID is unknown, this can be the Parent Organization ID. However, using the Sub-Organization ID is preferred due to performance reasons." + }, + "organizationName": { + "type": "string", + "description": "Human-readable name for an Organization." + }, + "userId": { + "type": "string", + "description": "Unique identifier for a given User." + }, + "username": { + "type": "string", + "description": "Human-readable name for a User." + }, + "apiKeyId": { + "type": "string", + "description": "Unique identifier for the created API key." + }, + "credentialBundle": { + "type": "string", + "description": "HPKE encrypted credential bundle" + } + }, + "required": [ + "organizationId", + "organizationName", + "userId", + "username", + "apiKeyId", + "credentialBundle" + ] + }, + "v1CreateReadWriteSessionResultV2": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization. If the request is being made by a user and their Sub-Organization ID is unknown, this can be the Parent Organization ID. However, using the Sub-Organization ID is preferred due to performance reasons." + }, + "organizationName": { + "type": "string", + "description": "Human-readable name for an Organization." + }, + "userId": { + "type": "string", + "description": "Unique identifier for a given User." + }, + "username": { + "type": "string", + "description": "Human-readable name for a User." + }, + "apiKeyId": { + "type": "string", + "description": "Unique identifier for the created API key." + }, + "credentialBundle": { + "type": "string", + "description": "HPKE encrypted credential bundle" + } + }, + "required": [ + "organizationId", + "organizationName", + "userId", + "username", + "apiKeyId", + "credentialBundle" + ] + }, + "v1CreateSubOrganizationIntent": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Name for this sub-organization" + }, + "rootAuthenticator": { + "$ref": "#/definitions/v1AuthenticatorParamsV2", + "description": "Root User authenticator for this new sub-organization" + } + }, + "required": ["name", "rootAuthenticator"] + }, + "v1CreateSubOrganizationIntentV2": { + "type": "object", + "properties": { + "subOrganizationName": { + "type": "string", + "description": "Name for this sub-organization" + }, + "rootUsers": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1RootUserParams" + }, + "description": "Root users to create within this sub-organization" + }, + "rootQuorumThreshold": { + "type": "integer", + "format": "int32", + "description": "The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users" + } + }, + "required": ["subOrganizationName", "rootUsers", "rootQuorumThreshold"] + }, + "v1CreateSubOrganizationIntentV3": { + "type": "object", + "properties": { + "subOrganizationName": { + "type": "string", + "description": "Name for this sub-organization" + }, + "rootUsers": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1RootUserParams" + }, + "description": "Root users to create within this sub-organization" + }, + "rootQuorumThreshold": { + "type": "integer", + "format": "int32", + "description": "The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users" + }, + "privateKeys": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1PrivateKeyParams" + }, + "description": "A list of Private Keys." + } + }, + "required": [ + "subOrganizationName", + "rootUsers", + "rootQuorumThreshold", + "privateKeys" + ] + }, + "v1CreateSubOrganizationIntentV4": { + "type": "object", + "properties": { + "subOrganizationName": { + "type": "string", + "description": "Name for this sub-organization" + }, + "rootUsers": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1RootUserParams" + }, + "description": "Root users to create within this sub-organization" + }, + "rootQuorumThreshold": { + "type": "integer", + "format": "int32", + "description": "The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users" + }, + "wallet": { + "$ref": "#/definitions/v1WalletParams", + "description": "The wallet to create for the sub-organization" + }, + "disableEmailRecovery": { + "type": "boolean", + "description": "Disable email recovery for the sub-organization" + }, + "disableEmailAuth": { + "type": "boolean", + "description": "Disable email auth for the sub-organization" + } + }, + "required": ["subOrganizationName", "rootUsers", "rootQuorumThreshold"] + }, + "v1CreateSubOrganizationIntentV5": { + "type": "object", + "properties": { + "subOrganizationName": { + "type": "string", + "description": "Name for this sub-organization" + }, + "rootUsers": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1RootUserParamsV2" + }, + "description": "Root users to create within this sub-organization" + }, + "rootQuorumThreshold": { + "type": "integer", + "format": "int32", + "description": "The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users" + }, + "wallet": { + "$ref": "#/definitions/v1WalletParams", + "description": "The wallet to create for the sub-organization" + }, + "disableEmailRecovery": { + "type": "boolean", + "description": "Disable email recovery for the sub-organization" + }, + "disableEmailAuth": { + "type": "boolean", + "description": "Disable email auth for the sub-organization" + } + }, + "required": ["subOrganizationName", "rootUsers", "rootQuorumThreshold"] + }, + "v1CreateSubOrganizationIntentV6": { + "type": "object", + "properties": { + "subOrganizationName": { + "type": "string", + "description": "Name for this sub-organization" + }, + "rootUsers": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1RootUserParamsV3" + }, + "description": "Root users to create within this sub-organization" + }, + "rootQuorumThreshold": { + "type": "integer", + "format": "int32", + "description": "The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users" + }, + "wallet": { + "$ref": "#/definitions/v1WalletParams", + "description": "The wallet to create for the sub-organization" + }, + "disableEmailRecovery": { + "type": "boolean", + "description": "Disable email recovery for the sub-organization" + }, + "disableEmailAuth": { + "type": "boolean", + "description": "Disable email auth for the sub-organization" + } + }, + "required": ["subOrganizationName", "rootUsers", "rootQuorumThreshold"] + }, + "v1CreateSubOrganizationIntentV7": { + "type": "object", + "properties": { + "subOrganizationName": { + "type": "string", + "description": "Name for this sub-organization" + }, + "rootUsers": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1RootUserParamsV4" + }, + "description": "Root users to create within this sub-organization" + }, + "rootQuorumThreshold": { + "type": "integer", + "format": "int32", + "description": "The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users" + }, + "wallet": { + "$ref": "#/definitions/v1WalletParams", + "description": "The wallet to create for the sub-organization" + }, + "disableEmailRecovery": { + "type": "boolean", + "description": "Disable email recovery for the sub-organization" + }, + "disableEmailAuth": { + "type": "boolean", + "description": "Disable email auth for the sub-organization" + }, + "disableSmsAuth": { + "type": "boolean", + "description": "Disable OTP SMS auth for the sub-organization" + }, + "disableOtpEmailAuth": { + "type": "boolean", + "description": "Disable OTP email auth for the sub-organization" + } + }, + "required": ["subOrganizationName", "rootUsers", "rootQuorumThreshold"] + }, + "v1CreateSubOrganizationRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_CREATE_SUB_ORGANIZATION_V7"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1CreateSubOrganizationIntentV7" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1CreateSubOrganizationResult": { + "type": "object", + "properties": { + "subOrganizationId": { + "type": "string" + }, + "rootUserIds": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": ["subOrganizationId"] + }, + "v1CreateSubOrganizationResultV3": { + "type": "object", + "properties": { + "subOrganizationId": { + "type": "string" + }, + "privateKeys": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1PrivateKeyResult" + }, + "description": "A list of Private Key IDs and addresses." + }, + "rootUserIds": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": ["subOrganizationId", "privateKeys"] + }, + "v1CreateSubOrganizationResultV4": { + "type": "object", + "properties": { + "subOrganizationId": { + "type": "string" + }, + "wallet": { + "$ref": "#/definitions/v1WalletResult" + }, + "rootUserIds": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": ["subOrganizationId"] + }, + "v1CreateSubOrganizationResultV5": { + "type": "object", + "properties": { + "subOrganizationId": { + "type": "string" + }, + "wallet": { + "$ref": "#/definitions/v1WalletResult" + }, + "rootUserIds": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": ["subOrganizationId"] + }, + "v1CreateSubOrganizationResultV6": { + "type": "object", + "properties": { + "subOrganizationId": { + "type": "string" + }, + "wallet": { + "$ref": "#/definitions/v1WalletResult" + }, + "rootUserIds": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": ["subOrganizationId"] + }, + "v1CreateSubOrganizationResultV7": { + "type": "object", + "properties": { + "subOrganizationId": { + "type": "string" + }, + "wallet": { + "$ref": "#/definitions/v1WalletResult" + }, + "rootUserIds": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": ["subOrganizationId"] + }, + "v1CreateUserTagIntent": { + "type": "object", + "properties": { + "userTagName": { + "type": "string", + "description": "Human-readable name for a User Tag." + }, + "userIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of User IDs." + } + }, + "required": ["userTagName", "userIds"] + }, + "v1CreateUserTagRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_CREATE_USER_TAG"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1CreateUserTagIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1CreateUserTagResult": { + "type": "object", + "properties": { + "userTagId": { + "type": "string", + "description": "Unique identifier for a given User Tag." + }, + "userIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of User IDs." + } + }, + "required": ["userTagId", "userIds"] + }, + "v1CreateUsersIntent": { + "type": "object", + "properties": { + "users": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1UserParams" + }, + "description": "A list of Users." + } + }, + "required": ["users"] + }, + "v1CreateUsersIntentV2": { + "type": "object", + "properties": { + "users": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1UserParamsV2" + }, + "description": "A list of Users." + } + }, + "required": ["users"] + }, + "v1CreateUsersIntentV3": { + "type": "object", + "properties": { + "users": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1UserParamsV3" + }, + "description": "A list of Users." + } + }, + "required": ["users"] + }, + "v1CreateUsersRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_CREATE_USERS_V3"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1CreateUsersIntentV3" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1CreateUsersResult": { + "type": "object", + "properties": { + "userIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of User IDs." + } + }, + "required": ["userIds"] + }, + "v1CreateWalletAccountsIntent": { + "type": "object", + "properties": { + "walletId": { + "type": "string", + "description": "Unique identifier for a given Wallet." + }, + "accounts": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1WalletAccountParams" + }, + "description": "A list of wallet Accounts." + } + }, + "required": ["walletId", "accounts"] + }, + "v1CreateWalletAccountsRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_CREATE_WALLET_ACCOUNTS"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1CreateWalletAccountsIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1CreateWalletAccountsResult": { + "type": "object", + "properties": { + "addresses": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of derived addresses." + } + }, + "required": ["addresses"] + }, + "v1CreateWalletIntent": { + "type": "object", + "properties": { + "walletName": { + "type": "string", + "description": "Human-readable name for a Wallet." + }, + "accounts": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1WalletAccountParams" + }, + "description": "A list of wallet Accounts. This field, if not needed, should be an empty array in your request body." + }, + "mnemonicLength": { + "type": "integer", + "format": "int32", + "description": "Length of mnemonic to generate the Wallet seed. Defaults to 12. Accepted values: 12, 15, 18, 21, 24." + } + }, + "required": ["walletName", "accounts"] + }, + "v1CreateWalletRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_CREATE_WALLET"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1CreateWalletIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1CreateWalletResult": { + "type": "object", + "properties": { + "walletId": { + "type": "string", + "description": "Unique identifier for a Wallet." + }, + "addresses": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of account addresses." + } + }, + "required": ["walletId", "addresses"] + }, + "v1CredPropsAuthenticationExtensionsClientOutputs": { + "type": "object", + "properties": { + "rk": { + "type": "boolean" + } + }, + "required": ["rk"] + }, + "v1CredentialType": { + "type": "string", + "enum": [ + "CREDENTIAL_TYPE_WEBAUTHN_AUTHENTICATOR", + "CREDENTIAL_TYPE_API_KEY_P256", + "CREDENTIAL_TYPE_RECOVER_USER_KEY_P256", + "CREDENTIAL_TYPE_API_KEY_SECP256K1", + "CREDENTIAL_TYPE_EMAIL_AUTH_KEY_P256", + "CREDENTIAL_TYPE_API_KEY_ED25519", + "CREDENTIAL_TYPE_OTP_AUTH_KEY_P256", + "CREDENTIAL_TYPE_READ_WRITE_SESSION_KEY_P256", + "CREDENTIAL_TYPE_OAUTH_KEY_P256", + "CREDENTIAL_TYPE_LOGIN" + ] + }, + "v1Curve": { + "type": "string", + "enum": ["CURVE_SECP256K1", "CURVE_ED25519"] + }, + "v1DeleteApiKeysIntent": { + "type": "object", + "properties": { + "userId": { + "type": "string", + "description": "Unique identifier for a given User." + }, + "apiKeyIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of API Key IDs." + } + }, + "required": ["userId", "apiKeyIds"] + }, + "v1DeleteApiKeysRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_DELETE_API_KEYS"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1DeleteApiKeysIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1DeleteApiKeysResult": { + "type": "object", + "properties": { + "apiKeyIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of API Key IDs." + } + }, + "required": ["apiKeyIds"] + }, + "v1DeleteAuthenticatorsIntent": { + "type": "object", + "properties": { + "userId": { + "type": "string", + "description": "Unique identifier for a given User." + }, + "authenticatorIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of Authenticator IDs." + } + }, + "required": ["userId", "authenticatorIds"] + }, + "v1DeleteAuthenticatorsRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_DELETE_AUTHENTICATORS"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1DeleteAuthenticatorsIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1DeleteAuthenticatorsResult": { + "type": "object", + "properties": { + "authenticatorIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Unique identifier for a given Authenticator." + } + }, + "required": ["authenticatorIds"] + }, + "v1DeleteInvitationIntent": { + "type": "object", + "properties": { + "invitationId": { + "type": "string", + "description": "Unique identifier for a given Invitation object." + } + }, + "required": ["invitationId"] + }, + "v1DeleteInvitationRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_DELETE_INVITATION"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1DeleteInvitationIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1DeleteInvitationResult": { + "type": "object", + "properties": { + "invitationId": { + "type": "string", + "description": "Unique identifier for a given Invitation." + } + }, + "required": ["invitationId"] + }, + "v1DeleteOauthProvidersIntent": { + "type": "object", + "properties": { + "userId": { + "type": "string", + "description": "The ID of the User to remove an Oauth provider from" + }, + "providerIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Unique identifier for a given Provider." + } + }, + "required": ["userId", "providerIds"] + }, + "v1DeleteOauthProvidersRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_DELETE_OAUTH_PROVIDERS"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1DeleteOauthProvidersIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1DeleteOauthProvidersResult": { + "type": "object", + "properties": { + "providerIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of unique identifiers for Oauth Providers" + } + }, + "required": ["providerIds"] + }, + "v1DeleteOrganizationIntent": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + } + }, + "required": ["organizationId"] + }, + "v1DeleteOrganizationResult": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + } + }, + "required": ["organizationId"] + }, + "v1DeletePolicyIntent": { + "type": "object", + "properties": { + "policyId": { + "type": "string", + "description": "Unique identifier for a given Policy." + } + }, + "required": ["policyId"] + }, + "v1DeletePolicyRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_DELETE_POLICY"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1DeletePolicyIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1DeletePolicyResult": { + "type": "object", + "properties": { + "policyId": { + "type": "string", + "description": "Unique identifier for a given Policy." + } + }, + "required": ["policyId"] + }, + "v1DeletePrivateKeyTagsIntent": { + "type": "object", + "properties": { + "privateKeyTagIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of Private Key Tag IDs." + } + }, + "required": ["privateKeyTagIds"] + }, + "v1DeletePrivateKeyTagsRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_DELETE_PRIVATE_KEY_TAGS"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1DeletePrivateKeyTagsIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1DeletePrivateKeyTagsResult": { + "type": "object", + "properties": { + "privateKeyTagIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of Private Key Tag IDs." + }, + "privateKeyIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of Private Key IDs." + } + }, + "required": ["privateKeyTagIds", "privateKeyIds"] + }, + "v1DeletePrivateKeysIntent": { + "type": "object", + "properties": { + "privateKeyIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "List of unique identifiers for private keys within an organization" + }, + "deleteWithoutExport": { + "type": "boolean", + "description": "Optional parameter for deleting the private keys, even if any have not been previously exported. If they have been exported, this field is ignored." + } + }, + "required": ["privateKeyIds"] + }, + "v1DeletePrivateKeysRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_DELETE_PRIVATE_KEYS"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1DeletePrivateKeysIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1DeletePrivateKeysResult": { + "type": "object", + "properties": { + "privateKeyIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of private key unique identifiers that were removed" + } + }, + "required": ["privateKeyIds"] + }, + "v1DeleteSubOrganizationIntent": { + "type": "object", + "properties": { + "deleteWithoutExport": { + "type": "boolean", + "description": "Sub-organization deletion, by default, requires associated wallets and private keys to be exported for security reasons. Set this boolean to true to force sub-organization deletion even if some wallets or private keys within it have not been exported yet. Default: false." + } + } + }, + "v1DeleteSubOrganizationRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_DELETE_SUB_ORGANIZATION"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1DeleteSubOrganizationIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1DeleteSubOrganizationResult": { + "type": "object", + "properties": { + "subOrganizationUuid": { + "type": "string", + "description": "Unique identifier of the sub organization that was removed" + } + }, + "required": ["subOrganizationUuid"] + }, + "v1DeleteUserTagsIntent": { + "type": "object", + "properties": { + "userTagIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of User Tag IDs." + } + }, + "required": ["userTagIds"] + }, + "v1DeleteUserTagsRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_DELETE_USER_TAGS"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1DeleteUserTagsIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1DeleteUserTagsResult": { + "type": "object", + "properties": { + "userTagIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of User Tag IDs." + }, + "userIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of User IDs." + } + }, + "required": ["userTagIds", "userIds"] + }, + "v1DeleteUsersIntent": { + "type": "object", + "properties": { + "userIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of User IDs." + } + }, + "required": ["userIds"] + }, + "v1DeleteUsersRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_DELETE_USERS"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1DeleteUsersIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1DeleteUsersResult": { + "type": "object", + "properties": { + "userIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of User IDs." + } + }, + "required": ["userIds"] + }, + "v1DeleteWalletsIntent": { + "type": "object", + "properties": { + "walletIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "List of unique identifiers for wallets within an organization" + }, + "deleteWithoutExport": { + "type": "boolean", + "description": "Optional parameter for deleting the wallets, even if any have not been previously exported. If they have been exported, this field is ignored." + } + }, + "required": ["walletIds"] + }, + "v1DeleteWalletsRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_DELETE_WALLETS"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1DeleteWalletsIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1DeleteWalletsResult": { + "type": "object", + "properties": { + "walletIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of wallet unique identifiers that were removed" + } + }, + "required": ["walletIds"] + }, + "v1DisablePrivateKeyIntent": { + "type": "object", + "properties": { + "privateKeyId": { + "type": "string", + "description": "Unique identifier for a given Private Key." + } + }, + "required": ["privateKeyId"] + }, + "v1DisablePrivateKeyResult": { + "type": "object", + "properties": { + "privateKeyId": { + "type": "string", + "description": "Unique identifier for a given Private Key." + } + }, + "required": ["privateKeyId"] + }, + "v1Effect": { + "type": "string", + "enum": ["EFFECT_ALLOW", "EFFECT_DENY"] + }, + "v1EmailAuthIntent": { + "type": "object", + "properties": { + "email": { + "type": "string", + "description": "Email of the authenticating user." + }, + "targetPublicKey": { + "type": "string", + "description": "Client-side public key generated by the user, to which the email auth bundle (credentials) will be encrypted." + }, + "apiKeyName": { + "type": "string", + "description": "Optional human-readable name for an API Key. If none provided, default to Email Auth - \u003cTimestamp\u003e" + }, + "expirationSeconds": { + "type": "string", + "description": "Expiration window (in seconds) indicating how long the API key is valid for. If not provided, a default of 15 minutes will be used." + }, + "emailCustomization": { + "$ref": "#/definitions/v1EmailCustomizationParams", + "description": "Optional parameters for customizing emails. If not provided, the default email will be used." + }, + "invalidateExisting": { + "type": "boolean", + "description": "Invalidate all other previously generated Email Auth API keys" + }, + "sendFromEmailAddress": { + "type": "string", + "description": "Optional custom email address from which to send the email" + }, + "sendFromEmailSenderName": { + "type": "string", + "description": "Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications'" + }, + "replyToEmailAddress": { + "type": "string", + "description": "Optional custom email address to use as reply-to" + } + }, + "required": ["email", "targetPublicKey"] + }, + "v1EmailAuthIntentV2": { + "type": "object", + "properties": { + "email": { + "type": "string", + "description": "Email of the authenticating user." + }, + "targetPublicKey": { + "type": "string", + "description": "Client-side public key generated by the user, to which the email auth bundle (credentials) will be encrypted." + }, + "apiKeyName": { + "type": "string", + "description": "Optional human-readable name for an API Key. If none provided, default to Email Auth - \u003cTimestamp\u003e" + }, + "expirationSeconds": { + "type": "string", + "description": "Expiration window (in seconds) indicating how long the API key is valid for. If not provided, a default of 15 minutes will be used." + }, + "emailCustomization": { + "$ref": "#/definitions/v1EmailCustomizationParams", + "description": "Optional parameters for customizing emails. If not provided, the default email will be used." + }, + "invalidateExisting": { + "type": "boolean", + "description": "Invalidate all other previously generated Email Auth API keys" + }, + "sendFromEmailAddress": { + "type": "string", + "description": "Optional custom email address from which to send the email" + }, + "sendFromEmailSenderName": { + "type": "string", + "description": "Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications'" + }, + "replyToEmailAddress": { + "type": "string", + "description": "Optional custom email address to use as reply-to" + } + }, + "required": ["email", "targetPublicKey"] + }, + "v1EmailAuthRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_EMAIL_AUTH_V2"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1EmailAuthIntentV2" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1EmailAuthResult": { + "type": "object", + "properties": { + "userId": { + "type": "string", + "description": "Unique identifier for the authenticating User." + }, + "apiKeyId": { + "type": "string", + "description": "Unique identifier for the created API key." + } + }, + "required": ["userId", "apiKeyId"] + }, + "v1EmailCustomizationParams": { + "type": "object", + "properties": { + "appName": { + "type": "string", + "description": "The name of the application." + }, + "logoUrl": { + "type": "string", + "description": "A URL pointing to a logo in PNG format. Note this logo will be resized to fit into 340px x 124px." + }, + "magicLinkTemplate": { + "type": "string", + "description": "A template for the URL to be used in a magic link button, e.g. `https://dapp.xyz/%s`. The auth bundle will be interpolated into the `%s`." + }, + "templateVariables": { + "type": "string", + "description": "JSON object containing key/value pairs to be used with custom templates." + }, + "templateId": { + "type": "string", + "description": "Unique identifier for a given Email Template. If not specified, the default is the most recent Email Template." + } + } + }, + "v1ExportPrivateKeyIntent": { + "type": "object", + "properties": { + "privateKeyId": { + "type": "string", + "description": "Unique identifier for a given Private Key." + }, + "targetPublicKey": { + "type": "string", + "description": "Client-side public key generated by the user, to which the export bundle will be encrypted." + } + }, + "required": ["privateKeyId", "targetPublicKey"] + }, + "v1ExportPrivateKeyRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_EXPORT_PRIVATE_KEY"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1ExportPrivateKeyIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1ExportPrivateKeyResult": { + "type": "object", + "properties": { + "privateKeyId": { + "type": "string", + "description": "Unique identifier for a given Private Key." + }, + "exportBundle": { + "type": "string", + "description": "Export bundle containing a private key encrypted to the client's target public key." + } + }, + "required": ["privateKeyId", "exportBundle"] + }, + "v1ExportWalletAccountIntent": { + "type": "object", + "properties": { + "address": { + "type": "string", + "description": "Address to identify Wallet Account." + }, + "targetPublicKey": { + "type": "string", + "description": "Client-side public key generated by the user, to which the export bundle will be encrypted." + } + }, + "required": ["address", "targetPublicKey"] + }, + "v1ExportWalletAccountRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_EXPORT_WALLET_ACCOUNT"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1ExportWalletAccountIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1ExportWalletAccountResult": { + "type": "object", + "properties": { + "address": { + "type": "string", + "description": "Address to identify Wallet Account." + }, + "exportBundle": { + "type": "string", + "description": "Export bundle containing a private key encrypted by the client's target public key." + } + }, + "required": ["address", "exportBundle"] + }, + "v1ExportWalletIntent": { + "type": "object", + "properties": { + "walletId": { + "type": "string", + "description": "Unique identifier for a given Wallet." + }, + "targetPublicKey": { + "type": "string", + "description": "Client-side public key generated by the user, to which the export bundle will be encrypted." + }, + "language": { + "$ref": "#/definitions/v1MnemonicLanguage", + "description": "The language of the mnemonic to export. Defaults to English." + } + }, + "required": ["walletId", "targetPublicKey"] + }, + "v1ExportWalletRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_EXPORT_WALLET"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1ExportWalletIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1ExportWalletResult": { + "type": "object", + "properties": { + "walletId": { + "type": "string", + "description": "Unique identifier for a given Wallet." + }, + "exportBundle": { + "type": "string", + "description": "Export bundle containing a wallet mnemonic + optional newline passphrase encrypted by the client's target public key." + } + }, + "required": ["walletId", "exportBundle"] + }, + "v1Feature": { + "type": "object", + "properties": { + "name": { + "$ref": "#/definitions/v1FeatureName" + }, + "value": { + "type": "string" + } + } + }, + "v1FeatureName": { + "type": "string", + "enum": [ + "FEATURE_NAME_ROOT_USER_EMAIL_RECOVERY", + "FEATURE_NAME_WEBAUTHN_ORIGINS", + "FEATURE_NAME_EMAIL_AUTH", + "FEATURE_NAME_EMAIL_RECOVERY", + "FEATURE_NAME_WEBHOOK", + "FEATURE_NAME_SMS_AUTH", + "FEATURE_NAME_OTP_EMAIL_AUTH" + ] + }, + "v1GetActivitiesRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "filterByStatus": { + "type": "array", + "items": { + "$ref": "#/definitions/v1ActivityStatus" + }, + "description": "Array of Activity Statuses filtering which Activities will be listed in the response." + }, + "paginationOptions": { + "$ref": "#/definitions/v1Pagination", + "description": "Parameters used for cursor-based pagination." + }, + "filterByType": { + "type": "array", + "items": { + "$ref": "#/definitions/v1ActivityType" + }, + "description": "Array of Activity Types filtering which Activities will be listed in the response." + } + }, + "required": ["organizationId"] + }, + "v1GetActivitiesResponse": { + "type": "object", + "properties": { + "activities": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1Activity" + }, + "description": "A list of Activities." + } + }, + "required": ["activities"] + }, + "v1GetActivityRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "activityId": { + "type": "string", + "description": "Unique identifier for a given Activity object." + } + }, + "required": ["organizationId", "activityId"] + }, + "v1GetApiKeyRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "apiKeyId": { + "type": "string", + "description": "Unique identifier for a given API key." + } + }, + "required": ["organizationId", "apiKeyId"] + }, + "v1GetApiKeyResponse": { + "type": "object", + "properties": { + "apiKey": { + "$ref": "#/definitions/v1ApiKey", + "description": "An API key." + } + }, + "required": ["apiKey"] + }, + "v1GetApiKeysRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "userId": { + "type": "string", + "description": "Unique identifier for a given User." + } + }, + "required": ["organizationId"] + }, + "v1GetApiKeysResponse": { + "type": "object", + "properties": { + "apiKeys": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1ApiKey" + }, + "description": "A list of API keys." + } + }, + "required": ["apiKeys"] + }, + "v1GetAttestationDocumentRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "enclaveType": { + "type": "string", + "description": "The enclave type, one of: ump, notarizer, signer, evm-parser" + } + }, + "required": ["organizationId", "enclaveType"] + }, + "v1GetAttestationDocumentResponse": { + "type": "object", + "properties": { + "attestationDocument": { + "type": "string", + "format": "byte", + "description": "Raw (CBOR-encoded) attestation document" + } + }, + "required": ["attestationDocument"] + }, + "v1GetAuthenticatorRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "authenticatorId": { + "type": "string", + "description": "Unique identifier for a given Authenticator." + } + }, + "required": ["organizationId", "authenticatorId"] + }, + "v1GetAuthenticatorResponse": { + "type": "object", + "properties": { + "authenticator": { + "$ref": "#/definitions/v1Authenticator", + "description": "An authenticator." + } + }, + "required": ["authenticator"] + }, + "v1GetAuthenticatorsRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "userId": { + "type": "string", + "description": "Unique identifier for a given User." + } + }, + "required": ["organizationId", "userId"] + }, + "v1GetAuthenticatorsResponse": { + "type": "object", + "properties": { + "authenticators": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1Authenticator" + }, + "description": "A list of authenticators." + } + }, + "required": ["authenticators"] + }, + "v1GetOauthProvidersRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "userId": { + "type": "string", + "description": "Unique identifier for a given User." + } + }, + "required": ["organizationId"] + }, + "v1GetOauthProvidersResponse": { + "type": "object", + "properties": { + "oauthProviders": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1OauthProvider" + }, + "description": "A list of Oauth Providers" + } + }, + "required": ["oauthProviders"] + }, + "v1GetOrganizationConfigsRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + } + }, + "required": ["organizationId"] + }, + "v1GetOrganizationConfigsResponse": { + "type": "object", + "properties": { + "configs": { + "$ref": "#/definitions/v1Config", + "description": "Organization configs including quorum settings and organization features" + } + }, + "required": ["configs"] + }, + "v1GetOrganizationRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + } + }, + "required": ["organizationId"] + }, + "v1GetOrganizationResponse": { + "type": "object", + "properties": { + "organizationData": { + "$ref": "#/definitions/v1OrganizationData", + "description": "Object representing the full current and deleted / disabled collection of Users, Policies, Private Keys, and Invitations attributable to a particular Organization." + } + }, + "required": ["organizationData"] + }, + "v1GetPoliciesRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + } + }, + "required": ["organizationId"] + }, + "v1GetPoliciesResponse": { + "type": "object", + "properties": { + "policies": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1Policy" + }, + "description": "A list of Policies." + } + }, + "required": ["policies"] + }, + "v1GetPolicyRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "policyId": { + "type": "string", + "description": "Unique identifier for a given Policy." + } + }, + "required": ["organizationId", "policyId"] + }, + "v1GetPolicyResponse": { + "type": "object", + "properties": { + "policy": { + "$ref": "#/definitions/v1Policy", + "description": "Object that codifies rules defining the actions that are permissible within an Organization." + } + }, + "required": ["policy"] + }, + "v1GetPrivateKeyRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "privateKeyId": { + "type": "string", + "description": "Unique identifier for a given Private Key." + } + }, + "required": ["organizationId", "privateKeyId"] + }, + "v1GetPrivateKeyResponse": { + "type": "object", + "properties": { + "privateKey": { + "$ref": "#/definitions/v1PrivateKey", + "description": "Cryptographic public/private key pair that can be used for cryptocurrency needs or more generalized encryption." + } + }, + "required": ["privateKey"] + }, + "v1GetPrivateKeysRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + } + }, + "required": ["organizationId"] + }, + "v1GetPrivateKeysResponse": { + "type": "object", + "properties": { + "privateKeys": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1PrivateKey" + }, + "description": "A list of Private Keys." + } + }, + "required": ["privateKeys"] + }, + "v1GetSubOrgIdsRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for the parent Organization. This is used to find sub-organizations within it." + }, + "filterType": { + "type": "string", + "description": "Specifies the type of filter to apply, i.e 'CREDENTIAL_ID', 'NAME', 'USERNAME', 'EMAIL', 'PHONE_NUMBER', 'OIDC_TOKEN' or 'PUBLIC_KEY'" + }, + "filterValue": { + "type": "string", + "description": "The value of the filter to apply for the specified type. For example, a specific email or name string." + }, + "paginationOptions": { + "$ref": "#/definitions/v1Pagination", + "description": "Parameters used for cursor-based pagination." + } + }, + "required": ["organizationId"] + }, + "v1GetSubOrgIdsResponse": { + "type": "object", + "properties": { + "organizationIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "List of unique identifiers for the matching sub-organizations." + } + }, + "required": ["organizationIds"] + }, + "v1GetUserRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "userId": { + "type": "string", + "description": "Unique identifier for a given User." + } + }, + "required": ["organizationId", "userId"] + }, + "v1GetUserResponse": { + "type": "object", + "properties": { + "user": { + "$ref": "#/definitions/v1User", + "description": "Web and/or API user within your Organization." + } + }, + "required": ["user"] + }, + "v1GetUsersRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + } + }, + "required": ["organizationId"] + }, + "v1GetUsersResponse": { + "type": "object", + "properties": { + "users": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1User" + }, + "description": "A list of Users." + } + }, + "required": ["users"] + }, + "v1GetVerifiedSubOrgIdsRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for the parent Organization. This is used to find sub-organizations within it." + }, + "filterType": { + "type": "string", + "description": "Specifies the type of filter to apply, i.e 'EMAIL', 'PHONE_NUMBER'" + }, + "filterValue": { + "type": "string", + "description": "The value of the filter to apply for the specified type. For example, a specific email or phone number string." + }, + "paginationOptions": { + "$ref": "#/definitions/v1Pagination", + "description": "Parameters used for cursor-based pagination." + } + }, + "required": ["organizationId"] + }, + "v1GetVerifiedSubOrgIdsResponse": { + "type": "object", + "properties": { + "organizationIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "List of unique identifiers for the matching sub-organizations." + } + }, + "required": ["organizationIds"] + }, + "v1GetWalletAccountRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "walletId": { + "type": "string", + "description": "Unique identifier for a given Wallet." + }, + "address": { + "type": "string", + "description": "Address corresponding to a Wallet Account." + }, + "path": { + "type": "string", + "description": "Path corresponding to a Wallet Account." + } + }, + "required": ["organizationId", "walletId"] + }, + "v1GetWalletAccountResponse": { + "type": "object", + "properties": { + "account": { + "$ref": "#/definitions/v1WalletAccount", + "description": "The resulting Wallet Account." + } + }, + "required": ["account"] + }, + "v1GetWalletAccountsRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "walletId": { + "type": "string", + "description": "Unique identifier for a given Wallet." + }, + "paginationOptions": { + "$ref": "#/definitions/v1Pagination", + "description": "Parameters used for cursor-based pagination." + } + }, + "required": ["organizationId", "walletId"] + }, + "v1GetWalletAccountsResponse": { + "type": "object", + "properties": { + "accounts": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1WalletAccount" + }, + "description": "A list of Accounts generated from a Wallet that share a common seed." + } + }, + "required": ["accounts"] + }, + "v1GetWalletRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "walletId": { + "type": "string", + "description": "Unique identifier for a given Wallet." + } + }, + "required": ["organizationId", "walletId"] + }, + "v1GetWalletResponse": { + "type": "object", + "properties": { + "wallet": { + "$ref": "#/definitions/v1Wallet", + "description": "A collection of deterministically generated cryptographic public / private key pairs that share a common seed" + } + }, + "required": ["wallet"] + }, + "v1GetWalletsRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + } + }, + "required": ["organizationId"] + }, + "v1GetWalletsResponse": { + "type": "object", + "properties": { + "wallets": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1Wallet" + }, + "description": "A list of Wallets." + } + }, + "required": ["wallets"] + }, + "v1GetWhoamiRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "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." + } + }, + "required": ["organizationId"] + }, + "v1GetWhoamiResponse": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "organizationName": { + "type": "string", + "description": "Human-readable name for an Organization." + }, + "userId": { + "type": "string", + "description": "Unique identifier for a given User." + }, + "username": { + "type": "string", + "description": "Human-readable name for a User." + } + }, + "required": ["organizationId", "organizationName", "userId", "username"] + }, + "v1HashFunction": { + "type": "string", + "enum": [ + "HASH_FUNCTION_NO_OP", + "HASH_FUNCTION_SHA256", + "HASH_FUNCTION_KECCAK256", + "HASH_FUNCTION_NOT_APPLICABLE" + ] + }, + "v1ImportPrivateKeyIntent": { + "type": "object", + "properties": { + "userId": { + "type": "string", + "description": "The ID of the User importing a Private Key." + }, + "privateKeyName": { + "type": "string", + "description": "Human-readable name for a Private Key." + }, + "encryptedBundle": { + "type": "string", + "description": "Bundle containing a raw private key encrypted to the enclave's target public key." + }, + "curve": { + "$ref": "#/definitions/v1Curve", + "description": "Cryptographic Curve used to generate a given Private Key." + }, + "addressFormats": { + "type": "array", + "items": { + "$ref": "#/definitions/v1AddressFormat" + }, + "description": "Cryptocurrency-specific formats for a derived address (e.g., Ethereum)." + } + }, + "required": [ + "userId", + "privateKeyName", + "encryptedBundle", + "curve", + "addressFormats" + ] + }, + "v1ImportPrivateKeyRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_IMPORT_PRIVATE_KEY"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1ImportPrivateKeyIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1ImportPrivateKeyResult": { + "type": "object", + "properties": { + "privateKeyId": { + "type": "string", + "description": "Unique identifier for a Private Key." + }, + "addresses": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/immutableactivityv1Address" + }, + "description": "A list of addresses." + } + }, + "required": ["privateKeyId", "addresses"] + }, + "v1ImportWalletIntent": { + "type": "object", + "properties": { + "userId": { + "type": "string", + "description": "The ID of the User importing a Wallet." + }, + "walletName": { + "type": "string", + "description": "Human-readable name for a Wallet." + }, + "encryptedBundle": { + "type": "string", + "description": "Bundle containing a wallet mnemonic encrypted to the enclave's target public key." + }, + "accounts": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1WalletAccountParams" + }, + "description": "A list of wallet Accounts." + } + }, + "required": ["userId", "walletName", "encryptedBundle", "accounts"] + }, + "v1ImportWalletRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_IMPORT_WALLET"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1ImportWalletIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1ImportWalletResult": { + "type": "object", + "properties": { + "walletId": { + "type": "string", + "description": "Unique identifier for a Wallet." + }, + "addresses": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of account addresses." + } + }, + "required": ["walletId", "addresses"] + }, + "v1InitImportPrivateKeyIntent": { + "type": "object", + "properties": { + "userId": { + "type": "string", + "description": "The ID of the User importing a Private Key." + } + }, + "required": ["userId"] + }, + "v1InitImportPrivateKeyRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_INIT_IMPORT_PRIVATE_KEY"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1InitImportPrivateKeyIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1InitImportPrivateKeyResult": { + "type": "object", + "properties": { + "importBundle": { + "type": "string", + "description": "Import bundle containing a public key and signature to use for importing client data." + } + }, + "required": ["importBundle"] + }, + "v1InitImportWalletIntent": { + "type": "object", + "properties": { + "userId": { + "type": "string", + "description": "The ID of the User importing a Wallet." + } + }, + "required": ["userId"] + }, + "v1InitImportWalletRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_INIT_IMPORT_WALLET"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1InitImportWalletIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1InitImportWalletResult": { + "type": "object", + "properties": { + "importBundle": { + "type": "string", + "description": "Import bundle containing a public key and signature to use for importing client data." + } + }, + "required": ["importBundle"] + }, + "v1InitOtpAuthIntent": { + "type": "object", + "properties": { + "otpType": { + "type": "string", + "description": "Enum to specifiy whether to send OTP via SMS or email" + }, + "contact": { + "type": "string", + "description": "Email or phone number to send the OTP code to" + }, + "emailCustomization": { + "$ref": "#/definitions/v1EmailCustomizationParams", + "description": "Optional parameters for customizing emails. If not provided, the default email will be used." + }, + "smsCustomization": { + "$ref": "#/definitions/v1SmsCustomizationParams", + "description": "Optional parameters for customizing SMS message. If not provided, the default sms message will be used." + }, + "userIdentifier": { + "type": "string", + "description": "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." + }, + "sendFromEmailAddress": { + "type": "string", + "description": "Optional custom email address from which to send the OTP email" + }, + "sendFromEmailSenderName": { + "type": "string", + "description": "Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications'" + }, + "replyToEmailAddress": { + "type": "string", + "description": "Optional custom email address to use as reply-to" + } + }, + "required": ["otpType", "contact"] + }, + "v1InitOtpAuthIntentV2": { + "type": "object", + "properties": { + "otpType": { + "type": "string", + "description": "Enum to specifiy whether to send OTP via SMS or email" + }, + "contact": { + "type": "string", + "description": "Email or phone number to send the OTP code to" + }, + "otpLength": { + "type": "integer", + "format": "int32", + "description": "Optional length of the OTP code. Default = 9" + }, + "emailCustomization": { + "$ref": "#/definitions/v1EmailCustomizationParams", + "description": "Optional parameters for customizing emails. If not provided, the default email will be used." + }, + "smsCustomization": { + "$ref": "#/definitions/v1SmsCustomizationParams", + "description": "Optional parameters for customizing SMS message. If not provided, the default sms message will be used." + }, + "userIdentifier": { + "type": "string", + "description": "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." + }, + "sendFromEmailAddress": { + "type": "string", + "description": "Optional custom email address from which to send the OTP email" + }, + "alphanumeric": { + "type": "boolean", + "description": "Optional flag to specify if the OTP code should be alphanumeric (Crockford’s Base32). Default = true" + }, + "sendFromEmailSenderName": { + "type": "string", + "description": "Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications'" + }, + "replyToEmailAddress": { + "type": "string", + "description": "Optional custom email address to use as reply-to" + } + }, + "required": ["otpType", "contact"] + }, + "v1InitOtpAuthRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_INIT_OTP_AUTH_V2"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1InitOtpAuthIntentV2" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1InitOtpAuthResult": { + "type": "object", + "properties": { + "otpId": { + "type": "string", + "description": "Unique identifier for an OTP authentication" + } + }, + "required": ["otpId"] + }, + "v1InitOtpAuthResultV2": { + "type": "object", + "properties": { + "otpId": { + "type": "string", + "description": "Unique identifier for an OTP authentication" + } + }, + "required": ["otpId"] + }, + "v1InitOtpIntent": { + "type": "object", + "properties": { + "otpType": { + "type": "string", + "description": "Whether to send OTP via SMS or email. Possible values: OTP_TYPE_SMS, OTP_TYPE_EMAIL" + }, + "contact": { + "type": "string", + "description": "Email or phone number to send the OTP code to" + }, + "otpLength": { + "type": "integer", + "format": "int32", + "description": "Optional length of the OTP code. Default = 9" + }, + "emailCustomization": { + "$ref": "#/definitions/v1EmailCustomizationParams", + "description": "Optional parameters for customizing emails. If not provided, the default email will be used." + }, + "smsCustomization": { + "$ref": "#/definitions/v1SmsCustomizationParams", + "description": "Optional parameters for customizing SMS message. If not provided, the default sms message will be used." + }, + "userIdentifier": { + "type": "string", + "description": "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." + }, + "sendFromEmailAddress": { + "type": "string", + "description": "Optional custom email address from which to send the OTP email" + }, + "alphanumeric": { + "type": "boolean", + "description": "Optional flag to specify if the OTP code should be alphanumeric (Crockford’s Base32). Default = true" + }, + "sendFromEmailSenderName": { + "type": "string", + "description": "Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications'" + }, + "expirationSeconds": { + "type": "string", + "description": "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)" + }, + "replyToEmailAddress": { + "type": "string", + "description": "Optional custom email address to use as reply-to" + } + }, + "required": ["otpType", "contact"] + }, + "v1InitOtpRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_INIT_OTP"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1InitOtpIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1InitOtpResult": { + "type": "object", + "properties": { + "otpId": { + "type": "string", + "description": "Unique identifier for an OTP authentication" + } + }, + "required": ["otpId"] + }, + "v1InitUserEmailRecoveryIntent": { + "type": "object", + "properties": { + "email": { + "type": "string", + "description": "Email of the user starting recovery" + }, + "targetPublicKey": { + "type": "string", + "description": "Client-side public key generated by the user, to which the recovery bundle will be encrypted." + }, + "expirationSeconds": { + "type": "string", + "description": "Expiration window (in seconds) indicating how long the recovery credential is valid for. If not provided, a default of 15 minutes will be used." + }, + "emailCustomization": { + "$ref": "#/definitions/v1EmailCustomizationParams", + "description": "Optional parameters for customizing emails. If not provided, the default email will be used." + } + }, + "required": ["email", "targetPublicKey"] + }, + "v1InitUserEmailRecoveryRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_INIT_USER_EMAIL_RECOVERY"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1InitUserEmailRecoveryIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1InitUserEmailRecoveryResult": { + "type": "object", + "properties": { + "userId": { + "type": "string", + "description": "Unique identifier for the user being recovered." + } + }, + "required": ["userId"] + }, + "v1Intent": { + "type": "object", + "properties": { + "createOrganizationIntent": { + "$ref": "#/definitions/v1CreateOrganizationIntent" + }, + "createAuthenticatorsIntent": { + "$ref": "#/definitions/v1CreateAuthenticatorsIntent" + }, + "createUsersIntent": { + "$ref": "#/definitions/v1CreateUsersIntent" + }, + "createPrivateKeysIntent": { + "$ref": "#/definitions/v1CreatePrivateKeysIntent" + }, + "signRawPayloadIntent": { + "$ref": "#/definitions/v1SignRawPayloadIntent" + }, + "createInvitationsIntent": { + "$ref": "#/definitions/v1CreateInvitationsIntent" + }, + "acceptInvitationIntent": { + "$ref": "#/definitions/v1AcceptInvitationIntent" + }, + "createPolicyIntent": { + "$ref": "#/definitions/v1CreatePolicyIntent" + }, + "disablePrivateKeyIntent": { + "$ref": "#/definitions/v1DisablePrivateKeyIntent" + }, + "deleteUsersIntent": { + "$ref": "#/definitions/v1DeleteUsersIntent" + }, + "deleteAuthenticatorsIntent": { + "$ref": "#/definitions/v1DeleteAuthenticatorsIntent" + }, + "deleteInvitationIntent": { + "$ref": "#/definitions/v1DeleteInvitationIntent" + }, + "deleteOrganizationIntent": { + "$ref": "#/definitions/v1DeleteOrganizationIntent" + }, + "deletePolicyIntent": { + "$ref": "#/definitions/v1DeletePolicyIntent" + }, + "createUserTagIntent": { + "$ref": "#/definitions/v1CreateUserTagIntent" + }, + "deleteUserTagsIntent": { + "$ref": "#/definitions/v1DeleteUserTagsIntent" + }, + "signTransactionIntent": { + "$ref": "#/definitions/v1SignTransactionIntent" + }, + "createApiKeysIntent": { + "$ref": "#/definitions/v1CreateApiKeysIntent" + }, + "deleteApiKeysIntent": { + "$ref": "#/definitions/v1DeleteApiKeysIntent" + }, + "approveActivityIntent": { + "$ref": "#/definitions/v1ApproveActivityIntent" + }, + "rejectActivityIntent": { + "$ref": "#/definitions/v1RejectActivityIntent" + }, + "createPrivateKeyTagIntent": { + "$ref": "#/definitions/v1CreatePrivateKeyTagIntent" + }, + "deletePrivateKeyTagsIntent": { + "$ref": "#/definitions/v1DeletePrivateKeyTagsIntent" + }, + "createPolicyIntentV2": { + "$ref": "#/definitions/v1CreatePolicyIntentV2" + }, + "setPaymentMethodIntent": { + "$ref": "#/definitions/billingSetPaymentMethodIntent" + }, + "activateBillingTierIntent": { + "$ref": "#/definitions/billingActivateBillingTierIntent" + }, + "deletePaymentMethodIntent": { + "$ref": "#/definitions/billingDeletePaymentMethodIntent" + }, + "createPolicyIntentV3": { + "$ref": "#/definitions/v1CreatePolicyIntentV3" + }, + "createApiOnlyUsersIntent": { + "$ref": "#/definitions/v1CreateApiOnlyUsersIntent" + }, + "updateRootQuorumIntent": { + "$ref": "#/definitions/v1UpdateRootQuorumIntent" + }, + "updateUserTagIntent": { + "$ref": "#/definitions/v1UpdateUserTagIntent" + }, + "updatePrivateKeyTagIntent": { + "$ref": "#/definitions/v1UpdatePrivateKeyTagIntent" + }, + "createAuthenticatorsIntentV2": { + "$ref": "#/definitions/v1CreateAuthenticatorsIntentV2" + }, + "acceptInvitationIntentV2": { + "$ref": "#/definitions/v1AcceptInvitationIntentV2" + }, + "createOrganizationIntentV2": { + "$ref": "#/definitions/v1CreateOrganizationIntentV2" + }, + "createUsersIntentV2": { + "$ref": "#/definitions/v1CreateUsersIntentV2" + }, + "createSubOrganizationIntent": { + "$ref": "#/definitions/v1CreateSubOrganizationIntent" + }, + "createSubOrganizationIntentV2": { + "$ref": "#/definitions/v1CreateSubOrganizationIntentV2" + }, + "updateAllowedOriginsIntent": { + "$ref": "#/definitions/v1UpdateAllowedOriginsIntent" + }, + "createPrivateKeysIntentV2": { + "$ref": "#/definitions/v1CreatePrivateKeysIntentV2" + }, + "updateUserIntent": { + "$ref": "#/definitions/v1UpdateUserIntent" + }, + "updatePolicyIntent": { + "$ref": "#/definitions/v1UpdatePolicyIntent" + }, + "setPaymentMethodIntentV2": { + "$ref": "#/definitions/billingSetPaymentMethodIntentV2" + }, + "createSubOrganizationIntentV3": { + "$ref": "#/definitions/v1CreateSubOrganizationIntentV3" + }, + "createWalletIntent": { + "$ref": "#/definitions/v1CreateWalletIntent" + }, + "createWalletAccountsIntent": { + "$ref": "#/definitions/v1CreateWalletAccountsIntent" + }, + "initUserEmailRecoveryIntent": { + "$ref": "#/definitions/v1InitUserEmailRecoveryIntent" + }, + "recoverUserIntent": { + "$ref": "#/definitions/v1RecoverUserIntent" + }, + "setOrganizationFeatureIntent": { + "$ref": "#/definitions/v1SetOrganizationFeatureIntent" + }, + "removeOrganizationFeatureIntent": { + "$ref": "#/definitions/v1RemoveOrganizationFeatureIntent" + }, + "signRawPayloadIntentV2": { + "$ref": "#/definitions/v1SignRawPayloadIntentV2" + }, + "signTransactionIntentV2": { + "$ref": "#/definitions/v1SignTransactionIntentV2" + }, + "exportPrivateKeyIntent": { + "$ref": "#/definitions/v1ExportPrivateKeyIntent" + }, + "exportWalletIntent": { + "$ref": "#/definitions/v1ExportWalletIntent" + }, + "createSubOrganizationIntentV4": { + "$ref": "#/definitions/v1CreateSubOrganizationIntentV4" + }, + "emailAuthIntent": { + "$ref": "#/definitions/v1EmailAuthIntent" + }, + "exportWalletAccountIntent": { + "$ref": "#/definitions/v1ExportWalletAccountIntent" + }, + "initImportWalletIntent": { + "$ref": "#/definitions/v1InitImportWalletIntent" + }, + "importWalletIntent": { + "$ref": "#/definitions/v1ImportWalletIntent" + }, + "initImportPrivateKeyIntent": { + "$ref": "#/definitions/v1InitImportPrivateKeyIntent" + }, + "importPrivateKeyIntent": { + "$ref": "#/definitions/v1ImportPrivateKeyIntent" + }, + "createPoliciesIntent": { + "$ref": "#/definitions/v1CreatePoliciesIntent" + }, + "signRawPayloadsIntent": { + "$ref": "#/definitions/v1SignRawPayloadsIntent" + }, + "createReadOnlySessionIntent": { + "$ref": "#/definitions/v1CreateReadOnlySessionIntent" + }, + "createOauthProvidersIntent": { + "$ref": "#/definitions/v1CreateOauthProvidersIntent" + }, + "deleteOauthProvidersIntent": { + "$ref": "#/definitions/v1DeleteOauthProvidersIntent" + }, + "createSubOrganizationIntentV5": { + "$ref": "#/definitions/v1CreateSubOrganizationIntentV5" + }, + "oauthIntent": { + "$ref": "#/definitions/v1OauthIntent" + }, + "createApiKeysIntentV2": { + "$ref": "#/definitions/v1CreateApiKeysIntentV2" + }, + "createReadWriteSessionIntent": { + "$ref": "#/definitions/v1CreateReadWriteSessionIntent" + }, + "emailAuthIntentV2": { + "$ref": "#/definitions/v1EmailAuthIntentV2" + }, + "createSubOrganizationIntentV6": { + "$ref": "#/definitions/v1CreateSubOrganizationIntentV6" + }, + "deletePrivateKeysIntent": { + "$ref": "#/definitions/v1DeletePrivateKeysIntent" + }, + "deleteWalletsIntent": { + "$ref": "#/definitions/v1DeleteWalletsIntent" + }, + "createReadWriteSessionIntentV2": { + "$ref": "#/definitions/v1CreateReadWriteSessionIntentV2" + }, + "deleteSubOrganizationIntent": { + "$ref": "#/definitions/v1DeleteSubOrganizationIntent" + }, + "initOtpAuthIntent": { + "$ref": "#/definitions/v1InitOtpAuthIntent" + }, + "otpAuthIntent": { + "$ref": "#/definitions/v1OtpAuthIntent" + }, + "createSubOrganizationIntentV7": { + "$ref": "#/definitions/v1CreateSubOrganizationIntentV7" + }, + "updateWalletIntent": { + "$ref": "#/definitions/v1UpdateWalletIntent" + }, + "updatePolicyIntentV2": { + "$ref": "#/definitions/v1UpdatePolicyIntentV2" + }, + "createUsersIntentV3": { + "$ref": "#/definitions/v1CreateUsersIntentV3" + }, + "initOtpAuthIntentV2": { + "$ref": "#/definitions/v1InitOtpAuthIntentV2" + }, + "initOtpIntent": { + "$ref": "#/definitions/v1InitOtpIntent" + }, + "verifyOtpIntent": { + "$ref": "#/definitions/v1VerifyOtpIntent" + }, + "otpLoginIntent": { + "$ref": "#/definitions/v1OtpLoginIntent" + }, + "stampLoginIntent": { + "$ref": "#/definitions/v1StampLoginIntent" + }, + "oauthLoginIntent": { + "$ref": "#/definitions/v1OauthLoginIntent" + } + } + }, + "v1Invitation": { + "type": "object", + "properties": { + "invitationId": { + "type": "string", + "description": "Unique identifier for a given Invitation object." + }, + "receiverUserName": { + "type": "string", + "description": "The name of the intended Invitation recipient." + }, + "receiverEmail": { + "type": "string", + "description": "The email address of the intended Invitation recipient." + }, + "receiverUserTags": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of tags assigned to the Invitation recipient." + }, + "accessType": { + "$ref": "#/definitions/v1AccessType", + "description": "The User's permissible access method(s)." + }, + "status": { + "$ref": "#/definitions/v1InvitationStatus", + "description": "The current processing status of a specified Invitation." + }, + "createdAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + }, + "updatedAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + }, + "senderUserId": { + "type": "string", + "description": "Unique identifier for the Sender of an Invitation." + } + }, + "required": [ + "invitationId", + "receiverUserName", + "receiverEmail", + "receiverUserTags", + "accessType", + "status", + "createdAt", + "updatedAt", + "senderUserId" + ] + }, + "v1InvitationParams": { + "type": "object", + "properties": { + "receiverUserName": { + "type": "string", + "description": "The name of the intended Invitation recipient." + }, + "receiverUserEmail": { + "type": "string", + "description": "The email address of the intended Invitation recipient." + }, + "receiverUserTags": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of tags assigned to the Invitation recipient. This field, if not needed, should be an empty array in your request body." + }, + "accessType": { + "$ref": "#/definitions/v1AccessType", + "description": "The User's permissible access method(s)." + }, + "senderUserId": { + "type": "string", + "description": "Unique identifier for the Sender of an Invitation." + } + }, + "required": [ + "receiverUserName", + "receiverUserEmail", + "receiverUserTags", + "accessType", + "senderUserId" + ] + }, + "v1InvitationStatus": { + "type": "string", + "enum": [ + "INVITATION_STATUS_CREATED", + "INVITATION_STATUS_ACCEPTED", + "INVITATION_STATUS_REVOKED" + ] + }, + "v1ListPrivateKeyTagsRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + } + }, + "required": ["organizationId"] + }, + "v1ListPrivateKeyTagsResponse": { + "type": "object", + "properties": { + "privateKeyTags": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/datav1Tag" + }, + "description": "A list of Private Key Tags" + } + }, + "required": ["privateKeyTags"] + }, + "v1ListUserTagsRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + } + }, + "required": ["organizationId"] + }, + "v1ListUserTagsResponse": { + "type": "object", + "properties": { + "userTags": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/datav1Tag" + }, + "description": "A list of User Tags" + } + }, + "required": ["userTags"] + }, + "v1MnemonicLanguage": { + "type": "string", + "enum": [ + "MNEMONIC_LANGUAGE_ENGLISH", + "MNEMONIC_LANGUAGE_SIMPLIFIED_CHINESE", + "MNEMONIC_LANGUAGE_TRADITIONAL_CHINESE", + "MNEMONIC_LANGUAGE_CZECH", + "MNEMONIC_LANGUAGE_FRENCH", + "MNEMONIC_LANGUAGE_ITALIAN", + "MNEMONIC_LANGUAGE_JAPANESE", + "MNEMONIC_LANGUAGE_KOREAN", + "MNEMONIC_LANGUAGE_SPANISH" + ] + }, + "v1NOOPCodegenAnchorResponse": { + "type": "object", + "properties": { + "stamp": { + "$ref": "#/definitions/v1WebAuthnStamp" + } + }, + "required": ["stamp"] + }, + "v1OauthIntent": { + "type": "object", + "properties": { + "oidcToken": { + "type": "string", + "description": "Base64 encoded OIDC token" + }, + "targetPublicKey": { + "type": "string", + "description": "Client-side public key generated by the user, to which the oauth bundle (credentials) will be encrypted." + }, + "apiKeyName": { + "type": "string", + "description": "Optional human-readable name for an API Key. If none provided, default to Oauth - \u003cTimestamp\u003e" + }, + "expirationSeconds": { + "type": "string", + "description": "Expiration window (in seconds) indicating how long the API key is valid for. If not provided, a default of 15 minutes will be used." + }, + "invalidateExisting": { + "type": "boolean", + "description": "Invalidate all other previously generated Oauth API keys" + } + }, + "required": ["oidcToken", "targetPublicKey"] + }, + "v1OauthLoginIntent": { + "type": "object", + "properties": { + "oidcToken": { + "type": "string", + "description": "Base64 encoded OIDC token" + }, + "publicKey": { + "type": "string", + "description": "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" + }, + "expirationSeconds": { + "type": "string", + "description": "Expiration window (in seconds) indicating how long the Session is valid for. If not provided, a default of 15 minutes will be used." + }, + "invalidateExisting": { + "type": "boolean", + "description": "Invalidate all other previously generated Login API keys" + } + }, + "required": ["oidcToken", "publicKey"] + }, + "v1OauthLoginRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_OAUTH_LOGIN"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1OauthLoginIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1OauthLoginResult": { + "type": "object", + "properties": { + "session": { + "type": "string", + "description": "Signed JWT containing an expiry, public key, session type, user id, and organization id" + } + }, + "required": ["session"] + }, + "v1OauthProvider": { + "type": "object", + "properties": { + "providerId": { + "type": "string", + "description": "Unique identifier for an OAuth Provider" + }, + "providerName": { + "type": "string", + "description": "Human-readable name to identify a Provider." + }, + "issuer": { + "type": "string", + "description": "The issuer of the token, typically a URL indicating the authentication server, e.g https://accounts.google.com" + }, + "audience": { + "type": "string", + "description": "Expected audience ('aud' attribute of the signed token) which represents the app ID" + }, + "subject": { + "type": "string", + "description": "Expected subject ('sub' attribute of the signed token) which represents the user ID" + }, + "createdAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + }, + "updatedAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + } + }, + "required": [ + "providerId", + "providerName", + "issuer", + "audience", + "subject", + "createdAt", + "updatedAt" + ] + }, + "v1OauthProviderParams": { + "type": "object", + "properties": { + "providerName": { + "type": "string", + "description": "Human-readable name to identify a Provider." + }, + "oidcToken": { + "type": "string", + "description": "Base64 encoded OIDC token" + } + }, + "required": ["providerName", "oidcToken"] + }, + "v1OauthRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_OAUTH"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1OauthIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1OauthResult": { + "type": "object", + "properties": { + "userId": { + "type": "string", + "description": "Unique identifier for the authenticating User." + }, + "apiKeyId": { + "type": "string", + "description": "Unique identifier for the created API key." + }, + "credentialBundle": { + "type": "string", + "description": "HPKE encrypted credential bundle" + } + }, + "required": ["userId", "apiKeyId", "credentialBundle"] + }, + "v1Operator": { + "type": "string", + "enum": [ + "OPERATOR_EQUAL", + "OPERATOR_MORE_THAN", + "OPERATOR_MORE_THAN_OR_EQUAL", + "OPERATOR_LESS_THAN", + "OPERATOR_LESS_THAN_OR_EQUAL", + "OPERATOR_CONTAINS", + "OPERATOR_NOT_EQUAL", + "OPERATOR_IN", + "OPERATOR_NOT_IN", + "OPERATOR_CONTAINS_ONE", + "OPERATOR_CONTAINS_ALL" + ] + }, + "v1OrganizationData": { + "type": "object", + "properties": { + "organizationId": { + "type": "string" + }, + "name": { + "type": "string" + }, + "users": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1User" + } + }, + "policies": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1Policy" + } + }, + "privateKeys": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1PrivateKey" + } + }, + "invitations": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1Invitation" + } + }, + "tags": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/datav1Tag" + } + }, + "rootQuorum": { + "$ref": "#/definitions/externaldatav1Quorum" + }, + "features": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1Feature" + } + }, + "wallets": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1Wallet" + } + } + } + }, + "v1OtpAuthIntent": { + "type": "object", + "properties": { + "otpId": { + "type": "string", + "description": "ID representing the result of an init OTP activity." + }, + "otpCode": { + "type": "string", + "description": "OTP sent out to a user's contact (email or SMS)" + }, + "targetPublicKey": { + "type": "string", + "description": "Client-side public key generated by the user, to which the OTP bundle (credentials) will be encrypted." + }, + "apiKeyName": { + "type": "string", + "description": "Optional human-readable name for an API Key. If none provided, default to OTP Auth - \u003cTimestamp\u003e" + }, + "expirationSeconds": { + "type": "string", + "description": "Expiration window (in seconds) indicating how long the API key is valid for. If not provided, a default of 15 minutes will be used." + }, + "invalidateExisting": { + "type": "boolean", + "description": "Invalidate all other previously generated OTP Auth API keys" + } + }, + "required": ["otpId", "otpCode", "targetPublicKey"] + }, + "v1OtpAuthRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_OTP_AUTH"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1OtpAuthIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1OtpAuthResult": { + "type": "object", + "properties": { + "userId": { + "type": "string", + "description": "Unique identifier for the authenticating User." + }, + "apiKeyId": { + "type": "string", + "description": "Unique identifier for the created API key." + }, + "credentialBundle": { + "type": "string", + "description": "HPKE encrypted credential bundle" + } + }, + "required": ["userId"] + }, + "v1OtpLoginIntent": { + "type": "object", + "properties": { + "verificationToken": { + "type": "string", + "description": "Signed JWT containing a unique id, expiry, verification type, contact" + }, + "publicKey": { + "type": "string", + "description": "Client-side public key generated by the user, which will be conditionally added to org data based on the validity of the verification token" + }, + "expirationSeconds": { + "type": "string", + "description": "Expiration window (in seconds) indicating how long the Session is valid for. If not provided, a default of 15 minutes will be used." + }, + "invalidateExisting": { + "type": "boolean", + "description": "Invalidate all other previously generated Login API keys" + } + }, + "required": ["verificationToken", "publicKey"] + }, + "v1OtpLoginRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_OTP_LOGIN"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1OtpLoginIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1OtpLoginResult": { + "type": "object", + "properties": { + "session": { + "type": "string", + "description": "Signed JWT containing an expiry, public key, session type, user id, and organization id" + } + }, + "required": ["session"] + }, + "v1Pagination": { + "type": "object", + "properties": { + "limit": { + "type": "string", + "description": "A limit of the number of object to be returned, between 1 and 100. Defaults to 10." + }, + "before": { + "type": "string", + "description": "A pagination cursor. This is an object ID that enables you to fetch all objects before this ID." + }, + "after": { + "type": "string", + "description": "A pagination cursor. This is an object ID that enables you to fetch all objects after this ID." + } + } + }, + "v1PathFormat": { + "type": "string", + "enum": ["PATH_FORMAT_BIP32"] + }, + "v1PayloadEncoding": { + "type": "string", + "enum": ["PAYLOAD_ENCODING_HEXADECIMAL", "PAYLOAD_ENCODING_TEXT_UTF8"] + }, + "v1Policy": { + "type": "object", + "properties": { + "policyId": { + "type": "string", + "description": "Unique identifier for a given Policy." + }, + "policyName": { + "type": "string", + "description": "Human-readable name for a Policy." + }, + "effect": { + "$ref": "#/definitions/v1Effect", + "description": "The instruction to DENY or ALLOW a particular activity following policy selector(s)." + }, + "createdAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + }, + "updatedAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + }, + "notes": { + "type": "string", + "description": "Human-readable notes added by a User to describe a particular policy." + }, + "consensus": { + "type": "string", + "description": "A consensus expression that evalutes to true or false." + }, + "condition": { + "type": "string", + "description": "A condition expression that evalutes to true or false." + } + }, + "required": [ + "policyId", + "policyName", + "effect", + "createdAt", + "updatedAt", + "notes", + "consensus", + "condition" + ] + }, + "v1PrivateKey": { + "type": "object", + "properties": { + "privateKeyId": { + "type": "string", + "description": "Unique identifier for a given Private Key." + }, + "publicKey": { + "type": "string", + "description": "The public component of a cryptographic key pair used to sign messages and transactions." + }, + "privateKeyName": { + "type": "string", + "description": "Human-readable name for a Private Key." + }, + "curve": { + "$ref": "#/definitions/v1Curve", + "description": "Cryptographic Curve used to generate a given Private Key." + }, + "addresses": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/externaldatav1Address" + }, + "description": "Derived cryptocurrency addresses for a given Private Key." + }, + "privateKeyTags": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of Private Key Tag IDs." + }, + "createdAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + }, + "updatedAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + }, + "exported": { + "type": "boolean", + "description": "True when a given Private Key is exported, false otherwise." + }, + "imported": { + "type": "boolean", + "description": "True when a given Private Key is imported, false otherwise." + } + }, + "required": [ + "privateKeyId", + "publicKey", + "privateKeyName", + "curve", + "addresses", + "privateKeyTags", + "createdAt", + "updatedAt", + "exported", + "imported" + ] + }, + "v1PrivateKeyParams": { + "type": "object", + "properties": { + "privateKeyName": { + "type": "string", + "description": "Human-readable name for a Private Key." + }, + "curve": { + "$ref": "#/definitions/v1Curve", + "description": "Cryptographic Curve used to generate a given Private Key." + }, + "privateKeyTags": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of Private Key Tag IDs. This field, if not needed, should be an empty array in your request body." + }, + "addressFormats": { + "type": "array", + "items": { + "$ref": "#/definitions/v1AddressFormat" + }, + "description": "Cryptocurrency-specific formats for a derived address (e.g., Ethereum)." + } + }, + "required": [ + "privateKeyName", + "curve", + "privateKeyTags", + "addressFormats" + ] + }, + "v1PrivateKeyResult": { + "type": "object", + "properties": { + "privateKeyId": { + "type": "string" + }, + "addresses": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/immutableactivityv1Address" + } + } + } + }, + "v1PublicKeyCredentialWithAttestation": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "type": { + "type": "string", + "enum": ["public-key"] + }, + "rawId": { + "type": "string" + }, + "authenticatorAttachment": { + "type": "string", + "enum": ["cross-platform", "platform"], + "x-nullable": true + }, + "response": { + "$ref": "#/definitions/v1AuthenticatorAttestationResponse" + }, + "clientExtensionResults": { + "$ref": "#/definitions/v1SimpleClientExtensionResults" + } + }, + "required": ["id", "type", "rawId", "response", "clientExtensionResults"] + }, + "v1RecoverUserIntent": { + "type": "object", + "properties": { + "authenticator": { + "$ref": "#/definitions/v1AuthenticatorParamsV2", + "description": "The new authenticator to register." + }, + "userId": { + "type": "string", + "description": "Unique identifier for the user performing recovery." + } + }, + "required": ["authenticator", "userId"] + }, + "v1RecoverUserRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_RECOVER_USER"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1RecoverUserIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1RecoverUserResult": { + "type": "object", + "properties": { + "authenticatorId": { + "type": "array", + "items": { + "type": "string" + }, + "description": "ID of the authenticator created." + } + }, + "required": ["authenticatorId"] + }, + "v1RejectActivityIntent": { + "type": "object", + "properties": { + "fingerprint": { + "type": "string", + "description": "An artifact verifying a User's action." + } + }, + "required": ["fingerprint"] + }, + "v1RejectActivityRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_REJECT_ACTIVITY"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1RejectActivityIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1RemoveOrganizationFeatureIntent": { + "type": "object", + "properties": { + "name": { + "$ref": "#/definitions/v1FeatureName", + "description": "Name of the feature to remove" + } + }, + "required": ["name"] + }, + "v1RemoveOrganizationFeatureRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_REMOVE_ORGANIZATION_FEATURE"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1RemoveOrganizationFeatureIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1RemoveOrganizationFeatureResult": { + "type": "object", + "properties": { + "features": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1Feature" + }, + "description": "Resulting list of organization features." + } + }, + "required": ["features"] + }, + "v1Result": { + "type": "object", + "properties": { + "createOrganizationResult": { + "$ref": "#/definitions/v1CreateOrganizationResult" + }, + "createAuthenticatorsResult": { + "$ref": "#/definitions/v1CreateAuthenticatorsResult" + }, + "createUsersResult": { + "$ref": "#/definitions/v1CreateUsersResult" + }, + "createPrivateKeysResult": { + "$ref": "#/definitions/v1CreatePrivateKeysResult" + }, + "createInvitationsResult": { + "$ref": "#/definitions/v1CreateInvitationsResult" + }, + "acceptInvitationResult": { + "$ref": "#/definitions/v1AcceptInvitationResult" + }, + "signRawPayloadResult": { + "$ref": "#/definitions/v1SignRawPayloadResult" + }, + "createPolicyResult": { + "$ref": "#/definitions/v1CreatePolicyResult" + }, + "disablePrivateKeyResult": { + "$ref": "#/definitions/v1DisablePrivateKeyResult" + }, + "deleteUsersResult": { + "$ref": "#/definitions/v1DeleteUsersResult" + }, + "deleteAuthenticatorsResult": { + "$ref": "#/definitions/v1DeleteAuthenticatorsResult" + }, + "deleteInvitationResult": { + "$ref": "#/definitions/v1DeleteInvitationResult" + }, + "deleteOrganizationResult": { + "$ref": "#/definitions/v1DeleteOrganizationResult" + }, + "deletePolicyResult": { + "$ref": "#/definitions/v1DeletePolicyResult" + }, + "createUserTagResult": { + "$ref": "#/definitions/v1CreateUserTagResult" + }, + "deleteUserTagsResult": { + "$ref": "#/definitions/v1DeleteUserTagsResult" + }, + "signTransactionResult": { + "$ref": "#/definitions/v1SignTransactionResult" + }, + "deleteApiKeysResult": { + "$ref": "#/definitions/v1DeleteApiKeysResult" + }, + "createApiKeysResult": { + "$ref": "#/definitions/v1CreateApiKeysResult" + }, + "createPrivateKeyTagResult": { + "$ref": "#/definitions/v1CreatePrivateKeyTagResult" + }, + "deletePrivateKeyTagsResult": { + "$ref": "#/definitions/v1DeletePrivateKeyTagsResult" + }, + "setPaymentMethodResult": { + "$ref": "#/definitions/billingSetPaymentMethodResult" + }, + "activateBillingTierResult": { + "$ref": "#/definitions/billingActivateBillingTierResult" + }, + "deletePaymentMethodResult": { + "$ref": "#/definitions/billingDeletePaymentMethodResult" + }, + "createApiOnlyUsersResult": { + "$ref": "#/definitions/v1CreateApiOnlyUsersResult" + }, + "updateRootQuorumResult": { + "$ref": "#/definitions/v1UpdateRootQuorumResult" + }, + "updateUserTagResult": { + "$ref": "#/definitions/v1UpdateUserTagResult" + }, + "updatePrivateKeyTagResult": { + "$ref": "#/definitions/v1UpdatePrivateKeyTagResult" + }, + "createSubOrganizationResult": { + "$ref": "#/definitions/v1CreateSubOrganizationResult" + }, + "updateAllowedOriginsResult": { + "$ref": "#/definitions/v1UpdateAllowedOriginsResult" + }, + "createPrivateKeysResultV2": { + "$ref": "#/definitions/v1CreatePrivateKeysResultV2" + }, + "updateUserResult": { + "$ref": "#/definitions/v1UpdateUserResult" + }, + "updatePolicyResult": { + "$ref": "#/definitions/v1UpdatePolicyResult" + }, + "createSubOrganizationResultV3": { + "$ref": "#/definitions/v1CreateSubOrganizationResultV3" + }, + "createWalletResult": { + "$ref": "#/definitions/v1CreateWalletResult" + }, + "createWalletAccountsResult": { + "$ref": "#/definitions/v1CreateWalletAccountsResult" + }, + "initUserEmailRecoveryResult": { + "$ref": "#/definitions/v1InitUserEmailRecoveryResult" + }, + "recoverUserResult": { + "$ref": "#/definitions/v1RecoverUserResult" + }, + "setOrganizationFeatureResult": { + "$ref": "#/definitions/v1SetOrganizationFeatureResult" + }, + "removeOrganizationFeatureResult": { + "$ref": "#/definitions/v1RemoveOrganizationFeatureResult" + }, + "exportPrivateKeyResult": { + "$ref": "#/definitions/v1ExportPrivateKeyResult" + }, + "exportWalletResult": { + "$ref": "#/definitions/v1ExportWalletResult" + }, + "createSubOrganizationResultV4": { + "$ref": "#/definitions/v1CreateSubOrganizationResultV4" + }, + "emailAuthResult": { + "$ref": "#/definitions/v1EmailAuthResult" + }, + "exportWalletAccountResult": { + "$ref": "#/definitions/v1ExportWalletAccountResult" + }, + "initImportWalletResult": { + "$ref": "#/definitions/v1InitImportWalletResult" + }, + "importWalletResult": { + "$ref": "#/definitions/v1ImportWalletResult" + }, + "initImportPrivateKeyResult": { + "$ref": "#/definitions/v1InitImportPrivateKeyResult" + }, + "importPrivateKeyResult": { + "$ref": "#/definitions/v1ImportPrivateKeyResult" + }, + "createPoliciesResult": { + "$ref": "#/definitions/v1CreatePoliciesResult" + }, + "signRawPayloadsResult": { + "$ref": "#/definitions/v1SignRawPayloadsResult" + }, + "createReadOnlySessionResult": { + "$ref": "#/definitions/v1CreateReadOnlySessionResult" + }, + "createOauthProvidersResult": { + "$ref": "#/definitions/v1CreateOauthProvidersResult" + }, + "deleteOauthProvidersResult": { + "$ref": "#/definitions/v1DeleteOauthProvidersResult" + }, + "createSubOrganizationResultV5": { + "$ref": "#/definitions/v1CreateSubOrganizationResultV5" + }, + "oauthResult": { + "$ref": "#/definitions/v1OauthResult" + }, + "createReadWriteSessionResult": { + "$ref": "#/definitions/v1CreateReadWriteSessionResult" + }, + "createSubOrganizationResultV6": { + "$ref": "#/definitions/v1CreateSubOrganizationResultV6" + }, + "deletePrivateKeysResult": { + "$ref": "#/definitions/v1DeletePrivateKeysResult" + }, + "deleteWalletsResult": { + "$ref": "#/definitions/v1DeleteWalletsResult" + }, + "createReadWriteSessionResultV2": { + "$ref": "#/definitions/v1CreateReadWriteSessionResultV2" + }, + "deleteSubOrganizationResult": { + "$ref": "#/definitions/v1DeleteSubOrganizationResult" + }, + "initOtpAuthResult": { + "$ref": "#/definitions/v1InitOtpAuthResult" + }, + "otpAuthResult": { + "$ref": "#/definitions/v1OtpAuthResult" + }, + "createSubOrganizationResultV7": { + "$ref": "#/definitions/v1CreateSubOrganizationResultV7" + }, + "updateWalletResult": { + "$ref": "#/definitions/v1UpdateWalletResult" + }, + "updatePolicyResultV2": { + "$ref": "#/definitions/v1UpdatePolicyResultV2" + }, + "initOtpAuthResultV2": { + "$ref": "#/definitions/v1InitOtpAuthResultV2" + }, + "initOtpResult": { + "$ref": "#/definitions/v1InitOtpResult" + }, + "verifyOtpResult": { + "$ref": "#/definitions/v1VerifyOtpResult" + }, + "otpLoginResult": { + "$ref": "#/definitions/v1OtpLoginResult" + }, + "stampLoginResult": { + "$ref": "#/definitions/v1StampLoginResult" + }, + "oauthLoginResult": { + "$ref": "#/definitions/v1OauthLoginResult" + } + } + }, + "v1RootUserParams": { + "type": "object", + "properties": { + "userName": { + "type": "string", + "description": "Human-readable name for a User." + }, + "userEmail": { + "type": "string", + "description": "The user's email address." + }, + "apiKeys": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/apiApiKeyParams" + }, + "description": "A list of API Key parameters. This field, if not needed, should be an empty array in your request body." + }, + "authenticators": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1AuthenticatorParamsV2" + }, + "description": "A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body." + } + }, + "required": ["userName", "apiKeys", "authenticators"] + }, + "v1RootUserParamsV2": { + "type": "object", + "properties": { + "userName": { + "type": "string", + "description": "Human-readable name for a User." + }, + "userEmail": { + "type": "string", + "description": "The user's email address." + }, + "apiKeys": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/apiApiKeyParams" + }, + "description": "A list of API Key parameters. This field, if not needed, should be an empty array in your request body." + }, + "authenticators": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1AuthenticatorParamsV2" + }, + "description": "A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body." + }, + "oauthProviders": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1OauthProviderParams" + }, + "description": "A list of Oauth providers. This field, if not needed, should be an empty array in your request body." + } + }, + "required": ["userName", "apiKeys", "authenticators", "oauthProviders"] + }, + "v1RootUserParamsV3": { + "type": "object", + "properties": { + "userName": { + "type": "string", + "description": "Human-readable name for a User." + }, + "userEmail": { + "type": "string", + "description": "The user's email address." + }, + "apiKeys": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1ApiKeyParamsV2" + }, + "description": "A list of API Key parameters. This field, if not needed, should be an empty array in your request body." + }, + "authenticators": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1AuthenticatorParamsV2" + }, + "description": "A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body." + }, + "oauthProviders": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1OauthProviderParams" + }, + "description": "A list of Oauth providers. This field, if not needed, should be an empty array in your request body." + } + }, + "required": ["userName", "apiKeys", "authenticators", "oauthProviders"] + }, + "v1RootUserParamsV4": { + "type": "object", + "properties": { + "userName": { + "type": "string", + "description": "Human-readable name for a User." + }, + "userEmail": { + "type": "string", + "description": "The user's email address." + }, + "userPhoneNumber": { + "type": "string", + "description": "The user's phone number in E.164 format e.g. +13214567890" + }, + "apiKeys": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1ApiKeyParamsV2" + }, + "description": "A list of API Key parameters. This field, if not needed, should be an empty array in your request body." + }, + "authenticators": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1AuthenticatorParamsV2" + }, + "description": "A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body." + }, + "oauthProviders": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1OauthProviderParams" + }, + "description": "A list of Oauth providers. This field, if not needed, should be an empty array in your request body." + } + }, + "required": ["userName", "apiKeys", "authenticators", "oauthProviders"] + }, + "v1Selector": { + "type": "object", + "properties": { + "subject": { + "type": "string" + }, + "operator": { + "$ref": "#/definitions/v1Operator" + }, + "target": { + "type": "string" + } + } + }, + "v1SelectorV2": { + "type": "object", + "properties": { + "subject": { + "type": "string" + }, + "operator": { + "$ref": "#/definitions/v1Operator" + }, + "targets": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "v1SetOrganizationFeatureIntent": { + "type": "object", + "properties": { + "name": { + "$ref": "#/definitions/v1FeatureName", + "description": "Name of the feature to set" + }, + "value": { + "type": "string", + "description": "Optional value for the feature. Will override existing values if feature is already set." + } + }, + "required": ["name", "value"] + }, + "v1SetOrganizationFeatureRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_SET_ORGANIZATION_FEATURE"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1SetOrganizationFeatureIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1SetOrganizationFeatureResult": { + "type": "object", + "properties": { + "features": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1Feature" + }, + "description": "Resulting list of organization features." + } + }, + "required": ["features"] + }, + "v1SignRawPayloadIntent": { + "type": "object", + "properties": { + "privateKeyId": { + "type": "string", + "description": "Unique identifier for a given Private Key." + }, + "payload": { + "type": "string", + "description": "Raw unsigned payload to be signed." + }, + "encoding": { + "$ref": "#/definitions/v1PayloadEncoding", + "description": "Encoding of the `payload` string. Turnkey uses this information to convert `payload` into bytes with the correct decoder (e.g. hex, utf8)." + }, + "hashFunction": { + "$ref": "#/definitions/v1HashFunction", + "description": "Hash function to apply to payload bytes before signing. This field must be set to HASH_FUNCTION_NOT_APPLICABLE for EdDSA/ed25519 signature requests; configurable payload hashing is not supported by RFC 8032." + } + }, + "required": ["privateKeyId", "payload", "encoding", "hashFunction"] + }, + "v1SignRawPayloadIntentV2": { + "type": "object", + "properties": { + "signWith": { + "type": "string", + "description": "A Wallet account address, Private Key address, or Private Key identifier." + }, + "payload": { + "type": "string", + "description": "Raw unsigned payload to be signed." + }, + "encoding": { + "$ref": "#/definitions/v1PayloadEncoding", + "description": "Encoding of the `payload` string. Turnkey uses this information to convert `payload` into bytes with the correct decoder (e.g. hex, utf8)." + }, + "hashFunction": { + "$ref": "#/definitions/v1HashFunction", + "description": "Hash function to apply to payload bytes before signing. This field must be set to HASH_FUNCTION_NOT_APPLICABLE for EdDSA/ed25519 signature requests; configurable payload hashing is not supported by RFC 8032." + } + }, + "required": ["signWith", "payload", "encoding", "hashFunction"] + }, + "v1SignRawPayloadRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_SIGN_RAW_PAYLOAD_V2"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1SignRawPayloadIntentV2" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1SignRawPayloadResult": { + "type": "object", + "properties": { + "r": { + "type": "string", + "description": "Component of an ECSDA signature." + }, + "s": { + "type": "string", + "description": "Component of an ECSDA signature." + }, + "v": { + "type": "string", + "description": "Component of an ECSDA signature." + } + }, + "required": ["r", "s", "v"] + }, + "v1SignRawPayloadsIntent": { + "type": "object", + "properties": { + "signWith": { + "type": "string", + "description": "A Wallet account address, Private Key address, or Private Key identifier." + }, + "payloads": { + "type": "array", + "items": { + "type": "string" + }, + "description": "An array of raw unsigned payloads to be signed." + }, + "encoding": { + "$ref": "#/definitions/v1PayloadEncoding", + "description": "Encoding of the `payload` string. Turnkey uses this information to convert `payload` into bytes with the correct decoder (e.g. hex, utf8)." + }, + "hashFunction": { + "$ref": "#/definitions/v1HashFunction", + "description": "Hash function to apply to payload bytes before signing. This field must be set to HASH_FUNCTION_NOT_APPLICABLE for EdDSA/ed25519 signature requests; configurable payload hashing is not supported by RFC 8032." + } + }, + "required": ["signWith", "payloads", "encoding", "hashFunction"] + }, + "v1SignRawPayloadsRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_SIGN_RAW_PAYLOADS"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1SignRawPayloadsIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1SignRawPayloadsResult": { + "type": "object", + "properties": { + "signatures": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1SignRawPayloadResult" + } + } + } + }, + "v1SignTransactionIntent": { + "type": "object", + "properties": { + "privateKeyId": { + "type": "string", + "description": "Unique identifier for a given Private Key." + }, + "unsignedTransaction": { + "type": "string", + "description": "Raw unsigned transaction to be signed by a particular Private Key." + }, + "type": { + "$ref": "#/definitions/v1TransactionType" + } + }, + "required": ["privateKeyId", "unsignedTransaction", "type"] + }, + "v1SignTransactionIntentV2": { + "type": "object", + "properties": { + "signWith": { + "type": "string", + "description": "A Wallet account address, Private Key address, or Private Key identifier." + }, + "unsignedTransaction": { + "type": "string", + "description": "Raw unsigned transaction to be signed" + }, + "type": { + "$ref": "#/definitions/v1TransactionType" + } + }, + "required": ["signWith", "unsignedTransaction", "type"] + }, + "v1SignTransactionRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_SIGN_TRANSACTION_V2"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1SignTransactionIntentV2" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1SignTransactionResult": { + "type": "object", + "properties": { + "signedTransaction": { + "type": "string" + } + }, + "required": ["signedTransaction"] + }, + "v1SimpleClientExtensionResults": { + "type": "object", + "properties": { + "appid": { + "type": "boolean" + }, + "appidExclude": { + "type": "boolean" + }, + "credProps": { + "$ref": "#/definitions/v1CredPropsAuthenticationExtensionsClientOutputs" + } + } + }, + "v1SmsCustomizationParams": { + "type": "object", + "properties": { + "template": { + "type": "string", + "description": "Template containing references to .OtpCode i.e Your OTP is {{.OtpCode}}" + } + } + }, + "v1StampLoginIntent": { + "type": "object", + "properties": { + "publicKey": { + "type": "string", + "description": "Client-side public key generated by the user, which will be conditionally added to org data based on the passkey stamp associated with this request" + }, + "expirationSeconds": { + "type": "string", + "description": "Expiration window (in seconds) indicating how long the Session is valid for. If not provided, a default of 15 minutes will be used." + }, + "invalidateExisting": { + "type": "boolean", + "description": "Invalidate all other previously generated Login API keys" + } + }, + "required": ["publicKey"] + }, + "v1StampLoginRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_STAMP_LOGIN"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1StampLoginIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1StampLoginResult": { + "type": "object", + "properties": { + "session": { + "type": "string", + "description": "Signed JWT containing an expiry, public key, session type, user id, and organization id" + } + }, + "required": ["session"] + }, + "v1TagType": { + "type": "string", + "enum": ["TAG_TYPE_USER", "TAG_TYPE_PRIVATE_KEY"] + }, + "v1TestRateLimitsRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "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." + }, + "isSetLimit": { + "type": "boolean", + "description": "Whether or not to set a limit on this request." + }, + "limit": { + "type": "integer", + "format": "int64", + "description": "Rate limit to set for org, if is_set_limit is set to true" + } + }, + "required": ["organizationId", "isSetLimit", "limit"] + }, + "v1TestRateLimitsResponse": { + "type": "object" + }, + "v1TransactionType": { + "type": "string", + "enum": [ + "TRANSACTION_TYPE_ETHEREUM", + "TRANSACTION_TYPE_SOLANA", + "TRANSACTION_TYPE_TRON" + ] + }, + "v1UpdateAllowedOriginsIntent": { + "type": "object", + "properties": { + "allowedOrigins": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Additional origins requests are allowed from besides Turnkey origins" + } + }, + "required": ["allowedOrigins"] + }, + "v1UpdateAllowedOriginsResult": { + "type": "object" + }, + "v1UpdatePolicyIntent": { + "type": "object", + "properties": { + "policyId": { + "type": "string", + "description": "Unique identifier for a given Policy." + }, + "policyName": { + "type": "string", + "description": "Human-readable name for a Policy." + }, + "policyEffect": { + "$ref": "#/definitions/v1Effect", + "description": "The instruction to DENY or ALLOW an activity (optional)." + }, + "policyCondition": { + "type": "string", + "description": "The condition expression that triggers the Effect (optional)." + }, + "policyConsensus": { + "type": "string", + "description": "The consensus expression that triggers the Effect (optional)." + }, + "policyNotes": { + "type": "string", + "description": "Accompanying notes for a Policy (optional)." + } + }, + "required": ["policyId"] + }, + "v1UpdatePolicyIntentV2": { + "type": "object", + "properties": { + "policyId": { + "type": "string", + "description": "Unique identifier for a given Policy." + }, + "policyName": { + "type": "string", + "description": "Human-readable name for a Policy." + }, + "policyEffect": { + "$ref": "#/definitions/v1Effect", + "description": "The instruction to DENY or ALLOW an activity (optional)." + }, + "policyCondition": { + "type": "string", + "description": "The condition expression that triggers the Effect (optional)." + }, + "policyConsensus": { + "type": "string", + "description": "The consensus expression that triggers the Effect (optional)." + }, + "policyNotes": { + "type": "string", + "description": "Accompanying notes for a Policy (optional)." + } + }, + "required": ["policyId"] + }, + "v1UpdatePolicyRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_UPDATE_POLICY_V2"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1UpdatePolicyIntentV2" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1UpdatePolicyResult": { + "type": "object", + "properties": { + "policyId": { + "type": "string", + "description": "Unique identifier for a given Policy." + } + }, + "required": ["policyId"] + }, + "v1UpdatePolicyResultV2": { + "type": "object", + "properties": { + "policyId": { + "type": "string", + "description": "Unique identifier for a given Policy." + } + }, + "required": ["policyId"] + }, + "v1UpdatePrivateKeyTagIntent": { + "type": "object", + "properties": { + "privateKeyTagId": { + "type": "string", + "description": "Unique identifier for a given Private Key Tag." + }, + "newPrivateKeyTagName": { + "type": "string", + "description": "The new, human-readable name for the tag with the given ID." + }, + "addPrivateKeyIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of Private Keys IDs to add this tag to." + }, + "removePrivateKeyIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of Private Key IDs to remove this tag from." + } + }, + "required": ["privateKeyTagId", "addPrivateKeyIds", "removePrivateKeyIds"] + }, + "v1UpdatePrivateKeyTagRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_UPDATE_PRIVATE_KEY_TAG"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1UpdatePrivateKeyTagIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1UpdatePrivateKeyTagResult": { + "type": "object", + "properties": { + "privateKeyTagId": { + "type": "string", + "description": "Unique identifier for a given Private Key Tag." + } + }, + "required": ["privateKeyTagId"] + }, + "v1UpdateRootQuorumIntent": { + "type": "object", + "properties": { + "threshold": { + "type": "integer", + "format": "int32", + "description": "The threshold of unique approvals to reach quorum." + }, + "userIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The unique identifiers of users who comprise the quorum set." + } + }, + "required": ["threshold", "userIds"] + }, + "v1UpdateRootQuorumRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_UPDATE_ROOT_QUORUM"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1UpdateRootQuorumIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1UpdateRootQuorumResult": { + "type": "object" + }, + "v1UpdateUserIntent": { + "type": "object", + "properties": { + "userId": { + "type": "string", + "description": "Unique identifier for a given User." + }, + "userName": { + "type": "string", + "description": "Human-readable name for a User." + }, + "userEmail": { + "type": "string", + "description": "The user's email address." + }, + "userTagIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "An updated list of User Tags to apply to this User. This field, if not needed, should be an empty array in your request body." + }, + "userPhoneNumber": { + "type": "string", + "description": "The user's phone number in E.164 format e.g. +13214567890" + } + }, + "required": ["userId"] + }, + "v1UpdateUserRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_UPDATE_USER"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1UpdateUserIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1UpdateUserResult": { + "type": "object", + "properties": { + "userId": { + "type": "string", + "description": "A User ID." + } + }, + "required": ["userId"] + }, + "v1UpdateUserTagIntent": { + "type": "object", + "properties": { + "userTagId": { + "type": "string", + "description": "Unique identifier for a given User Tag." + }, + "newUserTagName": { + "type": "string", + "description": "The new, human-readable name for the tag with the given ID." + }, + "addUserIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of User IDs to add this tag to." + }, + "removeUserIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of User IDs to remove this tag from." + } + }, + "required": ["userTagId", "addUserIds", "removeUserIds"] + }, + "v1UpdateUserTagRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_UPDATE_USER_TAG"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1UpdateUserTagIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1UpdateUserTagResult": { + "type": "object", + "properties": { + "userTagId": { + "type": "string", + "description": "Unique identifier for a given User Tag." + } + }, + "required": ["userTagId"] + }, + "v1UpdateWalletIntent": { + "type": "object", + "properties": { + "walletId": { + "type": "string", + "description": "Unique identifier for a given Wallet." + }, + "walletName": { + "type": "string", + "description": "Human-readable name for a Wallet." + } + }, + "required": ["walletId"] + }, + "v1UpdateWalletRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_UPDATE_WALLET"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1UpdateWalletIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1UpdateWalletResult": { + "type": "object", + "properties": { + "walletId": { + "type": "string", + "description": "A Wallet ID." + } + }, + "required": ["walletId"] + }, + "v1User": { + "type": "object", + "properties": { + "userId": { + "type": "string", + "description": "Unique identifier for a given User." + }, + "userName": { + "type": "string", + "description": "Human-readable name for a User." + }, + "userEmail": { + "type": "string", + "description": "The user's email address." + }, + "userPhoneNumber": { + "type": "string", + "description": "The user's phone number in E.164 format e.g. +13214567890" + }, + "authenticators": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1Authenticator" + }, + "description": "A list of Authenticator parameters." + }, + "apiKeys": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1ApiKey" + }, + "description": "A list of API Key parameters. This field, if not needed, should be an empty array in your request body." + }, + "userTags": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of User Tag IDs." + }, + "oauthProviders": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1OauthProvider" + }, + "description": "A list of Oauth Providers." + }, + "createdAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + }, + "updatedAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + } + }, + "required": [ + "userId", + "userName", + "authenticators", + "apiKeys", + "userTags", + "oauthProviders", + "createdAt", + "updatedAt" + ] + }, + "v1UserParams": { + "type": "object", + "properties": { + "userName": { + "type": "string", + "description": "Human-readable name for a User." + }, + "userEmail": { + "type": "string", + "description": "The user's email address." + }, + "accessType": { + "$ref": "#/definitions/v1AccessType", + "description": "The User's permissible access method(s)." + }, + "apiKeys": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/apiApiKeyParams" + }, + "description": "A list of API Key parameters. This field, if not needed, should be an empty array in your request body." + }, + "authenticators": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1AuthenticatorParams" + }, + "description": "A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body." + }, + "userTags": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of User Tag IDs. This field, if not needed, should be an empty array in your request body." + } + }, + "required": [ + "userName", + "accessType", + "apiKeys", + "authenticators", + "userTags" + ] + }, + "v1UserParamsV2": { + "type": "object", + "properties": { + "userName": { + "type": "string", + "description": "Human-readable name for a User." + }, + "userEmail": { + "type": "string", + "description": "The user's email address." + }, + "apiKeys": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/apiApiKeyParams" + }, + "description": "A list of API Key parameters. This field, if not needed, should be an empty array in your request body." + }, + "authenticators": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1AuthenticatorParamsV2" + }, + "description": "A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body." + }, + "userTags": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of User Tag IDs. This field, if not needed, should be an empty array in your request body." + } + }, + "required": ["userName", "apiKeys", "authenticators", "userTags"] + }, + "v1UserParamsV3": { + "type": "object", + "properties": { + "userName": { + "type": "string", + "description": "Human-readable name for a User." + }, + "userEmail": { + "type": "string", + "description": "The user's email address." + }, + "userPhoneNumber": { + "type": "string", + "description": "The user's phone number in E.164 format e.g. +13214567890" + }, + "apiKeys": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1ApiKeyParamsV2" + }, + "description": "A list of API Key parameters. This field, if not needed, should be an empty array in your request body." + }, + "authenticators": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1AuthenticatorParamsV2" + }, + "description": "A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body." + }, + "oauthProviders": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1OauthProviderParams" + }, + "description": "A list of Oauth providers. This field, if not needed, should be an empty array in your request body." + }, + "userTags": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of User Tag IDs. This field, if not needed, should be an empty array in your request body." + } + }, + "required": [ + "userName", + "apiKeys", + "authenticators", + "oauthProviders", + "userTags" + ] + }, + "v1VerifyOtpIntent": { + "type": "object", + "properties": { + "otpId": { + "type": "string", + "description": "ID representing the result of an init OTP activity." + }, + "otpCode": { + "type": "string", + "description": "OTP sent out to a user's contact (email or SMS)" + }, + "expirationSeconds": { + "type": "string", + "description": "Expiration window (in seconds) indicating how long the verification token is valid for. If not provided, a default of 1 hour will be used. Maximum value is 86400 seconds (24 hours)" + } + }, + "required": ["otpId", "otpCode"] + }, + "v1VerifyOtpRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_VERIFY_OTP"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1VerifyOtpIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1VerifyOtpResult": { + "type": "object", + "properties": { + "verificationToken": { + "type": "string", + "description": "Signed JWT containing a unique id, expiry, verification type, contact. Verification status of a user is updated when the token is consumed (in OTP_LOGIN requests)" + } + }, + "required": ["verificationToken"] + }, + "v1Vote": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "Unique identifier for a given Vote object." + }, + "userId": { + "type": "string", + "description": "Unique identifier for a given User." + }, + "user": { + "$ref": "#/definitions/v1User", + "description": "Web and/or API user within your Organization." + }, + "activityId": { + "type": "string", + "description": "Unique identifier for a given Activity object." + }, + "selection": { + "type": "string", + "enum": ["VOTE_SELECTION_APPROVED", "VOTE_SELECTION_REJECTED"] + }, + "message": { + "type": "string", + "description": "The raw message being signed within a Vote." + }, + "publicKey": { + "type": "string", + "description": "The public component of a cryptographic key pair used to sign messages and transactions." + }, + "signature": { + "type": "string", + "description": "The signature applied to a particular vote." + }, + "scheme": { + "type": "string", + "description": "Method used to produce a signature." + }, + "createdAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + } + }, + "required": [ + "id", + "userId", + "user", + "activityId", + "selection", + "message", + "publicKey", + "signature", + "scheme", + "createdAt" + ] + }, + "v1Wallet": { + "type": "object", + "properties": { + "walletId": { + "type": "string", + "description": "Unique identifier for a given Wallet." + }, + "walletName": { + "type": "string", + "description": "Human-readable name for a Wallet." + }, + "createdAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + }, + "updatedAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + }, + "exported": { + "type": "boolean", + "description": "True when a given Wallet is exported, false otherwise." + }, + "imported": { + "type": "boolean", + "description": "True when a given Wallet is imported, false otherwise." + } + }, + "required": [ + "walletId", + "walletName", + "createdAt", + "updatedAt", + "exported", + "imported" + ] + }, + "v1WalletAccount": { + "type": "object", + "properties": { + "walletAccountId": { + "type": "string", + "description": "Unique identifier for a given Wallet Account." + }, + "organizationId": { + "type": "string", + "description": "The Organization the Account belongs to." + }, + "walletId": { + "type": "string", + "description": "The Wallet the Account was derived from." + }, + "curve": { + "$ref": "#/definitions/v1Curve", + "description": "Cryptographic curve used to generate the Account." + }, + "pathFormat": { + "$ref": "#/definitions/v1PathFormat", + "description": "Path format used to generate the Account." + }, + "path": { + "type": "string", + "description": "Path used to generate the Account." + }, + "addressFormat": { + "$ref": "#/definitions/v1AddressFormat", + "description": "Address format used to generate the Account." + }, + "address": { + "type": "string", + "description": "Address generated using the Wallet seed and Account parameters." + }, + "createdAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + }, + "updatedAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + }, + "publicKey": { + "type": "string", + "description": "The public component of this wallet account's underlying cryptographic key pair." + } + }, + "required": [ + "walletAccountId", + "organizationId", + "walletId", + "curve", + "pathFormat", + "path", + "addressFormat", + "address", + "createdAt", + "updatedAt" + ] + }, + "v1WalletAccountParams": { + "type": "object", + "properties": { + "curve": { + "$ref": "#/definitions/v1Curve", + "description": "Cryptographic curve used to generate a wallet Account." + }, + "pathFormat": { + "$ref": "#/definitions/v1PathFormat", + "description": "Path format used to generate a wallet Account." + }, + "path": { + "type": "string", + "description": "Path used to generate a wallet Account." + }, + "addressFormat": { + "$ref": "#/definitions/v1AddressFormat", + "description": "Address format used to generate a wallet Acccount." + } + }, + "required": ["curve", "pathFormat", "path", "addressFormat"] + }, + "v1WalletParams": { + "type": "object", + "properties": { + "walletName": { + "type": "string", + "description": "Human-readable name for a Wallet." + }, + "accounts": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1WalletAccountParams" + }, + "description": "A list of wallet Accounts. This field, if not needed, should be an empty array in your request body." + }, + "mnemonicLength": { + "type": "integer", + "format": "int32", + "description": "Length of mnemonic to generate the Wallet seed. Defaults to 12. Accepted values: 12, 15, 18, 21, 24." + } + }, + "required": ["walletName", "accounts"] + }, + "v1WalletResult": { + "type": "object", + "properties": { + "walletId": { + "type": "string" + }, + "addresses": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of account addresses." + } + }, + "required": ["walletId", "addresses"] + }, + "v1WebAuthnStamp": { + "type": "object", + "properties": { + "credentialId": { + "type": "string", + "description": "A base64 url encoded Unique identifier for a given credential." + }, + "clientDataJson": { + "type": "string", + "description": "A base64 encoded payload containing metadata about the signing context and the challenge." + }, + "authenticatorData": { + "type": "string", + "description": "A base64 encoded payload containing metadata about the authenticator." + }, + "signature": { + "type": "string", + "description": "The base64 url encoded signature bytes contained within the WebAuthn assertion response." + } + }, + "required": [ + "credentialId", + "clientDataJson", + "authenticatorData", + "signature" + ] + } + }, + "securityDefinitions": { + "ApiKeyAuth": { + "type": "apiKey", + "name": "X-Stamp", + "in": "header" + }, + "AuthenticatorAuth": { + "type": "apiKey", + "name": "X-Stamp-WebAuthn", + "in": "header" + } + }, + "security": [ + { + "ApiKeyAuth": [] + }, + { + "AuthenticatorAuth": [] + } + ], + "x-tagGroups": [ + { + "name": "ORGANIZATIONS", + "tags": ["Organizations", "Invitations", "Policies", "Features"] + }, + { + "name": "WALLETS AND PRIVATE KEYS", + "tags": ["Wallets", "Signing", "Private Keys", "Private Key Tags"] + }, + { + "name": "USERS", + "tags": ["Users", "User Tags", "User Recovery", "User Auth"] + }, + { + "name": "CREDENTIALS", + "tags": ["Authenticators", "API Keys", "Sessions"] + }, + { + "name": "ACTIVITIES", + "tags": ["Activities", "Consensus"] + } + ] +} diff --git a/packages/sdk-js/src/__inputs__/public_api.types.ts b/packages/sdk-js/src/__inputs__/public_api.types.ts new file mode 100644 index 000000000..4ac44fc8f --- /dev/null +++ b/packages/sdk-js/src/__inputs__/public_api.types.ts @@ -0,0 +1,4714 @@ +/** + * This file was auto-generated by openapi-typescript. + * Do not make direct changes to the file. + */ + +export type paths = { + "/public/v1/query/get_activity": { + /** Get details about an Activity */ + post: operations["PublicApiService_GetActivity"]; + }; + "/public/v1/query/get_api_key": { + /** Get details about an API key */ + post: operations["PublicApiService_GetApiKey"]; + }; + "/public/v1/query/get_api_keys": { + /** Get details about API keys for a user */ + post: operations["PublicApiService_GetApiKeys"]; + }; + "/public/v1/query/get_attestation": { + /** Get the attestation document corresponding to an enclave. */ + post: operations["PublicApiService_GetAttestationDocument"]; + }; + "/public/v1/query/get_authenticator": { + /** Get details about an authenticator */ + post: operations["PublicApiService_GetAuthenticator"]; + }; + "/public/v1/query/get_authenticators": { + /** Get details about authenticators for a user */ + post: operations["PublicApiService_GetAuthenticators"]; + }; + "/public/v1/query/get_oauth_providers": { + /** Get details about Oauth providers for a user */ + post: operations["PublicApiService_GetOauthProviders"]; + }; + "/public/v1/query/get_organization": { + /** Get details about an Organization */ + post: operations["PublicApiService_GetOrganization"]; + }; + "/public/v1/query/get_organization_configs": { + /** Get quorum settings and features for an organization */ + post: operations["PublicApiService_GetOrganizationConfigs"]; + }; + "/public/v1/query/get_policy": { + /** Get details about a Policy */ + post: operations["PublicApiService_GetPolicy"]; + }; + "/public/v1/query/get_private_key": { + /** Get details about a Private Key */ + post: operations["PublicApiService_GetPrivateKey"]; + }; + "/public/v1/query/get_user": { + /** Get details about a User */ + post: operations["PublicApiService_GetUser"]; + }; + "/public/v1/query/get_wallet": { + /** Get details about a Wallet */ + post: operations["PublicApiService_GetWallet"]; + }; + "/public/v1/query/get_wallet_account": { + /** Get a single wallet account */ + post: operations["PublicApiService_GetWalletAccount"]; + }; + "/public/v1/query/list_activities": { + /** List all Activities within an Organization */ + post: operations["PublicApiService_GetActivities"]; + }; + "/public/v1/query/list_policies": { + /** List all Policies within an Organization */ + post: operations["PublicApiService_GetPolicies"]; + }; + "/public/v1/query/list_private_key_tags": { + /** List all Private Key Tags within an Organization */ + post: operations["PublicApiService_ListPrivateKeyTags"]; + }; + "/public/v1/query/list_private_keys": { + /** List all Private Keys within an Organization */ + post: operations["PublicApiService_GetPrivateKeys"]; + }; + "/public/v1/query/list_suborgs": { + /** Get all suborg IDs associated given a parent org ID and an optional filter. */ + post: operations["PublicApiService_GetSubOrgIds"]; + }; + "/public/v1/query/list_user_tags": { + /** List all User Tags within an Organization */ + post: operations["PublicApiService_ListUserTags"]; + }; + "/public/v1/query/list_users": { + /** List all Users within an Organization */ + post: operations["PublicApiService_GetUsers"]; + }; + "/public/v1/query/list_verified_suborgs": { + /** Get all email or phone verified suborg IDs associated given a parent org ID. */ + post: operations["PublicApiService_GetVerifiedSubOrgIds"]; + }; + "/public/v1/query/list_wallet_accounts": { + /** List all Accounts within a Wallet */ + post: operations["PublicApiService_GetWalletAccounts"]; + }; + "/public/v1/query/list_wallets": { + /** List all Wallets within an Organization */ + post: operations["PublicApiService_GetWallets"]; + }; + "/public/v1/query/whoami": { + /** Get basic information about your current API or WebAuthN user and their organization. Affords Sub-Organization look ups via Parent Organization for WebAuthN or API key users. */ + post: operations["PublicApiService_GetWhoami"]; + }; + "/public/v1/submit/approve_activity": { + /** Approve an Activity */ + post: operations["PublicApiService_ApproveActivity"]; + }; + "/public/v1/submit/create_api_keys": { + /** Add api keys to an existing User */ + post: operations["PublicApiService_CreateApiKeys"]; + }; + "/public/v1/submit/create_api_only_users": { + /** Create API-only Users in an existing Organization */ + post: operations["PublicApiService_CreateApiOnlyUsers"]; + }; + "/public/v1/submit/create_authenticators": { + /** Create Authenticators to authenticate requests to Turnkey */ + post: operations["PublicApiService_CreateAuthenticators"]; + }; + "/public/v1/submit/create_invitations": { + /** Create Invitations to join an existing Organization */ + post: operations["PublicApiService_CreateInvitations"]; + }; + "/public/v1/submit/create_oauth_providers": { + /** Creates Oauth providers for a specified user - BETA */ + post: operations["PublicApiService_CreateOauthProviders"]; + }; + "/public/v1/submit/create_policies": { + /** Create new Policies */ + post: operations["PublicApiService_CreatePolicies"]; + }; + "/public/v1/submit/create_policy": { + /** Create a new Policy */ + post: operations["PublicApiService_CreatePolicy"]; + }; + "/public/v1/submit/create_private_key_tag": { + /** Create a private key tag and add it to private keys. */ + post: operations["PublicApiService_CreatePrivateKeyTag"]; + }; + "/public/v1/submit/create_private_keys": { + /** Create new Private Keys */ + post: operations["PublicApiService_CreatePrivateKeys"]; + }; + "/public/v1/submit/create_read_only_session": { + /** Create a read only session for a user (valid for 1 hour) */ + post: operations["PublicApiService_CreateReadOnlySession"]; + }; + "/public/v1/submit/create_read_write_session": { + /** Create a read write session for a user */ + post: operations["PublicApiService_CreateReadWriteSession"]; + }; + "/public/v1/submit/create_sub_organization": { + /** Create a new Sub-Organization */ + post: operations["PublicApiService_CreateSubOrganization"]; + }; + "/public/v1/submit/create_user_tag": { + /** Create a user tag and add it to users. */ + post: operations["PublicApiService_CreateUserTag"]; + }; + "/public/v1/submit/create_users": { + /** Create Users in an existing Organization */ + post: operations["PublicApiService_CreateUsers"]; + }; + "/public/v1/submit/create_wallet": { + /** Create a Wallet and derive addresses */ + post: operations["PublicApiService_CreateWallet"]; + }; + "/public/v1/submit/create_wallet_accounts": { + /** Derive additional addresses using an existing wallet */ + post: operations["PublicApiService_CreateWalletAccounts"]; + }; + "/public/v1/submit/delete_api_keys": { + /** Remove api keys from a User */ + post: operations["PublicApiService_DeleteApiKeys"]; + }; + "/public/v1/submit/delete_authenticators": { + /** Remove authenticators from a User */ + post: operations["PublicApiService_DeleteAuthenticators"]; + }; + "/public/v1/submit/delete_invitation": { + /** Delete an existing Invitation */ + post: operations["PublicApiService_DeleteInvitation"]; + }; + "/public/v1/submit/delete_oauth_providers": { + /** Removes Oauth providers for a specified user - BETA */ + post: operations["PublicApiService_DeleteOauthProviders"]; + }; + "/public/v1/submit/delete_policy": { + /** Delete an existing Policy */ + post: operations["PublicApiService_DeletePolicy"]; + }; + "/public/v1/submit/delete_private_key_tags": { + /** Delete Private Key Tags within an Organization */ + post: operations["PublicApiService_DeletePrivateKeyTags"]; + }; + "/public/v1/submit/delete_private_keys": { + /** Deletes private keys for an organization */ + post: operations["PublicApiService_DeletePrivateKeys"]; + }; + "/public/v1/submit/delete_sub_organization": { + /** Deletes a sub organization */ + post: operations["PublicApiService_DeleteSubOrganization"]; + }; + "/public/v1/submit/delete_user_tags": { + /** Delete User Tags within an Organization */ + post: operations["PublicApiService_DeleteUserTags"]; + }; + "/public/v1/submit/delete_users": { + /** Delete Users within an Organization */ + post: operations["PublicApiService_DeleteUsers"]; + }; + "/public/v1/submit/delete_wallets": { + /** Deletes wallets for an organization */ + post: operations["PublicApiService_DeleteWallets"]; + }; + "/public/v1/submit/email_auth": { + /** Authenticate a user via Email */ + post: operations["PublicApiService_EmailAuth"]; + }; + "/public/v1/submit/export_private_key": { + /** Exports a Private Key */ + post: operations["PublicApiService_ExportPrivateKey"]; + }; + "/public/v1/submit/export_wallet": { + /** Exports a Wallet */ + post: operations["PublicApiService_ExportWallet"]; + }; + "/public/v1/submit/export_wallet_account": { + /** Exports a Wallet Account */ + post: operations["PublicApiService_ExportWalletAccount"]; + }; + "/public/v1/submit/import_private_key": { + /** Imports a private key */ + post: operations["PublicApiService_ImportPrivateKey"]; + }; + "/public/v1/submit/import_wallet": { + /** Imports a wallet */ + post: operations["PublicApiService_ImportWallet"]; + }; + "/public/v1/submit/init_import_private_key": { + /** Initializes a new private key import */ + post: operations["PublicApiService_InitImportPrivateKey"]; + }; + "/public/v1/submit/init_import_wallet": { + /** Initializes a new wallet import */ + post: operations["PublicApiService_InitImportWallet"]; + }; + "/public/v1/submit/init_otp": { + /** Initiate a Generic OTP activity */ + post: operations["PublicApiService_InitOtp"]; + }; + "/public/v1/submit/init_otp_auth": { + /** Initiate an OTP auth activity */ + post: operations["PublicApiService_InitOtpAuth"]; + }; + "/public/v1/submit/init_user_email_recovery": { + /** Initializes a new email recovery */ + post: operations["PublicApiService_InitUserEmailRecovery"]; + }; + "/public/v1/submit/oauth": { + /** Authenticate a user with an Oidc token (Oauth) - BETA */ + post: operations["PublicApiService_Oauth"]; + }; + "/public/v1/submit/oauth_login": { + /** Create an Oauth session for a user */ + post: operations["PublicApiService_OauthLogin"]; + }; + "/public/v1/submit/otp_auth": { + /** Authenticate a user with an OTP code sent via email or SMS */ + post: operations["PublicApiService_OtpAuth"]; + }; + "/public/v1/submit/otp_login": { + /** Create an OTP session for a user */ + post: operations["PublicApiService_OtpLogin"]; + }; + "/public/v1/submit/recover_user": { + /** Completes the process of recovering a user by adding an authenticator */ + post: operations["PublicApiService_RecoverUser"]; + }; + "/public/v1/submit/reject_activity": { + /** Reject an Activity */ + post: operations["PublicApiService_RejectActivity"]; + }; + "/public/v1/submit/remove_organization_feature": { + /** Removes an organization feature. This activity must be approved by the current root quorum. */ + post: operations["PublicApiService_RemoveOrganizationFeature"]; + }; + "/public/v1/submit/set_organization_feature": { + /** Sets an organization feature. This activity must be approved by the current root quorum. */ + post: operations["PublicApiService_SetOrganizationFeature"]; + }; + "/public/v1/submit/sign_raw_payload": { + /** Sign a raw payload */ + post: operations["PublicApiService_SignRawPayload"]; + }; + "/public/v1/submit/sign_raw_payloads": { + /** Sign multiple raw payloads with the same signing parameters */ + post: operations["PublicApiService_SignRawPayloads"]; + }; + "/public/v1/submit/sign_transaction": { + /** Sign a transaction */ + post: operations["PublicApiService_SignTransaction"]; + }; + "/public/v1/submit/stamp_login": { + /** Create a session for a user through stamping client side (api key, wallet client, or passkey client) */ + post: operations["PublicApiService_StampLogin"]; + }; + "/public/v1/submit/update_policy": { + /** Update an existing Policy */ + post: operations["PublicApiService_UpdatePolicy"]; + }; + "/public/v1/submit/update_private_key_tag": { + /** Update human-readable name or associated private keys. Note that this activity is atomic: all of the updates will succeed at once, or all of them will fail. */ + post: operations["PublicApiService_UpdatePrivateKeyTag"]; + }; + "/public/v1/submit/update_root_quorum": { + /** Set the threshold and members of the root quorum. This activity must be approved by the current root quorum. */ + post: operations["PublicApiService_UpdateRootQuorum"]; + }; + "/public/v1/submit/update_user": { + /** Update a User in an existing Organization */ + post: operations["PublicApiService_UpdateUser"]; + }; + "/public/v1/submit/update_user_tag": { + /** Update human-readable name or associated users. Note that this activity is atomic: all of the updates will succeed at once, or all of them will fail. */ + post: operations["PublicApiService_UpdateUserTag"]; + }; + "/public/v1/submit/update_wallet": { + /** Update a wallet for an organization */ + post: operations["PublicApiService_UpdateWallet"]; + }; + "/public/v1/submit/verify_otp": { + /** Verify a Generic OTP */ + post: operations["PublicApiService_VerifyOtp"]; + }; + "/tkhq/api/v1/noop-codegen-anchor": { + post: operations["PublicApiService_NOOPCodegenAnchor"]; + }; + "/tkhq/api/v1/test_rate_limits": { + /** Set a rate local rate limit just on the current endpoint, for purposes of testing with Vivosuite */ + post: operations["PublicApiService_TestRateLimits"]; + }; +}; + +export type definitions = { + apiApiKeyParams: { + /** @description Human-readable name for an API Key. */ + apiKeyName: string; + /** @description The public component of a cryptographic key pair used to sign messages and transactions. */ + publicKey: string; + /** @description Optional window (in seconds) indicating how long the API Key should last. */ + expirationSeconds?: string; + }; + billingActivateBillingTierIntent: { + /** @description The product that the customer wants to subscribe to. */ + productId: string; + }; + billingActivateBillingTierResult: { + /** @description The id of the product being subscribed to. */ + productId: string; + }; + billingDeletePaymentMethodIntent: { + /** @description The payment method that the customer wants to remove. */ + paymentMethodId: string; + }; + billingDeletePaymentMethodResult: { + /** @description The payment method that was removed. */ + paymentMethodId: string; + }; + billingSetPaymentMethodIntent: { + /** @description The account number of the customer's credit card. */ + number: string; + /** @description The verification digits of the customer's credit card. */ + cvv: string; + /** @description The month that the credit card expires. */ + expiryMonth: string; + /** @description The year that the credit card expires. */ + expiryYear: string; + /** @description The email that will receive invoices for the credit card. */ + cardHolderEmail: string; + /** @description The name associated with the credit card. */ + cardHolderName: string; + }; + billingSetPaymentMethodIntentV2: { + /** @description The id of the payment method that was created clientside. */ + paymentMethodId: string; + /** @description The email that will receive invoices for the credit card. */ + cardHolderEmail: string; + /** @description The name associated with the credit card. */ + cardHolderName: string; + }; + billingSetPaymentMethodResult: { + /** @description The last four digits of the credit card added. */ + lastFour: string; + /** @description The name associated with the payment method. */ + cardHolderName: string; + /** @description The email address associated with the payment method. */ + cardHolderEmail: string; + }; + datav1Tag: { + /** @description Unique identifier for a given Tag. */ + tagId: string; + /** @description Human-readable name for a Tag. */ + tagName: string; + tagType: definitions["v1TagType"]; + createdAt: definitions["externaldatav1Timestamp"]; + updatedAt: definitions["externaldatav1Timestamp"]; + }; + externaldatav1Address: { + format?: definitions["v1AddressFormat"]; + address?: string; + }; + externaldatav1Credential: { + /** @description The public component of a cryptographic key pair used to sign messages and transactions. */ + publicKey: string; + type: definitions["v1CredentialType"]; + }; + externaldatav1Quorum: { + /** + * Format: int32 + * @description Count of unique approvals required to meet quorum. + */ + threshold: number; + /** @description Unique identifiers of quorum set members. */ + userIds: string[]; + }; + externaldatav1Timestamp: { + seconds: string; + nanos: string; + }; + immutableactivityv1Address: { + format?: definitions["v1AddressFormat"]; + address?: string; + }; + protobufAny: { + "@type"?: string; + } & { [key: string]: unknown }; + rpcStatus: { + /** Format: int32 */ + code?: number; + message?: string; + details?: definitions["protobufAny"][]; + }; + v1AcceptInvitationIntent: { + /** @description Unique identifier for a given Invitation object. */ + invitationId: string; + /** @description Unique identifier for a given User. */ + userId: string; + /** @description WebAuthN hardware devices that can be used to log in to the Turnkey web app. */ + authenticator: definitions["v1AuthenticatorParams"]; + }; + v1AcceptInvitationIntentV2: { + /** @description Unique identifier for a given Invitation object. */ + invitationId: string; + /** @description Unique identifier for a given User. */ + userId: string; + /** @description WebAuthN hardware devices that can be used to log in to the Turnkey web app. */ + authenticator: definitions["v1AuthenticatorParamsV2"]; + }; + v1AcceptInvitationResult: { + /** @description Unique identifier for a given Invitation. */ + invitationId: string; + /** @description Unique identifier for a given User. */ + userId: string; + }; + /** @enum {string} */ + v1AccessType: "ACCESS_TYPE_WEB" | "ACCESS_TYPE_API" | "ACCESS_TYPE_ALL"; + v1Activity: { + /** @description Unique identifier for a given Activity object. */ + id: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + /** @description The current processing status of a specified Activity. */ + status: definitions["v1ActivityStatus"]; + /** @description Type of Activity, such as Add User, or Sign Transaction. */ + type: definitions["v1ActivityType"]; + /** @description Intent object crafted by Turnkey based on the user request, used to assess the permissibility of an action. */ + intent: definitions["v1Intent"]; + /** @description Result of the intended action. */ + result: definitions["v1Result"]; + /** @description A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. */ + votes: definitions["v1Vote"][]; + /** @description An artifact verifying a User's action. */ + fingerprint: string; + canApprove: boolean; + canReject: boolean; + createdAt: definitions["externaldatav1Timestamp"]; + updatedAt: definitions["externaldatav1Timestamp"]; + /** @description Failure reason of the intended action. */ + failure?: definitions["rpcStatus"]; + }; + v1ActivityResponse: { + /** @description An action that can that can be taken within the Turnkey infrastructure. */ + activity: definitions["v1Activity"]; + }; + /** @enum {string} */ + v1ActivityStatus: + | "ACTIVITY_STATUS_CREATED" + | "ACTIVITY_STATUS_PENDING" + | "ACTIVITY_STATUS_COMPLETED" + | "ACTIVITY_STATUS_FAILED" + | "ACTIVITY_STATUS_CONSENSUS_NEEDED" + | "ACTIVITY_STATUS_REJECTED"; + /** @enum {string} */ + v1ActivityType: + | "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"; + /** @enum {string} */ + v1AddressFormat: + | "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"; + v1ApiKey: { + /** @description A User credential that can be used to authenticate to Turnkey. */ + credential: definitions["externaldatav1Credential"]; + /** @description Unique identifier for a given API Key. */ + apiKeyId: string; + /** @description Human-readable name for an API Key. */ + apiKeyName: string; + createdAt: definitions["externaldatav1Timestamp"]; + updatedAt: definitions["externaldatav1Timestamp"]; + /** + * Format: uint64 + * @description Optional window (in seconds) indicating how long the API Key should last. + */ + expirationSeconds?: string; + }; + /** @enum {string} */ + v1ApiKeyCurve: + | "API_KEY_CURVE_P256" + | "API_KEY_CURVE_SECP256K1" + | "API_KEY_CURVE_ED25519"; + v1ApiKeyParamsV2: { + /** @description Human-readable name for an API Key. */ + apiKeyName: string; + /** @description The public component of a cryptographic key pair used to sign messages and transactions. */ + publicKey: string; + /** @description The curve type to be used for processing API key signatures. */ + curveType: definitions["v1ApiKeyCurve"]; + /** @description Optional window (in seconds) indicating how long the API Key should last. */ + expirationSeconds?: string; + }; + v1ApiOnlyUserParams: { + /** @description The name of the new API-only User. */ + userName: string; + /** @description The email address for this API-only User (optional). */ + userEmail?: string; + /** @description A list of tags assigned to the new API-only User. This field, if not needed, should be an empty array in your request body. */ + userTags: string[]; + /** @description A list of API Key parameters. This field, if not needed, should be an empty array in your request body. */ + apiKeys: definitions["apiApiKeyParams"][]; + }; + v1ApproveActivityIntent: { + /** @description An artifact verifying a User's action. */ + fingerprint: string; + }; + v1ApproveActivityRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_APPROVE_ACTIVITY"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1ApproveActivityIntent"]; + }; + v1Attestation: { + /** @description The cbor encoded then base64 url encoded id of the credential. */ + credentialId: string; + /** @description A base64 url encoded payload containing metadata about the signing context and the challenge. */ + clientDataJson: string; + /** @description A base64 url encoded payload containing authenticator data and any attestation the webauthn provider chooses. */ + attestationObject: string; + /** @description The type of authenticator transports. */ + transports: definitions["v1AuthenticatorTransport"][]; + }; + v1Authenticator: { + /** @description Types of transports that may be used by an Authenticator (e.g., USB, NFC, BLE). */ + transports: definitions["v1AuthenticatorTransport"][]; + attestationType: string; + /** @description Identifier indicating the type of the Security Key. */ + aaguid: string; + /** @description Unique identifier for a WebAuthn credential. */ + credentialId: string; + /** @description The type of Authenticator device. */ + model: string; + /** @description A User credential that can be used to authenticate to Turnkey. */ + credential: definitions["externaldatav1Credential"]; + /** @description Unique identifier for a given Authenticator. */ + authenticatorId: string; + /** @description Human-readable name for an Authenticator. */ + authenticatorName: string; + createdAt: definitions["externaldatav1Timestamp"]; + updatedAt: definitions["externaldatav1Timestamp"]; + }; + v1AuthenticatorAttestationResponse: { + clientDataJson: string; + attestationObject: string; + transports?: definitions["v1AuthenticatorTransport"][]; + /** @enum {string} */ + authenticatorAttachment?: "cross-platform" | "platform" | null; + }; + v1AuthenticatorParams: { + /** @description Human-readable name for an Authenticator. */ + authenticatorName: string; + /** @description Unique identifier for a given User. */ + userId: string; + attestation: definitions["v1PublicKeyCredentialWithAttestation"]; + /** @description Challenge presented for authentication purposes. */ + challenge: string; + }; + v1AuthenticatorParamsV2: { + /** @description Human-readable name for an Authenticator. */ + authenticatorName: string; + /** @description Challenge presented for authentication purposes. */ + challenge: string; + /** @description The attestation that proves custody of the authenticator and provides metadata about it. */ + attestation: definitions["v1Attestation"]; + }; + /** @enum {string} */ + v1AuthenticatorTransport: + | "AUTHENTICATOR_TRANSPORT_BLE" + | "AUTHENTICATOR_TRANSPORT_INTERNAL" + | "AUTHENTICATOR_TRANSPORT_NFC" + | "AUTHENTICATOR_TRANSPORT_USB" + | "AUTHENTICATOR_TRANSPORT_HYBRID"; + v1Config: { + features?: definitions["v1Feature"][]; + quorum?: definitions["externaldatav1Quorum"]; + }; + v1CreateApiKeysIntent: { + /** @description A list of API Keys. */ + apiKeys: definitions["apiApiKeyParams"][]; + /** @description Unique identifier for a given User. */ + userId: string; + }; + v1CreateApiKeysIntentV2: { + /** @description A list of API Keys. */ + apiKeys: definitions["v1ApiKeyParamsV2"][]; + /** @description Unique identifier for a given User. */ + userId: string; + }; + v1CreateApiKeysRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_CREATE_API_KEYS_V2"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1CreateApiKeysIntentV2"]; + }; + v1CreateApiKeysResult: { + /** @description A list of API Key IDs. */ + apiKeyIds: string[]; + }; + v1CreateApiOnlyUsersIntent: { + /** @description A list of API-only Users to create. */ + apiOnlyUsers: definitions["v1ApiOnlyUserParams"][]; + }; + v1CreateApiOnlyUsersRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_CREATE_API_ONLY_USERS"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1CreateApiOnlyUsersIntent"]; + }; + v1CreateApiOnlyUsersResult: { + /** @description A list of API-only User IDs. */ + userIds: string[]; + }; + v1CreateAuthenticatorsIntent: { + /** @description A list of Authenticators. */ + authenticators: definitions["v1AuthenticatorParams"][]; + /** @description Unique identifier for a given User. */ + userId: string; + }; + v1CreateAuthenticatorsIntentV2: { + /** @description A list of Authenticators. */ + authenticators: definitions["v1AuthenticatorParamsV2"][]; + /** @description Unique identifier for a given User. */ + userId: string; + }; + v1CreateAuthenticatorsRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_CREATE_AUTHENTICATORS_V2"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1CreateAuthenticatorsIntentV2"]; + }; + v1CreateAuthenticatorsResult: { + /** @description A list of Authenticator IDs. */ + authenticatorIds: string[]; + }; + v1CreateInvitationsIntent: { + /** @description A list of Invitations. */ + invitations: definitions["v1InvitationParams"][]; + }; + v1CreateInvitationsRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_CREATE_INVITATIONS"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1CreateInvitationsIntent"]; + }; + v1CreateInvitationsResult: { + /** @description A list of Invitation IDs */ + invitationIds: string[]; + }; + v1CreateOauthProvidersIntent: { + /** @description The ID of the User to add an Oauth provider to */ + userId: string; + /** @description A list of Oauth providers. */ + oauthProviders: definitions["v1OauthProviderParams"][]; + }; + v1CreateOauthProvidersRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_CREATE_OAUTH_PROVIDERS"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1CreateOauthProvidersIntent"]; + }; + v1CreateOauthProvidersResult: { + /** @description A list of unique identifiers for Oauth Providers */ + providerIds: string[]; + }; + v1CreateOrganizationIntent: { + /** @description Human-readable name for an Organization. */ + organizationName: string; + /** @description The root user's email address. */ + rootEmail: string; + /** @description The root user's Authenticator. */ + rootAuthenticator: definitions["v1AuthenticatorParams"]; + /** @description Unique identifier for the root user object. */ + rootUserId?: string; + }; + v1CreateOrganizationIntentV2: { + /** @description Human-readable name for an Organization. */ + organizationName: string; + /** @description The root user's email address. */ + rootEmail: string; + /** @description The root user's Authenticator. */ + rootAuthenticator: definitions["v1AuthenticatorParamsV2"]; + /** @description Unique identifier for the root user object. */ + rootUserId?: string; + }; + v1CreateOrganizationResult: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + }; + v1CreatePoliciesIntent: { + /** @description An array of policy intents to be created. */ + policies: definitions["v1CreatePolicyIntentV3"][]; + }; + v1CreatePoliciesRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_CREATE_POLICIES"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1CreatePoliciesIntent"]; + }; + v1CreatePoliciesResult: { + /** @description A list of unique identifiers for the created policies. */ + policyIds: string[]; + }; + v1CreatePolicyIntent: { + /** @description Human-readable name for a Policy. */ + policyName: string; + /** @description A list of simple functions each including a subject, target and boolean. See Policy Engine Language section for additional details. */ + selectors: definitions["v1Selector"][]; + /** @description The instruction to DENY or ALLOW a particular activity following policy selector(s). */ + effect: definitions["v1Effect"]; + notes?: string; + }; + v1CreatePolicyIntentV2: { + /** @description Human-readable name for a Policy. */ + policyName: string; + /** @description A list of simple functions each including a subject, target and boolean. See Policy Engine Language section for additional details. */ + selectors: definitions["v1SelectorV2"][]; + /** @description Whether to ALLOW or DENY requests that match the condition and consensus requirements. */ + effect: definitions["v1Effect"]; + notes?: string; + }; + v1CreatePolicyIntentV3: { + /** @description Human-readable name for a Policy. */ + policyName: string; + /** @description The instruction to DENY or ALLOW an activity. */ + effect: definitions["v1Effect"]; + /** @description The condition expression that triggers the Effect */ + condition?: string; + /** @description The consensus expression that triggers the Effect */ + consensus?: string; + notes?: string; + }; + v1CreatePolicyRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_CREATE_POLICY_V3"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1CreatePolicyIntentV3"]; + }; + v1CreatePolicyResult: { + /** @description Unique identifier for a given Policy. */ + policyId: string; + }; + v1CreatePrivateKeyTagIntent: { + /** @description Human-readable name for a Private Key Tag. */ + privateKeyTagName: string; + /** @description A list of Private Key IDs. */ + privateKeyIds: string[]; + }; + v1CreatePrivateKeyTagRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_CREATE_PRIVATE_KEY_TAG"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1CreatePrivateKeyTagIntent"]; + }; + v1CreatePrivateKeyTagResult: { + /** @description Unique identifier for a given Private Key Tag. */ + privateKeyTagId: string; + /** @description A list of Private Key IDs. */ + privateKeyIds: string[]; + }; + v1CreatePrivateKeysIntent: { + /** @description A list of Private Keys. */ + privateKeys: definitions["v1PrivateKeyParams"][]; + }; + v1CreatePrivateKeysIntentV2: { + /** @description A list of Private Keys. */ + privateKeys: definitions["v1PrivateKeyParams"][]; + }; + v1CreatePrivateKeysRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_CREATE_PRIVATE_KEYS_V2"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1CreatePrivateKeysIntentV2"]; + }; + v1CreatePrivateKeysResult: { + /** @description A list of Private Key IDs. */ + privateKeyIds: string[]; + }; + v1CreatePrivateKeysResultV2: { + /** @description A list of Private Key IDs and addresses. */ + privateKeys: definitions["v1PrivateKeyResult"][]; + }; + v1CreateReadOnlySessionIntent: { [key: string]: unknown }; + v1CreateReadOnlySessionRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_CREATE_READ_ONLY_SESSION"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1CreateReadOnlySessionIntent"]; + }; + v1CreateReadOnlySessionResult: { + /** @description Unique identifier for a given Organization. If the request is being made by a user and their Sub-Organization ID is unknown, this can be the Parent Organization ID. However, using the Sub-Organization ID is preferred due to performance reasons. */ + organizationId: string; + /** @description Human-readable name for an Organization. */ + organizationName: string; + /** @description Unique identifier for a given User. */ + userId: string; + /** @description Human-readable name for a User. */ + username: string; + /** @description String representing a read only session */ + session: string; + /** + * Format: uint64 + * @description UTC timestamp in seconds representing the expiry time for the read only session. + */ + sessionExpiry: string; + }; + v1CreateReadWriteSessionIntent: { + /** @description Client-side public key generated by the user, to which the read write session bundle (credentials) will be encrypted. */ + targetPublicKey: string; + /** @description Email of the user to create a read write session for */ + email: string; + /** @description Optional human-readable name for an API Key. If none provided, default to Read Write Session - */ + apiKeyName?: string; + /** @description Expiration window (in seconds) indicating how long the API key is valid for. If not provided, a default of 15 minutes will be used. */ + expirationSeconds?: string; + }; + v1CreateReadWriteSessionIntentV2: { + /** @description Client-side public key generated by the user, to which the read write session bundle (credentials) will be encrypted. */ + targetPublicKey: string; + /** @description Unique identifier for a given User. */ + userId?: string; + /** @description Optional human-readable name for an API Key. If none provided, default to Read Write Session - */ + apiKeyName?: string; + /** @description Expiration window (in seconds) indicating how long the API key is valid for. If not provided, a default of 15 minutes will be used. */ + expirationSeconds?: string; + /** @description Invalidate all other previously generated ReadWriteSession API keys */ + invalidateExisting?: boolean; + }; + v1CreateReadWriteSessionRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_CREATE_READ_WRITE_SESSION_V2"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1CreateReadWriteSessionIntentV2"]; + }; + v1CreateReadWriteSessionResult: { + /** @description Unique identifier for a given Organization. If the request is being made by a user and their Sub-Organization ID is unknown, this can be the Parent Organization ID. However, using the Sub-Organization ID is preferred due to performance reasons. */ + organizationId: string; + /** @description Human-readable name for an Organization. */ + organizationName: string; + /** @description Unique identifier for a given User. */ + userId: string; + /** @description Human-readable name for a User. */ + username: string; + /** @description Unique identifier for the created API key. */ + apiKeyId: string; + /** @description HPKE encrypted credential bundle */ + credentialBundle: string; + }; + v1CreateReadWriteSessionResultV2: { + /** @description Unique identifier for a given Organization. If the request is being made by a user and their Sub-Organization ID is unknown, this can be the Parent Organization ID. However, using the Sub-Organization ID is preferred due to performance reasons. */ + organizationId: string; + /** @description Human-readable name for an Organization. */ + organizationName: string; + /** @description Unique identifier for a given User. */ + userId: string; + /** @description Human-readable name for a User. */ + username: string; + /** @description Unique identifier for the created API key. */ + apiKeyId: string; + /** @description HPKE encrypted credential bundle */ + credentialBundle: string; + }; + v1CreateSubOrganizationIntent: { + /** @description Name for this sub-organization */ + name: string; + /** @description Root User authenticator for this new sub-organization */ + rootAuthenticator: definitions["v1AuthenticatorParamsV2"]; + }; + v1CreateSubOrganizationIntentV2: { + /** @description Name for this sub-organization */ + subOrganizationName: string; + /** @description Root users to create within this sub-organization */ + rootUsers: definitions["v1RootUserParams"][]; + /** + * Format: int32 + * @description The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users + */ + rootQuorumThreshold: number; + }; + v1CreateSubOrganizationIntentV3: { + /** @description Name for this sub-organization */ + subOrganizationName: string; + /** @description Root users to create within this sub-organization */ + rootUsers: definitions["v1RootUserParams"][]; + /** + * Format: int32 + * @description The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users + */ + rootQuorumThreshold: number; + /** @description A list of Private Keys. */ + privateKeys: definitions["v1PrivateKeyParams"][]; + }; + v1CreateSubOrganizationIntentV4: { + /** @description Name for this sub-organization */ + subOrganizationName: string; + /** @description Root users to create within this sub-organization */ + rootUsers: definitions["v1RootUserParams"][]; + /** + * Format: int32 + * @description The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users + */ + rootQuorumThreshold: number; + /** @description The wallet to create for the sub-organization */ + wallet?: definitions["v1WalletParams"]; + /** @description Disable email recovery for the sub-organization */ + disableEmailRecovery?: boolean; + /** @description Disable email auth for the sub-organization */ + disableEmailAuth?: boolean; + }; + v1CreateSubOrganizationIntentV5: { + /** @description Name for this sub-organization */ + subOrganizationName: string; + /** @description Root users to create within this sub-organization */ + rootUsers: definitions["v1RootUserParamsV2"][]; + /** + * Format: int32 + * @description The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users + */ + rootQuorumThreshold: number; + /** @description The wallet to create for the sub-organization */ + wallet?: definitions["v1WalletParams"]; + /** @description Disable email recovery for the sub-organization */ + disableEmailRecovery?: boolean; + /** @description Disable email auth for the sub-organization */ + disableEmailAuth?: boolean; + }; + v1CreateSubOrganizationIntentV6: { + /** @description Name for this sub-organization */ + subOrganizationName: string; + /** @description Root users to create within this sub-organization */ + rootUsers: definitions["v1RootUserParamsV3"][]; + /** + * Format: int32 + * @description The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users + */ + rootQuorumThreshold: number; + /** @description The wallet to create for the sub-organization */ + wallet?: definitions["v1WalletParams"]; + /** @description Disable email recovery for the sub-organization */ + disableEmailRecovery?: boolean; + /** @description Disable email auth for the sub-organization */ + disableEmailAuth?: boolean; + }; + v1CreateSubOrganizationIntentV7: { + /** @description Name for this sub-organization */ + subOrganizationName: string; + /** @description Root users to create within this sub-organization */ + rootUsers: definitions["v1RootUserParamsV4"][]; + /** + * Format: int32 + * @description The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users + */ + rootQuorumThreshold: number; + /** @description The wallet to create for the sub-organization */ + wallet?: definitions["v1WalletParams"]; + /** @description Disable email recovery for the sub-organization */ + disableEmailRecovery?: boolean; + /** @description Disable email auth for the sub-organization */ + disableEmailAuth?: boolean; + /** @description Disable OTP SMS auth for the sub-organization */ + disableSmsAuth?: boolean; + /** @description Disable OTP email auth for the sub-organization */ + disableOtpEmailAuth?: boolean; + }; + v1CreateSubOrganizationRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_CREATE_SUB_ORGANIZATION_V7"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1CreateSubOrganizationIntentV7"]; + }; + v1CreateSubOrganizationResult: { + subOrganizationId: string; + rootUserIds?: string[]; + }; + v1CreateSubOrganizationResultV3: { + subOrganizationId: string; + /** @description A list of Private Key IDs and addresses. */ + privateKeys: definitions["v1PrivateKeyResult"][]; + rootUserIds?: string[]; + }; + v1CreateSubOrganizationResultV4: { + subOrganizationId: string; + wallet?: definitions["v1WalletResult"]; + rootUserIds?: string[]; + }; + v1CreateSubOrganizationResultV5: { + subOrganizationId: string; + wallet?: definitions["v1WalletResult"]; + rootUserIds?: string[]; + }; + v1CreateSubOrganizationResultV6: { + subOrganizationId: string; + wallet?: definitions["v1WalletResult"]; + rootUserIds?: string[]; + }; + v1CreateSubOrganizationResultV7: { + subOrganizationId: string; + wallet?: definitions["v1WalletResult"]; + rootUserIds?: string[]; + }; + v1CreateUserTagIntent: { + /** @description Human-readable name for a User Tag. */ + userTagName: string; + /** @description A list of User IDs. */ + userIds: string[]; + }; + v1CreateUserTagRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_CREATE_USER_TAG"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1CreateUserTagIntent"]; + }; + v1CreateUserTagResult: { + /** @description Unique identifier for a given User Tag. */ + userTagId: string; + /** @description A list of User IDs. */ + userIds: string[]; + }; + v1CreateUsersIntent: { + /** @description A list of Users. */ + users: definitions["v1UserParams"][]; + }; + v1CreateUsersIntentV2: { + /** @description A list of Users. */ + users: definitions["v1UserParamsV2"][]; + }; + v1CreateUsersIntentV3: { + /** @description A list of Users. */ + users: definitions["v1UserParamsV3"][]; + }; + v1CreateUsersRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_CREATE_USERS_V3"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1CreateUsersIntentV3"]; + }; + v1CreateUsersResult: { + /** @description A list of User IDs. */ + userIds: string[]; + }; + v1CreateWalletAccountsIntent: { + /** @description Unique identifier for a given Wallet. */ + walletId: string; + /** @description A list of wallet Accounts. */ + accounts: definitions["v1WalletAccountParams"][]; + }; + v1CreateWalletAccountsRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_CREATE_WALLET_ACCOUNTS"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1CreateWalletAccountsIntent"]; + }; + v1CreateWalletAccountsResult: { + /** @description A list of derived addresses. */ + addresses: string[]; + }; + v1CreateWalletIntent: { + /** @description Human-readable name for a Wallet. */ + walletName: string; + /** @description A list of wallet Accounts. This field, if not needed, should be an empty array in your request body. */ + accounts: definitions["v1WalletAccountParams"][]; + /** + * Format: int32 + * @description Length of mnemonic to generate the Wallet seed. Defaults to 12. Accepted values: 12, 15, 18, 21, 24. + */ + mnemonicLength?: number; + }; + v1CreateWalletRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_CREATE_WALLET"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1CreateWalletIntent"]; + }; + v1CreateWalletResult: { + /** @description Unique identifier for a Wallet. */ + walletId: string; + /** @description A list of account addresses. */ + addresses: string[]; + }; + v1CredPropsAuthenticationExtensionsClientOutputs: { + rk: boolean; + }; + /** @enum {string} */ + v1CredentialType: + | "CREDENTIAL_TYPE_WEBAUTHN_AUTHENTICATOR" + | "CREDENTIAL_TYPE_API_KEY_P256" + | "CREDENTIAL_TYPE_RECOVER_USER_KEY_P256" + | "CREDENTIAL_TYPE_API_KEY_SECP256K1" + | "CREDENTIAL_TYPE_EMAIL_AUTH_KEY_P256" + | "CREDENTIAL_TYPE_API_KEY_ED25519" + | "CREDENTIAL_TYPE_OTP_AUTH_KEY_P256" + | "CREDENTIAL_TYPE_READ_WRITE_SESSION_KEY_P256" + | "CREDENTIAL_TYPE_OAUTH_KEY_P256" + | "CREDENTIAL_TYPE_LOGIN"; + /** @enum {string} */ + v1Curve: "CURVE_SECP256K1" | "CURVE_ED25519"; + v1DeleteApiKeysIntent: { + /** @description Unique identifier for a given User. */ + userId: string; + /** @description A list of API Key IDs. */ + apiKeyIds: string[]; + }; + v1DeleteApiKeysRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_DELETE_API_KEYS"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1DeleteApiKeysIntent"]; + }; + v1DeleteApiKeysResult: { + /** @description A list of API Key IDs. */ + apiKeyIds: string[]; + }; + v1DeleteAuthenticatorsIntent: { + /** @description Unique identifier for a given User. */ + userId: string; + /** @description A list of Authenticator IDs. */ + authenticatorIds: string[]; + }; + v1DeleteAuthenticatorsRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_DELETE_AUTHENTICATORS"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1DeleteAuthenticatorsIntent"]; + }; + v1DeleteAuthenticatorsResult: { + /** @description Unique identifier for a given Authenticator. */ + authenticatorIds: string[]; + }; + v1DeleteInvitationIntent: { + /** @description Unique identifier for a given Invitation object. */ + invitationId: string; + }; + v1DeleteInvitationRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_DELETE_INVITATION"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1DeleteInvitationIntent"]; + }; + v1DeleteInvitationResult: { + /** @description Unique identifier for a given Invitation. */ + invitationId: string; + }; + v1DeleteOauthProvidersIntent: { + /** @description The ID of the User to remove an Oauth provider from */ + userId: string; + /** @description Unique identifier for a given Provider. */ + providerIds: string[]; + }; + v1DeleteOauthProvidersRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_DELETE_OAUTH_PROVIDERS"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1DeleteOauthProvidersIntent"]; + }; + v1DeleteOauthProvidersResult: { + /** @description A list of unique identifiers for Oauth Providers */ + providerIds: string[]; + }; + v1DeleteOrganizationIntent: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + }; + v1DeleteOrganizationResult: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + }; + v1DeletePolicyIntent: { + /** @description Unique identifier for a given Policy. */ + policyId: string; + }; + v1DeletePolicyRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_DELETE_POLICY"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1DeletePolicyIntent"]; + }; + v1DeletePolicyResult: { + /** @description Unique identifier for a given Policy. */ + policyId: string; + }; + v1DeletePrivateKeyTagsIntent: { + /** @description A list of Private Key Tag IDs. */ + privateKeyTagIds: string[]; + }; + v1DeletePrivateKeyTagsRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_DELETE_PRIVATE_KEY_TAGS"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1DeletePrivateKeyTagsIntent"]; + }; + v1DeletePrivateKeyTagsResult: { + /** @description A list of Private Key Tag IDs. */ + privateKeyTagIds: string[]; + /** @description A list of Private Key IDs. */ + privateKeyIds: string[]; + }; + v1DeletePrivateKeysIntent: { + /** @description List of unique identifiers for private keys within an organization */ + privateKeyIds: string[]; + /** @description Optional parameter for deleting the private keys, even if any have not been previously exported. If they have been exported, this field is ignored. */ + deleteWithoutExport?: boolean; + }; + v1DeletePrivateKeysRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_DELETE_PRIVATE_KEYS"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1DeletePrivateKeysIntent"]; + }; + v1DeletePrivateKeysResult: { + /** @description A list of private key unique identifiers that were removed */ + privateKeyIds: string[]; + }; + v1DeleteSubOrganizationIntent: { + /** @description Sub-organization deletion, by default, requires associated wallets and private keys to be exported for security reasons. Set this boolean to true to force sub-organization deletion even if some wallets or private keys within it have not been exported yet. Default: false. */ + deleteWithoutExport?: boolean; + }; + v1DeleteSubOrganizationRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_DELETE_SUB_ORGANIZATION"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1DeleteSubOrganizationIntent"]; + }; + v1DeleteSubOrganizationResult: { + /** @description Unique identifier of the sub organization that was removed */ + subOrganizationUuid: string; + }; + v1DeleteUserTagsIntent: { + /** @description A list of User Tag IDs. */ + userTagIds: string[]; + }; + v1DeleteUserTagsRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_DELETE_USER_TAGS"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1DeleteUserTagsIntent"]; + }; + v1DeleteUserTagsResult: { + /** @description A list of User Tag IDs. */ + userTagIds: string[]; + /** @description A list of User IDs. */ + userIds: string[]; + }; + v1DeleteUsersIntent: { + /** @description A list of User IDs. */ + userIds: string[]; + }; + v1DeleteUsersRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_DELETE_USERS"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1DeleteUsersIntent"]; + }; + v1DeleteUsersResult: { + /** @description A list of User IDs. */ + userIds: string[]; + }; + v1DeleteWalletsIntent: { + /** @description List of unique identifiers for wallets within an organization */ + walletIds: string[]; + /** @description Optional parameter for deleting the wallets, even if any have not been previously exported. If they have been exported, this field is ignored. */ + deleteWithoutExport?: boolean; + }; + v1DeleteWalletsRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_DELETE_WALLETS"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1DeleteWalletsIntent"]; + }; + v1DeleteWalletsResult: { + /** @description A list of wallet unique identifiers that were removed */ + walletIds: string[]; + }; + v1DisablePrivateKeyIntent: { + /** @description Unique identifier for a given Private Key. */ + privateKeyId: string; + }; + v1DisablePrivateKeyResult: { + /** @description Unique identifier for a given Private Key. */ + privateKeyId: string; + }; + /** @enum {string} */ + v1Effect: "EFFECT_ALLOW" | "EFFECT_DENY"; + v1EmailAuthIntent: { + /** @description Email of the authenticating user. */ + email: string; + /** @description Client-side public key generated by the user, to which the email auth bundle (credentials) will be encrypted. */ + targetPublicKey: string; + /** @description Optional human-readable name for an API Key. If none provided, default to Email Auth - */ + apiKeyName?: string; + /** @description Expiration window (in seconds) indicating how long the API key is valid for. If not provided, a default of 15 minutes will be used. */ + expirationSeconds?: string; + /** @description Optional parameters for customizing emails. If not provided, the default email will be used. */ + emailCustomization?: definitions["v1EmailCustomizationParams"]; + /** @description Invalidate all other previously generated Email Auth API keys */ + invalidateExisting?: boolean; + /** @description Optional custom email address from which to send the email */ + sendFromEmailAddress?: string; + /** @description Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications' */ + sendFromEmailSenderName?: string; + /** @description Optional custom email address to use as reply-to */ + replyToEmailAddress?: string; + }; + v1EmailAuthIntentV2: { + /** @description Email of the authenticating user. */ + email: string; + /** @description Client-side public key generated by the user, to which the email auth bundle (credentials) will be encrypted. */ + targetPublicKey: string; + /** @description Optional human-readable name for an API Key. If none provided, default to Email Auth - */ + apiKeyName?: string; + /** @description Expiration window (in seconds) indicating how long the API key is valid for. If not provided, a default of 15 minutes will be used. */ + expirationSeconds?: string; + /** @description Optional parameters for customizing emails. If not provided, the default email will be used. */ + emailCustomization?: definitions["v1EmailCustomizationParams"]; + /** @description Invalidate all other previously generated Email Auth API keys */ + invalidateExisting?: boolean; + /** @description Optional custom email address from which to send the email */ + sendFromEmailAddress?: string; + /** @description Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications' */ + sendFromEmailSenderName?: string; + /** @description Optional custom email address to use as reply-to */ + replyToEmailAddress?: string; + }; + v1EmailAuthRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_EMAIL_AUTH_V2"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1EmailAuthIntentV2"]; + }; + v1EmailAuthResult: { + /** @description Unique identifier for the authenticating User. */ + userId: string; + /** @description Unique identifier for the created API key. */ + apiKeyId: string; + }; + v1EmailCustomizationParams: { + /** @description The name of the application. */ + appName?: string; + /** @description A URL pointing to a logo in PNG format. Note this logo will be resized to fit into 340px x 124px. */ + logoUrl?: string; + /** @description A template for the URL to be used in a magic link button, e.g. `https://dapp.xyz/%s`. The auth bundle will be interpolated into the `%s`. */ + magicLinkTemplate?: string; + /** @description JSON object containing key/value pairs to be used with custom templates. */ + templateVariables?: string; + /** @description Unique identifier for a given Email Template. If not specified, the default is the most recent Email Template. */ + templateId?: string; + }; + v1ExportPrivateKeyIntent: { + /** @description Unique identifier for a given Private Key. */ + privateKeyId: string; + /** @description Client-side public key generated by the user, to which the export bundle will be encrypted. */ + targetPublicKey: string; + }; + v1ExportPrivateKeyRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_EXPORT_PRIVATE_KEY"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1ExportPrivateKeyIntent"]; + }; + v1ExportPrivateKeyResult: { + /** @description Unique identifier for a given Private Key. */ + privateKeyId: string; + /** @description Export bundle containing a private key encrypted to the client's target public key. */ + exportBundle: string; + }; + v1ExportWalletAccountIntent: { + /** @description Address to identify Wallet Account. */ + address: string; + /** @description Client-side public key generated by the user, to which the export bundle will be encrypted. */ + targetPublicKey: string; + }; + v1ExportWalletAccountRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_EXPORT_WALLET_ACCOUNT"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1ExportWalletAccountIntent"]; + }; + v1ExportWalletAccountResult: { + /** @description Address to identify Wallet Account. */ + address: string; + /** @description Export bundle containing a private key encrypted by the client's target public key. */ + exportBundle: string; + }; + v1ExportWalletIntent: { + /** @description Unique identifier for a given Wallet. */ + walletId: string; + /** @description Client-side public key generated by the user, to which the export bundle will be encrypted. */ + targetPublicKey: string; + /** @description The language of the mnemonic to export. Defaults to English. */ + language?: definitions["v1MnemonicLanguage"]; + }; + v1ExportWalletRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_EXPORT_WALLET"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1ExportWalletIntent"]; + }; + v1ExportWalletResult: { + /** @description Unique identifier for a given Wallet. */ + walletId: string; + /** @description Export bundle containing a wallet mnemonic + optional newline passphrase encrypted by the client's target public key. */ + exportBundle: string; + }; + v1Feature: { + name?: definitions["v1FeatureName"]; + value?: string; + }; + /** @enum {string} */ + v1FeatureName: + | "FEATURE_NAME_ROOT_USER_EMAIL_RECOVERY" + | "FEATURE_NAME_WEBAUTHN_ORIGINS" + | "FEATURE_NAME_EMAIL_AUTH" + | "FEATURE_NAME_EMAIL_RECOVERY" + | "FEATURE_NAME_WEBHOOK" + | "FEATURE_NAME_SMS_AUTH" + | "FEATURE_NAME_OTP_EMAIL_AUTH"; + v1GetActivitiesRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + /** @description Array of Activity Statuses filtering which Activities will be listed in the response. */ + filterByStatus?: definitions["v1ActivityStatus"][]; + /** @description Parameters used for cursor-based pagination. */ + paginationOptions?: definitions["v1Pagination"]; + /** @description Array of Activity Types filtering which Activities will be listed in the response. */ + filterByType?: definitions["v1ActivityType"][]; + }; + v1GetActivitiesResponse: { + /** @description A list of Activities. */ + activities: definitions["v1Activity"][]; + }; + v1GetActivityRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + /** @description Unique identifier for a given Activity object. */ + activityId: string; + }; + v1GetApiKeyRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + /** @description Unique identifier for a given API key. */ + apiKeyId: string; + }; + v1GetApiKeyResponse: { + /** @description An API key. */ + apiKey: definitions["v1ApiKey"]; + }; + v1GetApiKeysRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + /** @description Unique identifier for a given User. */ + userId?: string; + }; + v1GetApiKeysResponse: { + /** @description A list of API keys. */ + apiKeys: definitions["v1ApiKey"][]; + }; + v1GetAttestationDocumentRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + /** @description The enclave type, one of: ump, notarizer, signer, evm-parser */ + enclaveType: string; + }; + v1GetAttestationDocumentResponse: { + /** + * Format: byte + * @description Raw (CBOR-encoded) attestation document + */ + attestationDocument: string; + }; + v1GetAuthenticatorRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + /** @description Unique identifier for a given Authenticator. */ + authenticatorId: string; + }; + v1GetAuthenticatorResponse: { + /** @description An authenticator. */ + authenticator: definitions["v1Authenticator"]; + }; + v1GetAuthenticatorsRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + /** @description Unique identifier for a given User. */ + userId: string; + }; + v1GetAuthenticatorsResponse: { + /** @description A list of authenticators. */ + authenticators: definitions["v1Authenticator"][]; + }; + v1GetOauthProvidersRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + /** @description Unique identifier for a given User. */ + userId?: string; + }; + v1GetOauthProvidersResponse: { + /** @description A list of Oauth Providers */ + oauthProviders: definitions["v1OauthProvider"][]; + }; + v1GetOrganizationConfigsRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + }; + v1GetOrganizationConfigsResponse: { + /** @description Organization configs including quorum settings and organization features */ + configs: definitions["v1Config"]; + }; + v1GetOrganizationRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + }; + v1GetOrganizationResponse: { + /** @description Object representing the full current and deleted / disabled collection of Users, Policies, Private Keys, and Invitations attributable to a particular Organization. */ + organizationData: definitions["v1OrganizationData"]; + }; + v1GetPoliciesRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + }; + v1GetPoliciesResponse: { + /** @description A list of Policies. */ + policies: definitions["v1Policy"][]; + }; + v1GetPolicyRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + /** @description Unique identifier for a given Policy. */ + policyId: string; + }; + v1GetPolicyResponse: { + /** @description Object that codifies rules defining the actions that are permissible within an Organization. */ + policy: definitions["v1Policy"]; + }; + v1GetPrivateKeyRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + /** @description Unique identifier for a given Private Key. */ + privateKeyId: string; + }; + v1GetPrivateKeyResponse: { + /** @description Cryptographic public/private key pair that can be used for cryptocurrency needs or more generalized encryption. */ + privateKey: definitions["v1PrivateKey"]; + }; + v1GetPrivateKeysRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + }; + v1GetPrivateKeysResponse: { + /** @description A list of Private Keys. */ + privateKeys: definitions["v1PrivateKey"][]; + }; + v1GetSubOrgIdsRequest: { + /** @description Unique identifier for the parent Organization. This is used to find sub-organizations within it. */ + organizationId: string; + /** @description Specifies the type of filter to apply, i.e 'CREDENTIAL_ID', 'NAME', 'USERNAME', 'EMAIL', 'PHONE_NUMBER', 'OIDC_TOKEN' or 'PUBLIC_KEY' */ + filterType?: string; + /** @description The value of the filter to apply for the specified type. For example, a specific email or name string. */ + filterValue?: string; + /** @description Parameters used for cursor-based pagination. */ + paginationOptions?: definitions["v1Pagination"]; + }; + v1GetSubOrgIdsResponse: { + /** @description List of unique identifiers for the matching sub-organizations. */ + organizationIds: string[]; + }; + v1GetUserRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + /** @description Unique identifier for a given User. */ + userId: string; + }; + v1GetUserResponse: { + /** @description Web and/or API user within your Organization. */ + user: definitions["v1User"]; + }; + v1GetUsersRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + }; + v1GetUsersResponse: { + /** @description A list of Users. */ + users: definitions["v1User"][]; + }; + v1GetVerifiedSubOrgIdsRequest: { + /** @description Unique identifier for the parent Organization. This is used to find sub-organizations within it. */ + organizationId: string; + /** @description Specifies the type of filter to apply, i.e 'EMAIL', 'PHONE_NUMBER' */ + filterType?: string; + /** @description The value of the filter to apply for the specified type. For example, a specific email or phone number string. */ + filterValue?: string; + /** @description Parameters used for cursor-based pagination. */ + paginationOptions?: definitions["v1Pagination"]; + }; + v1GetVerifiedSubOrgIdsResponse: { + /** @description List of unique identifiers for the matching sub-organizations. */ + organizationIds: string[]; + }; + v1GetWalletAccountRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + /** @description Unique identifier for a given Wallet. */ + walletId: string; + /** @description Address corresponding to a Wallet Account. */ + address?: string; + /** @description Path corresponding to a Wallet Account. */ + path?: string; + }; + v1GetWalletAccountResponse: { + /** @description The resulting Wallet Account. */ + account: definitions["v1WalletAccount"]; + }; + v1GetWalletAccountsRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + /** @description Unique identifier for a given Wallet. */ + walletId: string; + /** @description Parameters used for cursor-based pagination. */ + paginationOptions?: definitions["v1Pagination"]; + }; + v1GetWalletAccountsResponse: { + /** @description A list of Accounts generated from a Wallet that share a common seed. */ + accounts: definitions["v1WalletAccount"][]; + }; + v1GetWalletRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + /** @description Unique identifier for a given Wallet. */ + walletId: string; + }; + v1GetWalletResponse: { + /** @description A collection of deterministically generated cryptographic public / private key pairs that share a common seed */ + wallet: definitions["v1Wallet"]; + }; + v1GetWalletsRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + }; + v1GetWalletsResponse: { + /** @description A list of Wallets. */ + wallets: definitions["v1Wallet"][]; + }; + v1GetWhoamiRequest: { + /** @description 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. */ + organizationId: string; + }; + v1GetWhoamiResponse: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + /** @description Human-readable name for an Organization. */ + organizationName: string; + /** @description Unique identifier for a given User. */ + userId: string; + /** @description Human-readable name for a User. */ + username: string; + }; + /** @enum {string} */ + v1HashFunction: + | "HASH_FUNCTION_NO_OP" + | "HASH_FUNCTION_SHA256" + | "HASH_FUNCTION_KECCAK256" + | "HASH_FUNCTION_NOT_APPLICABLE"; + v1ImportPrivateKeyIntent: { + /** @description The ID of the User importing a Private Key. */ + userId: string; + /** @description Human-readable name for a Private Key. */ + privateKeyName: string; + /** @description Bundle containing a raw private key encrypted to the enclave's target public key. */ + encryptedBundle: string; + /** @description Cryptographic Curve used to generate a given Private Key. */ + curve: definitions["v1Curve"]; + /** @description Cryptocurrency-specific formats for a derived address (e.g., Ethereum). */ + addressFormats: definitions["v1AddressFormat"][]; + }; + v1ImportPrivateKeyRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_IMPORT_PRIVATE_KEY"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1ImportPrivateKeyIntent"]; + }; + v1ImportPrivateKeyResult: { + /** @description Unique identifier for a Private Key. */ + privateKeyId: string; + /** @description A list of addresses. */ + addresses: definitions["immutableactivityv1Address"][]; + }; + v1ImportWalletIntent: { + /** @description The ID of the User importing a Wallet. */ + userId: string; + /** @description Human-readable name for a Wallet. */ + walletName: string; + /** @description Bundle containing a wallet mnemonic encrypted to the enclave's target public key. */ + encryptedBundle: string; + /** @description A list of wallet Accounts. */ + accounts: definitions["v1WalletAccountParams"][]; + }; + v1ImportWalletRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_IMPORT_WALLET"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1ImportWalletIntent"]; + }; + v1ImportWalletResult: { + /** @description Unique identifier for a Wallet. */ + walletId: string; + /** @description A list of account addresses. */ + addresses: string[]; + }; + v1InitImportPrivateKeyIntent: { + /** @description The ID of the User importing a Private Key. */ + userId: string; + }; + v1InitImportPrivateKeyRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_INIT_IMPORT_PRIVATE_KEY"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1InitImportPrivateKeyIntent"]; + }; + v1InitImportPrivateKeyResult: { + /** @description Import bundle containing a public key and signature to use for importing client data. */ + importBundle: string; + }; + v1InitImportWalletIntent: { + /** @description The ID of the User importing a Wallet. */ + userId: string; + }; + v1InitImportWalletRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_INIT_IMPORT_WALLET"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1InitImportWalletIntent"]; + }; + v1InitImportWalletResult: { + /** @description Import bundle containing a public key and signature to use for importing client data. */ + importBundle: string; + }; + v1InitOtpAuthIntent: { + /** @description Enum to specifiy whether to send OTP via SMS or email */ + otpType: string; + /** @description Email or phone number to send the OTP code to */ + contact: string; + /** @description Optional parameters for customizing emails. If not provided, the default email will be used. */ + emailCustomization?: definitions["v1EmailCustomizationParams"]; + /** @description Optional parameters for customizing SMS message. If not provided, the default sms message will be used. */ + smsCustomization?: definitions["v1SmsCustomizationParams"]; + /** @description 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. */ + userIdentifier?: string; + /** @description Optional custom email address from which to send the OTP email */ + sendFromEmailAddress?: string; + /** @description Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications' */ + sendFromEmailSenderName?: string; + /** @description Optional custom email address to use as reply-to */ + replyToEmailAddress?: string; + }; + v1InitOtpAuthIntentV2: { + /** @description Enum to specifiy whether to send OTP via SMS or email */ + otpType: string; + /** @description Email or phone number to send the OTP code to */ + contact: string; + /** + * Format: int32 + * @description Optional length of the OTP code. Default = 9 + */ + otpLength?: number; + /** @description Optional parameters for customizing emails. If not provided, the default email will be used. */ + emailCustomization?: definitions["v1EmailCustomizationParams"]; + /** @description Optional parameters for customizing SMS message. If not provided, the default sms message will be used. */ + smsCustomization?: definitions["v1SmsCustomizationParams"]; + /** @description 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. */ + userIdentifier?: string; + /** @description Optional custom email address from which to send the OTP email */ + sendFromEmailAddress?: string; + /** @description Optional flag to specify if the OTP code should be alphanumeric (Crockford’s Base32). Default = true */ + alphanumeric?: boolean; + /** @description Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications' */ + sendFromEmailSenderName?: string; + /** @description Optional custom email address to use as reply-to */ + replyToEmailAddress?: string; + }; + v1InitOtpAuthRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_INIT_OTP_AUTH_V2"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1InitOtpAuthIntentV2"]; + }; + v1InitOtpAuthResult: { + /** @description Unique identifier for an OTP authentication */ + otpId: string; + }; + v1InitOtpAuthResultV2: { + /** @description Unique identifier for an OTP authentication */ + otpId: string; + }; + v1InitOtpIntent: { + /** @description Whether to send OTP via SMS or email. Possible values: OTP_TYPE_SMS, OTP_TYPE_EMAIL */ + otpType: string; + /** @description Email or phone number to send the OTP code to */ + contact: string; + /** + * Format: int32 + * @description Optional length of the OTP code. Default = 9 + */ + otpLength?: number; + /** @description Optional parameters for customizing emails. If not provided, the default email will be used. */ + emailCustomization?: definitions["v1EmailCustomizationParams"]; + /** @description Optional parameters for customizing SMS message. If not provided, the default sms message will be used. */ + smsCustomization?: definitions["v1SmsCustomizationParams"]; + /** @description 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. */ + userIdentifier?: string; + /** @description Optional custom email address from which to send the OTP email */ + sendFromEmailAddress?: string; + /** @description Optional flag to specify if the OTP code should be alphanumeric (Crockford’s Base32). Default = true */ + alphanumeric?: boolean; + /** @description Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications' */ + sendFromEmailSenderName?: string; + /** @description 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) */ + expirationSeconds?: string; + /** @description Optional custom email address to use as reply-to */ + replyToEmailAddress?: string; + }; + v1InitOtpRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_INIT_OTP"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1InitOtpIntent"]; + }; + v1InitOtpResult: { + /** @description Unique identifier for an OTP authentication */ + otpId: string; + }; + v1InitUserEmailRecoveryIntent: { + /** @description Email of the user starting recovery */ + email: string; + /** @description Client-side public key generated by the user, to which the recovery bundle will be encrypted. */ + targetPublicKey: string; + /** @description Expiration window (in seconds) indicating how long the recovery credential is valid for. If not provided, a default of 15 minutes will be used. */ + expirationSeconds?: string; + /** @description Optional parameters for customizing emails. If not provided, the default email will be used. */ + emailCustomization?: definitions["v1EmailCustomizationParams"]; + }; + v1InitUserEmailRecoveryRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_INIT_USER_EMAIL_RECOVERY"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1InitUserEmailRecoveryIntent"]; + }; + v1InitUserEmailRecoveryResult: { + /** @description Unique identifier for the user being recovered. */ + userId: string; + }; + v1Intent: { + createOrganizationIntent?: definitions["v1CreateOrganizationIntent"]; + createAuthenticatorsIntent?: definitions["v1CreateAuthenticatorsIntent"]; + createUsersIntent?: definitions["v1CreateUsersIntent"]; + createPrivateKeysIntent?: definitions["v1CreatePrivateKeysIntent"]; + signRawPayloadIntent?: definitions["v1SignRawPayloadIntent"]; + createInvitationsIntent?: definitions["v1CreateInvitationsIntent"]; + acceptInvitationIntent?: definitions["v1AcceptInvitationIntent"]; + createPolicyIntent?: definitions["v1CreatePolicyIntent"]; + disablePrivateKeyIntent?: definitions["v1DisablePrivateKeyIntent"]; + deleteUsersIntent?: definitions["v1DeleteUsersIntent"]; + deleteAuthenticatorsIntent?: definitions["v1DeleteAuthenticatorsIntent"]; + deleteInvitationIntent?: definitions["v1DeleteInvitationIntent"]; + deleteOrganizationIntent?: definitions["v1DeleteOrganizationIntent"]; + deletePolicyIntent?: definitions["v1DeletePolicyIntent"]; + createUserTagIntent?: definitions["v1CreateUserTagIntent"]; + deleteUserTagsIntent?: definitions["v1DeleteUserTagsIntent"]; + signTransactionIntent?: definitions["v1SignTransactionIntent"]; + createApiKeysIntent?: definitions["v1CreateApiKeysIntent"]; + deleteApiKeysIntent?: definitions["v1DeleteApiKeysIntent"]; + approveActivityIntent?: definitions["v1ApproveActivityIntent"]; + rejectActivityIntent?: definitions["v1RejectActivityIntent"]; + createPrivateKeyTagIntent?: definitions["v1CreatePrivateKeyTagIntent"]; + deletePrivateKeyTagsIntent?: definitions["v1DeletePrivateKeyTagsIntent"]; + createPolicyIntentV2?: definitions["v1CreatePolicyIntentV2"]; + setPaymentMethodIntent?: definitions["billingSetPaymentMethodIntent"]; + activateBillingTierIntent?: definitions["billingActivateBillingTierIntent"]; + deletePaymentMethodIntent?: definitions["billingDeletePaymentMethodIntent"]; + createPolicyIntentV3?: definitions["v1CreatePolicyIntentV3"]; + createApiOnlyUsersIntent?: definitions["v1CreateApiOnlyUsersIntent"]; + updateRootQuorumIntent?: definitions["v1UpdateRootQuorumIntent"]; + updateUserTagIntent?: definitions["v1UpdateUserTagIntent"]; + updatePrivateKeyTagIntent?: definitions["v1UpdatePrivateKeyTagIntent"]; + createAuthenticatorsIntentV2?: definitions["v1CreateAuthenticatorsIntentV2"]; + acceptInvitationIntentV2?: definitions["v1AcceptInvitationIntentV2"]; + createOrganizationIntentV2?: definitions["v1CreateOrganizationIntentV2"]; + createUsersIntentV2?: definitions["v1CreateUsersIntentV2"]; + createSubOrganizationIntent?: definitions["v1CreateSubOrganizationIntent"]; + createSubOrganizationIntentV2?: definitions["v1CreateSubOrganizationIntentV2"]; + updateAllowedOriginsIntent?: definitions["v1UpdateAllowedOriginsIntent"]; + createPrivateKeysIntentV2?: definitions["v1CreatePrivateKeysIntentV2"]; + updateUserIntent?: definitions["v1UpdateUserIntent"]; + updatePolicyIntent?: definitions["v1UpdatePolicyIntent"]; + setPaymentMethodIntentV2?: definitions["billingSetPaymentMethodIntentV2"]; + createSubOrganizationIntentV3?: definitions["v1CreateSubOrganizationIntentV3"]; + createWalletIntent?: definitions["v1CreateWalletIntent"]; + createWalletAccountsIntent?: definitions["v1CreateWalletAccountsIntent"]; + initUserEmailRecoveryIntent?: definitions["v1InitUserEmailRecoveryIntent"]; + recoverUserIntent?: definitions["v1RecoverUserIntent"]; + setOrganizationFeatureIntent?: definitions["v1SetOrganizationFeatureIntent"]; + removeOrganizationFeatureIntent?: definitions["v1RemoveOrganizationFeatureIntent"]; + signRawPayloadIntentV2?: definitions["v1SignRawPayloadIntentV2"]; + signTransactionIntentV2?: definitions["v1SignTransactionIntentV2"]; + exportPrivateKeyIntent?: definitions["v1ExportPrivateKeyIntent"]; + exportWalletIntent?: definitions["v1ExportWalletIntent"]; + createSubOrganizationIntentV4?: definitions["v1CreateSubOrganizationIntentV4"]; + emailAuthIntent?: definitions["v1EmailAuthIntent"]; + exportWalletAccountIntent?: definitions["v1ExportWalletAccountIntent"]; + initImportWalletIntent?: definitions["v1InitImportWalletIntent"]; + importWalletIntent?: definitions["v1ImportWalletIntent"]; + initImportPrivateKeyIntent?: definitions["v1InitImportPrivateKeyIntent"]; + importPrivateKeyIntent?: definitions["v1ImportPrivateKeyIntent"]; + createPoliciesIntent?: definitions["v1CreatePoliciesIntent"]; + signRawPayloadsIntent?: definitions["v1SignRawPayloadsIntent"]; + createReadOnlySessionIntent?: definitions["v1CreateReadOnlySessionIntent"]; + createOauthProvidersIntent?: definitions["v1CreateOauthProvidersIntent"]; + deleteOauthProvidersIntent?: definitions["v1DeleteOauthProvidersIntent"]; + createSubOrganizationIntentV5?: definitions["v1CreateSubOrganizationIntentV5"]; + oauthIntent?: definitions["v1OauthIntent"]; + createApiKeysIntentV2?: definitions["v1CreateApiKeysIntentV2"]; + createReadWriteSessionIntent?: definitions["v1CreateReadWriteSessionIntent"]; + emailAuthIntentV2?: definitions["v1EmailAuthIntentV2"]; + createSubOrganizationIntentV6?: definitions["v1CreateSubOrganizationIntentV6"]; + deletePrivateKeysIntent?: definitions["v1DeletePrivateKeysIntent"]; + deleteWalletsIntent?: definitions["v1DeleteWalletsIntent"]; + createReadWriteSessionIntentV2?: definitions["v1CreateReadWriteSessionIntentV2"]; + deleteSubOrganizationIntent?: definitions["v1DeleteSubOrganizationIntent"]; + initOtpAuthIntent?: definitions["v1InitOtpAuthIntent"]; + otpAuthIntent?: definitions["v1OtpAuthIntent"]; + createSubOrganizationIntentV7?: definitions["v1CreateSubOrganizationIntentV7"]; + updateWalletIntent?: definitions["v1UpdateWalletIntent"]; + updatePolicyIntentV2?: definitions["v1UpdatePolicyIntentV2"]; + createUsersIntentV3?: definitions["v1CreateUsersIntentV3"]; + initOtpAuthIntentV2?: definitions["v1InitOtpAuthIntentV2"]; + initOtpIntent?: definitions["v1InitOtpIntent"]; + verifyOtpIntent?: definitions["v1VerifyOtpIntent"]; + otpLoginIntent?: definitions["v1OtpLoginIntent"]; + stampLoginIntent?: definitions["v1StampLoginIntent"]; + oauthLoginIntent?: definitions["v1OauthLoginIntent"]; + }; + v1Invitation: { + /** @description Unique identifier for a given Invitation object. */ + invitationId: string; + /** @description The name of the intended Invitation recipient. */ + receiverUserName: string; + /** @description The email address of the intended Invitation recipient. */ + receiverEmail: string; + /** @description A list of tags assigned to the Invitation recipient. */ + receiverUserTags: string[]; + /** @description The User's permissible access method(s). */ + accessType: definitions["v1AccessType"]; + /** @description The current processing status of a specified Invitation. */ + status: definitions["v1InvitationStatus"]; + createdAt: definitions["externaldatav1Timestamp"]; + updatedAt: definitions["externaldatav1Timestamp"]; + /** @description Unique identifier for the Sender of an Invitation. */ + senderUserId: string; + }; + v1InvitationParams: { + /** @description The name of the intended Invitation recipient. */ + receiverUserName: string; + /** @description The email address of the intended Invitation recipient. */ + receiverUserEmail: string; + /** @description A list of tags assigned to the Invitation recipient. This field, if not needed, should be an empty array in your request body. */ + receiverUserTags: string[]; + /** @description The User's permissible access method(s). */ + accessType: definitions["v1AccessType"]; + /** @description Unique identifier for the Sender of an Invitation. */ + senderUserId: string; + }; + /** @enum {string} */ + v1InvitationStatus: + | "INVITATION_STATUS_CREATED" + | "INVITATION_STATUS_ACCEPTED" + | "INVITATION_STATUS_REVOKED"; + v1ListPrivateKeyTagsRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + }; + v1ListPrivateKeyTagsResponse: { + /** @description A list of Private Key Tags */ + privateKeyTags: definitions["datav1Tag"][]; + }; + v1ListUserTagsRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + }; + v1ListUserTagsResponse: { + /** @description A list of User Tags */ + userTags: definitions["datav1Tag"][]; + }; + /** @enum {string} */ + v1MnemonicLanguage: + | "MNEMONIC_LANGUAGE_ENGLISH" + | "MNEMONIC_LANGUAGE_SIMPLIFIED_CHINESE" + | "MNEMONIC_LANGUAGE_TRADITIONAL_CHINESE" + | "MNEMONIC_LANGUAGE_CZECH" + | "MNEMONIC_LANGUAGE_FRENCH" + | "MNEMONIC_LANGUAGE_ITALIAN" + | "MNEMONIC_LANGUAGE_JAPANESE" + | "MNEMONIC_LANGUAGE_KOREAN" + | "MNEMONIC_LANGUAGE_SPANISH"; + v1NOOPCodegenAnchorResponse: { + stamp: definitions["v1WebAuthnStamp"]; + }; + v1OauthIntent: { + /** @description Base64 encoded OIDC token */ + oidcToken: string; + /** @description Client-side public key generated by the user, to which the oauth bundle (credentials) will be encrypted. */ + targetPublicKey: string; + /** @description Optional human-readable name for an API Key. If none provided, default to Oauth - */ + apiKeyName?: string; + /** @description Expiration window (in seconds) indicating how long the API key is valid for. If not provided, a default of 15 minutes will be used. */ + expirationSeconds?: string; + /** @description Invalidate all other previously generated Oauth API keys */ + invalidateExisting?: boolean; + }; + v1OauthLoginIntent: { + /** @description Base64 encoded OIDC token */ + oidcToken: string; + /** @description 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 */ + publicKey: string; + /** @description Expiration window (in seconds) indicating how long the Session is valid for. If not provided, a default of 15 minutes will be used. */ + expirationSeconds?: string; + /** @description Invalidate all other previously generated Login API keys */ + invalidateExisting?: boolean; + }; + v1OauthLoginRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_OAUTH_LOGIN"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1OauthLoginIntent"]; + }; + v1OauthLoginResult: { + /** @description Signed JWT containing an expiry, public key, session type, user id, and organization id */ + session: string; + }; + v1OauthProvider: { + /** @description Unique identifier for an OAuth Provider */ + providerId: string; + /** @description Human-readable name to identify a Provider. */ + providerName: string; + /** @description The issuer of the token, typically a URL indicating the authentication server, e.g https://accounts.google.com */ + issuer: string; + /** @description Expected audience ('aud' attribute of the signed token) which represents the app ID */ + audience: string; + /** @description Expected subject ('sub' attribute of the signed token) which represents the user ID */ + subject: string; + createdAt: definitions["externaldatav1Timestamp"]; + updatedAt: definitions["externaldatav1Timestamp"]; + }; + v1OauthProviderParams: { + /** @description Human-readable name to identify a Provider. */ + providerName: string; + /** @description Base64 encoded OIDC token */ + oidcToken: string; + }; + v1OauthRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_OAUTH"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1OauthIntent"]; + }; + v1OauthResult: { + /** @description Unique identifier for the authenticating User. */ + userId: string; + /** @description Unique identifier for the created API key. */ + apiKeyId: string; + /** @description HPKE encrypted credential bundle */ + credentialBundle: string; + }; + /** @enum {string} */ + v1Operator: + | "OPERATOR_EQUAL" + | "OPERATOR_MORE_THAN" + | "OPERATOR_MORE_THAN_OR_EQUAL" + | "OPERATOR_LESS_THAN" + | "OPERATOR_LESS_THAN_OR_EQUAL" + | "OPERATOR_CONTAINS" + | "OPERATOR_NOT_EQUAL" + | "OPERATOR_IN" + | "OPERATOR_NOT_IN" + | "OPERATOR_CONTAINS_ONE" + | "OPERATOR_CONTAINS_ALL"; + v1OrganizationData: { + organizationId?: string; + name?: string; + users?: definitions["v1User"][]; + policies?: definitions["v1Policy"][]; + privateKeys?: definitions["v1PrivateKey"][]; + invitations?: definitions["v1Invitation"][]; + tags?: definitions["datav1Tag"][]; + rootQuorum?: definitions["externaldatav1Quorum"]; + features?: definitions["v1Feature"][]; + wallets?: definitions["v1Wallet"][]; + }; + v1OtpAuthIntent: { + /** @description ID representing the result of an init OTP activity. */ + otpId: string; + /** @description OTP sent out to a user's contact (email or SMS) */ + otpCode: string; + /** @description Client-side public key generated by the user, to which the OTP bundle (credentials) will be encrypted. */ + targetPublicKey: string; + /** @description Optional human-readable name for an API Key. If none provided, default to OTP Auth - */ + apiKeyName?: string; + /** @description Expiration window (in seconds) indicating how long the API key is valid for. If not provided, a default of 15 minutes will be used. */ + expirationSeconds?: string; + /** @description Invalidate all other previously generated OTP Auth API keys */ + invalidateExisting?: boolean; + }; + v1OtpAuthRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_OTP_AUTH"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1OtpAuthIntent"]; + }; + v1OtpAuthResult: { + /** @description Unique identifier for the authenticating User. */ + userId: string; + /** @description Unique identifier for the created API key. */ + apiKeyId?: string; + /** @description HPKE encrypted credential bundle */ + credentialBundle?: string; + }; + v1OtpLoginIntent: { + /** @description Signed JWT containing a unique id, expiry, verification type, contact */ + verificationToken: string; + /** @description Client-side public key generated by the user, which will be conditionally added to org data based on the validity of the verification token */ + publicKey: string; + /** @description Expiration window (in seconds) indicating how long the Session is valid for. If not provided, a default of 15 minutes will be used. */ + expirationSeconds?: string; + /** @description Invalidate all other previously generated Login API keys */ + invalidateExisting?: boolean; + }; + v1OtpLoginRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_OTP_LOGIN"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1OtpLoginIntent"]; + }; + v1OtpLoginResult: { + /** @description Signed JWT containing an expiry, public key, session type, user id, and organization id */ + session: string; + }; + v1Pagination: { + /** @description A limit of the number of object to be returned, between 1 and 100. Defaults to 10. */ + limit?: string; + /** @description A pagination cursor. This is an object ID that enables you to fetch all objects before this ID. */ + before?: string; + /** @description A pagination cursor. This is an object ID that enables you to fetch all objects after this ID. */ + after?: string; + }; + /** @enum {string} */ + v1PathFormat: "PATH_FORMAT_BIP32"; + /** @enum {string} */ + v1PayloadEncoding: + | "PAYLOAD_ENCODING_HEXADECIMAL" + | "PAYLOAD_ENCODING_TEXT_UTF8"; + v1Policy: { + /** @description Unique identifier for a given Policy. */ + policyId: string; + /** @description Human-readable name for a Policy. */ + policyName: string; + /** @description The instruction to DENY or ALLOW a particular activity following policy selector(s). */ + effect: definitions["v1Effect"]; + createdAt: definitions["externaldatav1Timestamp"]; + updatedAt: definitions["externaldatav1Timestamp"]; + /** @description Human-readable notes added by a User to describe a particular policy. */ + notes: string; + /** @description A consensus expression that evalutes to true or false. */ + consensus: string; + /** @description A condition expression that evalutes to true or false. */ + condition: string; + }; + v1PrivateKey: { + /** @description Unique identifier for a given Private Key. */ + privateKeyId: string; + /** @description The public component of a cryptographic key pair used to sign messages and transactions. */ + publicKey: string; + /** @description Human-readable name for a Private Key. */ + privateKeyName: string; + /** @description Cryptographic Curve used to generate a given Private Key. */ + curve: definitions["v1Curve"]; + /** @description Derived cryptocurrency addresses for a given Private Key. */ + addresses: definitions["externaldatav1Address"][]; + /** @description A list of Private Key Tag IDs. */ + privateKeyTags: string[]; + createdAt: definitions["externaldatav1Timestamp"]; + updatedAt: definitions["externaldatav1Timestamp"]; + /** @description True when a given Private Key is exported, false otherwise. */ + exported: boolean; + /** @description True when a given Private Key is imported, false otherwise. */ + imported: boolean; + }; + v1PrivateKeyParams: { + /** @description Human-readable name for a Private Key. */ + privateKeyName: string; + /** @description Cryptographic Curve used to generate a given Private Key. */ + curve: definitions["v1Curve"]; + /** @description A list of Private Key Tag IDs. This field, if not needed, should be an empty array in your request body. */ + privateKeyTags: string[]; + /** @description Cryptocurrency-specific formats for a derived address (e.g., Ethereum). */ + addressFormats: definitions["v1AddressFormat"][]; + }; + v1PrivateKeyResult: { + privateKeyId?: string; + addresses?: definitions["immutableactivityv1Address"][]; + }; + v1PublicKeyCredentialWithAttestation: { + id: string; + /** @enum {string} */ + type: "public-key"; + rawId: string; + /** @enum {string} */ + authenticatorAttachment?: "cross-platform" | "platform" | null; + response: definitions["v1AuthenticatorAttestationResponse"]; + clientExtensionResults: definitions["v1SimpleClientExtensionResults"]; + }; + v1RecoverUserIntent: { + /** @description The new authenticator to register. */ + authenticator: definitions["v1AuthenticatorParamsV2"]; + /** @description Unique identifier for the user performing recovery. */ + userId: string; + }; + v1RecoverUserRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_RECOVER_USER"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1RecoverUserIntent"]; + }; + v1RecoverUserResult: { + /** @description ID of the authenticator created. */ + authenticatorId: string[]; + }; + v1RejectActivityIntent: { + /** @description An artifact verifying a User's action. */ + fingerprint: string; + }; + v1RejectActivityRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_REJECT_ACTIVITY"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1RejectActivityIntent"]; + }; + v1RemoveOrganizationFeatureIntent: { + /** @description Name of the feature to remove */ + name: definitions["v1FeatureName"]; + }; + v1RemoveOrganizationFeatureRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_REMOVE_ORGANIZATION_FEATURE"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1RemoveOrganizationFeatureIntent"]; + }; + v1RemoveOrganizationFeatureResult: { + /** @description Resulting list of organization features. */ + features: definitions["v1Feature"][]; + }; + v1Result: { + createOrganizationResult?: definitions["v1CreateOrganizationResult"]; + createAuthenticatorsResult?: definitions["v1CreateAuthenticatorsResult"]; + createUsersResult?: definitions["v1CreateUsersResult"]; + createPrivateKeysResult?: definitions["v1CreatePrivateKeysResult"]; + createInvitationsResult?: definitions["v1CreateInvitationsResult"]; + acceptInvitationResult?: definitions["v1AcceptInvitationResult"]; + signRawPayloadResult?: definitions["v1SignRawPayloadResult"]; + createPolicyResult?: definitions["v1CreatePolicyResult"]; + disablePrivateKeyResult?: definitions["v1DisablePrivateKeyResult"]; + deleteUsersResult?: definitions["v1DeleteUsersResult"]; + deleteAuthenticatorsResult?: definitions["v1DeleteAuthenticatorsResult"]; + deleteInvitationResult?: definitions["v1DeleteInvitationResult"]; + deleteOrganizationResult?: definitions["v1DeleteOrganizationResult"]; + deletePolicyResult?: definitions["v1DeletePolicyResult"]; + createUserTagResult?: definitions["v1CreateUserTagResult"]; + deleteUserTagsResult?: definitions["v1DeleteUserTagsResult"]; + signTransactionResult?: definitions["v1SignTransactionResult"]; + deleteApiKeysResult?: definitions["v1DeleteApiKeysResult"]; + createApiKeysResult?: definitions["v1CreateApiKeysResult"]; + createPrivateKeyTagResult?: definitions["v1CreatePrivateKeyTagResult"]; + deletePrivateKeyTagsResult?: definitions["v1DeletePrivateKeyTagsResult"]; + setPaymentMethodResult?: definitions["billingSetPaymentMethodResult"]; + activateBillingTierResult?: definitions["billingActivateBillingTierResult"]; + deletePaymentMethodResult?: definitions["billingDeletePaymentMethodResult"]; + createApiOnlyUsersResult?: definitions["v1CreateApiOnlyUsersResult"]; + updateRootQuorumResult?: definitions["v1UpdateRootQuorumResult"]; + updateUserTagResult?: definitions["v1UpdateUserTagResult"]; + updatePrivateKeyTagResult?: definitions["v1UpdatePrivateKeyTagResult"]; + createSubOrganizationResult?: definitions["v1CreateSubOrganizationResult"]; + updateAllowedOriginsResult?: definitions["v1UpdateAllowedOriginsResult"]; + createPrivateKeysResultV2?: definitions["v1CreatePrivateKeysResultV2"]; + updateUserResult?: definitions["v1UpdateUserResult"]; + updatePolicyResult?: definitions["v1UpdatePolicyResult"]; + createSubOrganizationResultV3?: definitions["v1CreateSubOrganizationResultV3"]; + createWalletResult?: definitions["v1CreateWalletResult"]; + createWalletAccountsResult?: definitions["v1CreateWalletAccountsResult"]; + initUserEmailRecoveryResult?: definitions["v1InitUserEmailRecoveryResult"]; + recoverUserResult?: definitions["v1RecoverUserResult"]; + setOrganizationFeatureResult?: definitions["v1SetOrganizationFeatureResult"]; + removeOrganizationFeatureResult?: definitions["v1RemoveOrganizationFeatureResult"]; + exportPrivateKeyResult?: definitions["v1ExportPrivateKeyResult"]; + exportWalletResult?: definitions["v1ExportWalletResult"]; + createSubOrganizationResultV4?: definitions["v1CreateSubOrganizationResultV4"]; + emailAuthResult?: definitions["v1EmailAuthResult"]; + exportWalletAccountResult?: definitions["v1ExportWalletAccountResult"]; + initImportWalletResult?: definitions["v1InitImportWalletResult"]; + importWalletResult?: definitions["v1ImportWalletResult"]; + initImportPrivateKeyResult?: definitions["v1InitImportPrivateKeyResult"]; + importPrivateKeyResult?: definitions["v1ImportPrivateKeyResult"]; + createPoliciesResult?: definitions["v1CreatePoliciesResult"]; + signRawPayloadsResult?: definitions["v1SignRawPayloadsResult"]; + createReadOnlySessionResult?: definitions["v1CreateReadOnlySessionResult"]; + createOauthProvidersResult?: definitions["v1CreateOauthProvidersResult"]; + deleteOauthProvidersResult?: definitions["v1DeleteOauthProvidersResult"]; + createSubOrganizationResultV5?: definitions["v1CreateSubOrganizationResultV5"]; + oauthResult?: definitions["v1OauthResult"]; + createReadWriteSessionResult?: definitions["v1CreateReadWriteSessionResult"]; + createSubOrganizationResultV6?: definitions["v1CreateSubOrganizationResultV6"]; + deletePrivateKeysResult?: definitions["v1DeletePrivateKeysResult"]; + deleteWalletsResult?: definitions["v1DeleteWalletsResult"]; + createReadWriteSessionResultV2?: definitions["v1CreateReadWriteSessionResultV2"]; + deleteSubOrganizationResult?: definitions["v1DeleteSubOrganizationResult"]; + initOtpAuthResult?: definitions["v1InitOtpAuthResult"]; + otpAuthResult?: definitions["v1OtpAuthResult"]; + createSubOrganizationResultV7?: definitions["v1CreateSubOrganizationResultV7"]; + updateWalletResult?: definitions["v1UpdateWalletResult"]; + updatePolicyResultV2?: definitions["v1UpdatePolicyResultV2"]; + initOtpAuthResultV2?: definitions["v1InitOtpAuthResultV2"]; + initOtpResult?: definitions["v1InitOtpResult"]; + verifyOtpResult?: definitions["v1VerifyOtpResult"]; + otpLoginResult?: definitions["v1OtpLoginResult"]; + stampLoginResult?: definitions["v1StampLoginResult"]; + oauthLoginResult?: definitions["v1OauthLoginResult"]; + }; + v1RootUserParams: { + /** @description Human-readable name for a User. */ + userName: string; + /** @description The user's email address. */ + userEmail?: string; + /** @description A list of API Key parameters. This field, if not needed, should be an empty array in your request body. */ + apiKeys: definitions["apiApiKeyParams"][]; + /** @description A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. */ + authenticators: definitions["v1AuthenticatorParamsV2"][]; + }; + v1RootUserParamsV2: { + /** @description Human-readable name for a User. */ + userName: string; + /** @description The user's email address. */ + userEmail?: string; + /** @description A list of API Key parameters. This field, if not needed, should be an empty array in your request body. */ + apiKeys: definitions["apiApiKeyParams"][]; + /** @description A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. */ + authenticators: definitions["v1AuthenticatorParamsV2"][]; + /** @description A list of Oauth providers. This field, if not needed, should be an empty array in your request body. */ + oauthProviders: definitions["v1OauthProviderParams"][]; + }; + v1RootUserParamsV3: { + /** @description Human-readable name for a User. */ + userName: string; + /** @description The user's email address. */ + userEmail?: string; + /** @description A list of API Key parameters. This field, if not needed, should be an empty array in your request body. */ + apiKeys: definitions["v1ApiKeyParamsV2"][]; + /** @description A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. */ + authenticators: definitions["v1AuthenticatorParamsV2"][]; + /** @description A list of Oauth providers. This field, if not needed, should be an empty array in your request body. */ + oauthProviders: definitions["v1OauthProviderParams"][]; + }; + v1RootUserParamsV4: { + /** @description Human-readable name for a User. */ + userName: string; + /** @description The user's email address. */ + userEmail?: string; + /** @description The user's phone number in E.164 format e.g. +13214567890 */ + userPhoneNumber?: string; + /** @description A list of API Key parameters. This field, if not needed, should be an empty array in your request body. */ + apiKeys: definitions["v1ApiKeyParamsV2"][]; + /** @description A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. */ + authenticators: definitions["v1AuthenticatorParamsV2"][]; + /** @description A list of Oauth providers. This field, if not needed, should be an empty array in your request body. */ + oauthProviders: definitions["v1OauthProviderParams"][]; + }; + v1Selector: { + subject?: string; + operator?: definitions["v1Operator"]; + target?: string; + }; + v1SelectorV2: { + subject?: string; + operator?: definitions["v1Operator"]; + targets?: string[]; + }; + v1SetOrganizationFeatureIntent: { + /** @description Name of the feature to set */ + name: definitions["v1FeatureName"]; + /** @description Optional value for the feature. Will override existing values if feature is already set. */ + value: string; + }; + v1SetOrganizationFeatureRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_SET_ORGANIZATION_FEATURE"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1SetOrganizationFeatureIntent"]; + }; + v1SetOrganizationFeatureResult: { + /** @description Resulting list of organization features. */ + features: definitions["v1Feature"][]; + }; + v1SignRawPayloadIntent: { + /** @description Unique identifier for a given Private Key. */ + privateKeyId: string; + /** @description Raw unsigned payload to be signed. */ + payload: string; + /** @description Encoding of the `payload` string. Turnkey uses this information to convert `payload` into bytes with the correct decoder (e.g. hex, utf8). */ + encoding: definitions["v1PayloadEncoding"]; + /** @description Hash function to apply to payload bytes before signing. This field must be set to HASH_FUNCTION_NOT_APPLICABLE for EdDSA/ed25519 signature requests; configurable payload hashing is not supported by RFC 8032. */ + hashFunction: definitions["v1HashFunction"]; + }; + v1SignRawPayloadIntentV2: { + /** @description A Wallet account address, Private Key address, or Private Key identifier. */ + signWith: string; + /** @description Raw unsigned payload to be signed. */ + payload: string; + /** @description Encoding of the `payload` string. Turnkey uses this information to convert `payload` into bytes with the correct decoder (e.g. hex, utf8). */ + encoding: definitions["v1PayloadEncoding"]; + /** @description Hash function to apply to payload bytes before signing. This field must be set to HASH_FUNCTION_NOT_APPLICABLE for EdDSA/ed25519 signature requests; configurable payload hashing is not supported by RFC 8032. */ + hashFunction: definitions["v1HashFunction"]; + }; + v1SignRawPayloadRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_SIGN_RAW_PAYLOAD_V2"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1SignRawPayloadIntentV2"]; + }; + v1SignRawPayloadResult: { + /** @description Component of an ECSDA signature. */ + r: string; + /** @description Component of an ECSDA signature. */ + s: string; + /** @description Component of an ECSDA signature. */ + v: string; + }; + v1SignRawPayloadsIntent: { + /** @description A Wallet account address, Private Key address, or Private Key identifier. */ + signWith: string; + /** @description An array of raw unsigned payloads to be signed. */ + payloads: string[]; + /** @description Encoding of the `payload` string. Turnkey uses this information to convert `payload` into bytes with the correct decoder (e.g. hex, utf8). */ + encoding: definitions["v1PayloadEncoding"]; + /** @description Hash function to apply to payload bytes before signing. This field must be set to HASH_FUNCTION_NOT_APPLICABLE for EdDSA/ed25519 signature requests; configurable payload hashing is not supported by RFC 8032. */ + hashFunction: definitions["v1HashFunction"]; + }; + v1SignRawPayloadsRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_SIGN_RAW_PAYLOADS"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1SignRawPayloadsIntent"]; + }; + v1SignRawPayloadsResult: { + signatures?: definitions["v1SignRawPayloadResult"][]; + }; + v1SignTransactionIntent: { + /** @description Unique identifier for a given Private Key. */ + privateKeyId: string; + /** @description Raw unsigned transaction to be signed by a particular Private Key. */ + unsignedTransaction: string; + type: definitions["v1TransactionType"]; + }; + v1SignTransactionIntentV2: { + /** @description A Wallet account address, Private Key address, or Private Key identifier. */ + signWith: string; + /** @description Raw unsigned transaction to be signed */ + unsignedTransaction: string; + type: definitions["v1TransactionType"]; + }; + v1SignTransactionRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_SIGN_TRANSACTION_V2"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1SignTransactionIntentV2"]; + }; + v1SignTransactionResult: { + signedTransaction: string; + }; + v1SimpleClientExtensionResults: { + appid?: boolean; + appidExclude?: boolean; + credProps?: definitions["v1CredPropsAuthenticationExtensionsClientOutputs"]; + }; + v1SmsCustomizationParams: { + /** @description Template containing references to .OtpCode i.e Your OTP is {{.OtpCode}} */ + template?: string; + }; + v1StampLoginIntent: { + /** @description Client-side public key generated by the user, which will be conditionally added to org data based on the passkey stamp associated with this request */ + publicKey: string; + /** @description Expiration window (in seconds) indicating how long the Session is valid for. If not provided, a default of 15 minutes will be used. */ + expirationSeconds?: string; + /** @description Invalidate all other previously generated Login API keys */ + invalidateExisting?: boolean; + }; + v1StampLoginRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_STAMP_LOGIN"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1StampLoginIntent"]; + }; + v1StampLoginResult: { + /** @description Signed JWT containing an expiry, public key, session type, user id, and organization id */ + session: string; + }; + /** @enum {string} */ + v1TagType: "TAG_TYPE_USER" | "TAG_TYPE_PRIVATE_KEY"; + v1TestRateLimitsRequest: { + /** @description 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. */ + organizationId: string; + /** @description Whether or not to set a limit on this request. */ + isSetLimit: boolean; + /** + * Format: int64 + * @description Rate limit to set for org, if is_set_limit is set to true + */ + limit: number; + }; + v1TestRateLimitsResponse: { [key: string]: unknown }; + /** @enum {string} */ + v1TransactionType: + | "TRANSACTION_TYPE_ETHEREUM" + | "TRANSACTION_TYPE_SOLANA" + | "TRANSACTION_TYPE_TRON"; + v1UpdateAllowedOriginsIntent: { + /** @description Additional origins requests are allowed from besides Turnkey origins */ + allowedOrigins: string[]; + }; + v1UpdateAllowedOriginsResult: { [key: string]: unknown }; + v1UpdatePolicyIntent: { + /** @description Unique identifier for a given Policy. */ + policyId: string; + /** @description Human-readable name for a Policy. */ + policyName?: string; + /** @description The instruction to DENY or ALLOW an activity (optional). */ + policyEffect?: definitions["v1Effect"]; + /** @description The condition expression that triggers the Effect (optional). */ + policyCondition?: string; + /** @description The consensus expression that triggers the Effect (optional). */ + policyConsensus?: string; + /** @description Accompanying notes for a Policy (optional). */ + policyNotes?: string; + }; + v1UpdatePolicyIntentV2: { + /** @description Unique identifier for a given Policy. */ + policyId: string; + /** @description Human-readable name for a Policy. */ + policyName?: string; + /** @description The instruction to DENY or ALLOW an activity (optional). */ + policyEffect?: definitions["v1Effect"]; + /** @description The condition expression that triggers the Effect (optional). */ + policyCondition?: string; + /** @description The consensus expression that triggers the Effect (optional). */ + policyConsensus?: string; + /** @description Accompanying notes for a Policy (optional). */ + policyNotes?: string; + }; + v1UpdatePolicyRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_UPDATE_POLICY_V2"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1UpdatePolicyIntentV2"]; + }; + v1UpdatePolicyResult: { + /** @description Unique identifier for a given Policy. */ + policyId: string; + }; + v1UpdatePolicyResultV2: { + /** @description Unique identifier for a given Policy. */ + policyId: string; + }; + v1UpdatePrivateKeyTagIntent: { + /** @description Unique identifier for a given Private Key Tag. */ + privateKeyTagId: string; + /** @description The new, human-readable name for the tag with the given ID. */ + newPrivateKeyTagName?: string; + /** @description A list of Private Keys IDs to add this tag to. */ + addPrivateKeyIds: string[]; + /** @description A list of Private Key IDs to remove this tag from. */ + removePrivateKeyIds: string[]; + }; + v1UpdatePrivateKeyTagRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_UPDATE_PRIVATE_KEY_TAG"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1UpdatePrivateKeyTagIntent"]; + }; + v1UpdatePrivateKeyTagResult: { + /** @description Unique identifier for a given Private Key Tag. */ + privateKeyTagId: string; + }; + v1UpdateRootQuorumIntent: { + /** + * Format: int32 + * @description The threshold of unique approvals to reach quorum. + */ + threshold: number; + /** @description The unique identifiers of users who comprise the quorum set. */ + userIds: string[]; + }; + v1UpdateRootQuorumRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_UPDATE_ROOT_QUORUM"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1UpdateRootQuorumIntent"]; + }; + v1UpdateRootQuorumResult: { [key: string]: unknown }; + v1UpdateUserIntent: { + /** @description Unique identifier for a given User. */ + userId: string; + /** @description Human-readable name for a User. */ + userName?: string; + /** @description The user's email address. */ + userEmail?: string; + /** @description An updated list of User Tags to apply to this User. This field, if not needed, should be an empty array in your request body. */ + userTagIds?: string[]; + /** @description The user's phone number in E.164 format e.g. +13214567890 */ + userPhoneNumber?: string; + }; + v1UpdateUserRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_UPDATE_USER"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1UpdateUserIntent"]; + }; + v1UpdateUserResult: { + /** @description A User ID. */ + userId: string; + }; + v1UpdateUserTagIntent: { + /** @description Unique identifier for a given User Tag. */ + userTagId: string; + /** @description The new, human-readable name for the tag with the given ID. */ + newUserTagName?: string; + /** @description A list of User IDs to add this tag to. */ + addUserIds: string[]; + /** @description A list of User IDs to remove this tag from. */ + removeUserIds: string[]; + }; + v1UpdateUserTagRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_UPDATE_USER_TAG"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1UpdateUserTagIntent"]; + }; + v1UpdateUserTagResult: { + /** @description Unique identifier for a given User Tag. */ + userTagId: string; + }; + v1UpdateWalletIntent: { + /** @description Unique identifier for a given Wallet. */ + walletId: string; + /** @description Human-readable name for a Wallet. */ + walletName?: string; + }; + v1UpdateWalletRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_UPDATE_WALLET"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1UpdateWalletIntent"]; + }; + v1UpdateWalletResult: { + /** @description A Wallet ID. */ + walletId: string; + }; + v1User: { + /** @description Unique identifier for a given User. */ + userId: string; + /** @description Human-readable name for a User. */ + userName: string; + /** @description The user's email address. */ + userEmail?: string; + /** @description The user's phone number in E.164 format e.g. +13214567890 */ + userPhoneNumber?: string; + /** @description A list of Authenticator parameters. */ + authenticators: definitions["v1Authenticator"][]; + /** @description A list of API Key parameters. This field, if not needed, should be an empty array in your request body. */ + apiKeys: definitions["v1ApiKey"][]; + /** @description A list of User Tag IDs. */ + userTags: string[]; + /** @description A list of Oauth Providers. */ + oauthProviders: definitions["v1OauthProvider"][]; + createdAt: definitions["externaldatav1Timestamp"]; + updatedAt: definitions["externaldatav1Timestamp"]; + }; + v1UserParams: { + /** @description Human-readable name for a User. */ + userName: string; + /** @description The user's email address. */ + userEmail?: string; + /** @description The User's permissible access method(s). */ + accessType: definitions["v1AccessType"]; + /** @description A list of API Key parameters. This field, if not needed, should be an empty array in your request body. */ + apiKeys: definitions["apiApiKeyParams"][]; + /** @description A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. */ + authenticators: definitions["v1AuthenticatorParams"][]; + /** @description A list of User Tag IDs. This field, if not needed, should be an empty array in your request body. */ + userTags: string[]; + }; + v1UserParamsV2: { + /** @description Human-readable name for a User. */ + userName: string; + /** @description The user's email address. */ + userEmail?: string; + /** @description A list of API Key parameters. This field, if not needed, should be an empty array in your request body. */ + apiKeys: definitions["apiApiKeyParams"][]; + /** @description A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. */ + authenticators: definitions["v1AuthenticatorParamsV2"][]; + /** @description A list of User Tag IDs. This field, if not needed, should be an empty array in your request body. */ + userTags: string[]; + }; + v1UserParamsV3: { + /** @description Human-readable name for a User. */ + userName: string; + /** @description The user's email address. */ + userEmail?: string; + /** @description The user's phone number in E.164 format e.g. +13214567890 */ + userPhoneNumber?: string; + /** @description A list of API Key parameters. This field, if not needed, should be an empty array in your request body. */ + apiKeys: definitions["v1ApiKeyParamsV2"][]; + /** @description A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. */ + authenticators: definitions["v1AuthenticatorParamsV2"][]; + /** @description A list of Oauth providers. This field, if not needed, should be an empty array in your request body. */ + oauthProviders: definitions["v1OauthProviderParams"][]; + /** @description A list of User Tag IDs. This field, if not needed, should be an empty array in your request body. */ + userTags: string[]; + }; + v1VerifyOtpIntent: { + /** @description ID representing the result of an init OTP activity. */ + otpId: string; + /** @description OTP sent out to a user's contact (email or SMS) */ + otpCode: string; + /** @description Expiration window (in seconds) indicating how long the verification token is valid for. If not provided, a default of 1 hour will be used. Maximum value is 86400 seconds (24 hours) */ + expirationSeconds?: string; + }; + v1VerifyOtpRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_VERIFY_OTP"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1VerifyOtpIntent"]; + }; + v1VerifyOtpResult: { + /** @description Signed JWT containing a unique id, expiry, verification type, contact. Verification status of a user is updated when the token is consumed (in OTP_LOGIN requests) */ + verificationToken: string; + }; + v1Vote: { + /** @description Unique identifier for a given Vote object. */ + id: string; + /** @description Unique identifier for a given User. */ + userId: string; + /** @description Web and/or API user within your Organization. */ + user: definitions["v1User"]; + /** @description Unique identifier for a given Activity object. */ + activityId: string; + /** @enum {string} */ + selection: "VOTE_SELECTION_APPROVED" | "VOTE_SELECTION_REJECTED"; + /** @description The raw message being signed within a Vote. */ + message: string; + /** @description The public component of a cryptographic key pair used to sign messages and transactions. */ + publicKey: string; + /** @description The signature applied to a particular vote. */ + signature: string; + /** @description Method used to produce a signature. */ + scheme: string; + createdAt: definitions["externaldatav1Timestamp"]; + }; + v1Wallet: { + /** @description Unique identifier for a given Wallet. */ + walletId: string; + /** @description Human-readable name for a Wallet. */ + walletName: string; + createdAt: definitions["externaldatav1Timestamp"]; + updatedAt: definitions["externaldatav1Timestamp"]; + /** @description True when a given Wallet is exported, false otherwise. */ + exported: boolean; + /** @description True when a given Wallet is imported, false otherwise. */ + imported: boolean; + }; + v1WalletAccount: { + /** @description Unique identifier for a given Wallet Account. */ + walletAccountId: string; + /** @description The Organization the Account belongs to. */ + organizationId: string; + /** @description The Wallet the Account was derived from. */ + walletId: string; + /** @description Cryptographic curve used to generate the Account. */ + curve: definitions["v1Curve"]; + /** @description Path format used to generate the Account. */ + pathFormat: definitions["v1PathFormat"]; + /** @description Path used to generate the Account. */ + path: string; + /** @description Address format used to generate the Account. */ + addressFormat: definitions["v1AddressFormat"]; + /** @description Address generated using the Wallet seed and Account parameters. */ + address: string; + createdAt: definitions["externaldatav1Timestamp"]; + updatedAt: definitions["externaldatav1Timestamp"]; + /** @description The public component of this wallet account's underlying cryptographic key pair. */ + publicKey?: string; + }; + v1WalletAccountParams: { + /** @description Cryptographic curve used to generate a wallet Account. */ + curve: definitions["v1Curve"]; + /** @description Path format used to generate a wallet Account. */ + pathFormat: definitions["v1PathFormat"]; + /** @description Path used to generate a wallet Account. */ + path: string; + /** @description Address format used to generate a wallet Acccount. */ + addressFormat: definitions["v1AddressFormat"]; + }; + v1WalletParams: { + /** @description Human-readable name for a Wallet. */ + walletName: string; + /** @description A list of wallet Accounts. This field, if not needed, should be an empty array in your request body. */ + accounts: definitions["v1WalletAccountParams"][]; + /** + * Format: int32 + * @description Length of mnemonic to generate the Wallet seed. Defaults to 12. Accepted values: 12, 15, 18, 21, 24. + */ + mnemonicLength?: number; + }; + v1WalletResult: { + walletId: string; + /** @description A list of account addresses. */ + addresses: string[]; + }; + v1WebAuthnStamp: { + /** @description A base64 url encoded Unique identifier for a given credential. */ + credentialId: string; + /** @description A base64 encoded payload containing metadata about the signing context and the challenge. */ + clientDataJson: string; + /** @description A base64 encoded payload containing metadata about the authenticator. */ + authenticatorData: string; + /** @description The base64 url encoded signature bytes contained within the WebAuthn assertion response. */ + signature: string; + }; +}; + +export type operations = { + /** Get details about an Activity */ + PublicApiService_GetActivity: { + parameters: { + body: { + body: definitions["v1GetActivityRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Get details about an API key */ + PublicApiService_GetApiKey: { + parameters: { + body: { + body: definitions["v1GetApiKeyRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1GetApiKeyResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Get details about API keys for a user */ + PublicApiService_GetApiKeys: { + parameters: { + body: { + body: definitions["v1GetApiKeysRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1GetApiKeysResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Get the attestation document corresponding to an enclave. */ + PublicApiService_GetAttestationDocument: { + parameters: { + body: { + body: definitions["v1GetAttestationDocumentRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1GetAttestationDocumentResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Get details about an authenticator */ + PublicApiService_GetAuthenticator: { + parameters: { + body: { + body: definitions["v1GetAuthenticatorRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1GetAuthenticatorResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Get details about authenticators for a user */ + PublicApiService_GetAuthenticators: { + parameters: { + body: { + body: definitions["v1GetAuthenticatorsRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1GetAuthenticatorsResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Get details about Oauth providers for a user */ + PublicApiService_GetOauthProviders: { + parameters: { + body: { + body: definitions["v1GetOauthProvidersRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1GetOauthProvidersResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Get details about an Organization */ + PublicApiService_GetOrganization: { + parameters: { + body: { + body: definitions["v1GetOrganizationRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1GetOrganizationResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Get quorum settings and features for an organization */ + PublicApiService_GetOrganizationConfigs: { + parameters: { + body: { + body: definitions["v1GetOrganizationConfigsRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1GetOrganizationConfigsResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Get details about a Policy */ + PublicApiService_GetPolicy: { + parameters: { + body: { + body: definitions["v1GetPolicyRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1GetPolicyResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Get details about a Private Key */ + PublicApiService_GetPrivateKey: { + parameters: { + body: { + body: definitions["v1GetPrivateKeyRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1GetPrivateKeyResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Get details about a User */ + PublicApiService_GetUser: { + parameters: { + body: { + body: definitions["v1GetUserRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1GetUserResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Get details about a Wallet */ + PublicApiService_GetWallet: { + parameters: { + body: { + body: definitions["v1GetWalletRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1GetWalletResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Get a single wallet account */ + PublicApiService_GetWalletAccount: { + parameters: { + body: { + body: definitions["v1GetWalletAccountRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1GetWalletAccountResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** List all Activities within an Organization */ + PublicApiService_GetActivities: { + parameters: { + body: { + body: definitions["v1GetActivitiesRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1GetActivitiesResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** List all Policies within an Organization */ + PublicApiService_GetPolicies: { + parameters: { + body: { + body: definitions["v1GetPoliciesRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1GetPoliciesResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** List all Private Key Tags within an Organization */ + PublicApiService_ListPrivateKeyTags: { + parameters: { + body: { + body: definitions["v1ListPrivateKeyTagsRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ListPrivateKeyTagsResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** List all Private Keys within an Organization */ + PublicApiService_GetPrivateKeys: { + parameters: { + body: { + body: definitions["v1GetPrivateKeysRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1GetPrivateKeysResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Get all suborg IDs associated given a parent org ID and an optional filter. */ + PublicApiService_GetSubOrgIds: { + parameters: { + body: { + body: definitions["v1GetSubOrgIdsRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1GetSubOrgIdsResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** List all User Tags within an Organization */ + PublicApiService_ListUserTags: { + parameters: { + body: { + body: definitions["v1ListUserTagsRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ListUserTagsResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** List all Users within an Organization */ + PublicApiService_GetUsers: { + parameters: { + body: { + body: definitions["v1GetUsersRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1GetUsersResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Get all email or phone verified suborg IDs associated given a parent org ID. */ + PublicApiService_GetVerifiedSubOrgIds: { + parameters: { + body: { + body: definitions["v1GetVerifiedSubOrgIdsRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1GetVerifiedSubOrgIdsResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** List all Accounts within a Wallet */ + PublicApiService_GetWalletAccounts: { + parameters: { + body: { + body: definitions["v1GetWalletAccountsRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1GetWalletAccountsResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** List all Wallets within an Organization */ + PublicApiService_GetWallets: { + parameters: { + body: { + body: definitions["v1GetWalletsRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1GetWalletsResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Get basic information about your current API or WebAuthN user and their organization. Affords Sub-Organization look ups via Parent Organization for WebAuthN or API key users. */ + PublicApiService_GetWhoami: { + parameters: { + body: { + body: definitions["v1GetWhoamiRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1GetWhoamiResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Approve an Activity */ + PublicApiService_ApproveActivity: { + parameters: { + body: { + body: definitions["v1ApproveActivityRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Add api keys to an existing User */ + PublicApiService_CreateApiKeys: { + parameters: { + body: { + body: definitions["v1CreateApiKeysRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Create API-only Users in an existing Organization */ + PublicApiService_CreateApiOnlyUsers: { + parameters: { + body: { + body: definitions["v1CreateApiOnlyUsersRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Create Authenticators to authenticate requests to Turnkey */ + PublicApiService_CreateAuthenticators: { + parameters: { + body: { + body: definitions["v1CreateAuthenticatorsRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Create Invitations to join an existing Organization */ + PublicApiService_CreateInvitations: { + parameters: { + body: { + body: definitions["v1CreateInvitationsRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Creates Oauth providers for a specified user - BETA */ + PublicApiService_CreateOauthProviders: { + parameters: { + body: { + body: definitions["v1CreateOauthProvidersRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Create new Policies */ + PublicApiService_CreatePolicies: { + parameters: { + body: { + body: definitions["v1CreatePoliciesRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Create a new Policy */ + PublicApiService_CreatePolicy: { + parameters: { + body: { + body: definitions["v1CreatePolicyRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Create a private key tag and add it to private keys. */ + PublicApiService_CreatePrivateKeyTag: { + parameters: { + body: { + body: definitions["v1CreatePrivateKeyTagRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Create new Private Keys */ + PublicApiService_CreatePrivateKeys: { + parameters: { + body: { + body: definitions["v1CreatePrivateKeysRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Create a read only session for a user (valid for 1 hour) */ + PublicApiService_CreateReadOnlySession: { + parameters: { + body: { + body: definitions["v1CreateReadOnlySessionRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Create a read write session for a user */ + PublicApiService_CreateReadWriteSession: { + parameters: { + body: { + body: definitions["v1CreateReadWriteSessionRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Create a new Sub-Organization */ + PublicApiService_CreateSubOrganization: { + parameters: { + body: { + body: definitions["v1CreateSubOrganizationRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Create a user tag and add it to users. */ + PublicApiService_CreateUserTag: { + parameters: { + body: { + body: definitions["v1CreateUserTagRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Create Users in an existing Organization */ + PublicApiService_CreateUsers: { + parameters: { + body: { + body: definitions["v1CreateUsersRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Create a Wallet and derive addresses */ + PublicApiService_CreateWallet: { + parameters: { + body: { + body: definitions["v1CreateWalletRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Derive additional addresses using an existing wallet */ + PublicApiService_CreateWalletAccounts: { + parameters: { + body: { + body: definitions["v1CreateWalletAccountsRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Remove api keys from a User */ + PublicApiService_DeleteApiKeys: { + parameters: { + body: { + body: definitions["v1DeleteApiKeysRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Remove authenticators from a User */ + PublicApiService_DeleteAuthenticators: { + parameters: { + body: { + body: definitions["v1DeleteAuthenticatorsRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Delete an existing Invitation */ + PublicApiService_DeleteInvitation: { + parameters: { + body: { + body: definitions["v1DeleteInvitationRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Removes Oauth providers for a specified user - BETA */ + PublicApiService_DeleteOauthProviders: { + parameters: { + body: { + body: definitions["v1DeleteOauthProvidersRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Delete an existing Policy */ + PublicApiService_DeletePolicy: { + parameters: { + body: { + body: definitions["v1DeletePolicyRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Delete Private Key Tags within an Organization */ + PublicApiService_DeletePrivateKeyTags: { + parameters: { + body: { + body: definitions["v1DeletePrivateKeyTagsRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Deletes private keys for an organization */ + PublicApiService_DeletePrivateKeys: { + parameters: { + body: { + body: definitions["v1DeletePrivateKeysRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Deletes a sub organization */ + PublicApiService_DeleteSubOrganization: { + parameters: { + body: { + body: definitions["v1DeleteSubOrganizationRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Delete User Tags within an Organization */ + PublicApiService_DeleteUserTags: { + parameters: { + body: { + body: definitions["v1DeleteUserTagsRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Delete Users within an Organization */ + PublicApiService_DeleteUsers: { + parameters: { + body: { + body: definitions["v1DeleteUsersRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Deletes wallets for an organization */ + PublicApiService_DeleteWallets: { + parameters: { + body: { + body: definitions["v1DeleteWalletsRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Authenticate a user via Email */ + PublicApiService_EmailAuth: { + parameters: { + body: { + body: definitions["v1EmailAuthRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Exports a Private Key */ + PublicApiService_ExportPrivateKey: { + parameters: { + body: { + body: definitions["v1ExportPrivateKeyRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Exports a Wallet */ + PublicApiService_ExportWallet: { + parameters: { + body: { + body: definitions["v1ExportWalletRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Exports a Wallet Account */ + PublicApiService_ExportWalletAccount: { + parameters: { + body: { + body: definitions["v1ExportWalletAccountRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Imports a private key */ + PublicApiService_ImportPrivateKey: { + parameters: { + body: { + body: definitions["v1ImportPrivateKeyRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Imports a wallet */ + PublicApiService_ImportWallet: { + parameters: { + body: { + body: definitions["v1ImportWalletRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Initializes a new private key import */ + PublicApiService_InitImportPrivateKey: { + parameters: { + body: { + body: definitions["v1InitImportPrivateKeyRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Initializes a new wallet import */ + PublicApiService_InitImportWallet: { + parameters: { + body: { + body: definitions["v1InitImportWalletRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Initiate a Generic OTP activity */ + PublicApiService_InitOtp: { + parameters: { + body: { + body: definitions["v1InitOtpRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Initiate an OTP auth activity */ + PublicApiService_InitOtpAuth: { + parameters: { + body: { + body: definitions["v1InitOtpAuthRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Initializes a new email recovery */ + PublicApiService_InitUserEmailRecovery: { + parameters: { + body: { + body: definitions["v1InitUserEmailRecoveryRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Authenticate a user with an Oidc token (Oauth) - BETA */ + PublicApiService_Oauth: { + parameters: { + body: { + body: definitions["v1OauthRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Create an Oauth session for a user */ + PublicApiService_OauthLogin: { + parameters: { + body: { + body: definitions["v1OauthLoginRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Authenticate a user with an OTP code sent via email or SMS */ + PublicApiService_OtpAuth: { + parameters: { + body: { + body: definitions["v1OtpAuthRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Create an OTP session for a user */ + PublicApiService_OtpLogin: { + parameters: { + body: { + body: definitions["v1OtpLoginRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Completes the process of recovering a user by adding an authenticator */ + PublicApiService_RecoverUser: { + parameters: { + body: { + body: definitions["v1RecoverUserRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Reject an Activity */ + PublicApiService_RejectActivity: { + parameters: { + body: { + body: definitions["v1RejectActivityRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Removes an organization feature. This activity must be approved by the current root quorum. */ + PublicApiService_RemoveOrganizationFeature: { + parameters: { + body: { + body: definitions["v1RemoveOrganizationFeatureRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Sets an organization feature. This activity must be approved by the current root quorum. */ + PublicApiService_SetOrganizationFeature: { + parameters: { + body: { + body: definitions["v1SetOrganizationFeatureRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Sign a raw payload */ + PublicApiService_SignRawPayload: { + parameters: { + body: { + body: definitions["v1SignRawPayloadRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Sign multiple raw payloads with the same signing parameters */ + PublicApiService_SignRawPayloads: { + parameters: { + body: { + body: definitions["v1SignRawPayloadsRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Sign a transaction */ + PublicApiService_SignTransaction: { + parameters: { + body: { + body: definitions["v1SignTransactionRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Create a session for a user through stamping client side (api key, wallet client, or passkey client) */ + PublicApiService_StampLogin: { + parameters: { + body: { + body: definitions["v1StampLoginRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Update an existing Policy */ + PublicApiService_UpdatePolicy: { + parameters: { + body: { + body: definitions["v1UpdatePolicyRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Update human-readable name or associated private keys. Note that this activity is atomic: all of the updates will succeed at once, or all of them will fail. */ + PublicApiService_UpdatePrivateKeyTag: { + parameters: { + body: { + body: definitions["v1UpdatePrivateKeyTagRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Set the threshold and members of the root quorum. This activity must be approved by the current root quorum. */ + PublicApiService_UpdateRootQuorum: { + parameters: { + body: { + body: definitions["v1UpdateRootQuorumRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Update a User in an existing Organization */ + PublicApiService_UpdateUser: { + parameters: { + body: { + body: definitions["v1UpdateUserRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Update human-readable name or associated users. Note that this activity is atomic: all of the updates will succeed at once, or all of them will fail. */ + PublicApiService_UpdateUserTag: { + parameters: { + body: { + body: definitions["v1UpdateUserTagRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Update a wallet for an organization */ + PublicApiService_UpdateWallet: { + parameters: { + body: { + body: definitions["v1UpdateWalletRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Verify a Generic OTP */ + PublicApiService_VerifyOtp: { + parameters: { + body: { + body: definitions["v1VerifyOtpRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + PublicApiService_NOOPCodegenAnchor: { + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1NOOPCodegenAnchorResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Set a rate local rate limit just on the current endpoint, for purposes of testing with Vivosuite */ + PublicApiService_TestRateLimits: { + parameters: { + body: { + body: definitions["v1TestRateLimitsRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1TestRateLimitsResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; +}; + +export type external = {}; diff --git a/packages/sdk-js/src/__polyfills__/window.ts b/packages/sdk-js/src/__polyfills__/window.ts new file mode 100644 index 000000000..50aacef27 --- /dev/null +++ b/packages/sdk-js/src/__polyfills__/window.ts @@ -0,0 +1,25 @@ +const loadWindow = () => { + if (typeof window !== "undefined") { + return window; + } else { + return { + localStorage: { + getItem: (_key: string): string | null => { + return null; + }, + setItem: (_key: string, _value: string) => {}, + removeItem: (_key: string) => {}, + clear: () => {}, + key: (_index: number): string | null => { + return null; + }, + length: 0, + }, + location: { + hostname: "", + }, + }; + } +}; + +export default loadWindow(); diff --git a/packages/sdk-js/src/__types__/base.ts b/packages/sdk-js/src/__types__/base.ts new file mode 100644 index 000000000..fb929a08e --- /dev/null +++ b/packages/sdk-js/src/__types__/base.ts @@ -0,0 +1,167 @@ +import type { TActivityId, TActivityStatus } from "@turnkey/http"; +import type { WalletInterface, WalletStamper } from "@turnkey/wallet-stamper"; +import type { WebauthnStamper } from "@turnkey/webauthn-stamper"; +import type { IndexedDbStamper } from "@turnkey/indexed-db-stamper"; +import type { SessionType } from "@turnkey/sdk-types"; + +export type GrpcStatus = { + message: string; + code: number; + details: unknown[] | null; +}; + +export enum MethodType { + Get, + List, + Command, +} + +export type TStamp = { + stampHeaderName: string; + stampHeaderValue: string; +}; + +export interface TStamper { + stamp: (input: string) => Promise; +} + +export type THttpConfig = { + baseUrl: string; +}; + +export class TurnkeyRequestError extends Error { + details: any[] | null; + code: number; + + constructor(input: GrpcStatus) { + let turnkeyErrorMessage = `Turnkey error ${input.code}: ${input.message}`; + + if (input.details != null) { + turnkeyErrorMessage += ` (Details: ${JSON.stringify(input.details)})`; + } + + super(turnkeyErrorMessage); + + this.name = "TurnkeyRequestError"; + this.details = input.details ?? null; + this.code = input.code; + } +} + +export interface ActivityResponse { + activity: { + id: TActivityId; + status: TActivityStatus; + result: Record; + }; +} + +export interface ActivityMetadata { + activity: { + id: TActivityId; + status: TActivityStatus; + }; +} + +export type TActivityPollerConfig = { + intervalMs: number; + numRetries: number; +}; + +interface BaseSDKClientConfig { + apiBaseUrl: string; + organizationId: string; + activityPoller?: TActivityPollerConfig | undefined; +} + +interface SDKClientConfigWithStamper extends BaseSDKClientConfig { + stamper: TStamper; + passkeyStamper?: TStamper; + readOnlySession?: never; +} + +interface SDKClientConfigWithReadOnlySession extends BaseSDKClientConfig { + stamper?: never; + passkeyStamper?: TStamper; + readOnlySession: string; +} + +export type TurnkeySDKClientConfig = + | SDKClientConfigWithStamper + | SDKClientConfigWithReadOnlySession; + +export interface TurnkeySDKBrowserConfig { + apiBaseUrl: string; + defaultOrganizationId: string; + rpId?: string; + serverSignUrl?: string; + iframeUrl?: string; + dangerouslyOverrideIframeKeyTtl?: number; +} + +export type Stamper = WebauthnStamper | WalletStamper | IndexedDbStamper; + +export type queryOverrideParams = { + organizationId?: string; +}; + +export type commandOverrideParams = { + organizationId?: string; + timestampMs?: string; +}; + +export interface IframeClientParams { + iframeContainer: HTMLElement | null | undefined; + iframeUrl: string; + iframeElementId?: string; + dangerouslyOverrideIframeKeyTtl?: number; +} + +export interface PasskeyClientParams { + rpId?: string; + timeout?: number; + userVerification?: UserVerificationRequirement; + allowCredentials?: PublicKeyCredentialDescriptor[]; +} + +export interface RefreshSessionParams { + sessionType: SessionType; + expirationSeconds?: string | undefined; + publicKey?: string; +} + +export interface LoginWithBundleParams { + bundle: string; + expirationSeconds?: string; +} + +export interface LoginWithPasskeyParams { + sessionType: SessionType; + expirationSeconds?: string | undefined; + publicKey?: string; +} + +export interface LoginWithWalletParams { + sessionType: SessionType; + expirationSeconds?: string | undefined; + publicKey?: string; +} + +export interface TurnkeyWalletClientConfig extends SDKClientConfigWithStamper { + wallet: WalletInterface; +} + +/** + * The Client used to authenticate the user. + */ +export enum AuthClient { + Passkey = "passkey", + Wallet = "wallet", + Iframe = "iframe", + IndexedDb = "indexed-db", +} + +export enum StamperType { + IndexedDB = "indexed-db", + Passkey = "passkey", +} diff --git a/packages/sdk-js/src/index.ts b/packages/sdk-js/src/index.ts new file mode 100644 index 000000000..c6a3bc766 --- /dev/null +++ b/packages/sdk-js/src/index.ts @@ -0,0 +1,105 @@ +// marked as internal to prevent inclusion in the sdk-browser docs + +/** @internal */ +export { + ApiKeyStamper, + signWithApiKey, + type TApiKeyStamperConfig, +} from "@turnkey/api-key-stamper"; + +// marked as internal to prevent inclusion in the sdk-browser docs +/** @internal */ +export { + type TWebauthnStamperConfig, + WebauthnStamper, +} from "@turnkey/webauthn-stamper"; + +export { TurnkeyClient } from "./__clients__/core"; + +// export { getStorageValue, setStorageValue, StorageKeys } from "@storage"; + +// marked as internal to prevent inclusion in the sdk-browser docs +/** @internal */ +// export { +// defaultEthereumAccountAtIndex, +// DEFAULT_ETHEREUM_ACCOUNTS, +// defaultCosmosAccountAtIndex, +// DEFAULT_COSMOS_ACCOUNTS, +// defaultTronAccountAtIndex, +// DEFAULT_TRON_ACCOUNTS, +// defaultBitcoinMainnetP2PKHAccountAtIndex, +// DEFAULT_BITCOIN_MAINNET_P2PKH_ACCOUNTS, +// defaultBitcoinMainnetP2WPKHAccountAtIndex, +// DEFAULT_BITCOIN_MAINNET_P2WPKH_ACCOUNTS, +// defaultBitcoinMainnetP2WSHAccountAtIndex, +// DEFAULT_BITCOIN_MAINNET_P2WSH_ACCOUNTS, +// defaultBitcoinMainnetP2TRAccountAtIndex, +// DEFAULT_BITCOIN_MAINNET_P2TR_ACCOUNTS, +// defaultBitcoinMainnetP2SHAccountAtIndex, +// DEFAULT_BITCOIN_MAINNET_P2SH_ACCOUNTS, +// defaultBitcoinTestnetP2PKHAccountAtIndex, +// DEFAULT_BITCOIN_TESTNET_P2PKH_ACCOUNTS, +// defaultBitcoinTestnetP2WPKHAccountAtIndex, +// DEFAULT_BITCOIN_TESTNET_P2WPKH_ACCOUNTS, +// defaultBitcoinTestnetP2WSHAccountAtIndex, +// DEFAULT_BITCOIN_TESTNET_P2WSH_ACCOUNTS, +// defaultBitcoinTestnetP2TRAccountAtIndex, +// DEFAULT_BITCOIN_TESTNET_P2TR_ACCOUNTS, +// defaultBitcoinTestnetP2SHAccountAtIndex, +// DEFAULT_BITCOIN_TESTNET_P2SH_ACCOUNTS, +// defaultBitcoinSignetP2PKHAccountAtIndex, +// DEFAULT_BITCOIN_SIGNET_P2PKH_ACCOUNTS, +// defaultBitcoinSignetP2WPKHAccountAtIndex, +// DEFAULT_BITCOIN_SIGNET_P2WPKH_ACCOUNTS, +// defaultBitcoinSignetP2WSHAccountAtIndex, +// DEFAULT_BITCOIN_SIGNET_P2WSH_ACCOUNTS, +// defaultBitcoinSignetP2TRAccountAtIndex, +// DEFAULT_BITCOIN_SIGNET_P2TR_ACCOUNTS, +// defaultBitcoinSignetP2SHAccountAtIndex, +// DEFAULT_BITCOIN_SIGNET_P2SH_ACCOUNTS, +// defaultBitcoinRegtestP2PKHAccountAtIndex, +// DEFAULT_BITCOIN_REGTEST_P2PKH_ACCOUNTS, +// defaultBitcoinRegtestP2WPKHAccountAtIndex, +// DEFAULT_BITCOIN_REGTEST_P2WPKH_ACCOUNTS, +// defaultBitcoinRegtestP2WSHAccountAtIndex, +// DEFAULT_BITCOIN_REGTEST_P2WSH_ACCOUNTS, +// defaultBitcoinRegtestP2TRAccountAtIndex, +// DEFAULT_BITCOIN_REGTEST_P2TR_ACCOUNTS, +// defaultBitcoinRegtestP2SHAccountAtIndex, +// DEFAULT_BITCOIN_REGTEST_P2SH_ACCOUNTS, +// defaultDogeMainnetAccountAtIndex, +// DEFAULT_DOGE_MAINNET_ACCOUNTS, +// defaultDogeTestnetAccountAtIndex, +// DEFAULT_DOGE_TESTNET_ACCOUNTS, +// defaultSeiAccountAtIndex, +// DEFAULT_SEI_ACCOUNTS, +// defaultXrpAccountAtIndex, +// defaultSolanaAccountAtIndex, +// DEFAULT_SOLANA_ACCOUNTS, +// defaultSuiAccountAtIndex, +// DEFAULT_SUI_ACCOUNTS, +// defaultAptosAccountAtIndex, +// DEFAULT_APTOS_ACCOUNTS, +// defaultXlmAccountAtIndex, +// DEFAULT_XLM_ACCOUNTS, +// defaultTonV3r2AccountAtIndex, +// DEFAULT_TON_V3R2_ACCOUNTS, +// defaultTonV4r2AccountAtIndex, +// DEFAULT_TON_V4R2_ACCOUNTS, +// } from "./turnkey-helpers"; + +// marked as internal to prevent inclusion in the sdk-browser docs +/** @internal */ +// export type { WalletAccount } from "./turnkey-helpers"; + +// Export all types and values from __types__/base +export * from "./__types__/base"; + +// Export all models from models +// export * from "@models"; + +// export { type Session, SessionType } from "@turnkey/sdk-types"; + +// marked as internal to prevent inclusion in the sdk-browser docs +/** @internal */ +export type * as TurnkeySDKApiTypes from "./__generated__/sdk_api_types"; diff --git a/packages/sdk-js/src/storage.ts b/packages/sdk-js/src/storage.ts new file mode 100644 index 000000000..d18b8c752 --- /dev/null +++ b/packages/sdk-js/src/storage.ts @@ -0,0 +1,75 @@ +import type { Session } from "@turnkey/sdk-types"; +import WindowWrapper from "@polyfills/window"; +import type { AuthClient } from "./__types__/base"; + +export enum StorageKeys { + Session = "@turnkey/session/v2", + Client = "@turnkey/client", +} + +interface StorageValue { + [StorageKeys.Session]: string | Session; + [StorageKeys.Client]: AuthClient; +} + +enum StorageLocation { + Local = "local", + Secure = "secure", + Session = "session", +} + +const STORAGE_VALUE_LOCATIONS: Record = { + [StorageKeys.Session]: StorageLocation.Session, + [StorageKeys.Client]: StorageLocation.Session, +}; + +const STORAGE_LOCATIONS = { + [StorageLocation.Local]: WindowWrapper.localStorage, + [StorageLocation.Secure]: WindowWrapper.localStorage, + [StorageLocation.Session]: WindowWrapper.localStorage, +}; + +export const getStorageValue = async ( + storageKey: K +): Promise => { + const storageLocation: StorageLocation = STORAGE_VALUE_LOCATIONS[storageKey]; + const browserStorageLocation: Storage = STORAGE_LOCATIONS[storageLocation]; + const storageItem = browserStorageLocation.getItem(storageKey); + return storageItem ? JSON.parse(storageItem) : undefined; +}; + +export const setStorageValue = async ( + storageKey: K, + storageValue: StorageValue[K] +): Promise => { + const storageLocation: StorageLocation = STORAGE_VALUE_LOCATIONS[storageKey]; + const browserStorageLocation: Storage = STORAGE_LOCATIONS[storageLocation]; + browserStorageLocation.setItem(storageKey, JSON.stringify(storageValue)); +}; + +export const removeStorageValue = async ( + storageKey: K +): Promise => { + const storageLocation: StorageLocation = STORAGE_VALUE_LOCATIONS[storageKey]; + const browserStorageLocation: Storage = STORAGE_LOCATIONS[storageLocation]; + browserStorageLocation.removeItem(storageKey); +}; + +/** + * Saves a session and client to storage. + * + * @param {Session} session - The session response containing session details. + * @param {AuthClient} authClient - The authentication client used for the session. + * @throws Will throw an error if the authentication client is not set. + * @returns {Promise} A promise that resolves when the session is saved. + */ + +export const storeSession = async ( + session: string | Session, + client?: AuthClient +) => { + await setStorageValue(StorageKeys.Session, session); + if (client) { + await setStorageValue(StorageKeys.Client, client); + } +}; diff --git a/packages/sdk-js/src/utils.ts b/packages/sdk-js/src/utils.ts new file mode 100644 index 000000000..3d318b2aa --- /dev/null +++ b/packages/sdk-js/src/utils.ts @@ -0,0 +1,141 @@ +import { uint8ArrayFromHexString } from "@turnkey/encoding"; +import { + generateP256KeyPair, + buildAdditionalAssociatedData, + compressRawPublicKey, +} from "@turnkey/crypto"; + +import { Buffer } from "buffer"; +import bs58check from "bs58check"; +import { AeadId, CipherSuite, KdfId, KemId } from "hpke-js"; + +import type { EmbeddedAPIKey } from "./models"; +import { pointDecode } from "@turnkey/api-key-stamper"; +import type { Session } from "@turnkey/sdk-types"; + +// createEmbeddedAPIKey creates an embedded API key encrypted to a target key (typically embedded within an iframe). +// This returns a bundle that can be decrypted by that target key, as well as the public key of the newly created API key. +export const createEmbeddedAPIKey = async ( + targetPublicKey: string, +): Promise => { + const TURNKEY_HPKE_INFO = new TextEncoder().encode("turnkey_hpke"); + + // 1: create new API key (to be encrypted to the targetPublicKey) + const p256key = generateP256KeyPair(); + + // 2: set up encryption + const suite = new CipherSuite({ + kem: KemId.DhkemP256HkdfSha256, + kdf: KdfId.HkdfSha256, + aead: AeadId.Aes256Gcm, + }); + + // 3: import the targetPublicKey (i.e. passed in from the iframe) + const targetKeyBytes = uint8ArrayFromHexString(targetPublicKey); + + let jwk; + try { + jwk = pointDecode(targetKeyBytes); + } catch (e) { + // provide more context about the error that is being thrown + throw new Error( + `target public key is not a valid compressed public key: ${targetPublicKey}`, + ); + } + + const targetKey = await crypto.subtle.importKey( + "jwk", + jwk, + { + name: "ECDH", + namedCurve: "P-256", + }, + true, + [], + ); + + // 4: sender encrypts a message to the target key + const sender = await suite.createSenderContext({ + recipientPublicKey: targetKey, + info: TURNKEY_HPKE_INFO, + }); + const ciphertext = await sender.seal( + uint8ArrayFromHexString(p256key.privateKey), + buildAdditionalAssociatedData(new Uint8Array(sender.enc), targetKeyBytes), + ); + const ciphertextUint8Array = new Uint8Array(ciphertext); + + // 5: assemble bundle + const encappedKey = new Uint8Array(sender.enc); + const compressedEncappedKey = compressRawPublicKey(encappedKey); + const result = new Uint8Array( + compressedEncappedKey.length + ciphertextUint8Array.length, + ); + result.set(compressedEncappedKey); + result.set(ciphertextUint8Array, compressedEncappedKey.length); + + const base58encodedBundle = bs58check.encode(result); + + return { + authBundle: base58encodedBundle, + publicKey: p256key.publicKey, + }; +}; + +export const generateRandomBuffer = (): ArrayBuffer => { + const arr = new Uint8Array(32); + crypto.getRandomValues(arr); + return arr.buffer; +}; + +export const base64UrlEncode = (challenge: ArrayBuffer): string => { + return Buffer.from(challenge) + .toString("base64") + .replace(/\+/g, "-") + .replace(/\//g, "_") + .replace(/=/g, ""); +}; + +const hexByByte = Array.from({ length: 256 }, (_, i) => + i.toString(16).padStart(2, "0"), +); + +export const bytesToHex = (bytes: Uint8Array): string => { + let hex = "0x"; + if (bytes === undefined || bytes.length === 0) return hex; + for (const byte of bytes) { + hex += hexByByte[byte]; + } + return hex; +}; + +export function parseSession(token: string | Session): Session { + if (typeof token !== "string") { + return token; + } + const [, payload] = token.split("."); + if (!payload) { + throw new Error("Invalid JWT: Missing payload"); + } + + const decoded = JSON.parse(atob(payload)); + const { + exp, + public_key: publicKey, + session_type: sessionType, + user_id: userId, + organization_id: organizationId, + } = decoded; + + if (!exp || !publicKey || !sessionType || !userId || !organizationId) { + throw new Error("JWT payload missing required fields"); + } + + return { + sessionType, + userId, + organizationId, + expiry: exp, + token: publicKey, + }; +} diff --git a/packages/sdk-js/tsconfig.json b/packages/sdk-js/tsconfig.json new file mode 100644 index 000000000..323133555 --- /dev/null +++ b/packages/sdk-js/tsconfig.json @@ -0,0 +1,25 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "outDir": "./dist", + "rootDir": "./src", + "tsBuildInfoFile": "./.cache/.tsbuildinfo", + "lib": ["dom"], + "paths": { + "@polyfills/*": ["./src/__polyfills__/*"], + "@constants": ["./src/constants"], + "@models": ["./src/models"], + "@storage": ["./src/storage"], + "@types": ["./src/__types__/base"], + "@utils": ["./src/utils"] + } + }, + "include": ["src/**/*.ts", "src/**/*.js", "src/**/*.json"], + "exclude": ["**/__tests__/**/*", "**/__fixtures__/**/*"], + "references": [ + { "path": "../api-key-stamper" }, + { "path": "../http" }, + { "path": "../iframe-stamper" }, + { "path": "../webauthn-stamper" } + ] +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b1d11ff10..a9e439a66 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1294,6 +1294,66 @@ importers: specifier: ^2.4.2 version: 2.4.9 + examples/with-sdk-js: + dependencies: + '@turnkey/sdk-js': + specifier: workspace:* + version: link:../../packages/sdk-js + '@turnkey/sdk-react': + specifier: workspace:* + version: link:../../packages/sdk-react + '@turnkey/sdk-server': + specifier: workspace:* + version: link:../../packages/sdk-server + '@turnkey/sdk-types': + specifier: workspace:* + version: link:../../packages/sdk-types + '@types/node': + specifier: 20.3.1 + version: 20.3.1 + '@types/react': + specifier: 18.2.14 + version: 18.2.14 + '@types/react-dom': + specifier: 18.2.6 + version: 18.2.6 + axios: + specifier: '>1.8.2' + version: 1.8.3 + encoding: + specifier: ^0.1.13 + version: 0.1.13 + eslint: + specifier: 8.56.0 + version: 8.56.0 + eslint-config-next: + specifier: 14.2.25 + version: 14.2.25(eslint@8.56.0)(typescript@5.1.3) + esm: + specifier: ^3.2.25 + version: 3.2.25 + install: + specifier: ^0.13.0 + version: 0.13.0 + next: + specifier: ^14.2.25 + version: 14.2.25(@babel/core@7.26.9)(react-dom@18.2.0)(react@18.2.0) + npm: + specifier: ^9.7.2 + version: 9.7.2 + react: + specifier: 18.2.0 + version: 18.2.0 + react-dom: + specifier: 18.2.0 + version: 18.2.0(react@18.2.0) + react-hook-form: + specifier: ^7.45.1 + version: 7.45.1(react@18.2.0) + typescript: + specifier: 5.1.3 + version: 5.1.3 + examples/with-sdk-server: dependencies: '@turnkey/sdk-server': @@ -2091,6 +2151,52 @@ importers: specifier: 5.4.3 version: 5.4.3 + packages/sdk-js: + dependencies: + '@turnkey/api-key-stamper': + specifier: workspace:* + version: link:../api-key-stamper + '@turnkey/crypto': + specifier: workspace:* + version: link:../crypto + '@turnkey/encoding': + specifier: workspace:* + version: link:../encoding + '@turnkey/http': + specifier: workspace:* + version: link:../http + '@turnkey/indexed-db-stamper': + specifier: workspace:* + version: link:../indexed-db-stamper + '@turnkey/sdk-types': + specifier: workspace:* + version: link:../sdk-types + '@turnkey/wallet-stamper': + specifier: workspace:* + version: link:../wallet-stamper + '@turnkey/webauthn-stamper': + specifier: workspace:* + version: link:../webauthn-stamper + bs58check: + specifier: 3.0.1 + version: 3.0.1 + buffer: + specifier: ^6.0.3 + version: 6.0.3 + cross-fetch: + specifier: ^3.1.5 + version: 3.1.5 + hpke-js: + specifier: ^1.2.7 + version: 1.2.7 + devDependencies: + glob: + specifier: ^8.0.3 + version: 8.1.0 + typescript: + specifier: 5.4.3 + version: 5.4.3 + packages/sdk-react: dependencies: '@emotion/react': @@ -24713,10 +24819,26 @@ snapshots: inherits: 2.0.4 minimatch: 5.1.6 once: 1.4.0 + path-is-absolute: 1.0.1 - globals@11.12.0: {} + /glob@8.1.0: + resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} + engines: {node: '>=12'} + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 5.0.1 + once: 1.4.0 + dev: true - globals@13.24.0: + /globals@11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + + /globals@13.20.0: + resolution: {integrity: sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==} + engines: {node: '>=8'} dependencies: type-fest: 0.20.2 From 6272ce145f4fb3465b4effb79674e35ebd444944 Mon Sep 17 00:00:00 2001 From: Amir Cheikh Date: Mon, 9 Jun 2025 16:02:36 -0400 Subject: [PATCH 002/184] Cross platform session management init --- .codesandbox/ci.json | 3 +- examples/with-sdk-js/src/app/page.tsx | 7 +- packages/sdk-js/package.json | 11 +- packages/sdk-js/scripts/codegen.js | 79 +- packages/sdk-js/src/__clients__/core.ts | 166 +- .../src/__generated__/sdk-client-base.ts | 3618 +++++++++++------ .../sdk-js/src/__generated__/sdk_api_types.ts | 726 +++- packages/sdk-js/src/__storage__/base.ts | 52 + .../sdk-js/src/__storage__/mobile/storage.ts | 58 + .../sdk-js/src/__storage__/web/storage.ts | 33 + packages/sdk-js/src/__types__/base.ts | 58 +- packages/sdk-js/src/storage.ts | 75 - packages/sdk-js/src/utils.ts | 82 +- pnpm-lock.yaml | 6 +- 14 files changed, 3338 insertions(+), 1636 deletions(-) create mode 100644 packages/sdk-js/src/__storage__/base.ts create mode 100644 packages/sdk-js/src/__storage__/mobile/storage.ts create mode 100644 packages/sdk-js/src/__storage__/web/storage.ts delete mode 100644 packages/sdk-js/src/storage.ts diff --git a/.codesandbox/ci.json b/.codesandbox/ci.json index bc92c473c..a1eb1d97d 100644 --- a/.codesandbox/ci.json +++ b/.codesandbox/ci.json @@ -19,7 +19,8 @@ "packages/iframe-stamper", "packages/crypto", "packages/react-native-passkey-stamper", - "packages/telegram-cloud-storage-stamper" + "packages/telegram-cloud-storage-stamper", + "packages/sdk-js" ], "sandboxes": ["/examples/react-components"], "node": "20" diff --git a/examples/with-sdk-js/src/app/page.tsx b/examples/with-sdk-js/src/app/page.tsx index cde31302f..a3c92479e 100644 --- a/examples/with-sdk-js/src/app/page.tsx +++ b/examples/with-sdk-js/src/app/page.tsx @@ -23,7 +23,7 @@ export default function AuthPage() { }, }); - await turnkeyClient.indexedDBStamper?.init(); + await turnkeyClient.init(); setClient(turnkeyClient); }; @@ -31,10 +31,9 @@ export default function AuthPage() { }, []); const passkey = async () => { - const resp = await client?.httpClient.getWhoami({}, StamperType.Passkey); - console.log("Response from getWhoami:", resp); + await client?.loginWithPasskey({}); + //const resp = await client?.httpClient.getWhoami({}, StamperType.Passkey); }; - const indexedDB = async () => { const resp = await client?.httpClient.getWhoami({}); console.log("Response from getWhoami:", resp); diff --git a/packages/sdk-js/package.json b/packages/sdk-js/package.json index 59310a2cb..019155de3 100644 --- a/packages/sdk-js/package.json +++ b/packages/sdk-js/package.json @@ -31,13 +31,20 @@ "@turnkey/sdk-types": "workspace:*", "bs58check": "3.0.1", "buffer": "^6.0.3", - "cross-fetch": "^3.1.5", - "hpke-js": "^1.2.7" + "cross-fetch": "^3.1.5" }, "devDependencies": { "glob": "^8.0.3", "typescript": "5.4.3" }, + "peerDependencies": { + "react-native-keychain": "^8.1.0 || ^9.2.2 || ^10.0.0" + }, + "peerDependenciesMeta": { + "react-native-keychain": { + "optional": true + } + }, "engines": { "node": ">=18.0.0" }, diff --git a/packages/sdk-js/scripts/codegen.js b/packages/sdk-js/scripts/codegen.js index 224d62f38..a3327871a 100644 --- a/packages/sdk-js/scripts/codegen.js +++ b/packages/sdk-js/scripts/codegen.js @@ -266,12 +266,14 @@ const generateSDKClientFromSwagger = async (swaggerSpec, targetPath) => { imports.push('import type * as SdkApiTypes from "./sdk_api_types";'); - imports.push('import { StorageKeys, getStorageValue } from "../storage";'); + imports.push( + 'import { StorageBase, StorageKey } from "../__storage__/base";', + ); imports.push('import { parseSession } from "../utils";'); imports.push('import { StamperType } from "../__types__/base";'); - codeBuffer.push(` + codeBuffer.push(` export class TurnkeySDKClientBase { config: TurnkeySDKClientConfig; @@ -281,9 +283,13 @@ const generateSDKClientFromSwagger = async (swaggerSpec, targetPath) => { // Store stampers private indexedDBStamper?: TStamper | undefined; private passkeyStamper?: TStamper | undefined; + + // Storage manager + private storageManager?: StorageBase | undefined; constructor(config: TurnkeySDKClientConfig) { this.config = config; + if (config.stamper) { this.stamper = config.stamper; // Store as default IndexedDB stamper @@ -292,6 +298,9 @@ const generateSDKClientFromSwagger = async (swaggerSpec, targetPath) => { if (config.passkeyStamper) { this.passkeyStamper = config.passkeyStamper; } + if (config.storageManager) { + this.storageManager = config.storageManager; + } } private getStamper(stampWith?: StamperType): TStamper | undefined { @@ -445,37 +454,37 @@ const generateSDKClientFromSwagger = async (swaggerSpec, targetPath) => { const inputType = `T${operationNameWithoutNamespace}Body`; const responseType = `T${operationNameWithoutNamespace}Response`; -// For query methods -if (methodType === "query") { - codeBuffer.push( - `\n\t${methodName} = async (input: SdkApiTypes.${inputType}${ - METHODS_WITH_ONLY_OPTIONAL_PARAMETERS.includes(methodName) - ? " = {}" - : "" - }, stampWith?: StamperType): Promise => { - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); + // For query methods + if (methodType === "query") { + codeBuffer.push( + `\n\t${methodName} = async (input: SdkApiTypes.${inputType}${ + METHODS_WITH_ONLY_OPTIONAL_PARAMETERS.includes(methodName) + ? " = {}" + : "" + }, stampWith?: StamperType): Promise => { + let session = await this.storageManager?.getStorageValue(StorageKey.Session); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request("${endpointPath}", { ...input, organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId }, stampWith); }`, - ); - } else if (methodType === "command") { - // For command methods - const unversionedActivityType = `ACTIVITY_TYPE_${operationNameWithoutNamespace - .replace(/([a-z])([A-Z])/g, "$1_$2") - .toUpperCase()}`; - const versionedActivityType = - VERSIONED_ACTIVITY_TYPES[unversionedActivityType]; - - const resultKey = operationNameWithoutNamespace + "Result"; - const versionedMethodName = latestVersions[resultKey].formattedKeyName; - - codeBuffer.push( - `\n\t${methodName} = async (input: SdkApiTypes.${inputType}, stampWith?: StamperType): Promise => { + ); + } else if (methodType === "command") { + // For command methods + const unversionedActivityType = `ACTIVITY_TYPE_${operationNameWithoutNamespace + .replace(/([a-z])([A-Z])/g, "$1_$2") + .toUpperCase()}`; + const versionedActivityType = + VERSIONED_ACTIVITY_TYPES[unversionedActivityType]; + + const resultKey = operationNameWithoutNamespace + "Result"; + const versionedMethodName = latestVersions[resultKey].formattedKeyName; + + codeBuffer.push( + `\n\t${methodName} = async (input: SdkApiTypes.${inputType}, stampWith?: StamperType): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); + let session = await this.storageManager?.getStorageValue(StorageKey.Session); session = parseSession(session!); return this.command("${endpointPath}", { @@ -485,13 +494,13 @@ if (methodType === "query") { type: "${versionedActivityType ?? unversionedActivityType}" }, "${versionedMethodName}", stampWith); }`, - ); - } else if (methodType === "activityDecision") { - // For activityDecision methods - codeBuffer.push( - `\n\t${methodName} = async (input: SdkApiTypes.${inputType}, stampWith?: StamperType): Promise => { + ); + } else if (methodType === "activityDecision") { + // For activityDecision methods + codeBuffer.push( + `\n\t${methodName} = async (input: SdkApiTypes.${inputType}, stampWith?: StamperType): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); + let session = await this.storageManager?.getStorageValue(StorageKey.Session); session = parseSession(session!); return this.activityDecision("${endpointPath}", { @@ -503,8 +512,8 @@ if (methodType === "query") { .toUpperCase()}" }, stampWith); }`, - ); - } + ); + } // generate a stamping method for each method codeBuffer.push( `\n\tstamp${operationNameWithoutNamespace} = async (input: SdkApiTypes.${inputType}): Promise => { diff --git a/packages/sdk-js/src/__clients__/core.ts b/packages/sdk-js/src/__clients__/core.ts index 248969c25..2263b491b 100644 --- a/packages/sdk-js/src/__clients__/core.ts +++ b/packages/sdk-js/src/__clients__/core.ts @@ -2,16 +2,31 @@ import { IndexedDbStamper } from "@turnkey/indexed-db-stamper"; import { TurnkeySDKClientBase } from "../__generated__/sdk-client-base"; import { WebauthnStamper } from "@turnkey/webauthn-stamper"; import WindowWrapper from "@polyfills/window"; +import { SessionType, Session } from "@turnkey/sdk-types"; +import { + LoginWithPasskeyParams, + DEFAULT_SESSION_EXPIRATION_IN_SECONDS, + Passkey, + StamperType, +} from "@types"; // AHHHH, SDK-TYPES +import { base64UrlEncode, generateRandomBuffer } from "@utils"; +import { getWebAuthnAttestation } from "@turnkey/http"; +import { createStorageManager, StorageBase } from "../__storage__/base"; export class TurnkeyClient { config: any; // Type TBD - httpClient: TurnkeySDKClientBase; + httpClient!: TurnkeySDKClientBase; + + // TODO (Amir): Make these private indexedDBStamper: IndexedDbStamper | undefined; passkeyStamper: WebauthnStamper | undefined; + + storageManager!: StorageBase; + constructor( config: any, indexedDBStamper?: IndexedDbStamper, - passkeyStamper?: WebauthnStamper + passkeyStamper?: WebauthnStamper, ) { this.config = config; this.indexedDBStamper = indexedDBStamper || new IndexedDbStamper(); @@ -30,12 +45,155 @@ export class TurnkeyClient { }), }); - this.indexedDBStamper.init(); + // storageManager will be initialized asynchronously + } + + async init() { + await this.indexedDBStamper?.init(); + this.storageManager = await createStorageManager(); this.httpClient = new TurnkeySDKClientBase({ stamper: this.indexedDBStamper, // Maybe we should rename this passkeyStamper: this.passkeyStamper, - ...config, + storageManager: this.storageManager, + ...this.config, }); } + + /** + * Create a passkey for an end-user, taking care of various lower-level details. + * + * @returns {Promise} + */ + createUserPasskey = async ( + config: Record = {}, + ): Promise => { + const challenge = generateRandomBuffer(); + const encodedChallenge = base64UrlEncode(challenge); + const authenticatorUserId = generateRandomBuffer(); + + // WebAuthn credential options options can be found here: + // https://www.w3.org/TR/webauthn-2/#sctn-sample-registration + // + // All pubkey algorithms can be found here: https://www.iana.org/assignments/cose/cose.xhtml#algorithms + // Turnkey only supports ES256 (-7) and RS256 (-257) + // + // The pubkey type only supports one value, "public-key" + // See https://www.w3.org/TR/webauthn-2/#enumdef-publickeycredentialtype for more details + // TODO: consider un-nesting these config params + const webauthnConfig: CredentialCreationOptions = { + publicKey: { + rp: { + id: config.publicKey?.rp?.id ?? this.passkeyStamper?.rpId, + name: config.publicKey?.rp?.name ?? "", + }, + challenge: config.publicKey?.challenge ?? challenge, + pubKeyCredParams: config.publicKey?.pubKeyCredParams ?? [ + { + type: "public-key", + alg: -7, + }, + { + type: "public-key", + alg: -257, + }, + ], + user: { + id: config.publicKey?.user?.id ?? authenticatorUserId, + name: config.publicKey?.user?.name ?? "Default User", + displayName: config.publicKey?.user?.displayName ?? "Default User", + }, + authenticatorSelection: { + authenticatorAttachment: + config.publicKey?.authenticatorSelection?.authenticatorAttachment ?? + undefined, // default to empty + requireResidentKey: + config.publicKey?.authenticatorSelection?.requireResidentKey ?? + true, + residentKey: + config.publicKey?.authenticatorSelection?.residentKey ?? "required", + userVerification: + config.publicKey?.authenticatorSelection?.userVerification ?? + this.passkeyStamper?.userVerification ?? + "preferred", + }, + }, + }; + + const attestation = await getWebAuthnAttestation(webauthnConfig); + + return { + encodedChallenge: config.publicKey?.challenge + ? base64UrlEncode(config.publicKey?.challenge) + : encodedChallenge, + attestation, + }; + }; + + /** + * Log in with a passkey. + * To be used in conjunction with a `passkeyStamper` + * + * @param LoginWithPasskeyParams + * @param params.sessionType - The type of session to create + * @param params.publicKey - The public key of indexedDb + * @param params.expirationSeconds - Expiration time for the session in seconds. Defaults to 900 seconds or 15 minutes. + * @returns {Promise} + */ + loginWithPasskey = async (params: LoginWithPasskeyParams): Promise => { + try { + await this.indexedDBStamper?.resetKeyPair(); + const { + sessionType = SessionType.READ_WRITE, + publicKey = this.indexedDBStamper?.getPublicKey(), + expirationSeconds = DEFAULT_SESSION_EXPIRATION_IN_SECONDS, + } = params; + // Create a read-only session + if (sessionType === SessionType.READ_ONLY) { + const readOnlySessionResult = + await this.httpClient.createReadOnlySession({}, StamperType.Passkey); + + const session: Session = { + sessionType: SessionType.READ_ONLY, + userId: readOnlySessionResult.userId, + organizationId: readOnlySessionResult.organizationId, + expiry: Number(readOnlySessionResult.sessionExpiry), + token: readOnlySessionResult.session, // Once we have api key session scopes this can change + }; + await this.storageManager.storeSession(session); + // Create a read-write session + } else if (sessionType === SessionType.READ_WRITE) { + if (!publicKey) { + throw new Error( + "You must provide a publicKey to create a passkey read write session.", + ); + } + + const sessionResponse = await this.httpClient.stampLogin( + { + publicKey, + expirationSeconds, + }, + StamperType.Passkey, + ); + + const whoamiResponse = await this.httpClient.getWhoami({}); + + const session: Session = { + // Let's keep consistent with storing the actual session object rather than just the token + sessionType: SessionType.READ_ONLY, + userId: whoamiResponse.userId, + organizationId: whoamiResponse.organizationId, + expiry: Number(expirationSeconds), + token: sessionResponse.session, + }; + + await this.storageManager.storeSession(session); + } else { + throw new Error(`Invalid session type passed: ${sessionType}`); + } + } catch (error) { + throw new Error(`Unable to log in with the provided passkey: ${error}`); + } + }; } diff --git a/packages/sdk-js/src/__generated__/sdk-client-base.ts b/packages/sdk-js/src/__generated__/sdk-client-base.ts index 5f43a6c18..f168d947c 100644 --- a/packages/sdk-js/src/__generated__/sdk-client-base.ts +++ b/packages/sdk-js/src/__generated__/sdk-client-base.ts @@ -1,183 +1,231 @@ /* @generated by codegen. DO NOT EDIT BY HAND */ -import { TERMINAL_ACTIVITY_STATUSES, TActivityResponse, TActivityStatus, TSignedRequest } from "@turnkey/http"; +import { + TERMINAL_ACTIVITY_STATUSES, + TActivityResponse, + TActivityStatus, + TSignedRequest, +} from "@turnkey/http"; import type { definitions } from "../__inputs__/public_api.types"; -import { GrpcStatus, TStamper, TurnkeyRequestError, TurnkeySDKClientConfig } from "../__types__/base"; +import { + GrpcStatus, + TStamper, + TurnkeyRequestError, + TurnkeySDKClientConfig, +} from "../__types__/base"; import { VERSION } from "../__generated__/version"; import type * as SdkApiTypes from "./sdk_api_types"; -import { StorageKeys, getStorageValue } from "../storage"; +import { StorageBase, StorageKey } from "../__storage__/base"; import { parseSession } from "../utils"; import { StamperType } from "../__types__/base"; +export class TurnkeySDKClientBase { + config: TurnkeySDKClientConfig; - export class TurnkeySDKClientBase { - config: TurnkeySDKClientConfig; - - // Current active stamper - stamper?: TStamper | undefined; - - // Store stampers - private indexedDBStamper?: TStamper | undefined; - private passkeyStamper?: TStamper | undefined; - - constructor(config: TurnkeySDKClientConfig) { - this.config = config; - if (config.stamper) { - this.stamper = config.stamper; - // Store as default IndexedDB stamper - this.indexedDBStamper = config.stamper; - } - if (config.passkeyStamper) { - this.passkeyStamper = config.passkeyStamper; - } - } - - private getStamper(stampWith?: StamperType): TStamper | undefined { - if (!stampWith) return this.stamper; - - switch (stampWith) { - case StamperType.IndexedDB: - return this.indexedDBStamper; - case StamperType.Passkey: - return this.passkeyStamper; - default: - return this.stamper; - } - } - - async request( - url: string, - body: TBodyType, - stampWith?: StamperType - ): Promise { - const fullUrl = this.config.apiBaseUrl + url; - const stringifiedBody = JSON.stringify(body); - var headers: Record = { - "X-Client-Version": VERSION - } - - // Use the specified stamper for this request - const activeStamper = this.getStamper(stampWith); - - if (activeStamper) { - const stamp = await activeStamper.stamp(stringifiedBody); - headers[stamp.stampHeaderName] = stamp.stampHeaderValue - } - - if (this.config.readOnlySession){ - headers["X-Session"] = this.config.readOnlySession - } - - const response = await fetch(fullUrl, { - method: "POST", - headers: headers, - body: stringifiedBody, - redirect: "follow" - }); - - if (!response.ok) { - let res: GrpcStatus; - try { - res = await response.json(); - } catch (_) { - throw new Error(`${response.status} ${response.statusText}`); - } - - throw new TurnkeyRequestError(res); - } - - const data = await response.json(); - return data as TResponseType; - } - - async command( - url: string, - body: TBodyType, - resultKey: string, - stampWith?: StamperType - ): Promise { - const pollingDuration = this.config.activityPoller?.intervalMs ?? 1000; - const maxRetries = this.config.activityPoller?.numRetries ?? 3; - - const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms)); - - const handleResponse = (activityData: TActivityResponse): TResponseType => { - const { result, status } = activityData.activity; - - if (status === "ACTIVITY_STATUS_COMPLETED") { - return { - ...result[`${resultKey}` as keyof definitions["v1Result"]], - ...activityData - } as TResponseType; - } - - return activityData as TResponseType; - }; - - let attempts = 0; - - const pollStatus = async (activityId: string): Promise => { - const pollBody = { activityId }; - // Pass the stampWith parameter to getActivity - const pollData = await this.getActivity(pollBody, stampWith) as TActivityResponse; - - if (attempts > maxRetries) { - return handleResponse(pollData); - } - - attempts += 1; - - if (!TERMINAL_ACTIVITY_STATUSES.includes(pollData.activity.status as TActivityStatus)) { - await sleep(pollingDuration); - return pollStatus(activityId); - } + // Current active stamper + stamper?: TStamper | undefined; - return handleResponse(pollData); - }; + // Store stampers + private indexedDBStamper?: TStamper | undefined; + private passkeyStamper?: TStamper | undefined; + + // Storage manager + private storageManager?: StorageBase | undefined; - // Use the specified stamper for the initial request - const responseData = await this.request(url, body, stampWith) as TActivityResponse; - - if (!TERMINAL_ACTIVITY_STATUSES.includes(responseData.activity.status as TActivityStatus)) { - return pollStatus(responseData.activity.id); - } + constructor(config: TurnkeySDKClientConfig) { + this.config = config; - return handleResponse(responseData); + if (config.stamper) { + this.stamper = config.stamper; + // Store as default IndexedDB stamper + this.indexedDBStamper = config.stamper; + } + if (config.passkeyStamper) { + this.passkeyStamper = config.passkeyStamper; } + if (config.storageManager) { + this.storageManager = config.storageManager; + } + } - async activityDecision( - url: string, - body: TBodyType, - stampWith?: StamperType - ): Promise { - // Use the specified stamper for this request - const activityData = await this.request(url, body, stampWith) as TActivityResponse; + private getStamper(stampWith?: StamperType): TStamper | undefined { + if (!stampWith) return this.stamper; - return { - ...activityData["activity"]["result"], - ...activityData - } as TResponseType; + switch (stampWith) { + case StamperType.IndexedDB: + return this.indexedDBStamper; + case StamperType.Passkey: + return this.passkeyStamper; + default: + return this.stamper; } + } + async request( + url: string, + body: TBodyType, + stampWith?: StamperType, + ): Promise { + const fullUrl = this.config.apiBaseUrl + url; + const stringifiedBody = JSON.stringify(body); + var headers: Record = { + "X-Client-Version": VERSION, + }; - getActivity = async (input: SdkApiTypes.TGetActivityBody, stampWith?: StamperType): Promise => { - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - return this.request("/public/v1/query/get_activity", { - ...input, - organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId - }, stampWith); + // Use the specified stamper for this request + const activeStamper = this.getStamper(stampWith); + + if (activeStamper) { + const stamp = await activeStamper.stamp(stringifiedBody); + headers[stamp.stampHeaderName] = stamp.stampHeaderValue; + } + + if (this.config.readOnlySession) { + headers["X-Session"] = this.config.readOnlySession; + } + + const response = await fetch(fullUrl, { + method: "POST", + headers: headers, + body: stringifiedBody, + redirect: "follow", + }); + + if (!response.ok) { + let res: GrpcStatus; + try { + res = await response.json(); + } catch (_) { + throw new Error(`${response.status} ${response.statusText}`); + } + + throw new TurnkeyRequestError(res); } + const data = await response.json(); + return data as TResponseType; + } + + async command( + url: string, + body: TBodyType, + resultKey: string, + stampWith?: StamperType, + ): Promise { + const pollingDuration = this.config.activityPoller?.intervalMs ?? 1000; + const maxRetries = this.config.activityPoller?.numRetries ?? 3; + + const sleep = (ms: number) => + new Promise((resolve) => setTimeout(resolve, ms)); - stampGetActivity = async (input: SdkApiTypes.TGetActivityBody): Promise => { + const handleResponse = (activityData: TActivityResponse): TResponseType => { + const { result, status } = activityData.activity; + + if (status === "ACTIVITY_STATUS_COMPLETED") { + return { + ...result[`${resultKey}` as keyof definitions["v1Result"]], + ...activityData, + } as TResponseType; + } + + return activityData as TResponseType; + }; + + let attempts = 0; + + const pollStatus = async (activityId: string): Promise => { + const pollBody = { activityId }; + // Pass the stampWith parameter to getActivity + const pollData = (await this.getActivity( + pollBody, + stampWith, + )) as TActivityResponse; + + if (attempts > maxRetries) { + return handleResponse(pollData); + } + + attempts += 1; + + if ( + !TERMINAL_ACTIVITY_STATUSES.includes( + pollData.activity.status as TActivityStatus, + ) + ) { + await sleep(pollingDuration); + return pollStatus(activityId); + } + + return handleResponse(pollData); + }; + + // Use the specified stamper for the initial request + const responseData = (await this.request( + url, + body, + stampWith, + )) as TActivityResponse; + + if ( + !TERMINAL_ACTIVITY_STATUSES.includes( + responseData.activity.status as TActivityStatus, + ) + ) { + return pollStatus(responseData.activity.id); + } + + return handleResponse(responseData); + } + + async activityDecision( + url: string, + body: TBodyType, + stampWith?: StamperType, + ): Promise { + // Use the specified stamper for this request + const activityData = (await this.request( + url, + body, + stampWith, + )) as TActivityResponse; + + return { + ...activityData["activity"]["result"], + ...activityData, + } as TResponseType; + } + + getActivity = async ( + input: SdkApiTypes.TGetActivityBody, + stampWith?: StamperType, + ): Promise => { + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage + return this.request( + "/public/v1/query/get_activity", + { + ...input, + organizationId: + input.organizationId ?? + session?.organizationId ?? + this.config.organizationId, + }, + stampWith, + ); + }; + + stampGetActivity = async ( + input: SdkApiTypes.TGetActivityBody, + ): Promise => { if (!this.stamper) { return undefined; } @@ -189,20 +237,32 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } - + }; - getApiKey = async (input: SdkApiTypes.TGetApiKeyBody, stampWith?: StamperType): Promise => { - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - return this.request("/public/v1/query/get_api_key", { + getApiKey = async ( + input: SdkApiTypes.TGetApiKeyBody, + stampWith?: StamperType, + ): Promise => { + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage + return this.request( + "/public/v1/query/get_api_key", + { ...input, - organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId - }, stampWith); - } - + organizationId: + input.organizationId ?? + session?.organizationId ?? + this.config.organizationId, + }, + stampWith, + ); + }; - stampGetApiKey = async (input: SdkApiTypes.TGetApiKeyBody): Promise => { + stampGetApiKey = async ( + input: SdkApiTypes.TGetApiKeyBody, + ): Promise => { if (!this.stamper) { return undefined; } @@ -214,20 +274,32 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } - + }; - getApiKeys = async (input: SdkApiTypes.TGetApiKeysBody = {}, stampWith?: StamperType): Promise => { - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - return this.request("/public/v1/query/get_api_keys", { + getApiKeys = async ( + input: SdkApiTypes.TGetApiKeysBody = {}, + stampWith?: StamperType, + ): Promise => { + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage + return this.request( + "/public/v1/query/get_api_keys", + { ...input, - organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId - }, stampWith); - } + organizationId: + input.organizationId ?? + session?.organizationId ?? + this.config.organizationId, + }, + stampWith, + ); + }; - - stampGetApiKeys = async (input: SdkApiTypes.TGetApiKeysBody): Promise => { + stampGetApiKeys = async ( + input: SdkApiTypes.TGetApiKeysBody, + ): Promise => { if (!this.stamper) { return undefined; } @@ -239,20 +311,32 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; - - getAttestationDocument = async (input: SdkApiTypes.TGetAttestationDocumentBody, stampWith?: StamperType): Promise => { - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - return this.request("/public/v1/query/get_attestation", { + getAttestationDocument = async ( + input: SdkApiTypes.TGetAttestationDocumentBody, + stampWith?: StamperType, + ): Promise => { + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage + return this.request( + "/public/v1/query/get_attestation", + { ...input, - organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId - }, stampWith); - } - + organizationId: + input.organizationId ?? + session?.organizationId ?? + this.config.organizationId, + }, + stampWith, + ); + }; - stampGetAttestationDocument = async (input: SdkApiTypes.TGetAttestationDocumentBody): Promise => { + stampGetAttestationDocument = async ( + input: SdkApiTypes.TGetAttestationDocumentBody, + ): Promise => { if (!this.stamper) { return undefined; } @@ -264,24 +348,37 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } - + }; - getAuthenticator = async (input: SdkApiTypes.TGetAuthenticatorBody, stampWith?: StamperType): Promise => { - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - return this.request("/public/v1/query/get_authenticator", { + getAuthenticator = async ( + input: SdkApiTypes.TGetAuthenticatorBody, + stampWith?: StamperType, + ): Promise => { + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage + return this.request( + "/public/v1/query/get_authenticator", + { ...input, - organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId - }, stampWith); - } - + organizationId: + input.organizationId ?? + session?.organizationId ?? + this.config.organizationId, + }, + stampWith, + ); + }; - stampGetAuthenticator = async (input: SdkApiTypes.TGetAuthenticatorBody): Promise => { + stampGetAuthenticator = async ( + input: SdkApiTypes.TGetAuthenticatorBody, + ): Promise => { if (!this.stamper) { return undefined; } - const fullUrl = this.config.apiBaseUrl + "/public/v1/query/get_authenticator"; + const fullUrl = + this.config.apiBaseUrl + "/public/v1/query/get_authenticator"; const body = JSON.stringify(input); const stamp = await this.stamper.stamp(body); return { @@ -289,24 +386,37 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; - - getAuthenticators = async (input: SdkApiTypes.TGetAuthenticatorsBody, stampWith?: StamperType): Promise => { - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - return this.request("/public/v1/query/get_authenticators", { + getAuthenticators = async ( + input: SdkApiTypes.TGetAuthenticatorsBody, + stampWith?: StamperType, + ): Promise => { + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage + return this.request( + "/public/v1/query/get_authenticators", + { ...input, - organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId - }, stampWith); - } + organizationId: + input.organizationId ?? + session?.organizationId ?? + this.config.organizationId, + }, + stampWith, + ); + }; - - stampGetAuthenticators = async (input: SdkApiTypes.TGetAuthenticatorsBody): Promise => { + stampGetAuthenticators = async ( + input: SdkApiTypes.TGetAuthenticatorsBody, + ): Promise => { if (!this.stamper) { return undefined; } - const fullUrl = this.config.apiBaseUrl + "/public/v1/query/get_authenticators"; + const fullUrl = + this.config.apiBaseUrl + "/public/v1/query/get_authenticators"; const body = JSON.stringify(input); const stamp = await this.stamper.stamp(body); return { @@ -314,24 +424,37 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } - + }; - getOauthProviders = async (input: SdkApiTypes.TGetOauthProvidersBody, stampWith?: StamperType): Promise => { - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - return this.request("/public/v1/query/get_oauth_providers", { + getOauthProviders = async ( + input: SdkApiTypes.TGetOauthProvidersBody, + stampWith?: StamperType, + ): Promise => { + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage + return this.request( + "/public/v1/query/get_oauth_providers", + { ...input, - organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId - }, stampWith); - } - + organizationId: + input.organizationId ?? + session?.organizationId ?? + this.config.organizationId, + }, + stampWith, + ); + }; - stampGetOauthProviders = async (input: SdkApiTypes.TGetOauthProvidersBody): Promise => { + stampGetOauthProviders = async ( + input: SdkApiTypes.TGetOauthProvidersBody, + ): Promise => { if (!this.stamper) { return undefined; } - const fullUrl = this.config.apiBaseUrl + "/public/v1/query/get_oauth_providers"; + const fullUrl = + this.config.apiBaseUrl + "/public/v1/query/get_oauth_providers"; const body = JSON.stringify(input); const stamp = await this.stamper.stamp(body); return { @@ -339,24 +462,37 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } - + }; - getOrganization = async (input: SdkApiTypes.TGetOrganizationBody = {}, stampWith?: StamperType): Promise => { - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - return this.request("/public/v1/query/get_organization", { + getOrganization = async ( + input: SdkApiTypes.TGetOrganizationBody = {}, + stampWith?: StamperType, + ): Promise => { + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage + return this.request( + "/public/v1/query/get_organization", + { ...input, - organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId - }, stampWith); - } + organizationId: + input.organizationId ?? + session?.organizationId ?? + this.config.organizationId, + }, + stampWith, + ); + }; - - stampGetOrganization = async (input: SdkApiTypes.TGetOrganizationBody): Promise => { + stampGetOrganization = async ( + input: SdkApiTypes.TGetOrganizationBody, + ): Promise => { if (!this.stamper) { return undefined; } - const fullUrl = this.config.apiBaseUrl + "/public/v1/query/get_organization"; + const fullUrl = + this.config.apiBaseUrl + "/public/v1/query/get_organization"; const body = JSON.stringify(input); const stamp = await this.stamper.stamp(body); return { @@ -364,24 +500,37 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; - - getOrganizationConfigs = async (input: SdkApiTypes.TGetOrganizationConfigsBody, stampWith?: StamperType): Promise => { - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - return this.request("/public/v1/query/get_organization_configs", { + getOrganizationConfigs = async ( + input: SdkApiTypes.TGetOrganizationConfigsBody, + stampWith?: StamperType, + ): Promise => { + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage + return this.request( + "/public/v1/query/get_organization_configs", + { ...input, - organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId - }, stampWith); - } - + organizationId: + input.organizationId ?? + session?.organizationId ?? + this.config.organizationId, + }, + stampWith, + ); + }; - stampGetOrganizationConfigs = async (input: SdkApiTypes.TGetOrganizationConfigsBody): Promise => { + stampGetOrganizationConfigs = async ( + input: SdkApiTypes.TGetOrganizationConfigsBody, + ): Promise => { if (!this.stamper) { return undefined; } - const fullUrl = this.config.apiBaseUrl + "/public/v1/query/get_organization_configs"; + const fullUrl = + this.config.apiBaseUrl + "/public/v1/query/get_organization_configs"; const body = JSON.stringify(input); const stamp = await this.stamper.stamp(body); return { @@ -389,20 +538,32 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } - + }; - getPolicy = async (input: SdkApiTypes.TGetPolicyBody, stampWith?: StamperType): Promise => { - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - return this.request("/public/v1/query/get_policy", { + getPolicy = async ( + input: SdkApiTypes.TGetPolicyBody, + stampWith?: StamperType, + ): Promise => { + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage + return this.request( + "/public/v1/query/get_policy", + { ...input, - organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId - }, stampWith); - } - + organizationId: + input.organizationId ?? + session?.organizationId ?? + this.config.organizationId, + }, + stampWith, + ); + }; - stampGetPolicy = async (input: SdkApiTypes.TGetPolicyBody): Promise => { + stampGetPolicy = async ( + input: SdkApiTypes.TGetPolicyBody, + ): Promise => { if (!this.stamper) { return undefined; } @@ -414,20 +575,32 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; - - getPrivateKey = async (input: SdkApiTypes.TGetPrivateKeyBody, stampWith?: StamperType): Promise => { - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - return this.request("/public/v1/query/get_private_key", { + getPrivateKey = async ( + input: SdkApiTypes.TGetPrivateKeyBody, + stampWith?: StamperType, + ): Promise => { + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage + return this.request( + "/public/v1/query/get_private_key", + { ...input, - organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId - }, stampWith); - } + organizationId: + input.organizationId ?? + session?.organizationId ?? + this.config.organizationId, + }, + stampWith, + ); + }; - - stampGetPrivateKey = async (input: SdkApiTypes.TGetPrivateKeyBody): Promise => { + stampGetPrivateKey = async ( + input: SdkApiTypes.TGetPrivateKeyBody, + ): Promise => { if (!this.stamper) { return undefined; } @@ -439,20 +612,32 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } - + }; - getUser = async (input: SdkApiTypes.TGetUserBody, stampWith?: StamperType): Promise => { - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - return this.request("/public/v1/query/get_user", { + getUser = async ( + input: SdkApiTypes.TGetUserBody, + stampWith?: StamperType, + ): Promise => { + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage + return this.request( + "/public/v1/query/get_user", + { ...input, - organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId - }, stampWith); - } - + organizationId: + input.organizationId ?? + session?.organizationId ?? + this.config.organizationId, + }, + stampWith, + ); + }; - stampGetUser = async (input: SdkApiTypes.TGetUserBody): Promise => { + stampGetUser = async ( + input: SdkApiTypes.TGetUserBody, + ): Promise => { if (!this.stamper) { return undefined; } @@ -464,20 +649,32 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } - + }; - getWallet = async (input: SdkApiTypes.TGetWalletBody, stampWith?: StamperType): Promise => { - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - return this.request("/public/v1/query/get_wallet", { + getWallet = async ( + input: SdkApiTypes.TGetWalletBody, + stampWith?: StamperType, + ): Promise => { + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage + return this.request( + "/public/v1/query/get_wallet", + { ...input, - organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId - }, stampWith); - } - + organizationId: + input.organizationId ?? + session?.organizationId ?? + this.config.organizationId, + }, + stampWith, + ); + }; - stampGetWallet = async (input: SdkApiTypes.TGetWalletBody): Promise => { + stampGetWallet = async ( + input: SdkApiTypes.TGetWalletBody, + ): Promise => { if (!this.stamper) { return undefined; } @@ -489,24 +686,37 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } - + }; - getWalletAccount = async (input: SdkApiTypes.TGetWalletAccountBody, stampWith?: StamperType): Promise => { - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - return this.request("/public/v1/query/get_wallet_account", { + getWalletAccount = async ( + input: SdkApiTypes.TGetWalletAccountBody, + stampWith?: StamperType, + ): Promise => { + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage + return this.request( + "/public/v1/query/get_wallet_account", + { ...input, - organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId - }, stampWith); - } + organizationId: + input.organizationId ?? + session?.organizationId ?? + this.config.organizationId, + }, + stampWith, + ); + }; - - stampGetWalletAccount = async (input: SdkApiTypes.TGetWalletAccountBody): Promise => { + stampGetWalletAccount = async ( + input: SdkApiTypes.TGetWalletAccountBody, + ): Promise => { if (!this.stamper) { return undefined; } - const fullUrl = this.config.apiBaseUrl + "/public/v1/query/get_wallet_account"; + const fullUrl = + this.config.apiBaseUrl + "/public/v1/query/get_wallet_account"; const body = JSON.stringify(input); const stamp = await this.stamper.stamp(body); return { @@ -514,20 +724,32 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; - - getActivities = async (input: SdkApiTypes.TGetActivitiesBody = {}, stampWith?: StamperType): Promise => { - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - return this.request("/public/v1/query/list_activities", { + getActivities = async ( + input: SdkApiTypes.TGetActivitiesBody = {}, + stampWith?: StamperType, + ): Promise => { + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage + return this.request( + "/public/v1/query/list_activities", + { ...input, - organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId - }, stampWith); - } - + organizationId: + input.organizationId ?? + session?.organizationId ?? + this.config.organizationId, + }, + stampWith, + ); + }; - stampGetActivities = async (input: SdkApiTypes.TGetActivitiesBody): Promise => { + stampGetActivities = async ( + input: SdkApiTypes.TGetActivitiesBody, + ): Promise => { if (!this.stamper) { return undefined; } @@ -539,20 +761,32 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } - + }; - getPolicies = async (input: SdkApiTypes.TGetPoliciesBody = {}, stampWith?: StamperType): Promise => { - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - return this.request("/public/v1/query/list_policies", { + getPolicies = async ( + input: SdkApiTypes.TGetPoliciesBody = {}, + stampWith?: StamperType, + ): Promise => { + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage + return this.request( + "/public/v1/query/list_policies", + { ...input, - organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId - }, stampWith); - } - + organizationId: + input.organizationId ?? + session?.organizationId ?? + this.config.organizationId, + }, + stampWith, + ); + }; - stampGetPolicies = async (input: SdkApiTypes.TGetPoliciesBody): Promise => { + stampGetPolicies = async ( + input: SdkApiTypes.TGetPoliciesBody, + ): Promise => { if (!this.stamper) { return undefined; } @@ -564,24 +798,37 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; - - listPrivateKeyTags = async (input: SdkApiTypes.TListPrivateKeyTagsBody, stampWith?: StamperType): Promise => { - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - return this.request("/public/v1/query/list_private_key_tags", { + listPrivateKeyTags = async ( + input: SdkApiTypes.TListPrivateKeyTagsBody, + stampWith?: StamperType, + ): Promise => { + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage + return this.request( + "/public/v1/query/list_private_key_tags", + { ...input, - organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId - }, stampWith); - } + organizationId: + input.organizationId ?? + session?.organizationId ?? + this.config.organizationId, + }, + stampWith, + ); + }; - - stampListPrivateKeyTags = async (input: SdkApiTypes.TListPrivateKeyTagsBody): Promise => { + stampListPrivateKeyTags = async ( + input: SdkApiTypes.TListPrivateKeyTagsBody, + ): Promise => { if (!this.stamper) { return undefined; } - const fullUrl = this.config.apiBaseUrl + "/public/v1/query/list_private_key_tags"; + const fullUrl = + this.config.apiBaseUrl + "/public/v1/query/list_private_key_tags"; const body = JSON.stringify(input); const stamp = await this.stamper.stamp(body); return { @@ -589,24 +836,37 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } - + }; - getPrivateKeys = async (input: SdkApiTypes.TGetPrivateKeysBody = {}, stampWith?: StamperType): Promise => { - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - return this.request("/public/v1/query/list_private_keys", { + getPrivateKeys = async ( + input: SdkApiTypes.TGetPrivateKeysBody = {}, + stampWith?: StamperType, + ): Promise => { + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage + return this.request( + "/public/v1/query/list_private_keys", + { ...input, - organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId - }, stampWith); - } - + organizationId: + input.organizationId ?? + session?.organizationId ?? + this.config.organizationId, + }, + stampWith, + ); + }; - stampGetPrivateKeys = async (input: SdkApiTypes.TGetPrivateKeysBody): Promise => { + stampGetPrivateKeys = async ( + input: SdkApiTypes.TGetPrivateKeysBody, + ): Promise => { if (!this.stamper) { return undefined; } - const fullUrl = this.config.apiBaseUrl + "/public/v1/query/list_private_keys"; + const fullUrl = + this.config.apiBaseUrl + "/public/v1/query/list_private_keys"; const body = JSON.stringify(input); const stamp = await this.stamper.stamp(body); return { @@ -614,20 +874,32 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } - + }; - getSubOrgIds = async (input: SdkApiTypes.TGetSubOrgIdsBody = {}, stampWith?: StamperType): Promise => { - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - return this.request("/public/v1/query/list_suborgs", { + getSubOrgIds = async ( + input: SdkApiTypes.TGetSubOrgIdsBody = {}, + stampWith?: StamperType, + ): Promise => { + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage + return this.request( + "/public/v1/query/list_suborgs", + { ...input, - organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId - }, stampWith); - } + organizationId: + input.organizationId ?? + session?.organizationId ?? + this.config.organizationId, + }, + stampWith, + ); + }; - - stampGetSubOrgIds = async (input: SdkApiTypes.TGetSubOrgIdsBody): Promise => { + stampGetSubOrgIds = async ( + input: SdkApiTypes.TGetSubOrgIdsBody, + ): Promise => { if (!this.stamper) { return undefined; } @@ -639,20 +911,32 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; - - listUserTags = async (input: SdkApiTypes.TListUserTagsBody = {}, stampWith?: StamperType): Promise => { - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - return this.request("/public/v1/query/list_user_tags", { + listUserTags = async ( + input: SdkApiTypes.TListUserTagsBody = {}, + stampWith?: StamperType, + ): Promise => { + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage + return this.request( + "/public/v1/query/list_user_tags", + { ...input, - organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId - }, stampWith); - } - + organizationId: + input.organizationId ?? + session?.organizationId ?? + this.config.organizationId, + }, + stampWith, + ); + }; - stampListUserTags = async (input: SdkApiTypes.TListUserTagsBody): Promise => { + stampListUserTags = async ( + input: SdkApiTypes.TListUserTagsBody, + ): Promise => { if (!this.stamper) { return undefined; } @@ -664,20 +948,32 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } - + }; - getUsers = async (input: SdkApiTypes.TGetUsersBody = {}, stampWith?: StamperType): Promise => { - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - return this.request("/public/v1/query/list_users", { + getUsers = async ( + input: SdkApiTypes.TGetUsersBody = {}, + stampWith?: StamperType, + ): Promise => { + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage + return this.request( + "/public/v1/query/list_users", + { ...input, - organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId - }, stampWith); - } - + organizationId: + input.organizationId ?? + session?.organizationId ?? + this.config.organizationId, + }, + stampWith, + ); + }; - stampGetUsers = async (input: SdkApiTypes.TGetUsersBody): Promise => { + stampGetUsers = async ( + input: SdkApiTypes.TGetUsersBody, + ): Promise => { if (!this.stamper) { return undefined; } @@ -689,24 +985,37 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; - - getVerifiedSubOrgIds = async (input: SdkApiTypes.TGetVerifiedSubOrgIdsBody, stampWith?: StamperType): Promise => { - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - return this.request("/public/v1/query/list_verified_suborgs", { + getVerifiedSubOrgIds = async ( + input: SdkApiTypes.TGetVerifiedSubOrgIdsBody, + stampWith?: StamperType, + ): Promise => { + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage + return this.request( + "/public/v1/query/list_verified_suborgs", + { ...input, - organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId - }, stampWith); - } + organizationId: + input.organizationId ?? + session?.organizationId ?? + this.config.organizationId, + }, + stampWith, + ); + }; - - stampGetVerifiedSubOrgIds = async (input: SdkApiTypes.TGetVerifiedSubOrgIdsBody): Promise => { + stampGetVerifiedSubOrgIds = async ( + input: SdkApiTypes.TGetVerifiedSubOrgIdsBody, + ): Promise => { if (!this.stamper) { return undefined; } - const fullUrl = this.config.apiBaseUrl + "/public/v1/query/list_verified_suborgs"; + const fullUrl = + this.config.apiBaseUrl + "/public/v1/query/list_verified_suborgs"; const body = JSON.stringify(input); const stamp = await this.stamper.stamp(body); return { @@ -714,24 +1023,37 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; - - getWalletAccounts = async (input: SdkApiTypes.TGetWalletAccountsBody, stampWith?: StamperType): Promise => { - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - return this.request("/public/v1/query/list_wallet_accounts", { + getWalletAccounts = async ( + input: SdkApiTypes.TGetWalletAccountsBody, + stampWith?: StamperType, + ): Promise => { + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage + return this.request( + "/public/v1/query/list_wallet_accounts", + { ...input, - organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId - }, stampWith); - } + organizationId: + input.organizationId ?? + session?.organizationId ?? + this.config.organizationId, + }, + stampWith, + ); + }; - - stampGetWalletAccounts = async (input: SdkApiTypes.TGetWalletAccountsBody): Promise => { + stampGetWalletAccounts = async ( + input: SdkApiTypes.TGetWalletAccountsBody, + ): Promise => { if (!this.stamper) { return undefined; } - const fullUrl = this.config.apiBaseUrl + "/public/v1/query/list_wallet_accounts"; + const fullUrl = + this.config.apiBaseUrl + "/public/v1/query/list_wallet_accounts"; const body = JSON.stringify(input); const stamp = await this.stamper.stamp(body); return { @@ -739,20 +1061,32 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } - + }; - getWallets = async (input: SdkApiTypes.TGetWalletsBody = {}, stampWith?: StamperType): Promise => { - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - return this.request("/public/v1/query/list_wallets", { + getWallets = async ( + input: SdkApiTypes.TGetWalletsBody = {}, + stampWith?: StamperType, + ): Promise => { + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage + return this.request( + "/public/v1/query/list_wallets", + { ...input, - organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId - }, stampWith); - } - + organizationId: + input.organizationId ?? + session?.organizationId ?? + this.config.organizationId, + }, + stampWith, + ); + }; - stampGetWallets = async (input: SdkApiTypes.TGetWalletsBody): Promise => { + stampGetWallets = async ( + input: SdkApiTypes.TGetWalletsBody, + ): Promise => { if (!this.stamper) { return undefined; } @@ -764,20 +1098,32 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } - + }; - getWhoami = async (input: SdkApiTypes.TGetWhoamiBody = {}, stampWith?: StamperType): Promise => { - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - return this.request("/public/v1/query/whoami", { + getWhoami = async ( + input: SdkApiTypes.TGetWhoamiBody = {}, + stampWith?: StamperType, + ): Promise => { + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage + return this.request( + "/public/v1/query/whoami", + { ...input, - organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId - }, stampWith); - } + organizationId: + input.organizationId ?? + session?.organizationId ?? + this.config.organizationId, + }, + stampWith, + ); + }; - - stampGetWhoami = async (input: SdkApiTypes.TGetWhoamiBody): Promise => { + stampGetWhoami = async ( + input: SdkApiTypes.TGetWhoamiBody, + ): Promise => { if (!this.stamper) { return undefined; } @@ -789,28 +1135,40 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } - - - approveActivity = async (input: SdkApiTypes.TApproveActivityBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - return this.activityDecision("/public/v1/submit/approve_activity", - { - parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), - timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_APPROVE_ACTIVITY" - }, stampWith); - } + }; + approveActivity = async ( + input: SdkApiTypes.TApproveActivityBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); + return this.activityDecision( + "/public/v1/submit/approve_activity", + { + parameters: rest, + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_APPROVE_ACTIVITY", + }, + stampWith, + ); + }; - stampApproveActivity = async (input: SdkApiTypes.TApproveActivityBody): Promise => { + stampApproveActivity = async ( + input: SdkApiTypes.TApproveActivityBody, + ): Promise => { if (!this.stamper) { return undefined; } - const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/approve_activity"; + const fullUrl = + this.config.apiBaseUrl + "/public/v1/submit/approve_activity"; const body = JSON.stringify(input); const stamp = await this.stamper.stamp(body); return { @@ -818,28 +1176,42 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + createApiKeys = async ( + input: SdkApiTypes.TCreateApiKeysBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - createApiKeys = async (input: SdkApiTypes.TCreateApiKeysBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/create_api_keys", { + return this.command( + "/public/v1/submit/create_api_keys", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_CREATE_API_KEYS_V2" - }, "createApiKeysResult", stampWith); - } - + type: "ACTIVITY_TYPE_CREATE_API_KEYS_V2", + }, + "createApiKeysResult", + stampWith, + ); + }; - stampCreateApiKeys = async (input: SdkApiTypes.TCreateApiKeysBody): Promise => { + stampCreateApiKeys = async ( + input: SdkApiTypes.TCreateApiKeysBody, + ): Promise => { if (!this.stamper) { return undefined; } - const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/create_api_keys"; + const fullUrl = + this.config.apiBaseUrl + "/public/v1/submit/create_api_keys"; const body = JSON.stringify(input); const stamp = await this.stamper.stamp(body); return { @@ -847,28 +1219,42 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + createApiOnlyUsers = async ( + input: SdkApiTypes.TCreateApiOnlyUsersBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - createApiOnlyUsers = async (input: SdkApiTypes.TCreateApiOnlyUsersBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/create_api_only_users", { + return this.command( + "/public/v1/submit/create_api_only_users", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_CREATE_API_ONLY_USERS" - }, "createApiOnlyUsersResult", stampWith); - } + type: "ACTIVITY_TYPE_CREATE_API_ONLY_USERS", + }, + "createApiOnlyUsersResult", + stampWith, + ); + }; - - stampCreateApiOnlyUsers = async (input: SdkApiTypes.TCreateApiOnlyUsersBody): Promise => { + stampCreateApiOnlyUsers = async ( + input: SdkApiTypes.TCreateApiOnlyUsersBody, + ): Promise => { if (!this.stamper) { return undefined; } - const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/create_api_only_users"; + const fullUrl = + this.config.apiBaseUrl + "/public/v1/submit/create_api_only_users"; const body = JSON.stringify(input); const stamp = await this.stamper.stamp(body); return { @@ -876,28 +1262,42 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + createAuthenticators = async ( + input: SdkApiTypes.TCreateAuthenticatorsBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - createAuthenticators = async (input: SdkApiTypes.TCreateAuthenticatorsBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/create_authenticators", { + return this.command( + "/public/v1/submit/create_authenticators", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_CREATE_AUTHENTICATORS_V2" - }, "createAuthenticatorsResult", stampWith); - } + type: "ACTIVITY_TYPE_CREATE_AUTHENTICATORS_V2", + }, + "createAuthenticatorsResult", + stampWith, + ); + }; - - stampCreateAuthenticators = async (input: SdkApiTypes.TCreateAuthenticatorsBody): Promise => { + stampCreateAuthenticators = async ( + input: SdkApiTypes.TCreateAuthenticatorsBody, + ): Promise => { if (!this.stamper) { return undefined; } - const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/create_authenticators"; + const fullUrl = + this.config.apiBaseUrl + "/public/v1/submit/create_authenticators"; const body = JSON.stringify(input); const stamp = await this.stamper.stamp(body); return { @@ -905,28 +1305,42 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + createInvitations = async ( + input: SdkApiTypes.TCreateInvitationsBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - createInvitations = async (input: SdkApiTypes.TCreateInvitationsBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/create_invitations", { + return this.command( + "/public/v1/submit/create_invitations", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_CREATE_INVITATIONS" - }, "createInvitationsResult", stampWith); - } - + type: "ACTIVITY_TYPE_CREATE_INVITATIONS", + }, + "createInvitationsResult", + stampWith, + ); + }; - stampCreateInvitations = async (input: SdkApiTypes.TCreateInvitationsBody): Promise => { + stampCreateInvitations = async ( + input: SdkApiTypes.TCreateInvitationsBody, + ): Promise => { if (!this.stamper) { return undefined; } - const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/create_invitations"; + const fullUrl = + this.config.apiBaseUrl + "/public/v1/submit/create_invitations"; const body = JSON.stringify(input); const stamp = await this.stamper.stamp(body); return { @@ -934,28 +1348,42 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + createOauthProviders = async ( + input: SdkApiTypes.TCreateOauthProvidersBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - createOauthProviders = async (input: SdkApiTypes.TCreateOauthProvidersBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/create_oauth_providers", { + return this.command( + "/public/v1/submit/create_oauth_providers", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_CREATE_OAUTH_PROVIDERS" - }, "createOauthProvidersResult", stampWith); - } - + type: "ACTIVITY_TYPE_CREATE_OAUTH_PROVIDERS", + }, + "createOauthProvidersResult", + stampWith, + ); + }; - stampCreateOauthProviders = async (input: SdkApiTypes.TCreateOauthProvidersBody): Promise => { + stampCreateOauthProviders = async ( + input: SdkApiTypes.TCreateOauthProvidersBody, + ): Promise => { if (!this.stamper) { return undefined; } - const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/create_oauth_providers"; + const fullUrl = + this.config.apiBaseUrl + "/public/v1/submit/create_oauth_providers"; const body = JSON.stringify(input); const stamp = await this.stamper.stamp(body); return { @@ -963,28 +1391,42 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + createPolicies = async ( + input: SdkApiTypes.TCreatePoliciesBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - createPolicies = async (input: SdkApiTypes.TCreatePoliciesBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/create_policies", { + return this.command( + "/public/v1/submit/create_policies", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_CREATE_POLICIES" - }, "createPoliciesResult", stampWith); - } - + type: "ACTIVITY_TYPE_CREATE_POLICIES", + }, + "createPoliciesResult", + stampWith, + ); + }; - stampCreatePolicies = async (input: SdkApiTypes.TCreatePoliciesBody): Promise => { + stampCreatePolicies = async ( + input: SdkApiTypes.TCreatePoliciesBody, + ): Promise => { if (!this.stamper) { return undefined; } - const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/create_policies"; + const fullUrl = + this.config.apiBaseUrl + "/public/v1/submit/create_policies"; const body = JSON.stringify(input); const stamp = await this.stamper.stamp(body); return { @@ -992,24 +1434,37 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + createPolicy = async ( + input: SdkApiTypes.TCreatePolicyBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - createPolicy = async (input: SdkApiTypes.TCreatePolicyBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/create_policy", { + return this.command( + "/public/v1/submit/create_policy", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_CREATE_POLICY_V3" - }, "createPolicyResult", stampWith); - } + type: "ACTIVITY_TYPE_CREATE_POLICY_V3", + }, + "createPolicyResult", + stampWith, + ); + }; - - stampCreatePolicy = async (input: SdkApiTypes.TCreatePolicyBody): Promise => { + stampCreatePolicy = async ( + input: SdkApiTypes.TCreatePolicyBody, + ): Promise => { if (!this.stamper) { return undefined; } @@ -1021,28 +1476,42 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + createPrivateKeyTag = async ( + input: SdkApiTypes.TCreatePrivateKeyTagBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - createPrivateKeyTag = async (input: SdkApiTypes.TCreatePrivateKeyTagBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/create_private_key_tag", { + return this.command( + "/public/v1/submit/create_private_key_tag", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_CREATE_PRIVATE_KEY_TAG" - }, "createPrivateKeyTagResult", stampWith); - } - + type: "ACTIVITY_TYPE_CREATE_PRIVATE_KEY_TAG", + }, + "createPrivateKeyTagResult", + stampWith, + ); + }; - stampCreatePrivateKeyTag = async (input: SdkApiTypes.TCreatePrivateKeyTagBody): Promise => { + stampCreatePrivateKeyTag = async ( + input: SdkApiTypes.TCreatePrivateKeyTagBody, + ): Promise => { if (!this.stamper) { return undefined; } - const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/create_private_key_tag"; + const fullUrl = + this.config.apiBaseUrl + "/public/v1/submit/create_private_key_tag"; const body = JSON.stringify(input); const stamp = await this.stamper.stamp(body); return { @@ -1050,28 +1519,42 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + createPrivateKeys = async ( + input: SdkApiTypes.TCreatePrivateKeysBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - createPrivateKeys = async (input: SdkApiTypes.TCreatePrivateKeysBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/create_private_keys", { + return this.command( + "/public/v1/submit/create_private_keys", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_CREATE_PRIVATE_KEYS_V2" - }, "createPrivateKeysResultV2", stampWith); - } - + type: "ACTIVITY_TYPE_CREATE_PRIVATE_KEYS_V2", + }, + "createPrivateKeysResultV2", + stampWith, + ); + }; - stampCreatePrivateKeys = async (input: SdkApiTypes.TCreatePrivateKeysBody): Promise => { + stampCreatePrivateKeys = async ( + input: SdkApiTypes.TCreatePrivateKeysBody, + ): Promise => { if (!this.stamper) { return undefined; } - const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/create_private_keys"; + const fullUrl = + this.config.apiBaseUrl + "/public/v1/submit/create_private_keys"; const body = JSON.stringify(input); const stamp = await this.stamper.stamp(body); return { @@ -1079,28 +1562,42 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + createReadOnlySession = async ( + input: SdkApiTypes.TCreateReadOnlySessionBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - createReadOnlySession = async (input: SdkApiTypes.TCreateReadOnlySessionBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/create_read_only_session", { + return this.command( + "/public/v1/submit/create_read_only_session", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_CREATE_READ_ONLY_SESSION" - }, "createReadOnlySessionResult", stampWith); - } + type: "ACTIVITY_TYPE_CREATE_READ_ONLY_SESSION", + }, + "createReadOnlySessionResult", + stampWith, + ); + }; - - stampCreateReadOnlySession = async (input: SdkApiTypes.TCreateReadOnlySessionBody): Promise => { + stampCreateReadOnlySession = async ( + input: SdkApiTypes.TCreateReadOnlySessionBody, + ): Promise => { if (!this.stamper) { return undefined; } - const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/create_read_only_session"; + const fullUrl = + this.config.apiBaseUrl + "/public/v1/submit/create_read_only_session"; const body = JSON.stringify(input); const stamp = await this.stamper.stamp(body); return { @@ -1108,28 +1605,42 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + createReadWriteSession = async ( + input: SdkApiTypes.TCreateReadWriteSessionBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - createReadWriteSession = async (input: SdkApiTypes.TCreateReadWriteSessionBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/create_read_write_session", { + return this.command( + "/public/v1/submit/create_read_write_session", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_CREATE_READ_WRITE_SESSION_V2" - }, "createReadWriteSessionResultV2", stampWith); - } + type: "ACTIVITY_TYPE_CREATE_READ_WRITE_SESSION_V2", + }, + "createReadWriteSessionResultV2", + stampWith, + ); + }; - - stampCreateReadWriteSession = async (input: SdkApiTypes.TCreateReadWriteSessionBody): Promise => { + stampCreateReadWriteSession = async ( + input: SdkApiTypes.TCreateReadWriteSessionBody, + ): Promise => { if (!this.stamper) { return undefined; } - const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/create_read_write_session"; + const fullUrl = + this.config.apiBaseUrl + "/public/v1/submit/create_read_write_session"; const body = JSON.stringify(input); const stamp = await this.stamper.stamp(body); return { @@ -1137,28 +1648,42 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + createSubOrganization = async ( + input: SdkApiTypes.TCreateSubOrganizationBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - createSubOrganization = async (input: SdkApiTypes.TCreateSubOrganizationBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/create_sub_organization", { + return this.command( + "/public/v1/submit/create_sub_organization", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_CREATE_SUB_ORGANIZATION_V7" - }, "createSubOrganizationResultV7", stampWith); - } - + type: "ACTIVITY_TYPE_CREATE_SUB_ORGANIZATION_V7", + }, + "createSubOrganizationResultV7", + stampWith, + ); + }; - stampCreateSubOrganization = async (input: SdkApiTypes.TCreateSubOrganizationBody): Promise => { + stampCreateSubOrganization = async ( + input: SdkApiTypes.TCreateSubOrganizationBody, + ): Promise => { if (!this.stamper) { return undefined; } - const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/create_sub_organization"; + const fullUrl = + this.config.apiBaseUrl + "/public/v1/submit/create_sub_organization"; const body = JSON.stringify(input); const stamp = await this.stamper.stamp(body); return { @@ -1166,28 +1691,42 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + createUserTag = async ( + input: SdkApiTypes.TCreateUserTagBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - createUserTag = async (input: SdkApiTypes.TCreateUserTagBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/create_user_tag", { + return this.command( + "/public/v1/submit/create_user_tag", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_CREATE_USER_TAG" - }, "createUserTagResult", stampWith); - } - + type: "ACTIVITY_TYPE_CREATE_USER_TAG", + }, + "createUserTagResult", + stampWith, + ); + }; - stampCreateUserTag = async (input: SdkApiTypes.TCreateUserTagBody): Promise => { + stampCreateUserTag = async ( + input: SdkApiTypes.TCreateUserTagBody, + ): Promise => { if (!this.stamper) { return undefined; } - const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/create_user_tag"; + const fullUrl = + this.config.apiBaseUrl + "/public/v1/submit/create_user_tag"; const body = JSON.stringify(input); const stamp = await this.stamper.stamp(body); return { @@ -1195,24 +1734,37 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + createUsers = async ( + input: SdkApiTypes.TCreateUsersBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - createUsers = async (input: SdkApiTypes.TCreateUsersBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/create_users", { + return this.command( + "/public/v1/submit/create_users", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_CREATE_USERS_V3" - }, "createUsersResult", stampWith); - } - + type: "ACTIVITY_TYPE_CREATE_USERS_V3", + }, + "createUsersResult", + stampWith, + ); + }; - stampCreateUsers = async (input: SdkApiTypes.TCreateUsersBody): Promise => { + stampCreateUsers = async ( + input: SdkApiTypes.TCreateUsersBody, + ): Promise => { if (!this.stamper) { return undefined; } @@ -1224,24 +1776,37 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + createWallet = async ( + input: SdkApiTypes.TCreateWalletBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - createWallet = async (input: SdkApiTypes.TCreateWalletBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/create_wallet", { + return this.command( + "/public/v1/submit/create_wallet", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_CREATE_WALLET" - }, "createWalletResult", stampWith); - } + type: "ACTIVITY_TYPE_CREATE_WALLET", + }, + "createWalletResult", + stampWith, + ); + }; - - stampCreateWallet = async (input: SdkApiTypes.TCreateWalletBody): Promise => { + stampCreateWallet = async ( + input: SdkApiTypes.TCreateWalletBody, + ): Promise => { if (!this.stamper) { return undefined; } @@ -1253,28 +1818,42 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + createWalletAccounts = async ( + input: SdkApiTypes.TCreateWalletAccountsBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - createWalletAccounts = async (input: SdkApiTypes.TCreateWalletAccountsBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/create_wallet_accounts", { + return this.command( + "/public/v1/submit/create_wallet_accounts", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_CREATE_WALLET_ACCOUNTS" - }, "createWalletAccountsResult", stampWith); - } + type: "ACTIVITY_TYPE_CREATE_WALLET_ACCOUNTS", + }, + "createWalletAccountsResult", + stampWith, + ); + }; - - stampCreateWalletAccounts = async (input: SdkApiTypes.TCreateWalletAccountsBody): Promise => { + stampCreateWalletAccounts = async ( + input: SdkApiTypes.TCreateWalletAccountsBody, + ): Promise => { if (!this.stamper) { return undefined; } - const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/create_wallet_accounts"; + const fullUrl = + this.config.apiBaseUrl + "/public/v1/submit/create_wallet_accounts"; const body = JSON.stringify(input); const stamp = await this.stamper.stamp(body); return { @@ -1282,28 +1861,42 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + deleteApiKeys = async ( + input: SdkApiTypes.TDeleteApiKeysBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - deleteApiKeys = async (input: SdkApiTypes.TDeleteApiKeysBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/delete_api_keys", { + return this.command( + "/public/v1/submit/delete_api_keys", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_DELETE_API_KEYS" - }, "deleteApiKeysResult", stampWith); - } - + type: "ACTIVITY_TYPE_DELETE_API_KEYS", + }, + "deleteApiKeysResult", + stampWith, + ); + }; - stampDeleteApiKeys = async (input: SdkApiTypes.TDeleteApiKeysBody): Promise => { + stampDeleteApiKeys = async ( + input: SdkApiTypes.TDeleteApiKeysBody, + ): Promise => { if (!this.stamper) { return undefined; } - const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/delete_api_keys"; + const fullUrl = + this.config.apiBaseUrl + "/public/v1/submit/delete_api_keys"; const body = JSON.stringify(input); const stamp = await this.stamper.stamp(body); return { @@ -1311,28 +1904,42 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + deleteAuthenticators = async ( + input: SdkApiTypes.TDeleteAuthenticatorsBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - deleteAuthenticators = async (input: SdkApiTypes.TDeleteAuthenticatorsBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/delete_authenticators", { + return this.command( + "/public/v1/submit/delete_authenticators", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_DELETE_AUTHENTICATORS" - }, "deleteAuthenticatorsResult", stampWith); - } - + type: "ACTIVITY_TYPE_DELETE_AUTHENTICATORS", + }, + "deleteAuthenticatorsResult", + stampWith, + ); + }; - stampDeleteAuthenticators = async (input: SdkApiTypes.TDeleteAuthenticatorsBody): Promise => { + stampDeleteAuthenticators = async ( + input: SdkApiTypes.TDeleteAuthenticatorsBody, + ): Promise => { if (!this.stamper) { return undefined; } - const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/delete_authenticators"; + const fullUrl = + this.config.apiBaseUrl + "/public/v1/submit/delete_authenticators"; const body = JSON.stringify(input); const stamp = await this.stamper.stamp(body); return { @@ -1340,28 +1947,42 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + deleteInvitation = async ( + input: SdkApiTypes.TDeleteInvitationBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - deleteInvitation = async (input: SdkApiTypes.TDeleteInvitationBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/delete_invitation", { + return this.command( + "/public/v1/submit/delete_invitation", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_DELETE_INVITATION" - }, "deleteInvitationResult", stampWith); - } - + type: "ACTIVITY_TYPE_DELETE_INVITATION", + }, + "deleteInvitationResult", + stampWith, + ); + }; - stampDeleteInvitation = async (input: SdkApiTypes.TDeleteInvitationBody): Promise => { + stampDeleteInvitation = async ( + input: SdkApiTypes.TDeleteInvitationBody, + ): Promise => { if (!this.stamper) { return undefined; } - const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/delete_invitation"; + const fullUrl = + this.config.apiBaseUrl + "/public/v1/submit/delete_invitation"; const body = JSON.stringify(input); const stamp = await this.stamper.stamp(body); return { @@ -1369,28 +1990,42 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + deleteOauthProviders = async ( + input: SdkApiTypes.TDeleteOauthProvidersBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - deleteOauthProviders = async (input: SdkApiTypes.TDeleteOauthProvidersBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/delete_oauth_providers", { + return this.command( + "/public/v1/submit/delete_oauth_providers", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_DELETE_OAUTH_PROVIDERS" - }, "deleteOauthProvidersResult", stampWith); - } + type: "ACTIVITY_TYPE_DELETE_OAUTH_PROVIDERS", + }, + "deleteOauthProvidersResult", + stampWith, + ); + }; - - stampDeleteOauthProviders = async (input: SdkApiTypes.TDeleteOauthProvidersBody): Promise => { + stampDeleteOauthProviders = async ( + input: SdkApiTypes.TDeleteOauthProvidersBody, + ): Promise => { if (!this.stamper) { return undefined; } - const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/delete_oauth_providers"; + const fullUrl = + this.config.apiBaseUrl + "/public/v1/submit/delete_oauth_providers"; const body = JSON.stringify(input); const stamp = await this.stamper.stamp(body); return { @@ -1398,24 +2033,37 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + deletePolicy = async ( + input: SdkApiTypes.TDeletePolicyBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - deletePolicy = async (input: SdkApiTypes.TDeletePolicyBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/delete_policy", { + return this.command( + "/public/v1/submit/delete_policy", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_DELETE_POLICY" - }, "deletePolicyResult", stampWith); - } - + type: "ACTIVITY_TYPE_DELETE_POLICY", + }, + "deletePolicyResult", + stampWith, + ); + }; - stampDeletePolicy = async (input: SdkApiTypes.TDeletePolicyBody): Promise => { + stampDeletePolicy = async ( + input: SdkApiTypes.TDeletePolicyBody, + ): Promise => { if (!this.stamper) { return undefined; } @@ -1427,28 +2075,42 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + deletePrivateKeyTags = async ( + input: SdkApiTypes.TDeletePrivateKeyTagsBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - deletePrivateKeyTags = async (input: SdkApiTypes.TDeletePrivateKeyTagsBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/delete_private_key_tags", { + return this.command( + "/public/v1/submit/delete_private_key_tags", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_DELETE_PRIVATE_KEY_TAGS" - }, "deletePrivateKeyTagsResult", stampWith); - } - + type: "ACTIVITY_TYPE_DELETE_PRIVATE_KEY_TAGS", + }, + "deletePrivateKeyTagsResult", + stampWith, + ); + }; - stampDeletePrivateKeyTags = async (input: SdkApiTypes.TDeletePrivateKeyTagsBody): Promise => { + stampDeletePrivateKeyTags = async ( + input: SdkApiTypes.TDeletePrivateKeyTagsBody, + ): Promise => { if (!this.stamper) { return undefined; } - const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/delete_private_key_tags"; + const fullUrl = + this.config.apiBaseUrl + "/public/v1/submit/delete_private_key_tags"; const body = JSON.stringify(input); const stamp = await this.stamper.stamp(body); return { @@ -1456,28 +2118,42 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + deletePrivateKeys = async ( + input: SdkApiTypes.TDeletePrivateKeysBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - deletePrivateKeys = async (input: SdkApiTypes.TDeletePrivateKeysBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/delete_private_keys", { + return this.command( + "/public/v1/submit/delete_private_keys", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_DELETE_PRIVATE_KEYS" - }, "deletePrivateKeysResult", stampWith); - } + type: "ACTIVITY_TYPE_DELETE_PRIVATE_KEYS", + }, + "deletePrivateKeysResult", + stampWith, + ); + }; - - stampDeletePrivateKeys = async (input: SdkApiTypes.TDeletePrivateKeysBody): Promise => { + stampDeletePrivateKeys = async ( + input: SdkApiTypes.TDeletePrivateKeysBody, + ): Promise => { if (!this.stamper) { return undefined; } - const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/delete_private_keys"; + const fullUrl = + this.config.apiBaseUrl + "/public/v1/submit/delete_private_keys"; const body = JSON.stringify(input); const stamp = await this.stamper.stamp(body); return { @@ -1485,28 +2161,42 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + deleteSubOrganization = async ( + input: SdkApiTypes.TDeleteSubOrganizationBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - deleteSubOrganization = async (input: SdkApiTypes.TDeleteSubOrganizationBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/delete_sub_organization", { + return this.command( + "/public/v1/submit/delete_sub_organization", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_DELETE_SUB_ORGANIZATION" - }, "deleteSubOrganizationResult", stampWith); - } + type: "ACTIVITY_TYPE_DELETE_SUB_ORGANIZATION", + }, + "deleteSubOrganizationResult", + stampWith, + ); + }; - - stampDeleteSubOrganization = async (input: SdkApiTypes.TDeleteSubOrganizationBody): Promise => { + stampDeleteSubOrganization = async ( + input: SdkApiTypes.TDeleteSubOrganizationBody, + ): Promise => { if (!this.stamper) { return undefined; } - const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/delete_sub_organization"; + const fullUrl = + this.config.apiBaseUrl + "/public/v1/submit/delete_sub_organization"; const body = JSON.stringify(input); const stamp = await this.stamper.stamp(body); return { @@ -1514,28 +2204,42 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + deleteUserTags = async ( + input: SdkApiTypes.TDeleteUserTagsBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - deleteUserTags = async (input: SdkApiTypes.TDeleteUserTagsBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/delete_user_tags", { + return this.command( + "/public/v1/submit/delete_user_tags", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_DELETE_USER_TAGS" - }, "deleteUserTagsResult", stampWith); - } - + type: "ACTIVITY_TYPE_DELETE_USER_TAGS", + }, + "deleteUserTagsResult", + stampWith, + ); + }; - stampDeleteUserTags = async (input: SdkApiTypes.TDeleteUserTagsBody): Promise => { + stampDeleteUserTags = async ( + input: SdkApiTypes.TDeleteUserTagsBody, + ): Promise => { if (!this.stamper) { return undefined; } - const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/delete_user_tags"; + const fullUrl = + this.config.apiBaseUrl + "/public/v1/submit/delete_user_tags"; const body = JSON.stringify(input); const stamp = await this.stamper.stamp(body); return { @@ -1543,24 +2247,37 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + deleteUsers = async ( + input: SdkApiTypes.TDeleteUsersBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - deleteUsers = async (input: SdkApiTypes.TDeleteUsersBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/delete_users", { + return this.command( + "/public/v1/submit/delete_users", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_DELETE_USERS" - }, "deleteUsersResult", stampWith); - } - + type: "ACTIVITY_TYPE_DELETE_USERS", + }, + "deleteUsersResult", + stampWith, + ); + }; - stampDeleteUsers = async (input: SdkApiTypes.TDeleteUsersBody): Promise => { + stampDeleteUsers = async ( + input: SdkApiTypes.TDeleteUsersBody, + ): Promise => { if (!this.stamper) { return undefined; } @@ -1572,24 +2289,37 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + deleteWallets = async ( + input: SdkApiTypes.TDeleteWalletsBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - deleteWallets = async (input: SdkApiTypes.TDeleteWalletsBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/delete_wallets", { + return this.command( + "/public/v1/submit/delete_wallets", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_DELETE_WALLETS" - }, "deleteWalletsResult", stampWith); - } - + type: "ACTIVITY_TYPE_DELETE_WALLETS", + }, + "deleteWalletsResult", + stampWith, + ); + }; - stampDeleteWallets = async (input: SdkApiTypes.TDeleteWalletsBody): Promise => { + stampDeleteWallets = async ( + input: SdkApiTypes.TDeleteWalletsBody, + ): Promise => { if (!this.stamper) { return undefined; } @@ -1601,24 +2331,37 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + emailAuth = async ( + input: SdkApiTypes.TEmailAuthBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - emailAuth = async (input: SdkApiTypes.TEmailAuthBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/email_auth", { + return this.command( + "/public/v1/submit/email_auth", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_EMAIL_AUTH_V2" - }, "emailAuthResult", stampWith); - } + type: "ACTIVITY_TYPE_EMAIL_AUTH_V2", + }, + "emailAuthResult", + stampWith, + ); + }; - - stampEmailAuth = async (input: SdkApiTypes.TEmailAuthBody): Promise => { + stampEmailAuth = async ( + input: SdkApiTypes.TEmailAuthBody, + ): Promise => { if (!this.stamper) { return undefined; } @@ -1630,28 +2373,42 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + exportPrivateKey = async ( + input: SdkApiTypes.TExportPrivateKeyBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - exportPrivateKey = async (input: SdkApiTypes.TExportPrivateKeyBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/export_private_key", { + return this.command( + "/public/v1/submit/export_private_key", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_EXPORT_PRIVATE_KEY" - }, "exportPrivateKeyResult", stampWith); - } + type: "ACTIVITY_TYPE_EXPORT_PRIVATE_KEY", + }, + "exportPrivateKeyResult", + stampWith, + ); + }; - - stampExportPrivateKey = async (input: SdkApiTypes.TExportPrivateKeyBody): Promise => { + stampExportPrivateKey = async ( + input: SdkApiTypes.TExportPrivateKeyBody, + ): Promise => { if (!this.stamper) { return undefined; } - const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/export_private_key"; + const fullUrl = + this.config.apiBaseUrl + "/public/v1/submit/export_private_key"; const body = JSON.stringify(input); const stamp = await this.stamper.stamp(body); return { @@ -1659,24 +2416,37 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + exportWallet = async ( + input: SdkApiTypes.TExportWalletBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - exportWallet = async (input: SdkApiTypes.TExportWalletBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/export_wallet", { + return this.command( + "/public/v1/submit/export_wallet", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_EXPORT_WALLET" - }, "exportWalletResult", stampWith); - } - + type: "ACTIVITY_TYPE_EXPORT_WALLET", + }, + "exportWalletResult", + stampWith, + ); + }; - stampExportWallet = async (input: SdkApiTypes.TExportWalletBody): Promise => { + stampExportWallet = async ( + input: SdkApiTypes.TExportWalletBody, + ): Promise => { if (!this.stamper) { return undefined; } @@ -1688,28 +2458,42 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + exportWalletAccount = async ( + input: SdkApiTypes.TExportWalletAccountBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - exportWalletAccount = async (input: SdkApiTypes.TExportWalletAccountBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/export_wallet_account", { + return this.command( + "/public/v1/submit/export_wallet_account", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_EXPORT_WALLET_ACCOUNT" - }, "exportWalletAccountResult", stampWith); - } - + type: "ACTIVITY_TYPE_EXPORT_WALLET_ACCOUNT", + }, + "exportWalletAccountResult", + stampWith, + ); + }; - stampExportWalletAccount = async (input: SdkApiTypes.TExportWalletAccountBody): Promise => { + stampExportWalletAccount = async ( + input: SdkApiTypes.TExportWalletAccountBody, + ): Promise => { if (!this.stamper) { return undefined; } - const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/export_wallet_account"; + const fullUrl = + this.config.apiBaseUrl + "/public/v1/submit/export_wallet_account"; const body = JSON.stringify(input); const stamp = await this.stamper.stamp(body); return { @@ -1717,28 +2501,42 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + importPrivateKey = async ( + input: SdkApiTypes.TImportPrivateKeyBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - importPrivateKey = async (input: SdkApiTypes.TImportPrivateKeyBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/import_private_key", { + return this.command( + "/public/v1/submit/import_private_key", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_IMPORT_PRIVATE_KEY" - }, "importPrivateKeyResult", stampWith); - } - + type: "ACTIVITY_TYPE_IMPORT_PRIVATE_KEY", + }, + "importPrivateKeyResult", + stampWith, + ); + }; - stampImportPrivateKey = async (input: SdkApiTypes.TImportPrivateKeyBody): Promise => { + stampImportPrivateKey = async ( + input: SdkApiTypes.TImportPrivateKeyBody, + ): Promise => { if (!this.stamper) { return undefined; } - const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/import_private_key"; + const fullUrl = + this.config.apiBaseUrl + "/public/v1/submit/import_private_key"; const body = JSON.stringify(input); const stamp = await this.stamper.stamp(body); return { @@ -1746,24 +2544,37 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + importWallet = async ( + input: SdkApiTypes.TImportWalletBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - importWallet = async (input: SdkApiTypes.TImportWalletBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/import_wallet", { + return this.command( + "/public/v1/submit/import_wallet", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_IMPORT_WALLET" - }, "importWalletResult", stampWith); - } + type: "ACTIVITY_TYPE_IMPORT_WALLET", + }, + "importWalletResult", + stampWith, + ); + }; - - stampImportWallet = async (input: SdkApiTypes.TImportWalletBody): Promise => { + stampImportWallet = async ( + input: SdkApiTypes.TImportWalletBody, + ): Promise => { if (!this.stamper) { return undefined; } @@ -1775,28 +2586,42 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + initImportPrivateKey = async ( + input: SdkApiTypes.TInitImportPrivateKeyBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - initImportPrivateKey = async (input: SdkApiTypes.TInitImportPrivateKeyBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/init_import_private_key", { + return this.command( + "/public/v1/submit/init_import_private_key", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_INIT_IMPORT_PRIVATE_KEY" - }, "initImportPrivateKeyResult", stampWith); - } - + type: "ACTIVITY_TYPE_INIT_IMPORT_PRIVATE_KEY", + }, + "initImportPrivateKeyResult", + stampWith, + ); + }; - stampInitImportPrivateKey = async (input: SdkApiTypes.TInitImportPrivateKeyBody): Promise => { + stampInitImportPrivateKey = async ( + input: SdkApiTypes.TInitImportPrivateKeyBody, + ): Promise => { if (!this.stamper) { return undefined; } - const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/init_import_private_key"; + const fullUrl = + this.config.apiBaseUrl + "/public/v1/submit/init_import_private_key"; const body = JSON.stringify(input); const stamp = await this.stamper.stamp(body); return { @@ -1804,28 +2629,42 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + initImportWallet = async ( + input: SdkApiTypes.TInitImportWalletBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - initImportWallet = async (input: SdkApiTypes.TInitImportWalletBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/init_import_wallet", { + return this.command( + "/public/v1/submit/init_import_wallet", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_INIT_IMPORT_WALLET" - }, "initImportWalletResult", stampWith); - } - + type: "ACTIVITY_TYPE_INIT_IMPORT_WALLET", + }, + "initImportWalletResult", + stampWith, + ); + }; - stampInitImportWallet = async (input: SdkApiTypes.TInitImportWalletBody): Promise => { + stampInitImportWallet = async ( + input: SdkApiTypes.TInitImportWalletBody, + ): Promise => { if (!this.stamper) { return undefined; } - const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/init_import_wallet"; + const fullUrl = + this.config.apiBaseUrl + "/public/v1/submit/init_import_wallet"; const body = JSON.stringify(input); const stamp = await this.stamper.stamp(body); return { @@ -1833,24 +2672,37 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + initOtp = async ( + input: SdkApiTypes.TInitOtpBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - initOtp = async (input: SdkApiTypes.TInitOtpBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/init_otp", { + return this.command( + "/public/v1/submit/init_otp", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_INIT_OTP" - }, "initOtpResult", stampWith); - } + type: "ACTIVITY_TYPE_INIT_OTP", + }, + "initOtpResult", + stampWith, + ); + }; - - stampInitOtp = async (input: SdkApiTypes.TInitOtpBody): Promise => { + stampInitOtp = async ( + input: SdkApiTypes.TInitOtpBody, + ): Promise => { if (!this.stamper) { return undefined; } @@ -1862,24 +2714,37 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + initOtpAuth = async ( + input: SdkApiTypes.TInitOtpAuthBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - initOtpAuth = async (input: SdkApiTypes.TInitOtpAuthBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/init_otp_auth", { + return this.command( + "/public/v1/submit/init_otp_auth", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_INIT_OTP_AUTH_V2" - }, "initOtpAuthResultV2", stampWith); - } + type: "ACTIVITY_TYPE_INIT_OTP_AUTH_V2", + }, + "initOtpAuthResultV2", + stampWith, + ); + }; - - stampInitOtpAuth = async (input: SdkApiTypes.TInitOtpAuthBody): Promise => { + stampInitOtpAuth = async ( + input: SdkApiTypes.TInitOtpAuthBody, + ): Promise => { if (!this.stamper) { return undefined; } @@ -1891,28 +2756,42 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + initUserEmailRecovery = async ( + input: SdkApiTypes.TInitUserEmailRecoveryBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - initUserEmailRecovery = async (input: SdkApiTypes.TInitUserEmailRecoveryBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/init_user_email_recovery", { + return this.command( + "/public/v1/submit/init_user_email_recovery", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_INIT_USER_EMAIL_RECOVERY" - }, "initUserEmailRecoveryResult", stampWith); - } - + type: "ACTIVITY_TYPE_INIT_USER_EMAIL_RECOVERY", + }, + "initUserEmailRecoveryResult", + stampWith, + ); + }; - stampInitUserEmailRecovery = async (input: SdkApiTypes.TInitUserEmailRecoveryBody): Promise => { + stampInitUserEmailRecovery = async ( + input: SdkApiTypes.TInitUserEmailRecoveryBody, + ): Promise => { if (!this.stamper) { return undefined; } - const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/init_user_email_recovery"; + const fullUrl = + this.config.apiBaseUrl + "/public/v1/submit/init_user_email_recovery"; const body = JSON.stringify(input); const stamp = await this.stamper.stamp(body); return { @@ -1920,24 +2799,37 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + oauth = async ( + input: SdkApiTypes.TOauthBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - oauth = async (input: SdkApiTypes.TOauthBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/oauth", { + return this.command( + "/public/v1/submit/oauth", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_OAUTH" - }, "oauthResult", stampWith); - } - + type: "ACTIVITY_TYPE_OAUTH", + }, + "oauthResult", + stampWith, + ); + }; - stampOauth = async (input: SdkApiTypes.TOauthBody): Promise => { + stampOauth = async ( + input: SdkApiTypes.TOauthBody, + ): Promise => { if (!this.stamper) { return undefined; } @@ -1949,24 +2841,37 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + oauthLogin = async ( + input: SdkApiTypes.TOauthLoginBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - oauthLogin = async (input: SdkApiTypes.TOauthLoginBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/oauth_login", { + return this.command( + "/public/v1/submit/oauth_login", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_OAUTH_LOGIN" - }, "oauthLoginResult", stampWith); - } - + type: "ACTIVITY_TYPE_OAUTH_LOGIN", + }, + "oauthLoginResult", + stampWith, + ); + }; - stampOauthLogin = async (input: SdkApiTypes.TOauthLoginBody): Promise => { + stampOauthLogin = async ( + input: SdkApiTypes.TOauthLoginBody, + ): Promise => { if (!this.stamper) { return undefined; } @@ -1978,24 +2883,37 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + otpAuth = async ( + input: SdkApiTypes.TOtpAuthBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - otpAuth = async (input: SdkApiTypes.TOtpAuthBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/otp_auth", { + return this.command( + "/public/v1/submit/otp_auth", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_OTP_AUTH" - }, "otpAuthResult", stampWith); - } + type: "ACTIVITY_TYPE_OTP_AUTH", + }, + "otpAuthResult", + stampWith, + ); + }; - - stampOtpAuth = async (input: SdkApiTypes.TOtpAuthBody): Promise => { + stampOtpAuth = async ( + input: SdkApiTypes.TOtpAuthBody, + ): Promise => { if (!this.stamper) { return undefined; } @@ -2007,24 +2925,37 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + otpLogin = async ( + input: SdkApiTypes.TOtpLoginBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - otpLogin = async (input: SdkApiTypes.TOtpLoginBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/otp_login", { + return this.command( + "/public/v1/submit/otp_login", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_OTP_LOGIN" - }, "otpLoginResult", stampWith); - } + type: "ACTIVITY_TYPE_OTP_LOGIN", + }, + "otpLoginResult", + stampWith, + ); + }; - - stampOtpLogin = async (input: SdkApiTypes.TOtpLoginBody): Promise => { + stampOtpLogin = async ( + input: SdkApiTypes.TOtpLoginBody, + ): Promise => { if (!this.stamper) { return undefined; } @@ -2036,24 +2967,37 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + recoverUser = async ( + input: SdkApiTypes.TRecoverUserBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - recoverUser = async (input: SdkApiTypes.TRecoverUserBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/recover_user", { + return this.command( + "/public/v1/submit/recover_user", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_RECOVER_USER" - }, "recoverUserResult", stampWith); - } - + type: "ACTIVITY_TYPE_RECOVER_USER", + }, + "recoverUserResult", + stampWith, + ); + }; - stampRecoverUser = async (input: SdkApiTypes.TRecoverUserBody): Promise => { + stampRecoverUser = async ( + input: SdkApiTypes.TRecoverUserBody, + ): Promise => { if (!this.stamper) { return undefined; } @@ -2065,28 +3009,40 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } - - - rejectActivity = async (input: SdkApiTypes.TRejectActivityBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - return this.activityDecision("/public/v1/submit/reject_activity", - { - parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), - timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_REJECT_ACTIVITY" - }, stampWith); - } + }; + rejectActivity = async ( + input: SdkApiTypes.TRejectActivityBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); + return this.activityDecision( + "/public/v1/submit/reject_activity", + { + parameters: rest, + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, + timestampMs: timestampMs ?? String(Date.now()), + type: "ACTIVITY_TYPE_REJECT_ACTIVITY", + }, + stampWith, + ); + }; - stampRejectActivity = async (input: SdkApiTypes.TRejectActivityBody): Promise => { + stampRejectActivity = async ( + input: SdkApiTypes.TRejectActivityBody, + ): Promise => { if (!this.stamper) { return undefined; } - const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/reject_activity"; + const fullUrl = + this.config.apiBaseUrl + "/public/v1/submit/reject_activity"; const body = JSON.stringify(input); const stamp = await this.stamper.stamp(body); return { @@ -2094,28 +3050,42 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + removeOrganizationFeature = async ( + input: SdkApiTypes.TRemoveOrganizationFeatureBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - removeOrganizationFeature = async (input: SdkApiTypes.TRemoveOrganizationFeatureBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/remove_organization_feature", { + return this.command( + "/public/v1/submit/remove_organization_feature", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_REMOVE_ORGANIZATION_FEATURE" - }, "removeOrganizationFeatureResult", stampWith); - } + type: "ACTIVITY_TYPE_REMOVE_ORGANIZATION_FEATURE", + }, + "removeOrganizationFeatureResult", + stampWith, + ); + }; - - stampRemoveOrganizationFeature = async (input: SdkApiTypes.TRemoveOrganizationFeatureBody): Promise => { + stampRemoveOrganizationFeature = async ( + input: SdkApiTypes.TRemoveOrganizationFeatureBody, + ): Promise => { if (!this.stamper) { return undefined; } - const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/remove_organization_feature"; + const fullUrl = + this.config.apiBaseUrl + "/public/v1/submit/remove_organization_feature"; const body = JSON.stringify(input); const stamp = await this.stamper.stamp(body); return { @@ -2123,28 +3093,42 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + setOrganizationFeature = async ( + input: SdkApiTypes.TSetOrganizationFeatureBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - setOrganizationFeature = async (input: SdkApiTypes.TSetOrganizationFeatureBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/set_organization_feature", { + return this.command( + "/public/v1/submit/set_organization_feature", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_SET_ORGANIZATION_FEATURE" - }, "setOrganizationFeatureResult", stampWith); - } - + type: "ACTIVITY_TYPE_SET_ORGANIZATION_FEATURE", + }, + "setOrganizationFeatureResult", + stampWith, + ); + }; - stampSetOrganizationFeature = async (input: SdkApiTypes.TSetOrganizationFeatureBody): Promise => { + stampSetOrganizationFeature = async ( + input: SdkApiTypes.TSetOrganizationFeatureBody, + ): Promise => { if (!this.stamper) { return undefined; } - const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/set_organization_feature"; + const fullUrl = + this.config.apiBaseUrl + "/public/v1/submit/set_organization_feature"; const body = JSON.stringify(input); const stamp = await this.stamper.stamp(body); return { @@ -2152,28 +3136,42 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + signRawPayload = async ( + input: SdkApiTypes.TSignRawPayloadBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - signRawPayload = async (input: SdkApiTypes.TSignRawPayloadBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/sign_raw_payload", { + return this.command( + "/public/v1/submit/sign_raw_payload", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_SIGN_RAW_PAYLOAD_V2" - }, "signRawPayloadResult", stampWith); - } - + type: "ACTIVITY_TYPE_SIGN_RAW_PAYLOAD_V2", + }, + "signRawPayloadResult", + stampWith, + ); + }; - stampSignRawPayload = async (input: SdkApiTypes.TSignRawPayloadBody): Promise => { + stampSignRawPayload = async ( + input: SdkApiTypes.TSignRawPayloadBody, + ): Promise => { if (!this.stamper) { return undefined; } - const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/sign_raw_payload"; + const fullUrl = + this.config.apiBaseUrl + "/public/v1/submit/sign_raw_payload"; const body = JSON.stringify(input); const stamp = await this.stamper.stamp(body); return { @@ -2181,28 +3179,42 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + signRawPayloads = async ( + input: SdkApiTypes.TSignRawPayloadsBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - signRawPayloads = async (input: SdkApiTypes.TSignRawPayloadsBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/sign_raw_payloads", { + return this.command( + "/public/v1/submit/sign_raw_payloads", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_SIGN_RAW_PAYLOADS" - }, "signRawPayloadsResult", stampWith); - } + type: "ACTIVITY_TYPE_SIGN_RAW_PAYLOADS", + }, + "signRawPayloadsResult", + stampWith, + ); + }; - - stampSignRawPayloads = async (input: SdkApiTypes.TSignRawPayloadsBody): Promise => { + stampSignRawPayloads = async ( + input: SdkApiTypes.TSignRawPayloadsBody, + ): Promise => { if (!this.stamper) { return undefined; } - const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/sign_raw_payloads"; + const fullUrl = + this.config.apiBaseUrl + "/public/v1/submit/sign_raw_payloads"; const body = JSON.stringify(input); const stamp = await this.stamper.stamp(body); return { @@ -2210,28 +3222,42 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + signTransaction = async ( + input: SdkApiTypes.TSignTransactionBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - signTransaction = async (input: SdkApiTypes.TSignTransactionBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/sign_transaction", { + return this.command( + "/public/v1/submit/sign_transaction", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_SIGN_TRANSACTION_V2" - }, "signTransactionResult", stampWith); - } + type: "ACTIVITY_TYPE_SIGN_TRANSACTION_V2", + }, + "signTransactionResult", + stampWith, + ); + }; - - stampSignTransaction = async (input: SdkApiTypes.TSignTransactionBody): Promise => { + stampSignTransaction = async ( + input: SdkApiTypes.TSignTransactionBody, + ): Promise => { if (!this.stamper) { return undefined; } - const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/sign_transaction"; + const fullUrl = + this.config.apiBaseUrl + "/public/v1/submit/sign_transaction"; const body = JSON.stringify(input); const stamp = await this.stamper.stamp(body); return { @@ -2239,24 +3265,37 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + stampLogin = async ( + input: SdkApiTypes.TStampLoginBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - stampLogin = async (input: SdkApiTypes.TStampLoginBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/stamp_login", { + return this.command( + "/public/v1/submit/stamp_login", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_STAMP_LOGIN" - }, "stampLoginResult", stampWith); - } - + type: "ACTIVITY_TYPE_STAMP_LOGIN", + }, + "stampLoginResult", + stampWith, + ); + }; - stampStampLogin = async (input: SdkApiTypes.TStampLoginBody): Promise => { + stampStampLogin = async ( + input: SdkApiTypes.TStampLoginBody, + ): Promise => { if (!this.stamper) { return undefined; } @@ -2268,24 +3307,37 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + updatePolicy = async ( + input: SdkApiTypes.TUpdatePolicyBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - updatePolicy = async (input: SdkApiTypes.TUpdatePolicyBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/update_policy", { + return this.command( + "/public/v1/submit/update_policy", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_UPDATE_POLICY_V2" - }, "updatePolicyResultV2", stampWith); - } - + type: "ACTIVITY_TYPE_UPDATE_POLICY_V2", + }, + "updatePolicyResultV2", + stampWith, + ); + }; - stampUpdatePolicy = async (input: SdkApiTypes.TUpdatePolicyBody): Promise => { + stampUpdatePolicy = async ( + input: SdkApiTypes.TUpdatePolicyBody, + ): Promise => { if (!this.stamper) { return undefined; } @@ -2297,28 +3349,42 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + updatePrivateKeyTag = async ( + input: SdkApiTypes.TUpdatePrivateKeyTagBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - updatePrivateKeyTag = async (input: SdkApiTypes.TUpdatePrivateKeyTagBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/update_private_key_tag", { + return this.command( + "/public/v1/submit/update_private_key_tag", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_UPDATE_PRIVATE_KEY_TAG" - }, "updatePrivateKeyTagResult", stampWith); - } - + type: "ACTIVITY_TYPE_UPDATE_PRIVATE_KEY_TAG", + }, + "updatePrivateKeyTagResult", + stampWith, + ); + }; - stampUpdatePrivateKeyTag = async (input: SdkApiTypes.TUpdatePrivateKeyTagBody): Promise => { + stampUpdatePrivateKeyTag = async ( + input: SdkApiTypes.TUpdatePrivateKeyTagBody, + ): Promise => { if (!this.stamper) { return undefined; } - const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/update_private_key_tag"; + const fullUrl = + this.config.apiBaseUrl + "/public/v1/submit/update_private_key_tag"; const body = JSON.stringify(input); const stamp = await this.stamper.stamp(body); return { @@ -2326,28 +3392,42 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + updateRootQuorum = async ( + input: SdkApiTypes.TUpdateRootQuorumBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - updateRootQuorum = async (input: SdkApiTypes.TUpdateRootQuorumBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/update_root_quorum", { + return this.command( + "/public/v1/submit/update_root_quorum", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_UPDATE_ROOT_QUORUM" - }, "updateRootQuorumResult", stampWith); - } + type: "ACTIVITY_TYPE_UPDATE_ROOT_QUORUM", + }, + "updateRootQuorumResult", + stampWith, + ); + }; - - stampUpdateRootQuorum = async (input: SdkApiTypes.TUpdateRootQuorumBody): Promise => { + stampUpdateRootQuorum = async ( + input: SdkApiTypes.TUpdateRootQuorumBody, + ): Promise => { if (!this.stamper) { return undefined; } - const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/update_root_quorum"; + const fullUrl = + this.config.apiBaseUrl + "/public/v1/submit/update_root_quorum"; const body = JSON.stringify(input); const stamp = await this.stamper.stamp(body); return { @@ -2355,24 +3435,37 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + updateUser = async ( + input: SdkApiTypes.TUpdateUserBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - updateUser = async (input: SdkApiTypes.TUpdateUserBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/update_user", { + return this.command( + "/public/v1/submit/update_user", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_UPDATE_USER" - }, "updateUserResult", stampWith); - } + type: "ACTIVITY_TYPE_UPDATE_USER", + }, + "updateUserResult", + stampWith, + ); + }; - - stampUpdateUser = async (input: SdkApiTypes.TUpdateUserBody): Promise => { + stampUpdateUser = async ( + input: SdkApiTypes.TUpdateUserBody, + ): Promise => { if (!this.stamper) { return undefined; } @@ -2384,28 +3477,42 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + updateUserTag = async ( + input: SdkApiTypes.TUpdateUserTagBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - updateUserTag = async (input: SdkApiTypes.TUpdateUserTagBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/update_user_tag", { + return this.command( + "/public/v1/submit/update_user_tag", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_UPDATE_USER_TAG" - }, "updateUserTagResult", stampWith); - } - + type: "ACTIVITY_TYPE_UPDATE_USER_TAG", + }, + "updateUserTagResult", + stampWith, + ); + }; - stampUpdateUserTag = async (input: SdkApiTypes.TUpdateUserTagBody): Promise => { + stampUpdateUserTag = async ( + input: SdkApiTypes.TUpdateUserTagBody, + ): Promise => { if (!this.stamper) { return undefined; } - const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/update_user_tag"; + const fullUrl = + this.config.apiBaseUrl + "/public/v1/submit/update_user_tag"; const body = JSON.stringify(input); const stamp = await this.stamper.stamp(body); return { @@ -2413,24 +3520,37 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + updateWallet = async ( + input: SdkApiTypes.TUpdateWalletBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - updateWallet = async (input: SdkApiTypes.TUpdateWalletBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/update_wallet", { + return this.command( + "/public/v1/submit/update_wallet", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_UPDATE_WALLET" - }, "updateWalletResult", stampWith); - } - + type: "ACTIVITY_TYPE_UPDATE_WALLET", + }, + "updateWalletResult", + stampWith, + ); + }; - stampUpdateWallet = async (input: SdkApiTypes.TUpdateWalletBody): Promise => { + stampUpdateWallet = async ( + input: SdkApiTypes.TUpdateWalletBody, + ): Promise => { if (!this.stamper) { return undefined; } @@ -2442,24 +3562,37 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } + }; + verifyOtp = async ( + input: SdkApiTypes.TVerifyOtpBody, + stampWith?: StamperType, + ): Promise => { + const { organizationId, timestampMs, ...rest } = input; + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); - verifyOtp = async (input: SdkApiTypes.TVerifyOtpBody, stampWith?: StamperType): Promise => { - const { organizationId, timestampMs, ...rest } = input; - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - - return this.command("/public/v1/submit/verify_otp", { + return this.command( + "/public/v1/submit/verify_otp", + { parameters: rest, - organizationId: organizationId ?? (session?.organizationId ?? this.config.organizationId), + organizationId: + organizationId ?? + session?.organizationId ?? + this.config.organizationId, timestampMs: timestampMs ?? String(Date.now()), - type: "ACTIVITY_TYPE_VERIFY_OTP" - }, "verifyOtpResult", stampWith); - } - + type: "ACTIVITY_TYPE_VERIFY_OTP", + }, + "verifyOtpResult", + stampWith, + ); + }; - stampVerifyOtp = async (input: SdkApiTypes.TVerifyOtpBody): Promise => { + stampVerifyOtp = async ( + input: SdkApiTypes.TVerifyOtpBody, + ): Promise => { if (!this.stamper) { return undefined; } @@ -2471,20 +3604,32 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } - + }; - testRateLimits = async (input: SdkApiTypes.TTestRateLimitsBody, stampWith?: StamperType): Promise => { - let session = await getStorageValue(StorageKeys.Session); - session = parseSession(session!); - return this.request("/tkhq/api/v1/test_rate_limits", { + testRateLimits = async ( + input: SdkApiTypes.TTestRateLimitsBody, + stampWith?: StamperType, + ): Promise => { + let session = await this.storageManager?.getStorageValue( + StorageKey.Session, + ); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage + return this.request( + "/tkhq/api/v1/test_rate_limits", + { ...input, - organizationId: input.organizationId ?? session?.organizationId ?? this.config.organizationId - }, stampWith); - } - + organizationId: + input.organizationId ?? + session?.organizationId ?? + this.config.organizationId, + }, + stampWith, + ); + }; - stampTestRateLimits = async (input: SdkApiTypes.TTestRateLimitsBody): Promise => { + stampTestRateLimits = async ( + input: SdkApiTypes.TTestRateLimitsBody, + ): Promise => { if (!this.stamper) { return undefined; } @@ -2496,6 +3641,5 @@ import { StamperType } from "../__types__/base"; stamp: stamp, url: fullUrl, }; - } - -} \ No newline at end of file + }; +} diff --git a/packages/sdk-js/src/__generated__/sdk_api_types.ts b/packages/sdk-js/src/__generated__/sdk_api_types.ts index 3c56a2ba2..63c6ab48b 100644 --- a/packages/sdk-js/src/__generated__/sdk_api_types.ts +++ b/packages/sdk-js/src/__generated__/sdk_api_types.ts @@ -2,510 +2,886 @@ import type { operations, definitions } from "../__inputs__/public_api.types"; -import type { queryOverrideParams, commandOverrideParams } from "../__types__/base"; +import type { + queryOverrideParams, + commandOverrideParams, +} from "../__types__/base"; -export type TGetActivityResponse = operations["PublicApiService_GetActivity"]["responses"]["200"]["schema"]; +export type TGetActivityResponse = + operations["PublicApiService_GetActivity"]["responses"]["200"]["schema"]; export type TGetActivityInput = { body: TGetActivityBody }; -export type TGetActivityBody = Omit & queryOverrideParams; +export type TGetActivityBody = Omit< + operations["PublicApiService_GetActivity"]["parameters"]["body"]["body"], + "organizationId" +> & + queryOverrideParams; -export type TGetApiKeyResponse = operations["PublicApiService_GetApiKey"]["responses"]["200"]["schema"]; +export type TGetApiKeyResponse = + operations["PublicApiService_GetApiKey"]["responses"]["200"]["schema"]; export type TGetApiKeyInput = { body: TGetApiKeyBody }; -export type TGetApiKeyBody = Omit & queryOverrideParams; +export type TGetApiKeyBody = Omit< + operations["PublicApiService_GetApiKey"]["parameters"]["body"]["body"], + "organizationId" +> & + queryOverrideParams; -export type TGetApiKeysResponse = operations["PublicApiService_GetApiKeys"]["responses"]["200"]["schema"]; +export type TGetApiKeysResponse = + operations["PublicApiService_GetApiKeys"]["responses"]["200"]["schema"]; export type TGetApiKeysInput = { body: TGetApiKeysBody }; -export type TGetApiKeysBody = Omit & queryOverrideParams; +export type TGetApiKeysBody = Omit< + operations["PublicApiService_GetApiKeys"]["parameters"]["body"]["body"], + "organizationId" +> & + queryOverrideParams; -export type TGetAttestationDocumentResponse = operations["PublicApiService_GetAttestationDocument"]["responses"]["200"]["schema"]; +export type TGetAttestationDocumentResponse = + operations["PublicApiService_GetAttestationDocument"]["responses"]["200"]["schema"]; -export type TGetAttestationDocumentInput = { body: TGetAttestationDocumentBody }; +export type TGetAttestationDocumentInput = { + body: TGetAttestationDocumentBody; +}; -export type TGetAttestationDocumentBody = Omit & queryOverrideParams; +export type TGetAttestationDocumentBody = Omit< + operations["PublicApiService_GetAttestationDocument"]["parameters"]["body"]["body"], + "organizationId" +> & + queryOverrideParams; -export type TGetAuthenticatorResponse = operations["PublicApiService_GetAuthenticator"]["responses"]["200"]["schema"]; +export type TGetAuthenticatorResponse = + operations["PublicApiService_GetAuthenticator"]["responses"]["200"]["schema"]; export type TGetAuthenticatorInput = { body: TGetAuthenticatorBody }; -export type TGetAuthenticatorBody = Omit & queryOverrideParams; +export type TGetAuthenticatorBody = Omit< + operations["PublicApiService_GetAuthenticator"]["parameters"]["body"]["body"], + "organizationId" +> & + queryOverrideParams; -export type TGetAuthenticatorsResponse = operations["PublicApiService_GetAuthenticators"]["responses"]["200"]["schema"]; +export type TGetAuthenticatorsResponse = + operations["PublicApiService_GetAuthenticators"]["responses"]["200"]["schema"]; export type TGetAuthenticatorsInput = { body: TGetAuthenticatorsBody }; -export type TGetAuthenticatorsBody = Omit & queryOverrideParams; +export type TGetAuthenticatorsBody = Omit< + operations["PublicApiService_GetAuthenticators"]["parameters"]["body"]["body"], + "organizationId" +> & + queryOverrideParams; -export type TGetOauthProvidersResponse = operations["PublicApiService_GetOauthProviders"]["responses"]["200"]["schema"]; +export type TGetOauthProvidersResponse = + operations["PublicApiService_GetOauthProviders"]["responses"]["200"]["schema"]; export type TGetOauthProvidersInput = { body: TGetOauthProvidersBody }; -export type TGetOauthProvidersBody = Omit & queryOverrideParams; +export type TGetOauthProvidersBody = Omit< + operations["PublicApiService_GetOauthProviders"]["parameters"]["body"]["body"], + "organizationId" +> & + queryOverrideParams; -export type TGetOrganizationResponse = operations["PublicApiService_GetOrganization"]["responses"]["200"]["schema"]; +export type TGetOrganizationResponse = + operations["PublicApiService_GetOrganization"]["responses"]["200"]["schema"]; export type TGetOrganizationInput = { body: TGetOrganizationBody }; -export type TGetOrganizationBody = Omit & queryOverrideParams; +export type TGetOrganizationBody = Omit< + operations["PublicApiService_GetOrganization"]["parameters"]["body"]["body"], + "organizationId" +> & + queryOverrideParams; -export type TGetOrganizationConfigsResponse = operations["PublicApiService_GetOrganizationConfigs"]["responses"]["200"]["schema"]; +export type TGetOrganizationConfigsResponse = + operations["PublicApiService_GetOrganizationConfigs"]["responses"]["200"]["schema"]; -export type TGetOrganizationConfigsInput = { body: TGetOrganizationConfigsBody }; +export type TGetOrganizationConfigsInput = { + body: TGetOrganizationConfigsBody; +}; -export type TGetOrganizationConfigsBody = Omit & queryOverrideParams; +export type TGetOrganizationConfigsBody = Omit< + operations["PublicApiService_GetOrganizationConfigs"]["parameters"]["body"]["body"], + "organizationId" +> & + queryOverrideParams; -export type TGetPolicyResponse = operations["PublicApiService_GetPolicy"]["responses"]["200"]["schema"]; +export type TGetPolicyResponse = + operations["PublicApiService_GetPolicy"]["responses"]["200"]["schema"]; export type TGetPolicyInput = { body: TGetPolicyBody }; -export type TGetPolicyBody = Omit & queryOverrideParams; +export type TGetPolicyBody = Omit< + operations["PublicApiService_GetPolicy"]["parameters"]["body"]["body"], + "organizationId" +> & + queryOverrideParams; -export type TGetPrivateKeyResponse = operations["PublicApiService_GetPrivateKey"]["responses"]["200"]["schema"]; +export type TGetPrivateKeyResponse = + operations["PublicApiService_GetPrivateKey"]["responses"]["200"]["schema"]; export type TGetPrivateKeyInput = { body: TGetPrivateKeyBody }; -export type TGetPrivateKeyBody = Omit & queryOverrideParams; +export type TGetPrivateKeyBody = Omit< + operations["PublicApiService_GetPrivateKey"]["parameters"]["body"]["body"], + "organizationId" +> & + queryOverrideParams; -export type TGetUserResponse = operations["PublicApiService_GetUser"]["responses"]["200"]["schema"]; +export type TGetUserResponse = + operations["PublicApiService_GetUser"]["responses"]["200"]["schema"]; export type TGetUserInput = { body: TGetUserBody }; -export type TGetUserBody = Omit & queryOverrideParams; +export type TGetUserBody = Omit< + operations["PublicApiService_GetUser"]["parameters"]["body"]["body"], + "organizationId" +> & + queryOverrideParams; -export type TGetWalletResponse = operations["PublicApiService_GetWallet"]["responses"]["200"]["schema"]; +export type TGetWalletResponse = + operations["PublicApiService_GetWallet"]["responses"]["200"]["schema"]; export type TGetWalletInput = { body: TGetWalletBody }; -export type TGetWalletBody = Omit & queryOverrideParams; +export type TGetWalletBody = Omit< + operations["PublicApiService_GetWallet"]["parameters"]["body"]["body"], + "organizationId" +> & + queryOverrideParams; -export type TGetWalletAccountResponse = operations["PublicApiService_GetWalletAccount"]["responses"]["200"]["schema"]; +export type TGetWalletAccountResponse = + operations["PublicApiService_GetWalletAccount"]["responses"]["200"]["schema"]; export type TGetWalletAccountInput = { body: TGetWalletAccountBody }; -export type TGetWalletAccountBody = Omit & queryOverrideParams; +export type TGetWalletAccountBody = Omit< + operations["PublicApiService_GetWalletAccount"]["parameters"]["body"]["body"], + "organizationId" +> & + queryOverrideParams; -export type TGetActivitiesResponse = operations["PublicApiService_GetActivities"]["responses"]["200"]["schema"]; +export type TGetActivitiesResponse = + operations["PublicApiService_GetActivities"]["responses"]["200"]["schema"]; export type TGetActivitiesInput = { body: TGetActivitiesBody }; -export type TGetActivitiesBody = Omit & queryOverrideParams; +export type TGetActivitiesBody = Omit< + operations["PublicApiService_GetActivities"]["parameters"]["body"]["body"], + "organizationId" +> & + queryOverrideParams; -export type TGetPoliciesResponse = operations["PublicApiService_GetPolicies"]["responses"]["200"]["schema"]; +export type TGetPoliciesResponse = + operations["PublicApiService_GetPolicies"]["responses"]["200"]["schema"]; export type TGetPoliciesInput = { body: TGetPoliciesBody }; -export type TGetPoliciesBody = Omit & queryOverrideParams; +export type TGetPoliciesBody = Omit< + operations["PublicApiService_GetPolicies"]["parameters"]["body"]["body"], + "organizationId" +> & + queryOverrideParams; -export type TListPrivateKeyTagsResponse = operations["PublicApiService_ListPrivateKeyTags"]["responses"]["200"]["schema"]; +export type TListPrivateKeyTagsResponse = + operations["PublicApiService_ListPrivateKeyTags"]["responses"]["200"]["schema"]; export type TListPrivateKeyTagsInput = { body: TListPrivateKeyTagsBody }; -export type TListPrivateKeyTagsBody = Omit & queryOverrideParams; +export type TListPrivateKeyTagsBody = Omit< + operations["PublicApiService_ListPrivateKeyTags"]["parameters"]["body"]["body"], + "organizationId" +> & + queryOverrideParams; -export type TGetPrivateKeysResponse = operations["PublicApiService_GetPrivateKeys"]["responses"]["200"]["schema"]; +export type TGetPrivateKeysResponse = + operations["PublicApiService_GetPrivateKeys"]["responses"]["200"]["schema"]; export type TGetPrivateKeysInput = { body: TGetPrivateKeysBody }; -export type TGetPrivateKeysBody = Omit & queryOverrideParams; +export type TGetPrivateKeysBody = Omit< + operations["PublicApiService_GetPrivateKeys"]["parameters"]["body"]["body"], + "organizationId" +> & + queryOverrideParams; -export type TGetSubOrgIdsResponse = operations["PublicApiService_GetSubOrgIds"]["responses"]["200"]["schema"]; +export type TGetSubOrgIdsResponse = + operations["PublicApiService_GetSubOrgIds"]["responses"]["200"]["schema"]; export type TGetSubOrgIdsInput = { body: TGetSubOrgIdsBody }; -export type TGetSubOrgIdsBody = Omit & queryOverrideParams; +export type TGetSubOrgIdsBody = Omit< + operations["PublicApiService_GetSubOrgIds"]["parameters"]["body"]["body"], + "organizationId" +> & + queryOverrideParams; -export type TListUserTagsResponse = operations["PublicApiService_ListUserTags"]["responses"]["200"]["schema"]; +export type TListUserTagsResponse = + operations["PublicApiService_ListUserTags"]["responses"]["200"]["schema"]; export type TListUserTagsInput = { body: TListUserTagsBody }; -export type TListUserTagsBody = Omit & queryOverrideParams; +export type TListUserTagsBody = Omit< + operations["PublicApiService_ListUserTags"]["parameters"]["body"]["body"], + "organizationId" +> & + queryOverrideParams; -export type TGetUsersResponse = operations["PublicApiService_GetUsers"]["responses"]["200"]["schema"]; +export type TGetUsersResponse = + operations["PublicApiService_GetUsers"]["responses"]["200"]["schema"]; export type TGetUsersInput = { body: TGetUsersBody }; -export type TGetUsersBody = Omit & queryOverrideParams; +export type TGetUsersBody = Omit< + operations["PublicApiService_GetUsers"]["parameters"]["body"]["body"], + "organizationId" +> & + queryOverrideParams; -export type TGetVerifiedSubOrgIdsResponse = operations["PublicApiService_GetVerifiedSubOrgIds"]["responses"]["200"]["schema"]; +export type TGetVerifiedSubOrgIdsResponse = + operations["PublicApiService_GetVerifiedSubOrgIds"]["responses"]["200"]["schema"]; export type TGetVerifiedSubOrgIdsInput = { body: TGetVerifiedSubOrgIdsBody }; -export type TGetVerifiedSubOrgIdsBody = Omit & queryOverrideParams; +export type TGetVerifiedSubOrgIdsBody = Omit< + operations["PublicApiService_GetVerifiedSubOrgIds"]["parameters"]["body"]["body"], + "organizationId" +> & + queryOverrideParams; -export type TGetWalletAccountsResponse = operations["PublicApiService_GetWalletAccounts"]["responses"]["200"]["schema"]; +export type TGetWalletAccountsResponse = + operations["PublicApiService_GetWalletAccounts"]["responses"]["200"]["schema"]; export type TGetWalletAccountsInput = { body: TGetWalletAccountsBody }; -export type TGetWalletAccountsBody = Omit & queryOverrideParams; +export type TGetWalletAccountsBody = Omit< + operations["PublicApiService_GetWalletAccounts"]["parameters"]["body"]["body"], + "organizationId" +> & + queryOverrideParams; -export type TGetWalletsResponse = operations["PublicApiService_GetWallets"]["responses"]["200"]["schema"]; +export type TGetWalletsResponse = + operations["PublicApiService_GetWallets"]["responses"]["200"]["schema"]; export type TGetWalletsInput = { body: TGetWalletsBody }; -export type TGetWalletsBody = Omit & queryOverrideParams; +export type TGetWalletsBody = Omit< + operations["PublicApiService_GetWallets"]["parameters"]["body"]["body"], + "organizationId" +> & + queryOverrideParams; -export type TGetWhoamiResponse = operations["PublicApiService_GetWhoami"]["responses"]["200"]["schema"]; +export type TGetWhoamiResponse = + operations["PublicApiService_GetWhoami"]["responses"]["200"]["schema"]; export type TGetWhoamiInput = { body: TGetWhoamiBody }; -export type TGetWhoamiBody = Omit & queryOverrideParams; +export type TGetWhoamiBody = Omit< + operations["PublicApiService_GetWhoami"]["parameters"]["body"]["body"], + "organizationId" +> & + queryOverrideParams; -export type TApproveActivityResponse = operations["PublicApiService_ApproveActivity"]["responses"]["200"]["schema"]["activity"]["result"] & definitions["v1ActivityResponse"]; +export type TApproveActivityResponse = + operations["PublicApiService_ApproveActivity"]["responses"]["200"]["schema"]["activity"]["result"] & + definitions["v1ActivityResponse"]; export type TApproveActivityInput = { body: TApproveActivityBody }; -export type TApproveActivityBody = operations["PublicApiService_ApproveActivity"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TApproveActivityBody = + operations["PublicApiService_ApproveActivity"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TCreateApiKeysResponse = operations["PublicApiService_CreateApiKeys"]["responses"]["200"]["schema"]["activity"]["result"]["createApiKeysResult"] & definitions["v1ActivityResponse"]; +export type TCreateApiKeysResponse = + operations["PublicApiService_CreateApiKeys"]["responses"]["200"]["schema"]["activity"]["result"]["createApiKeysResult"] & + definitions["v1ActivityResponse"]; export type TCreateApiKeysInput = { body: TCreateApiKeysBody }; -export type TCreateApiKeysBody = operations["PublicApiService_CreateApiKeys"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TCreateApiKeysBody = + operations["PublicApiService_CreateApiKeys"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TCreateApiOnlyUsersResponse = operations["PublicApiService_CreateApiOnlyUsers"]["responses"]["200"]["schema"]["activity"]["result"]["createApiOnlyUsersResult"] & definitions["v1ActivityResponse"]; +export type TCreateApiOnlyUsersResponse = + operations["PublicApiService_CreateApiOnlyUsers"]["responses"]["200"]["schema"]["activity"]["result"]["createApiOnlyUsersResult"] & + definitions["v1ActivityResponse"]; export type TCreateApiOnlyUsersInput = { body: TCreateApiOnlyUsersBody }; -export type TCreateApiOnlyUsersBody = operations["PublicApiService_CreateApiOnlyUsers"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TCreateApiOnlyUsersBody = + operations["PublicApiService_CreateApiOnlyUsers"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TCreateAuthenticatorsResponse = operations["PublicApiService_CreateAuthenticators"]["responses"]["200"]["schema"]["activity"]["result"]["createAuthenticatorsResult"] & definitions["v1ActivityResponse"]; +export type TCreateAuthenticatorsResponse = + operations["PublicApiService_CreateAuthenticators"]["responses"]["200"]["schema"]["activity"]["result"]["createAuthenticatorsResult"] & + definitions["v1ActivityResponse"]; export type TCreateAuthenticatorsInput = { body: TCreateAuthenticatorsBody }; -export type TCreateAuthenticatorsBody = operations["PublicApiService_CreateAuthenticators"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TCreateAuthenticatorsBody = + operations["PublicApiService_CreateAuthenticators"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TCreateInvitationsResponse = operations["PublicApiService_CreateInvitations"]["responses"]["200"]["schema"]["activity"]["result"]["createInvitationsResult"] & definitions["v1ActivityResponse"]; +export type TCreateInvitationsResponse = + operations["PublicApiService_CreateInvitations"]["responses"]["200"]["schema"]["activity"]["result"]["createInvitationsResult"] & + definitions["v1ActivityResponse"]; export type TCreateInvitationsInput = { body: TCreateInvitationsBody }; -export type TCreateInvitationsBody = operations["PublicApiService_CreateInvitations"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TCreateInvitationsBody = + operations["PublicApiService_CreateInvitations"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TCreateOauthProvidersResponse = operations["PublicApiService_CreateOauthProviders"]["responses"]["200"]["schema"]["activity"]["result"]["createOauthProvidersResult"] & definitions["v1ActivityResponse"]; +export type TCreateOauthProvidersResponse = + operations["PublicApiService_CreateOauthProviders"]["responses"]["200"]["schema"]["activity"]["result"]["createOauthProvidersResult"] & + definitions["v1ActivityResponse"]; export type TCreateOauthProvidersInput = { body: TCreateOauthProvidersBody }; -export type TCreateOauthProvidersBody = operations["PublicApiService_CreateOauthProviders"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TCreateOauthProvidersBody = + operations["PublicApiService_CreateOauthProviders"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TCreatePoliciesResponse = operations["PublicApiService_CreatePolicies"]["responses"]["200"]["schema"]["activity"]["result"]["createPoliciesResult"] & definitions["v1ActivityResponse"]; +export type TCreatePoliciesResponse = + operations["PublicApiService_CreatePolicies"]["responses"]["200"]["schema"]["activity"]["result"]["createPoliciesResult"] & + definitions["v1ActivityResponse"]; export type TCreatePoliciesInput = { body: TCreatePoliciesBody }; -export type TCreatePoliciesBody = operations["PublicApiService_CreatePolicies"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TCreatePoliciesBody = + operations["PublicApiService_CreatePolicies"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TCreatePolicyResponse = operations["PublicApiService_CreatePolicy"]["responses"]["200"]["schema"]["activity"]["result"]["createPolicyResult"] & definitions["v1ActivityResponse"]; +export type TCreatePolicyResponse = + operations["PublicApiService_CreatePolicy"]["responses"]["200"]["schema"]["activity"]["result"]["createPolicyResult"] & + definitions["v1ActivityResponse"]; export type TCreatePolicyInput = { body: TCreatePolicyBody }; -export type TCreatePolicyBody = operations["PublicApiService_CreatePolicy"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TCreatePolicyBody = + operations["PublicApiService_CreatePolicy"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TCreatePrivateKeyTagResponse = operations["PublicApiService_CreatePrivateKeyTag"]["responses"]["200"]["schema"]["activity"]["result"]["createPrivateKeyTagResult"] & definitions["v1ActivityResponse"]; +export type TCreatePrivateKeyTagResponse = + operations["PublicApiService_CreatePrivateKeyTag"]["responses"]["200"]["schema"]["activity"]["result"]["createPrivateKeyTagResult"] & + definitions["v1ActivityResponse"]; export type TCreatePrivateKeyTagInput = { body: TCreatePrivateKeyTagBody }; -export type TCreatePrivateKeyTagBody = operations["PublicApiService_CreatePrivateKeyTag"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TCreatePrivateKeyTagBody = + operations["PublicApiService_CreatePrivateKeyTag"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TCreatePrivateKeysResponse = operations["PublicApiService_CreatePrivateKeys"]["responses"]["200"]["schema"]["activity"]["result"]["createPrivateKeysResultV2"] & definitions["v1ActivityResponse"]; +export type TCreatePrivateKeysResponse = + operations["PublicApiService_CreatePrivateKeys"]["responses"]["200"]["schema"]["activity"]["result"]["createPrivateKeysResultV2"] & + definitions["v1ActivityResponse"]; export type TCreatePrivateKeysInput = { body: TCreatePrivateKeysBody }; -export type TCreatePrivateKeysBody = operations["PublicApiService_CreatePrivateKeys"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TCreatePrivateKeysBody = + operations["PublicApiService_CreatePrivateKeys"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TCreateReadOnlySessionResponse = operations["PublicApiService_CreateReadOnlySession"]["responses"]["200"]["schema"]["activity"]["result"]["createReadOnlySessionResult"] & definitions["v1ActivityResponse"]; +export type TCreateReadOnlySessionResponse = + operations["PublicApiService_CreateReadOnlySession"]["responses"]["200"]["schema"]["activity"]["result"]["createReadOnlySessionResult"] & + definitions["v1ActivityResponse"]; export type TCreateReadOnlySessionInput = { body: TCreateReadOnlySessionBody }; -export type TCreateReadOnlySessionBody = operations["PublicApiService_CreateReadOnlySession"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TCreateReadOnlySessionBody = + operations["PublicApiService_CreateReadOnlySession"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TCreateReadWriteSessionResponse = operations["PublicApiService_CreateReadWriteSession"]["responses"]["200"]["schema"]["activity"]["result"]["createReadWriteSessionResultV2"] & definitions["v1ActivityResponse"]; +export type TCreateReadWriteSessionResponse = + operations["PublicApiService_CreateReadWriteSession"]["responses"]["200"]["schema"]["activity"]["result"]["createReadWriteSessionResultV2"] & + definitions["v1ActivityResponse"]; -export type TCreateReadWriteSessionInput = { body: TCreateReadWriteSessionBody }; +export type TCreateReadWriteSessionInput = { + body: TCreateReadWriteSessionBody; +}; -export type TCreateReadWriteSessionBody = operations["PublicApiService_CreateReadWriteSession"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TCreateReadWriteSessionBody = + operations["PublicApiService_CreateReadWriteSession"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TCreateSubOrganizationResponse = operations["PublicApiService_CreateSubOrganization"]["responses"]["200"]["schema"]["activity"]["result"]["createSubOrganizationResultV7"] & definitions["v1ActivityResponse"]; +export type TCreateSubOrganizationResponse = + operations["PublicApiService_CreateSubOrganization"]["responses"]["200"]["schema"]["activity"]["result"]["createSubOrganizationResultV7"] & + definitions["v1ActivityResponse"]; export type TCreateSubOrganizationInput = { body: TCreateSubOrganizationBody }; -export type TCreateSubOrganizationBody = operations["PublicApiService_CreateSubOrganization"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TCreateSubOrganizationBody = + operations["PublicApiService_CreateSubOrganization"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TCreateUserTagResponse = operations["PublicApiService_CreateUserTag"]["responses"]["200"]["schema"]["activity"]["result"]["createUserTagResult"] & definitions["v1ActivityResponse"]; +export type TCreateUserTagResponse = + operations["PublicApiService_CreateUserTag"]["responses"]["200"]["schema"]["activity"]["result"]["createUserTagResult"] & + definitions["v1ActivityResponse"]; export type TCreateUserTagInput = { body: TCreateUserTagBody }; -export type TCreateUserTagBody = operations["PublicApiService_CreateUserTag"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TCreateUserTagBody = + operations["PublicApiService_CreateUserTag"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TCreateUsersResponse = operations["PublicApiService_CreateUsers"]["responses"]["200"]["schema"]["activity"]["result"]["createUsersResult"] & definitions["v1ActivityResponse"]; +export type TCreateUsersResponse = + operations["PublicApiService_CreateUsers"]["responses"]["200"]["schema"]["activity"]["result"]["createUsersResult"] & + definitions["v1ActivityResponse"]; export type TCreateUsersInput = { body: TCreateUsersBody }; -export type TCreateUsersBody = operations["PublicApiService_CreateUsers"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TCreateUsersBody = + operations["PublicApiService_CreateUsers"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TCreateWalletResponse = operations["PublicApiService_CreateWallet"]["responses"]["200"]["schema"]["activity"]["result"]["createWalletResult"] & definitions["v1ActivityResponse"]; +export type TCreateWalletResponse = + operations["PublicApiService_CreateWallet"]["responses"]["200"]["schema"]["activity"]["result"]["createWalletResult"] & + definitions["v1ActivityResponse"]; export type TCreateWalletInput = { body: TCreateWalletBody }; -export type TCreateWalletBody = operations["PublicApiService_CreateWallet"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TCreateWalletBody = + operations["PublicApiService_CreateWallet"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TCreateWalletAccountsResponse = operations["PublicApiService_CreateWalletAccounts"]["responses"]["200"]["schema"]["activity"]["result"]["createWalletAccountsResult"] & definitions["v1ActivityResponse"]; +export type TCreateWalletAccountsResponse = + operations["PublicApiService_CreateWalletAccounts"]["responses"]["200"]["schema"]["activity"]["result"]["createWalletAccountsResult"] & + definitions["v1ActivityResponse"]; export type TCreateWalletAccountsInput = { body: TCreateWalletAccountsBody }; -export type TCreateWalletAccountsBody = operations["PublicApiService_CreateWalletAccounts"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TCreateWalletAccountsBody = + operations["PublicApiService_CreateWalletAccounts"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TDeleteApiKeysResponse = operations["PublicApiService_DeleteApiKeys"]["responses"]["200"]["schema"]["activity"]["result"]["deleteApiKeysResult"] & definitions["v1ActivityResponse"]; +export type TDeleteApiKeysResponse = + operations["PublicApiService_DeleteApiKeys"]["responses"]["200"]["schema"]["activity"]["result"]["deleteApiKeysResult"] & + definitions["v1ActivityResponse"]; export type TDeleteApiKeysInput = { body: TDeleteApiKeysBody }; -export type TDeleteApiKeysBody = operations["PublicApiService_DeleteApiKeys"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TDeleteApiKeysBody = + operations["PublicApiService_DeleteApiKeys"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TDeleteAuthenticatorsResponse = operations["PublicApiService_DeleteAuthenticators"]["responses"]["200"]["schema"]["activity"]["result"]["deleteAuthenticatorsResult"] & definitions["v1ActivityResponse"]; +export type TDeleteAuthenticatorsResponse = + operations["PublicApiService_DeleteAuthenticators"]["responses"]["200"]["schema"]["activity"]["result"]["deleteAuthenticatorsResult"] & + definitions["v1ActivityResponse"]; export type TDeleteAuthenticatorsInput = { body: TDeleteAuthenticatorsBody }; -export type TDeleteAuthenticatorsBody = operations["PublicApiService_DeleteAuthenticators"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TDeleteAuthenticatorsBody = + operations["PublicApiService_DeleteAuthenticators"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TDeleteInvitationResponse = operations["PublicApiService_DeleteInvitation"]["responses"]["200"]["schema"]["activity"]["result"]["deleteInvitationResult"] & definitions["v1ActivityResponse"]; +export type TDeleteInvitationResponse = + operations["PublicApiService_DeleteInvitation"]["responses"]["200"]["schema"]["activity"]["result"]["deleteInvitationResult"] & + definitions["v1ActivityResponse"]; export type TDeleteInvitationInput = { body: TDeleteInvitationBody }; -export type TDeleteInvitationBody = operations["PublicApiService_DeleteInvitation"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TDeleteInvitationBody = + operations["PublicApiService_DeleteInvitation"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TDeleteOauthProvidersResponse = operations["PublicApiService_DeleteOauthProviders"]["responses"]["200"]["schema"]["activity"]["result"]["deleteOauthProvidersResult"] & definitions["v1ActivityResponse"]; +export type TDeleteOauthProvidersResponse = + operations["PublicApiService_DeleteOauthProviders"]["responses"]["200"]["schema"]["activity"]["result"]["deleteOauthProvidersResult"] & + definitions["v1ActivityResponse"]; export type TDeleteOauthProvidersInput = { body: TDeleteOauthProvidersBody }; -export type TDeleteOauthProvidersBody = operations["PublicApiService_DeleteOauthProviders"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TDeleteOauthProvidersBody = + operations["PublicApiService_DeleteOauthProviders"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TDeletePolicyResponse = operations["PublicApiService_DeletePolicy"]["responses"]["200"]["schema"]["activity"]["result"]["deletePolicyResult"] & definitions["v1ActivityResponse"]; +export type TDeletePolicyResponse = + operations["PublicApiService_DeletePolicy"]["responses"]["200"]["schema"]["activity"]["result"]["deletePolicyResult"] & + definitions["v1ActivityResponse"]; export type TDeletePolicyInput = { body: TDeletePolicyBody }; -export type TDeletePolicyBody = operations["PublicApiService_DeletePolicy"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TDeletePolicyBody = + operations["PublicApiService_DeletePolicy"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TDeletePrivateKeyTagsResponse = operations["PublicApiService_DeletePrivateKeyTags"]["responses"]["200"]["schema"]["activity"]["result"]["deletePrivateKeyTagsResult"] & definitions["v1ActivityResponse"]; +export type TDeletePrivateKeyTagsResponse = + operations["PublicApiService_DeletePrivateKeyTags"]["responses"]["200"]["schema"]["activity"]["result"]["deletePrivateKeyTagsResult"] & + definitions["v1ActivityResponse"]; export type TDeletePrivateKeyTagsInput = { body: TDeletePrivateKeyTagsBody }; -export type TDeletePrivateKeyTagsBody = operations["PublicApiService_DeletePrivateKeyTags"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TDeletePrivateKeyTagsBody = + operations["PublicApiService_DeletePrivateKeyTags"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TDeletePrivateKeysResponse = operations["PublicApiService_DeletePrivateKeys"]["responses"]["200"]["schema"]["activity"]["result"]["deletePrivateKeysResult"] & definitions["v1ActivityResponse"]; +export type TDeletePrivateKeysResponse = + operations["PublicApiService_DeletePrivateKeys"]["responses"]["200"]["schema"]["activity"]["result"]["deletePrivateKeysResult"] & + definitions["v1ActivityResponse"]; export type TDeletePrivateKeysInput = { body: TDeletePrivateKeysBody }; -export type TDeletePrivateKeysBody = operations["PublicApiService_DeletePrivateKeys"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TDeletePrivateKeysBody = + operations["PublicApiService_DeletePrivateKeys"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TDeleteSubOrganizationResponse = operations["PublicApiService_DeleteSubOrganization"]["responses"]["200"]["schema"]["activity"]["result"]["deleteSubOrganizationResult"] & definitions["v1ActivityResponse"]; +export type TDeleteSubOrganizationResponse = + operations["PublicApiService_DeleteSubOrganization"]["responses"]["200"]["schema"]["activity"]["result"]["deleteSubOrganizationResult"] & + definitions["v1ActivityResponse"]; export type TDeleteSubOrganizationInput = { body: TDeleteSubOrganizationBody }; -export type TDeleteSubOrganizationBody = operations["PublicApiService_DeleteSubOrganization"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TDeleteSubOrganizationBody = + operations["PublicApiService_DeleteSubOrganization"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TDeleteUserTagsResponse = operations["PublicApiService_DeleteUserTags"]["responses"]["200"]["schema"]["activity"]["result"]["deleteUserTagsResult"] & definitions["v1ActivityResponse"]; +export type TDeleteUserTagsResponse = + operations["PublicApiService_DeleteUserTags"]["responses"]["200"]["schema"]["activity"]["result"]["deleteUserTagsResult"] & + definitions["v1ActivityResponse"]; export type TDeleteUserTagsInput = { body: TDeleteUserTagsBody }; -export type TDeleteUserTagsBody = operations["PublicApiService_DeleteUserTags"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TDeleteUserTagsBody = + operations["PublicApiService_DeleteUserTags"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TDeleteUsersResponse = operations["PublicApiService_DeleteUsers"]["responses"]["200"]["schema"]["activity"]["result"]["deleteUsersResult"] & definitions["v1ActivityResponse"]; +export type TDeleteUsersResponse = + operations["PublicApiService_DeleteUsers"]["responses"]["200"]["schema"]["activity"]["result"]["deleteUsersResult"] & + definitions["v1ActivityResponse"]; export type TDeleteUsersInput = { body: TDeleteUsersBody }; -export type TDeleteUsersBody = operations["PublicApiService_DeleteUsers"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TDeleteUsersBody = + operations["PublicApiService_DeleteUsers"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TDeleteWalletsResponse = operations["PublicApiService_DeleteWallets"]["responses"]["200"]["schema"]["activity"]["result"]["deleteWalletsResult"] & definitions["v1ActivityResponse"]; +export type TDeleteWalletsResponse = + operations["PublicApiService_DeleteWallets"]["responses"]["200"]["schema"]["activity"]["result"]["deleteWalletsResult"] & + definitions["v1ActivityResponse"]; export type TDeleteWalletsInput = { body: TDeleteWalletsBody }; -export type TDeleteWalletsBody = operations["PublicApiService_DeleteWallets"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TDeleteWalletsBody = + operations["PublicApiService_DeleteWallets"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TEmailAuthResponse = operations["PublicApiService_EmailAuth"]["responses"]["200"]["schema"]["activity"]["result"]["emailAuthResult"] & definitions["v1ActivityResponse"]; +export type TEmailAuthResponse = + operations["PublicApiService_EmailAuth"]["responses"]["200"]["schema"]["activity"]["result"]["emailAuthResult"] & + definitions["v1ActivityResponse"]; export type TEmailAuthInput = { body: TEmailAuthBody }; -export type TEmailAuthBody = operations["PublicApiService_EmailAuth"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TEmailAuthBody = + operations["PublicApiService_EmailAuth"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TExportPrivateKeyResponse = operations["PublicApiService_ExportPrivateKey"]["responses"]["200"]["schema"]["activity"]["result"]["exportPrivateKeyResult"] & definitions["v1ActivityResponse"]; +export type TExportPrivateKeyResponse = + operations["PublicApiService_ExportPrivateKey"]["responses"]["200"]["schema"]["activity"]["result"]["exportPrivateKeyResult"] & + definitions["v1ActivityResponse"]; export type TExportPrivateKeyInput = { body: TExportPrivateKeyBody }; -export type TExportPrivateKeyBody = operations["PublicApiService_ExportPrivateKey"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TExportPrivateKeyBody = + operations["PublicApiService_ExportPrivateKey"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TExportWalletResponse = operations["PublicApiService_ExportWallet"]["responses"]["200"]["schema"]["activity"]["result"]["exportWalletResult"] & definitions["v1ActivityResponse"]; +export type TExportWalletResponse = + operations["PublicApiService_ExportWallet"]["responses"]["200"]["schema"]["activity"]["result"]["exportWalletResult"] & + definitions["v1ActivityResponse"]; export type TExportWalletInput = { body: TExportWalletBody }; -export type TExportWalletBody = operations["PublicApiService_ExportWallet"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TExportWalletBody = + operations["PublicApiService_ExportWallet"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TExportWalletAccountResponse = operations["PublicApiService_ExportWalletAccount"]["responses"]["200"]["schema"]["activity"]["result"]["exportWalletAccountResult"] & definitions["v1ActivityResponse"]; +export type TExportWalletAccountResponse = + operations["PublicApiService_ExportWalletAccount"]["responses"]["200"]["schema"]["activity"]["result"]["exportWalletAccountResult"] & + definitions["v1ActivityResponse"]; export type TExportWalletAccountInput = { body: TExportWalletAccountBody }; -export type TExportWalletAccountBody = operations["PublicApiService_ExportWalletAccount"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TExportWalletAccountBody = + operations["PublicApiService_ExportWalletAccount"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TImportPrivateKeyResponse = operations["PublicApiService_ImportPrivateKey"]["responses"]["200"]["schema"]["activity"]["result"]["importPrivateKeyResult"] & definitions["v1ActivityResponse"]; +export type TImportPrivateKeyResponse = + operations["PublicApiService_ImportPrivateKey"]["responses"]["200"]["schema"]["activity"]["result"]["importPrivateKeyResult"] & + definitions["v1ActivityResponse"]; export type TImportPrivateKeyInput = { body: TImportPrivateKeyBody }; -export type TImportPrivateKeyBody = operations["PublicApiService_ImportPrivateKey"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TImportPrivateKeyBody = + operations["PublicApiService_ImportPrivateKey"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TImportWalletResponse = operations["PublicApiService_ImportWallet"]["responses"]["200"]["schema"]["activity"]["result"]["importWalletResult"] & definitions["v1ActivityResponse"]; +export type TImportWalletResponse = + operations["PublicApiService_ImportWallet"]["responses"]["200"]["schema"]["activity"]["result"]["importWalletResult"] & + definitions["v1ActivityResponse"]; export type TImportWalletInput = { body: TImportWalletBody }; -export type TImportWalletBody = operations["PublicApiService_ImportWallet"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TImportWalletBody = + operations["PublicApiService_ImportWallet"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TInitImportPrivateKeyResponse = operations["PublicApiService_InitImportPrivateKey"]["responses"]["200"]["schema"]["activity"]["result"]["initImportPrivateKeyResult"] & definitions["v1ActivityResponse"]; +export type TInitImportPrivateKeyResponse = + operations["PublicApiService_InitImportPrivateKey"]["responses"]["200"]["schema"]["activity"]["result"]["initImportPrivateKeyResult"] & + definitions["v1ActivityResponse"]; export type TInitImportPrivateKeyInput = { body: TInitImportPrivateKeyBody }; -export type TInitImportPrivateKeyBody = operations["PublicApiService_InitImportPrivateKey"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TInitImportPrivateKeyBody = + operations["PublicApiService_InitImportPrivateKey"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TInitImportWalletResponse = operations["PublicApiService_InitImportWallet"]["responses"]["200"]["schema"]["activity"]["result"]["initImportWalletResult"] & definitions["v1ActivityResponse"]; +export type TInitImportWalletResponse = + operations["PublicApiService_InitImportWallet"]["responses"]["200"]["schema"]["activity"]["result"]["initImportWalletResult"] & + definitions["v1ActivityResponse"]; export type TInitImportWalletInput = { body: TInitImportWalletBody }; -export type TInitImportWalletBody = operations["PublicApiService_InitImportWallet"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TInitImportWalletBody = + operations["PublicApiService_InitImportWallet"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TInitOtpResponse = operations["PublicApiService_InitOtp"]["responses"]["200"]["schema"]["activity"]["result"]["initOtpResult"] & definitions["v1ActivityResponse"]; +export type TInitOtpResponse = + operations["PublicApiService_InitOtp"]["responses"]["200"]["schema"]["activity"]["result"]["initOtpResult"] & + definitions["v1ActivityResponse"]; export type TInitOtpInput = { body: TInitOtpBody }; -export type TInitOtpBody = operations["PublicApiService_InitOtp"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TInitOtpBody = + operations["PublicApiService_InitOtp"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TInitOtpAuthResponse = operations["PublicApiService_InitOtpAuth"]["responses"]["200"]["schema"]["activity"]["result"]["initOtpAuthResultV2"] & definitions["v1ActivityResponse"]; +export type TInitOtpAuthResponse = + operations["PublicApiService_InitOtpAuth"]["responses"]["200"]["schema"]["activity"]["result"]["initOtpAuthResultV2"] & + definitions["v1ActivityResponse"]; export type TInitOtpAuthInput = { body: TInitOtpAuthBody }; -export type TInitOtpAuthBody = operations["PublicApiService_InitOtpAuth"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TInitOtpAuthBody = + operations["PublicApiService_InitOtpAuth"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TInitUserEmailRecoveryResponse = operations["PublicApiService_InitUserEmailRecovery"]["responses"]["200"]["schema"]["activity"]["result"]["initUserEmailRecoveryResult"] & definitions["v1ActivityResponse"]; +export type TInitUserEmailRecoveryResponse = + operations["PublicApiService_InitUserEmailRecovery"]["responses"]["200"]["schema"]["activity"]["result"]["initUserEmailRecoveryResult"] & + definitions["v1ActivityResponse"]; export type TInitUserEmailRecoveryInput = { body: TInitUserEmailRecoveryBody }; -export type TInitUserEmailRecoveryBody = operations["PublicApiService_InitUserEmailRecovery"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TInitUserEmailRecoveryBody = + operations["PublicApiService_InitUserEmailRecovery"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TOauthResponse = operations["PublicApiService_Oauth"]["responses"]["200"]["schema"]["activity"]["result"]["oauthResult"] & definitions["v1ActivityResponse"]; +export type TOauthResponse = + operations["PublicApiService_Oauth"]["responses"]["200"]["schema"]["activity"]["result"]["oauthResult"] & + definitions["v1ActivityResponse"]; export type TOauthInput = { body: TOauthBody }; -export type TOauthBody = operations["PublicApiService_Oauth"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TOauthBody = + operations["PublicApiService_Oauth"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TOauthLoginResponse = operations["PublicApiService_OauthLogin"]["responses"]["200"]["schema"]["activity"]["result"]["oauthLoginResult"] & definitions["v1ActivityResponse"]; +export type TOauthLoginResponse = + operations["PublicApiService_OauthLogin"]["responses"]["200"]["schema"]["activity"]["result"]["oauthLoginResult"] & + definitions["v1ActivityResponse"]; export type TOauthLoginInput = { body: TOauthLoginBody }; -export type TOauthLoginBody = operations["PublicApiService_OauthLogin"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TOauthLoginBody = + operations["PublicApiService_OauthLogin"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TOtpAuthResponse = operations["PublicApiService_OtpAuth"]["responses"]["200"]["schema"]["activity"]["result"]["otpAuthResult"] & definitions["v1ActivityResponse"]; +export type TOtpAuthResponse = + operations["PublicApiService_OtpAuth"]["responses"]["200"]["schema"]["activity"]["result"]["otpAuthResult"] & + definitions["v1ActivityResponse"]; export type TOtpAuthInput = { body: TOtpAuthBody }; -export type TOtpAuthBody = operations["PublicApiService_OtpAuth"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TOtpAuthBody = + operations["PublicApiService_OtpAuth"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TOtpLoginResponse = operations["PublicApiService_OtpLogin"]["responses"]["200"]["schema"]["activity"]["result"]["otpLoginResult"] & definitions["v1ActivityResponse"]; +export type TOtpLoginResponse = + operations["PublicApiService_OtpLogin"]["responses"]["200"]["schema"]["activity"]["result"]["otpLoginResult"] & + definitions["v1ActivityResponse"]; export type TOtpLoginInput = { body: TOtpLoginBody }; -export type TOtpLoginBody = operations["PublicApiService_OtpLogin"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TOtpLoginBody = + operations["PublicApiService_OtpLogin"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TRecoverUserResponse = operations["PublicApiService_RecoverUser"]["responses"]["200"]["schema"]["activity"]["result"]["recoverUserResult"] & definitions["v1ActivityResponse"]; +export type TRecoverUserResponse = + operations["PublicApiService_RecoverUser"]["responses"]["200"]["schema"]["activity"]["result"]["recoverUserResult"] & + definitions["v1ActivityResponse"]; export type TRecoverUserInput = { body: TRecoverUserBody }; -export type TRecoverUserBody = operations["PublicApiService_RecoverUser"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TRecoverUserBody = + operations["PublicApiService_RecoverUser"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TRejectActivityResponse = operations["PublicApiService_RejectActivity"]["responses"]["200"]["schema"]["activity"]["result"] & definitions["v1ActivityResponse"]; +export type TRejectActivityResponse = + operations["PublicApiService_RejectActivity"]["responses"]["200"]["schema"]["activity"]["result"] & + definitions["v1ActivityResponse"]; export type TRejectActivityInput = { body: TRejectActivityBody }; -export type TRejectActivityBody = operations["PublicApiService_RejectActivity"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TRejectActivityBody = + operations["PublicApiService_RejectActivity"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TRemoveOrganizationFeatureResponse = operations["PublicApiService_RemoveOrganizationFeature"]["responses"]["200"]["schema"]["activity"]["result"]["removeOrganizationFeatureResult"] & definitions["v1ActivityResponse"]; +export type TRemoveOrganizationFeatureResponse = + operations["PublicApiService_RemoveOrganizationFeature"]["responses"]["200"]["schema"]["activity"]["result"]["removeOrganizationFeatureResult"] & + definitions["v1ActivityResponse"]; -export type TRemoveOrganizationFeatureInput = { body: TRemoveOrganizationFeatureBody }; +export type TRemoveOrganizationFeatureInput = { + body: TRemoveOrganizationFeatureBody; +}; -export type TRemoveOrganizationFeatureBody = operations["PublicApiService_RemoveOrganizationFeature"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TRemoveOrganizationFeatureBody = + operations["PublicApiService_RemoveOrganizationFeature"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TSetOrganizationFeatureResponse = operations["PublicApiService_SetOrganizationFeature"]["responses"]["200"]["schema"]["activity"]["result"]["setOrganizationFeatureResult"] & definitions["v1ActivityResponse"]; +export type TSetOrganizationFeatureResponse = + operations["PublicApiService_SetOrganizationFeature"]["responses"]["200"]["schema"]["activity"]["result"]["setOrganizationFeatureResult"] & + definitions["v1ActivityResponse"]; -export type TSetOrganizationFeatureInput = { body: TSetOrganizationFeatureBody }; +export type TSetOrganizationFeatureInput = { + body: TSetOrganizationFeatureBody; +}; -export type TSetOrganizationFeatureBody = operations["PublicApiService_SetOrganizationFeature"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TSetOrganizationFeatureBody = + operations["PublicApiService_SetOrganizationFeature"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TSignRawPayloadResponse = operations["PublicApiService_SignRawPayload"]["responses"]["200"]["schema"]["activity"]["result"]["signRawPayloadResult"] & definitions["v1ActivityResponse"]; +export type TSignRawPayloadResponse = + operations["PublicApiService_SignRawPayload"]["responses"]["200"]["schema"]["activity"]["result"]["signRawPayloadResult"] & + definitions["v1ActivityResponse"]; export type TSignRawPayloadInput = { body: TSignRawPayloadBody }; -export type TSignRawPayloadBody = operations["PublicApiService_SignRawPayload"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TSignRawPayloadBody = + operations["PublicApiService_SignRawPayload"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TSignRawPayloadsResponse = operations["PublicApiService_SignRawPayloads"]["responses"]["200"]["schema"]["activity"]["result"]["signRawPayloadsResult"] & definitions["v1ActivityResponse"]; +export type TSignRawPayloadsResponse = + operations["PublicApiService_SignRawPayloads"]["responses"]["200"]["schema"]["activity"]["result"]["signRawPayloadsResult"] & + definitions["v1ActivityResponse"]; export type TSignRawPayloadsInput = { body: TSignRawPayloadsBody }; -export type TSignRawPayloadsBody = operations["PublicApiService_SignRawPayloads"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TSignRawPayloadsBody = + operations["PublicApiService_SignRawPayloads"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TSignTransactionResponse = operations["PublicApiService_SignTransaction"]["responses"]["200"]["schema"]["activity"]["result"]["signTransactionResult"] & definitions["v1ActivityResponse"]; +export type TSignTransactionResponse = + operations["PublicApiService_SignTransaction"]["responses"]["200"]["schema"]["activity"]["result"]["signTransactionResult"] & + definitions["v1ActivityResponse"]; export type TSignTransactionInput = { body: TSignTransactionBody }; -export type TSignTransactionBody = operations["PublicApiService_SignTransaction"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TSignTransactionBody = + operations["PublicApiService_SignTransaction"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TStampLoginResponse = operations["PublicApiService_StampLogin"]["responses"]["200"]["schema"]["activity"]["result"]["stampLoginResult"] & definitions["v1ActivityResponse"]; +export type TStampLoginResponse = + operations["PublicApiService_StampLogin"]["responses"]["200"]["schema"]["activity"]["result"]["stampLoginResult"] & + definitions["v1ActivityResponse"]; export type TStampLoginInput = { body: TStampLoginBody }; -export type TStampLoginBody = operations["PublicApiService_StampLogin"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TStampLoginBody = + operations["PublicApiService_StampLogin"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TUpdatePolicyResponse = operations["PublicApiService_UpdatePolicy"]["responses"]["200"]["schema"]["activity"]["result"]["updatePolicyResultV2"] & definitions["v1ActivityResponse"]; +export type TUpdatePolicyResponse = + operations["PublicApiService_UpdatePolicy"]["responses"]["200"]["schema"]["activity"]["result"]["updatePolicyResultV2"] & + definitions["v1ActivityResponse"]; export type TUpdatePolicyInput = { body: TUpdatePolicyBody }; -export type TUpdatePolicyBody = operations["PublicApiService_UpdatePolicy"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TUpdatePolicyBody = + operations["PublicApiService_UpdatePolicy"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TUpdatePrivateKeyTagResponse = operations["PublicApiService_UpdatePrivateKeyTag"]["responses"]["200"]["schema"]["activity"]["result"]["updatePrivateKeyTagResult"] & definitions["v1ActivityResponse"]; +export type TUpdatePrivateKeyTagResponse = + operations["PublicApiService_UpdatePrivateKeyTag"]["responses"]["200"]["schema"]["activity"]["result"]["updatePrivateKeyTagResult"] & + definitions["v1ActivityResponse"]; export type TUpdatePrivateKeyTagInput = { body: TUpdatePrivateKeyTagBody }; -export type TUpdatePrivateKeyTagBody = operations["PublicApiService_UpdatePrivateKeyTag"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TUpdatePrivateKeyTagBody = + operations["PublicApiService_UpdatePrivateKeyTag"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TUpdateRootQuorumResponse = operations["PublicApiService_UpdateRootQuorum"]["responses"]["200"]["schema"]["activity"]["result"]["updateRootQuorumResult"] & definitions["v1ActivityResponse"]; +export type TUpdateRootQuorumResponse = + operations["PublicApiService_UpdateRootQuorum"]["responses"]["200"]["schema"]["activity"]["result"]["updateRootQuorumResult"] & + definitions["v1ActivityResponse"]; export type TUpdateRootQuorumInput = { body: TUpdateRootQuorumBody }; -export type TUpdateRootQuorumBody = operations["PublicApiService_UpdateRootQuorum"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TUpdateRootQuorumBody = + operations["PublicApiService_UpdateRootQuorum"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TUpdateUserResponse = operations["PublicApiService_UpdateUser"]["responses"]["200"]["schema"]["activity"]["result"]["updateUserResult"] & definitions["v1ActivityResponse"]; +export type TUpdateUserResponse = + operations["PublicApiService_UpdateUser"]["responses"]["200"]["schema"]["activity"]["result"]["updateUserResult"] & + definitions["v1ActivityResponse"]; export type TUpdateUserInput = { body: TUpdateUserBody }; -export type TUpdateUserBody = operations["PublicApiService_UpdateUser"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TUpdateUserBody = + operations["PublicApiService_UpdateUser"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TUpdateUserTagResponse = operations["PublicApiService_UpdateUserTag"]["responses"]["200"]["schema"]["activity"]["result"]["updateUserTagResult"] & definitions["v1ActivityResponse"]; +export type TUpdateUserTagResponse = + operations["PublicApiService_UpdateUserTag"]["responses"]["200"]["schema"]["activity"]["result"]["updateUserTagResult"] & + definitions["v1ActivityResponse"]; export type TUpdateUserTagInput = { body: TUpdateUserTagBody }; -export type TUpdateUserTagBody = operations["PublicApiService_UpdateUserTag"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TUpdateUserTagBody = + operations["PublicApiService_UpdateUserTag"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TUpdateWalletResponse = operations["PublicApiService_UpdateWallet"]["responses"]["200"]["schema"]["activity"]["result"]["updateWalletResult"] & definitions["v1ActivityResponse"]; +export type TUpdateWalletResponse = + operations["PublicApiService_UpdateWallet"]["responses"]["200"]["schema"]["activity"]["result"]["updateWalletResult"] & + definitions["v1ActivityResponse"]; export type TUpdateWalletInput = { body: TUpdateWalletBody }; -export type TUpdateWalletBody = operations["PublicApiService_UpdateWallet"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TUpdateWalletBody = + operations["PublicApiService_UpdateWallet"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TVerifyOtpResponse = operations["PublicApiService_VerifyOtp"]["responses"]["200"]["schema"]["activity"]["result"]["verifyOtpResult"] & definitions["v1ActivityResponse"]; +export type TVerifyOtpResponse = + operations["PublicApiService_VerifyOtp"]["responses"]["200"]["schema"]["activity"]["result"]["verifyOtpResult"] & + definitions["v1ActivityResponse"]; export type TVerifyOtpInput = { body: TVerifyOtpBody }; -export type TVerifyOtpBody = operations["PublicApiService_VerifyOtp"]["parameters"]["body"]["body"]["parameters"] & commandOverrideParams; +export type TVerifyOtpBody = + operations["PublicApiService_VerifyOtp"]["parameters"]["body"]["body"]["parameters"] & + commandOverrideParams; -export type TNOOPCodegenAnchorResponse = operations["PublicApiService_NOOPCodegenAnchor"]["responses"]["200"]["schema"]; +export type TNOOPCodegenAnchorResponse = + operations["PublicApiService_NOOPCodegenAnchor"]["responses"]["200"]["schema"]; -export type TTestRateLimitsResponse = operations["PublicApiService_TestRateLimits"]["responses"]["200"]["schema"]; +export type TTestRateLimitsResponse = + operations["PublicApiService_TestRateLimits"]["responses"]["200"]["schema"]; export type TTestRateLimitsInput = { body: TTestRateLimitsBody }; -export type TTestRateLimitsBody = Omit & queryOverrideParams; \ No newline at end of file +export type TTestRateLimitsBody = Omit< + operations["PublicApiService_TestRateLimits"]["parameters"]["body"]["body"], + "organizationId" +> & + queryOverrideParams; diff --git a/packages/sdk-js/src/__storage__/base.ts b/packages/sdk-js/src/__storage__/base.ts new file mode 100644 index 000000000..7d615d480 --- /dev/null +++ b/packages/sdk-js/src/__storage__/base.ts @@ -0,0 +1,52 @@ +import { Session } from "@turnkey/sdk-types"; +import { AuthClient } from ".."; +import { WebStorageManager } from "./web/storage"; + +export enum StorageKey { + Session = "@turnkey/session/v2", + Client = "@turnkey/client", +} +export interface StorageValue { + [StorageKey.Session]: Session; + [StorageKey.Client]: AuthClient; // TODO (Amir): I don't think we need this +} + +export interface StorageBase { + getStorageValue( + key: K, + ): Promise; + setStorageValue( + storageKey: K, + storageValue: StorageValue[K], + ): Promise; + removeStorageValue(storageKey: K): Promise; + storeSession(session: Session): Promise; +} + +export const isReactNative = (): boolean => { + return ( + typeof navigator !== "undefined" && navigator.product === "ReactNative" + ); +}; + +export const isWeb = (): boolean => { + return typeof window !== "undefined" && typeof document !== "undefined"; +}; + +export async function createStorageManager(): Promise { + if (isReactNative()) { + try { + // Dynamic import to prevent bundling the native module in web environments + const { MobileStorageManager } = await import("./mobile/storage"); + return new MobileStorageManager(); + } catch (error) { + throw new Error( + `Failed to load native secure storage, falling back to memory storage: ${error}`, + ); + } + } else if (isWeb()) { + return new WebStorageManager(); + } else { + throw new Error("Unsupported environment for storage manager."); + } +} diff --git a/packages/sdk-js/src/__storage__/mobile/storage.ts b/packages/sdk-js/src/__storage__/mobile/storage.ts new file mode 100644 index 000000000..282b89142 --- /dev/null +++ b/packages/sdk-js/src/__storage__/mobile/storage.ts @@ -0,0 +1,58 @@ +import type { Session } from "@turnkey/sdk-types"; + +import { StorageBase, StorageKey, StorageValue } from "../base"; + +export class MobileStorageManager implements StorageBase { + Keychain = require("react-native-keychain"); + + getStorageValue = async ( + storageKey: K, + ): Promise => { + try { + const result = await this.Keychain.getGenericPassword({ + service: storageKey, + }); + + if (result && result.password) { + return JSON.parse(result.password); + } + return undefined; + } catch (error) { + console.error("Error retrieving from Keychain:", error); + return undefined; + } + }; + + setStorageValue = async ( + storageKey: K, + storageValue: StorageValue[K], + ): Promise => { + try { + const result = await this.Keychain.setGenericPassword( + storageKey, + JSON.stringify(storageValue), + { service: storageKey }, + ); + return !!result; + } catch (error) { + console.error("Error storing in Keychain:", error); + return false; + } + }; + + removeStorageValue = async ( + storageKey: K, + ): Promise => { + try { + await this.Keychain.resetGenericPassword({ + service: storageKey, + }); + } catch (error) { + console.error("Error removing from Keychain:", error); + } + }; + + storeSession = async (session: Session): Promise => { + return await this.setStorageValue(StorageKey.Session, session); + }; +} diff --git a/packages/sdk-js/src/__storage__/web/storage.ts b/packages/sdk-js/src/__storage__/web/storage.ts new file mode 100644 index 000000000..5662fba3f --- /dev/null +++ b/packages/sdk-js/src/__storage__/web/storage.ts @@ -0,0 +1,33 @@ +import type { Session } from "@turnkey/sdk-types"; +import WindowWrapper from "@polyfills/window"; + +import { StorageBase, StorageKey, StorageValue } from "../base"; + +const browserStorage = WindowWrapper.localStorage; + +export class WebStorageManager implements StorageBase { + // TODO (Amir): try catch + getStorageValue = async ( + storageKey: K, + ): Promise => { + const storageItem = browserStorage.getItem(storageKey); + return storageItem ? JSON.parse(storageItem) : undefined; + }; + + setStorageValue = async ( + storageKey: K, + storageValue: StorageValue[K], + ): Promise => { + browserStorage.setItem(storageKey, JSON.stringify(storageValue)); + }; + + removeStorageValue = async ( + storageKey: K, + ): Promise => { + browserStorage.removeItem(storageKey); + }; + + storeSession = async (session: Session): Promise => { + return await this.setStorageValue(StorageKey.Session, session); + }; +} diff --git a/packages/sdk-js/src/__types__/base.ts b/packages/sdk-js/src/__types__/base.ts index fb929a08e..11f20721b 100644 --- a/packages/sdk-js/src/__types__/base.ts +++ b/packages/sdk-js/src/__types__/base.ts @@ -3,6 +3,11 @@ import type { WalletInterface, WalletStamper } from "@turnkey/wallet-stamper"; import type { WebauthnStamper } from "@turnkey/webauthn-stamper"; import type { IndexedDbStamper } from "@turnkey/indexed-db-stamper"; import type { SessionType } from "@turnkey/sdk-types"; +import { StorageBase } from "../__storage__/base"; + +// TODO (Amir): Get all this outta here and move to sdk-types. Or not, we could just have everything in this package + +export const DEFAULT_SESSION_EXPIRATION_IN_SECONDS = "900"; // 15 minutes export type GrpcStatus = { message: string; @@ -68,28 +73,44 @@ export type TActivityPollerConfig = { numRetries: number; }; -interface BaseSDKClientConfig { - apiBaseUrl: string; +export interface SubOrganization { organizationId: string; - activityPoller?: TActivityPollerConfig | undefined; + organizationName: string; } -interface SDKClientConfigWithStamper extends BaseSDKClientConfig { - stamper: TStamper; - passkeyStamper?: TStamper; - readOnlySession?: never; -} +export type EmbeddedAPIKey = { + authBundle: string; + publicKey: string; +}; -interface SDKClientConfigWithReadOnlySession extends BaseSDKClientConfig { +export type Passkey = { + encodedChallenge: string; + attestation: { + credentialId: string; + clientDataJson: string; + attestationObject: string; + transports: ( + | "AUTHENTICATOR_TRANSPORT_BLE" + | "AUTHENTICATOR_TRANSPORT_INTERNAL" + | "AUTHENTICATOR_TRANSPORT_NFC" + | "AUTHENTICATOR_TRANSPORT_USB" + | "AUTHENTICATOR_TRANSPORT_HYBRID" + )[]; + }; +}; + +export interface TurnkeySDKClientConfig { + apiBaseUrl: string; + organizationId: string; + + // TODO (Amir): Remove this in a user-facing config and add passkey and wallet configs + activityPoller?: TActivityPollerConfig | undefined; stamper?: never; passkeyStamper?: TStamper; - readOnlySession: string; + storageManager?: StorageBase; + readOnlySession?: string; } -export type TurnkeySDKClientConfig = - | SDKClientConfigWithStamper - | SDKClientConfigWithReadOnlySession; - export interface TurnkeySDKBrowserConfig { apiBaseUrl: string; defaultOrganizationId: string; @@ -136,7 +157,7 @@ export interface LoginWithBundleParams { } export interface LoginWithPasskeyParams { - sessionType: SessionType; + sessionType?: SessionType; expirationSeconds?: string | undefined; publicKey?: string; } @@ -147,9 +168,9 @@ export interface LoginWithWalletParams { publicKey?: string; } -export interface TurnkeyWalletClientConfig extends SDKClientConfigWithStamper { - wallet: WalletInterface; -} +// export interface TurnkeyWalletClientConfig extends SDKClientConfigWithStamper { +// wallet: WalletInterface; +// } /** * The Client used to authenticate the user. @@ -157,7 +178,6 @@ export interface TurnkeyWalletClientConfig extends SDKClientConfigWithStamper { export enum AuthClient { Passkey = "passkey", Wallet = "wallet", - Iframe = "iframe", IndexedDb = "indexed-db", } diff --git a/packages/sdk-js/src/storage.ts b/packages/sdk-js/src/storage.ts deleted file mode 100644 index d18b8c752..000000000 --- a/packages/sdk-js/src/storage.ts +++ /dev/null @@ -1,75 +0,0 @@ -import type { Session } from "@turnkey/sdk-types"; -import WindowWrapper from "@polyfills/window"; -import type { AuthClient } from "./__types__/base"; - -export enum StorageKeys { - Session = "@turnkey/session/v2", - Client = "@turnkey/client", -} - -interface StorageValue { - [StorageKeys.Session]: string | Session; - [StorageKeys.Client]: AuthClient; -} - -enum StorageLocation { - Local = "local", - Secure = "secure", - Session = "session", -} - -const STORAGE_VALUE_LOCATIONS: Record = { - [StorageKeys.Session]: StorageLocation.Session, - [StorageKeys.Client]: StorageLocation.Session, -}; - -const STORAGE_LOCATIONS = { - [StorageLocation.Local]: WindowWrapper.localStorage, - [StorageLocation.Secure]: WindowWrapper.localStorage, - [StorageLocation.Session]: WindowWrapper.localStorage, -}; - -export const getStorageValue = async ( - storageKey: K -): Promise => { - const storageLocation: StorageLocation = STORAGE_VALUE_LOCATIONS[storageKey]; - const browserStorageLocation: Storage = STORAGE_LOCATIONS[storageLocation]; - const storageItem = browserStorageLocation.getItem(storageKey); - return storageItem ? JSON.parse(storageItem) : undefined; -}; - -export const setStorageValue = async ( - storageKey: K, - storageValue: StorageValue[K] -): Promise => { - const storageLocation: StorageLocation = STORAGE_VALUE_LOCATIONS[storageKey]; - const browserStorageLocation: Storage = STORAGE_LOCATIONS[storageLocation]; - browserStorageLocation.setItem(storageKey, JSON.stringify(storageValue)); -}; - -export const removeStorageValue = async ( - storageKey: K -): Promise => { - const storageLocation: StorageLocation = STORAGE_VALUE_LOCATIONS[storageKey]; - const browserStorageLocation: Storage = STORAGE_LOCATIONS[storageLocation]; - browserStorageLocation.removeItem(storageKey); -}; - -/** - * Saves a session and client to storage. - * - * @param {Session} session - The session response containing session details. - * @param {AuthClient} authClient - The authentication client used for the session. - * @throws Will throw an error if the authentication client is not set. - * @returns {Promise} A promise that resolves when the session is saved. - */ - -export const storeSession = async ( - session: string | Session, - client?: AuthClient -) => { - await setStorageValue(StorageKeys.Session, session); - if (client) { - await setStorageValue(StorageKeys.Client, client); - } -}; diff --git a/packages/sdk-js/src/utils.ts b/packages/sdk-js/src/utils.ts index 3d318b2aa..577b58eaa 100644 --- a/packages/sdk-js/src/utils.ts +++ b/packages/sdk-js/src/utils.ts @@ -1,87 +1,7 @@ -import { uint8ArrayFromHexString } from "@turnkey/encoding"; -import { - generateP256KeyPair, - buildAdditionalAssociatedData, - compressRawPublicKey, -} from "@turnkey/crypto"; - import { Buffer } from "buffer"; -import bs58check from "bs58check"; -import { AeadId, CipherSuite, KdfId, KemId } from "hpke-js"; -import type { EmbeddedAPIKey } from "./models"; -import { pointDecode } from "@turnkey/api-key-stamper"; import type { Session } from "@turnkey/sdk-types"; -// createEmbeddedAPIKey creates an embedded API key encrypted to a target key (typically embedded within an iframe). -// This returns a bundle that can be decrypted by that target key, as well as the public key of the newly created API key. -export const createEmbeddedAPIKey = async ( - targetPublicKey: string, -): Promise => { - const TURNKEY_HPKE_INFO = new TextEncoder().encode("turnkey_hpke"); - - // 1: create new API key (to be encrypted to the targetPublicKey) - const p256key = generateP256KeyPair(); - - // 2: set up encryption - const suite = new CipherSuite({ - kem: KemId.DhkemP256HkdfSha256, - kdf: KdfId.HkdfSha256, - aead: AeadId.Aes256Gcm, - }); - - // 3: import the targetPublicKey (i.e. passed in from the iframe) - const targetKeyBytes = uint8ArrayFromHexString(targetPublicKey); - - let jwk; - try { - jwk = pointDecode(targetKeyBytes); - } catch (e) { - // provide more context about the error that is being thrown - throw new Error( - `target public key is not a valid compressed public key: ${targetPublicKey}`, - ); - } - - const targetKey = await crypto.subtle.importKey( - "jwk", - jwk, - { - name: "ECDH", - namedCurve: "P-256", - }, - true, - [], - ); - - // 4: sender encrypts a message to the target key - const sender = await suite.createSenderContext({ - recipientPublicKey: targetKey, - info: TURNKEY_HPKE_INFO, - }); - const ciphertext = await sender.seal( - uint8ArrayFromHexString(p256key.privateKey), - buildAdditionalAssociatedData(new Uint8Array(sender.enc), targetKeyBytes), - ); - const ciphertextUint8Array = new Uint8Array(ciphertext); - - // 5: assemble bundle - const encappedKey = new Uint8Array(sender.enc); - const compressedEncappedKey = compressRawPublicKey(encappedKey); - const result = new Uint8Array( - compressedEncappedKey.length + ciphertextUint8Array.length, - ); - result.set(compressedEncappedKey); - result.set(ciphertextUint8Array, compressedEncappedKey.length); - - const base58encodedBundle = bs58check.encode(result); - - return { - authBundle: base58encodedBundle, - publicKey: p256key.publicKey, - }; -}; - export const generateRandomBuffer = (): ArrayBuffer => { const arr = new Uint8Array(32); crypto.getRandomValues(arr); @@ -97,7 +17,7 @@ export const base64UrlEncode = (challenge: ArrayBuffer): string => { }; const hexByByte = Array.from({ length: 256 }, (_, i) => - i.toString(16).padStart(2, "0"), + i.toString(16).padStart(2, "0") ); export const bytesToHex = (bytes: Uint8Array): string => { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a9e439a66..906119331 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2186,9 +2186,9 @@ importers: cross-fetch: specifier: ^3.1.5 version: 3.1.5 - hpke-js: - specifier: ^1.2.7 - version: 1.2.7 + react-native-keychain: + specifier: ^8.1.0 || ^9.2.2 || ^10.0.0 + version: 8.1.0 devDependencies: glob: specifier: ^8.0.3 From e0e5ffc006157633351461d5f6b7eccf91b84d32 Mon Sep 17 00:00:00 2001 From: Amir Cheikh Date: Mon, 9 Jun 2025 17:44:20 -0400 Subject: [PATCH 003/184] Platform specific stampers (WIP) --- packages/sdk-js/src/__clients__/core.ts | 111 ++++++++++++++++++------ packages/sdk-js/src/__storage__/base.ts | 11 +-- packages/sdk-js/src/utils.ts | 12 ++- 3 files changed, 96 insertions(+), 38 deletions(-) diff --git a/packages/sdk-js/src/__clients__/core.ts b/packages/sdk-js/src/__clients__/core.ts index 2263b491b..d77b39abd 100644 --- a/packages/sdk-js/src/__clients__/core.ts +++ b/packages/sdk-js/src/__clients__/core.ts @@ -9,7 +9,12 @@ import { Passkey, StamperType, } from "@types"; // AHHHH, SDK-TYPES -import { base64UrlEncode, generateRandomBuffer } from "@utils"; +import { + base64UrlEncode, + generateRandomBuffer, + isReactNative, + isWeb, +} from "@utils"; import { getWebAuthnAttestation } from "@turnkey/http"; import { createStorageManager, StorageBase } from "../__storage__/base"; @@ -17,44 +22,95 @@ export class TurnkeyClient { config: any; // Type TBD httpClient!: TurnkeySDKClientBase; - // TODO (Amir): Make these private - indexedDBStamper: IndexedDbStamper | undefined; - passkeyStamper: WebauthnStamper | undefined; + // Platform-agnostic stampers + private indexedDBStamper?: IndexedDbStamper | undefined; + private passkeyStamper?: WebauthnStamper | undefined; + + // Mobile-specific stampers + private secureStorageStamper?: any | undefined; // TODO (Amir): Implement proper type + private mobilePasskeyStamper?: any | undefined; // TODO (Amir): Implement proper type + + // The active default stamper for the current platform + private activeStamper?: any; // TODO (Amir): This should be a type that encompasses the default "api key" stamper. indexedDB for web, secure storage for mobile. storageManager!: StorageBase; constructor( config: any, + + // Users can pass in their own stampers, or we will create them. Should we remove this? indexedDBStamper?: IndexedDbStamper, passkeyStamper?: WebauthnStamper, + secureStorageStamper?: any, // TODO: Add proper type + mobilePasskeyStamper?: any, // TODO: Add proper type ) { this.config = config; - this.indexedDBStamper = indexedDBStamper || new IndexedDbStamper(); - this.passkeyStamper = - passkeyStamper || - new WebauthnStamper({ - rpId: config?.passkeyConfig?.rpId ?? WindowWrapper.location.hostname, - ...(config?.passkeyConfig?.timeout !== undefined && { - timeout: config?.passkeyConfig?.timeout, - }), - ...(config?.passkeyConfig?.userVerification !== undefined && { - userVerification: config?.passkeyConfig?.userVerification, - }), - ...(config?.passkeyConfig?.allowCredentials !== undefined && { - allowCredentials: config?.passkeyConfig?.allowCredentials, - }), - }); - - // storageManager will be initialized asynchronously + + // Just store any explicitly provided stampers + this.indexedDBStamper = indexedDBStamper; + this.passkeyStamper = passkeyStamper; + this.secureStorageStamper = secureStorageStamper; + this.mobilePasskeyStamper = mobilePasskeyStamper; + + // Actual initialization will happen in init() } async init() { - await this.indexedDBStamper?.init(); + // Initialize platform-specific stampers + if (isWeb()) { + // Web environment - use IndexedDB and WebAuthn if not provided + if (!this.indexedDBStamper) { + this.indexedDBStamper = new IndexedDbStamper(); + } + + if (!this.passkeyStamper) { + this.passkeyStamper = new WebauthnStamper({ + rpId: + this.config?.passkeyConfig?.rpId ?? WindowWrapper.location.hostname, + ...(this.config?.passkeyConfig?.timeout !== undefined && { + timeout: this.config?.passkeyConfig?.timeout, + }), + ...(this.config?.passkeyConfig?.userVerification !== undefined && { + userVerification: this.config?.passkeyConfig?.userVerification, + }), + ...(this.config?.passkeyConfig?.allowCredentials !== undefined && { + allowCredentials: this.config?.passkeyConfig?.allowCredentials, + }), + }); + } + + // Initialize the IndexedDB stamper (don't put this in the if statement above, indexedDBStamper can be passed in but not initted yet!) + await this.indexedDBStamper.init(); + + // Set default active stamper for web + this.activeStamper = this.indexedDBStamper; + } else if (isReactNative()) { + // React Native environment - use mobile-specific stampers + + if (!this.secureStorageStamper) { + // TODO: Initialize secureStorageStamper + // this.secureStorageStamper = new SecureStorageStamper(); + } + + if (!this.mobilePasskeyStamper) { + // TODO: Initialize mobilePasskeyStamper + // this.mobilePasskeyStamper = new MobilePasskeyStamper(); + } + + // Initialize the secure storage stamper if needed + // await this.secureStorageStamper.init(); + + // Set default active stamper for mobile + this.activeStamper = this.secureStorageStamper; + } + + // Initialize storage manager this.storageManager = await createStorageManager(); + // Initialize the HTTP client with the appropriate stampers this.httpClient = new TurnkeySDKClientBase({ - stamper: this.indexedDBStamper, // Maybe we should rename this - passkeyStamper: this.passkeyStamper, + stamper: this.activeStamper, + passkeyStamper: isWeb() ? this.passkeyStamper : this.mobilePasskeyStamper, storageManager: this.storageManager, ...this.config, }); @@ -68,6 +124,7 @@ export class TurnkeyClient { createUserPasskey = async ( config: Record = {}, ): Promise => { + // TODO (Amir): Make this work for mobile as well const challenge = generateRandomBuffer(); const encodedChallenge = base64UrlEncode(challenge); const authenticatorUserId = generateRandomBuffer(); @@ -142,10 +199,10 @@ export class TurnkeyClient { */ loginWithPasskey = async (params: LoginWithPasskeyParams): Promise => { try { - await this.indexedDBStamper?.resetKeyPair(); + await this.indexedDBStamper?.resetKeyPair(); // TODO (Amir): Once implemented, this should be activeStamper.resetKeyPair(); const { sessionType = SessionType.READ_WRITE, - publicKey = this.indexedDBStamper?.getPublicKey(), + publicKey = this.indexedDBStamper?.getPublicKey(), // TODO (Amir): Once implemented, this should be activeStamper.getPublicKey(); expirationSeconds = DEFAULT_SESSION_EXPIRATION_IN_SECONDS, } = params; // Create a read-only session @@ -180,7 +237,7 @@ export class TurnkeyClient { const whoamiResponse = await this.httpClient.getWhoami({}); const session: Session = { - // Let's keep consistent with storing the actual session object rather than just the token + // Note (Amir): Let's keep consistent with storing the actual session object rather than just the token sessionType: SessionType.READ_ONLY, userId: whoamiResponse.userId, organizationId: whoamiResponse.organizationId, diff --git a/packages/sdk-js/src/__storage__/base.ts b/packages/sdk-js/src/__storage__/base.ts index 7d615d480..15892a7cc 100644 --- a/packages/sdk-js/src/__storage__/base.ts +++ b/packages/sdk-js/src/__storage__/base.ts @@ -1,6 +1,7 @@ import { Session } from "@turnkey/sdk-types"; import { AuthClient } from ".."; import { WebStorageManager } from "./web/storage"; +import { isReactNative, isWeb } from "@utils"; export enum StorageKey { Session = "@turnkey/session/v2", @@ -23,16 +24,6 @@ export interface StorageBase { storeSession(session: Session): Promise; } -export const isReactNative = (): boolean => { - return ( - typeof navigator !== "undefined" && navigator.product === "ReactNative" - ); -}; - -export const isWeb = (): boolean => { - return typeof window !== "undefined" && typeof document !== "undefined"; -}; - export async function createStorageManager(): Promise { if (isReactNative()) { try { diff --git a/packages/sdk-js/src/utils.ts b/packages/sdk-js/src/utils.ts index 577b58eaa..5dfc507ab 100644 --- a/packages/sdk-js/src/utils.ts +++ b/packages/sdk-js/src/utils.ts @@ -2,6 +2,16 @@ import { Buffer } from "buffer"; import type { Session } from "@turnkey/sdk-types"; +export const isReactNative = (): boolean => { + return ( + typeof navigator !== "undefined" && navigator.product === "ReactNative" + ); +}; + +export const isWeb = (): boolean => { + return typeof window !== "undefined" && typeof document !== "undefined"; +}; + export const generateRandomBuffer = (): ArrayBuffer => { const arr = new Uint8Array(32); crypto.getRandomValues(arr); @@ -17,7 +27,7 @@ export const base64UrlEncode = (challenge: ArrayBuffer): string => { }; const hexByByte = Array.from({ length: 256 }, (_, i) => - i.toString(16).padStart(2, "0") + i.toString(16).padStart(2, "0"), ); export const bytesToHex = (bytes: Uint8Array): string => { From ac5c6d52eac28cec8b33f2b178a94b3e349cfd9e Mon Sep 17 00:00:00 2001 From: Amir Cheikh Date: Tue, 10 Jun 2025 17:45:39 -0400 Subject: [PATCH 004/184] Multi session and multi keypair storage (web only) --- packages/sdk-js/package.json | 1 + packages/sdk-js/src/__clients__/core.ts | 102 ++- .../src/__generated__/sdk-client-base.ts | 690 +++++++++--------- packages/sdk-js/src/__stampers__/base.ts | 64 ++ .../sdk-js/src/__stampers__/web/stamper.ts | 221 ++++++ packages/sdk-js/src/__storage__/base.ts | 57 +- .../sdk-js/src/__storage__/mobile/storage.ts | 102 +-- .../sdk-js/src/__storage__/web/storage.ts | 89 ++- packages/sdk-js/src/__types__/base.ts | 3 +- packages/sdk-js/src/utils.ts | 8 +- pnpm-lock.yaml | 25 + 11 files changed, 862 insertions(+), 500 deletions(-) create mode 100644 packages/sdk-js/src/__stampers__/base.ts create mode 100644 packages/sdk-js/src/__stampers__/web/stamper.ts diff --git a/packages/sdk-js/package.json b/packages/sdk-js/package.json index 019155de3..924748ccc 100644 --- a/packages/sdk-js/package.json +++ b/packages/sdk-js/package.json @@ -30,6 +30,7 @@ "@turnkey/indexed-db-stamper": "workspace:*", "@turnkey/sdk-types": "workspace:*", "bs58check": "3.0.1", + "jwt-decode": "4.0.0", "buffer": "^6.0.3", "cross-fetch": "^3.1.5" }, diff --git a/packages/sdk-js/src/__clients__/core.ts b/packages/sdk-js/src/__clients__/core.ts index d77b39abd..2af6d33c7 100644 --- a/packages/sdk-js/src/__clients__/core.ts +++ b/packages/sdk-js/src/__clients__/core.ts @@ -1,4 +1,3 @@ -import { IndexedDbStamper } from "@turnkey/indexed-db-stamper"; import { TurnkeySDKClientBase } from "../__generated__/sdk-client-base"; import { WebauthnStamper } from "@turnkey/webauthn-stamper"; import WindowWrapper from "@polyfills/window"; @@ -12,44 +11,45 @@ import { import { base64UrlEncode, generateRandomBuffer, + getPubKeyFromToken, isReactNative, isWeb, } from "@utils"; import { getWebAuthnAttestation } from "@turnkey/http"; -import { createStorageManager, StorageBase } from "../__storage__/base"; +import { + createStorageManager, + StorageBase, + SessionKey, +} from "../__storage__/base"; +import { CrossPlatformApiKeyStamper } from "../__stampers__/base"; export class TurnkeyClient { config: any; // Type TBD httpClient!: TurnkeySDKClientBase; - // Platform-agnostic stampers - private indexedDBStamper?: IndexedDbStamper | undefined; - private passkeyStamper?: WebauthnStamper | undefined; + // public session?: Session | undefined; // TODO (Amir): Define session type + // public user?: any; // TODO (Amir): Define user type + // public wallets?: any; // TODO (Amir): Define wallets type - // Mobile-specific stampers - private secureStorageStamper?: any | undefined; // TODO (Amir): Implement proper type + private apiKeyStamper?: CrossPlatformApiKeyStamper | undefined; + private passkeyStamper?: WebauthnStamper | undefined; private mobilePasskeyStamper?: any | undefined; // TODO (Amir): Implement proper type - // The active default stamper for the current platform - private activeStamper?: any; // TODO (Amir): This should be a type that encompasses the default "api key" stamper. indexedDB for web, secure storage for mobile. - storageManager!: StorageBase; constructor( config: any, // Users can pass in their own stampers, or we will create them. Should we remove this? - indexedDBStamper?: IndexedDbStamper, + apiKeyStamper?: CrossPlatformApiKeyStamper, passkeyStamper?: WebauthnStamper, - secureStorageStamper?: any, // TODO: Add proper type - mobilePasskeyStamper?: any, // TODO: Add proper type + mobilePasskeyStamper?: any // TODO: Add proper type ) { this.config = config; // Just store any explicitly provided stampers - this.indexedDBStamper = indexedDBStamper; + this.apiKeyStamper = apiKeyStamper; this.passkeyStamper = passkeyStamper; - this.secureStorageStamper = secureStorageStamper; this.mobilePasskeyStamper = mobilePasskeyStamper; // Actual initialization will happen in init() @@ -58,11 +58,6 @@ export class TurnkeyClient { async init() { // Initialize platform-specific stampers if (isWeb()) { - // Web environment - use IndexedDB and WebAuthn if not provided - if (!this.indexedDBStamper) { - this.indexedDBStamper = new IndexedDbStamper(); - } - if (!this.passkeyStamper) { this.passkeyStamper = new WebauthnStamper({ rpId: @@ -78,38 +73,21 @@ export class TurnkeyClient { }), }); } - - // Initialize the IndexedDB stamper (don't put this in the if statement above, indexedDBStamper can be passed in but not initted yet!) - await this.indexedDBStamper.init(); - - // Set default active stamper for web - this.activeStamper = this.indexedDBStamper; } else if (isReactNative()) { - // React Native environment - use mobile-specific stampers - - if (!this.secureStorageStamper) { - // TODO: Initialize secureStorageStamper - // this.secureStorageStamper = new SecureStorageStamper(); - } - if (!this.mobilePasskeyStamper) { // TODO: Initialize mobilePasskeyStamper // this.mobilePasskeyStamper = new MobilePasskeyStamper(); } - - // Initialize the secure storage stamper if needed - // await this.secureStorageStamper.init(); - - // Set default active stamper for mobile - this.activeStamper = this.secureStorageStamper; } // Initialize storage manager this.storageManager = await createStorageManager(); + this.apiKeyStamper = new CrossPlatformApiKeyStamper(this.storageManager); + // Initialize the HTTP client with the appropriate stampers this.httpClient = new TurnkeySDKClientBase({ - stamper: this.activeStamper, + stamper: this.apiKeyStamper, passkeyStamper: isWeb() ? this.passkeyStamper : this.mobilePasskeyStamper, storageManager: this.storageManager, ...this.config, @@ -122,7 +100,7 @@ export class TurnkeyClient { * @returns {Promise} */ createUserPasskey = async ( - config: Record = {}, + config: Record = {} ): Promise => { // TODO (Amir): Make this work for mobile as well const challenge = generateRandomBuffer(); @@ -187,23 +165,14 @@ export class TurnkeyClient { }; }; - /** - * Log in with a passkey. - * To be used in conjunction with a `passkeyStamper` - * - * @param LoginWithPasskeyParams - * @param params.sessionType - The type of session to create - * @param params.publicKey - The public key of indexedDb - * @param params.expirationSeconds - Expiration time for the session in seconds. Defaults to 900 seconds or 15 minutes. - * @returns {Promise} - */ loginWithPasskey = async (params: LoginWithPasskeyParams): Promise => { try { - await this.indexedDBStamper?.resetKeyPair(); // TODO (Amir): Once implemented, this should be activeStamper.resetKeyPair(); + const generatedPublicKey = await this.apiKeyStamper?.createKeyPair(); const { sessionType = SessionType.READ_WRITE, - publicKey = this.indexedDBStamper?.getPublicKey(), // TODO (Amir): Once implemented, this should be activeStamper.getPublicKey(); + publicKey = generatedPublicKey, expirationSeconds = DEFAULT_SESSION_EXPIRATION_IN_SECONDS, + sessionKey = SessionKey.DefaultSessionkey, } = params; // Create a read-only session if (sessionType === SessionType.READ_ONLY) { @@ -217,21 +186,38 @@ export class TurnkeyClient { expiry: Number(readOnlySessionResult.sessionExpiry), token: readOnlySessionResult.session, // Once we have api key session scopes this can change }; - await this.storageManager.storeSession(session); + await this.storageManager.storeSession(session, sessionKey); // Create a read-write session } else if (sessionType === SessionType.READ_WRITE) { if (!publicKey) { throw new Error( - "You must provide a publicKey to create a passkey read write session.", + "You must provide a publicKey to create a passkey read write session." ); } - const sessionResponse = await this.httpClient.stampLogin( { publicKey, expirationSeconds, }, - StamperType.Passkey, + StamperType.Passkey + ); + + // TODO (Amir): This should be done in a helper or something. It's very strange that we have to delete the key pair here + const sessionToReplace = + await this.storageManager.getSession(sessionKey); + if (sessionToReplace) { + const pubkey = getPubKeyFromToken(sessionToReplace.token); + await this.apiKeyStamper?.deleteKeyPair(pubkey); + } + + await this.storageManager.storeSession( + { + /// THIS IS SO DUMB! + sessionType: SessionType.READ_WRITE, + expiry: Number(expirationSeconds), + token: sessionResponse.session, + } as any, + sessionKey ); const whoamiResponse = await this.httpClient.getWhoami({}); @@ -245,7 +231,7 @@ export class TurnkeyClient { token: sessionResponse.session, }; - await this.storageManager.storeSession(session); + await this.storageManager.storeSession(session, sessionKey); } else { throw new Error(`Invalid session type passed: ${sessionType}`); } diff --git a/packages/sdk-js/src/__generated__/sdk-client-base.ts b/packages/sdk-js/src/__generated__/sdk-client-base.ts index f168d947c..7f397d374 100644 --- a/packages/sdk-js/src/__generated__/sdk-client-base.ts +++ b/packages/sdk-js/src/__generated__/sdk-client-base.ts @@ -20,7 +20,7 @@ import { VERSION } from "../__generated__/version"; import type * as SdkApiTypes from "./sdk_api_types"; -import { StorageBase, StorageKey } from "../__storage__/base"; +import { StorageBase, SessionKey } from "../__storage__/base"; import { parseSession } from "../utils"; @@ -71,7 +71,7 @@ export class TurnkeySDKClientBase { async request( url: string, body: TBodyType, - stampWith?: StamperType, + stampWith?: StamperType ): Promise { const fullUrl = this.config.apiBaseUrl + url; const stringifiedBody = JSON.stringify(body); @@ -117,7 +117,7 @@ export class TurnkeySDKClientBase { url: string, body: TBodyType, resultKey: string, - stampWith?: StamperType, + stampWith?: StamperType ): Promise { const pollingDuration = this.config.activityPoller?.intervalMs ?? 1000; const maxRetries = this.config.activityPoller?.numRetries ?? 3; @@ -145,7 +145,7 @@ export class TurnkeySDKClientBase { // Pass the stampWith parameter to getActivity const pollData = (await this.getActivity( pollBody, - stampWith, + stampWith )) as TActivityResponse; if (attempts > maxRetries) { @@ -156,7 +156,7 @@ export class TurnkeySDKClientBase { if ( !TERMINAL_ACTIVITY_STATUSES.includes( - pollData.activity.status as TActivityStatus, + pollData.activity.status as TActivityStatus ) ) { await sleep(pollingDuration); @@ -170,12 +170,12 @@ export class TurnkeySDKClientBase { const responseData = (await this.request( url, body, - stampWith, + stampWith )) as TActivityResponse; if ( !TERMINAL_ACTIVITY_STATUSES.includes( - responseData.activity.status as TActivityStatus, + responseData.activity.status as TActivityStatus ) ) { return pollStatus(responseData.activity.id); @@ -187,13 +187,13 @@ export class TurnkeySDKClientBase { async activityDecision( url: string, body: TBodyType, - stampWith?: StamperType, + stampWith?: StamperType ): Promise { // Use the specified stamper for this request const activityData = (await this.request( url, body, - stampWith, + stampWith )) as TActivityResponse; return { @@ -204,10 +204,10 @@ export class TurnkeySDKClientBase { getActivity = async ( input: SdkApiTypes.TGetActivityBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -219,12 +219,12 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith, + stampWith ); }; stampGetActivity = async ( - input: SdkApiTypes.TGetActivityBody, + input: SdkApiTypes.TGetActivityBody ): Promise => { if (!this.stamper) { return undefined; @@ -241,10 +241,10 @@ export class TurnkeySDKClientBase { getApiKey = async ( input: SdkApiTypes.TGetApiKeyBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -256,12 +256,12 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith, + stampWith ); }; stampGetApiKey = async ( - input: SdkApiTypes.TGetApiKeyBody, + input: SdkApiTypes.TGetApiKeyBody ): Promise => { if (!this.stamper) { return undefined; @@ -278,10 +278,10 @@ export class TurnkeySDKClientBase { getApiKeys = async ( input: SdkApiTypes.TGetApiKeysBody = {}, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -293,12 +293,12 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith, + stampWith ); }; stampGetApiKeys = async ( - input: SdkApiTypes.TGetApiKeysBody, + input: SdkApiTypes.TGetApiKeysBody ): Promise => { if (!this.stamper) { return undefined; @@ -315,10 +315,10 @@ export class TurnkeySDKClientBase { getAttestationDocument = async ( input: SdkApiTypes.TGetAttestationDocumentBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -330,12 +330,12 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith, + stampWith ); }; stampGetAttestationDocument = async ( - input: SdkApiTypes.TGetAttestationDocumentBody, + input: SdkApiTypes.TGetAttestationDocumentBody ): Promise => { if (!this.stamper) { return undefined; @@ -352,10 +352,10 @@ export class TurnkeySDKClientBase { getAuthenticator = async ( input: SdkApiTypes.TGetAuthenticatorBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -367,12 +367,12 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith, + stampWith ); }; stampGetAuthenticator = async ( - input: SdkApiTypes.TGetAuthenticatorBody, + input: SdkApiTypes.TGetAuthenticatorBody ): Promise => { if (!this.stamper) { return undefined; @@ -390,10 +390,10 @@ export class TurnkeySDKClientBase { getAuthenticators = async ( input: SdkApiTypes.TGetAuthenticatorsBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -405,12 +405,12 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith, + stampWith ); }; stampGetAuthenticators = async ( - input: SdkApiTypes.TGetAuthenticatorsBody, + input: SdkApiTypes.TGetAuthenticatorsBody ): Promise => { if (!this.stamper) { return undefined; @@ -428,10 +428,10 @@ export class TurnkeySDKClientBase { getOauthProviders = async ( input: SdkApiTypes.TGetOauthProvidersBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -443,12 +443,12 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith, + stampWith ); }; stampGetOauthProviders = async ( - input: SdkApiTypes.TGetOauthProvidersBody, + input: SdkApiTypes.TGetOauthProvidersBody ): Promise => { if (!this.stamper) { return undefined; @@ -466,10 +466,10 @@ export class TurnkeySDKClientBase { getOrganization = async ( input: SdkApiTypes.TGetOrganizationBody = {}, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -481,12 +481,12 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith, + stampWith ); }; stampGetOrganization = async ( - input: SdkApiTypes.TGetOrganizationBody, + input: SdkApiTypes.TGetOrganizationBody ): Promise => { if (!this.stamper) { return undefined; @@ -504,10 +504,10 @@ export class TurnkeySDKClientBase { getOrganizationConfigs = async ( input: SdkApiTypes.TGetOrganizationConfigsBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -519,12 +519,12 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith, + stampWith ); }; stampGetOrganizationConfigs = async ( - input: SdkApiTypes.TGetOrganizationConfigsBody, + input: SdkApiTypes.TGetOrganizationConfigsBody ): Promise => { if (!this.stamper) { return undefined; @@ -542,10 +542,10 @@ export class TurnkeySDKClientBase { getPolicy = async ( input: SdkApiTypes.TGetPolicyBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -557,12 +557,12 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith, + stampWith ); }; stampGetPolicy = async ( - input: SdkApiTypes.TGetPolicyBody, + input: SdkApiTypes.TGetPolicyBody ): Promise => { if (!this.stamper) { return undefined; @@ -579,10 +579,10 @@ export class TurnkeySDKClientBase { getPrivateKey = async ( input: SdkApiTypes.TGetPrivateKeyBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -594,12 +594,12 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith, + stampWith ); }; stampGetPrivateKey = async ( - input: SdkApiTypes.TGetPrivateKeyBody, + input: SdkApiTypes.TGetPrivateKeyBody ): Promise => { if (!this.stamper) { return undefined; @@ -616,10 +616,10 @@ export class TurnkeySDKClientBase { getUser = async ( input: SdkApiTypes.TGetUserBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -631,12 +631,12 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith, + stampWith ); }; stampGetUser = async ( - input: SdkApiTypes.TGetUserBody, + input: SdkApiTypes.TGetUserBody ): Promise => { if (!this.stamper) { return undefined; @@ -653,10 +653,10 @@ export class TurnkeySDKClientBase { getWallet = async ( input: SdkApiTypes.TGetWalletBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -668,12 +668,12 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith, + stampWith ); }; stampGetWallet = async ( - input: SdkApiTypes.TGetWalletBody, + input: SdkApiTypes.TGetWalletBody ): Promise => { if (!this.stamper) { return undefined; @@ -690,10 +690,10 @@ export class TurnkeySDKClientBase { getWalletAccount = async ( input: SdkApiTypes.TGetWalletAccountBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -705,12 +705,12 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith, + stampWith ); }; stampGetWalletAccount = async ( - input: SdkApiTypes.TGetWalletAccountBody, + input: SdkApiTypes.TGetWalletAccountBody ): Promise => { if (!this.stamper) { return undefined; @@ -728,10 +728,10 @@ export class TurnkeySDKClientBase { getActivities = async ( input: SdkApiTypes.TGetActivitiesBody = {}, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -743,12 +743,12 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith, + stampWith ); }; stampGetActivities = async ( - input: SdkApiTypes.TGetActivitiesBody, + input: SdkApiTypes.TGetActivitiesBody ): Promise => { if (!this.stamper) { return undefined; @@ -765,10 +765,10 @@ export class TurnkeySDKClientBase { getPolicies = async ( input: SdkApiTypes.TGetPoliciesBody = {}, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -780,12 +780,12 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith, + stampWith ); }; stampGetPolicies = async ( - input: SdkApiTypes.TGetPoliciesBody, + input: SdkApiTypes.TGetPoliciesBody ): Promise => { if (!this.stamper) { return undefined; @@ -802,10 +802,10 @@ export class TurnkeySDKClientBase { listPrivateKeyTags = async ( input: SdkApiTypes.TListPrivateKeyTagsBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -817,12 +817,12 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith, + stampWith ); }; stampListPrivateKeyTags = async ( - input: SdkApiTypes.TListPrivateKeyTagsBody, + input: SdkApiTypes.TListPrivateKeyTagsBody ): Promise => { if (!this.stamper) { return undefined; @@ -840,10 +840,10 @@ export class TurnkeySDKClientBase { getPrivateKeys = async ( input: SdkApiTypes.TGetPrivateKeysBody = {}, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -855,12 +855,12 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith, + stampWith ); }; stampGetPrivateKeys = async ( - input: SdkApiTypes.TGetPrivateKeysBody, + input: SdkApiTypes.TGetPrivateKeysBody ): Promise => { if (!this.stamper) { return undefined; @@ -878,10 +878,10 @@ export class TurnkeySDKClientBase { getSubOrgIds = async ( input: SdkApiTypes.TGetSubOrgIdsBody = {}, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -893,12 +893,12 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith, + stampWith ); }; stampGetSubOrgIds = async ( - input: SdkApiTypes.TGetSubOrgIdsBody, + input: SdkApiTypes.TGetSubOrgIdsBody ): Promise => { if (!this.stamper) { return undefined; @@ -915,10 +915,10 @@ export class TurnkeySDKClientBase { listUserTags = async ( input: SdkApiTypes.TListUserTagsBody = {}, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -930,12 +930,12 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith, + stampWith ); }; stampListUserTags = async ( - input: SdkApiTypes.TListUserTagsBody, + input: SdkApiTypes.TListUserTagsBody ): Promise => { if (!this.stamper) { return undefined; @@ -952,10 +952,10 @@ export class TurnkeySDKClientBase { getUsers = async ( input: SdkApiTypes.TGetUsersBody = {}, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -967,12 +967,12 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith, + stampWith ); }; stampGetUsers = async ( - input: SdkApiTypes.TGetUsersBody, + input: SdkApiTypes.TGetUsersBody ): Promise => { if (!this.stamper) { return undefined; @@ -989,10 +989,10 @@ export class TurnkeySDKClientBase { getVerifiedSubOrgIds = async ( input: SdkApiTypes.TGetVerifiedSubOrgIdsBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -1004,12 +1004,12 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith, + stampWith ); }; stampGetVerifiedSubOrgIds = async ( - input: SdkApiTypes.TGetVerifiedSubOrgIdsBody, + input: SdkApiTypes.TGetVerifiedSubOrgIdsBody ): Promise => { if (!this.stamper) { return undefined; @@ -1027,10 +1027,10 @@ export class TurnkeySDKClientBase { getWalletAccounts = async ( input: SdkApiTypes.TGetWalletAccountsBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -1042,12 +1042,12 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith, + stampWith ); }; stampGetWalletAccounts = async ( - input: SdkApiTypes.TGetWalletAccountsBody, + input: SdkApiTypes.TGetWalletAccountsBody ): Promise => { if (!this.stamper) { return undefined; @@ -1065,10 +1065,10 @@ export class TurnkeySDKClientBase { getWallets = async ( input: SdkApiTypes.TGetWalletsBody = {}, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -1080,12 +1080,12 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith, + stampWith ); }; stampGetWallets = async ( - input: SdkApiTypes.TGetWalletsBody, + input: SdkApiTypes.TGetWalletsBody ): Promise => { if (!this.stamper) { return undefined; @@ -1102,10 +1102,10 @@ export class TurnkeySDKClientBase { getWhoami = async ( input: SdkApiTypes.TGetWhoamiBody = {}, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -1117,12 +1117,12 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith, + stampWith ); }; stampGetWhoami = async ( - input: SdkApiTypes.TGetWhoamiBody, + input: SdkApiTypes.TGetWhoamiBody ): Promise => { if (!this.stamper) { return undefined; @@ -1139,11 +1139,11 @@ export class TurnkeySDKClientBase { approveActivity = async ( input: SdkApiTypes.TApproveActivityBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); return this.activityDecision( @@ -1157,12 +1157,12 @@ export class TurnkeySDKClientBase { timestampMs: timestampMs ?? String(Date.now()), type: "ACTIVITY_TYPE_APPROVE_ACTIVITY", }, - stampWith, + stampWith ); }; stampApproveActivity = async ( - input: SdkApiTypes.TApproveActivityBody, + input: SdkApiTypes.TApproveActivityBody ): Promise => { if (!this.stamper) { return undefined; @@ -1180,11 +1180,11 @@ export class TurnkeySDKClientBase { createApiKeys = async ( input: SdkApiTypes.TCreateApiKeysBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -1200,12 +1200,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_CREATE_API_KEYS_V2", }, "createApiKeysResult", - stampWith, + stampWith ); }; stampCreateApiKeys = async ( - input: SdkApiTypes.TCreateApiKeysBody, + input: SdkApiTypes.TCreateApiKeysBody ): Promise => { if (!this.stamper) { return undefined; @@ -1223,11 +1223,11 @@ export class TurnkeySDKClientBase { createApiOnlyUsers = async ( input: SdkApiTypes.TCreateApiOnlyUsersBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -1243,12 +1243,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_CREATE_API_ONLY_USERS", }, "createApiOnlyUsersResult", - stampWith, + stampWith ); }; stampCreateApiOnlyUsers = async ( - input: SdkApiTypes.TCreateApiOnlyUsersBody, + input: SdkApiTypes.TCreateApiOnlyUsersBody ): Promise => { if (!this.stamper) { return undefined; @@ -1266,11 +1266,11 @@ export class TurnkeySDKClientBase { createAuthenticators = async ( input: SdkApiTypes.TCreateAuthenticatorsBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -1286,12 +1286,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_CREATE_AUTHENTICATORS_V2", }, "createAuthenticatorsResult", - stampWith, + stampWith ); }; stampCreateAuthenticators = async ( - input: SdkApiTypes.TCreateAuthenticatorsBody, + input: SdkApiTypes.TCreateAuthenticatorsBody ): Promise => { if (!this.stamper) { return undefined; @@ -1309,11 +1309,11 @@ export class TurnkeySDKClientBase { createInvitations = async ( input: SdkApiTypes.TCreateInvitationsBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -1329,12 +1329,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_CREATE_INVITATIONS", }, "createInvitationsResult", - stampWith, + stampWith ); }; stampCreateInvitations = async ( - input: SdkApiTypes.TCreateInvitationsBody, + input: SdkApiTypes.TCreateInvitationsBody ): Promise => { if (!this.stamper) { return undefined; @@ -1352,11 +1352,11 @@ export class TurnkeySDKClientBase { createOauthProviders = async ( input: SdkApiTypes.TCreateOauthProvidersBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -1372,12 +1372,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_CREATE_OAUTH_PROVIDERS", }, "createOauthProvidersResult", - stampWith, + stampWith ); }; stampCreateOauthProviders = async ( - input: SdkApiTypes.TCreateOauthProvidersBody, + input: SdkApiTypes.TCreateOauthProvidersBody ): Promise => { if (!this.stamper) { return undefined; @@ -1395,11 +1395,11 @@ export class TurnkeySDKClientBase { createPolicies = async ( input: SdkApiTypes.TCreatePoliciesBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -1415,12 +1415,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_CREATE_POLICIES", }, "createPoliciesResult", - stampWith, + stampWith ); }; stampCreatePolicies = async ( - input: SdkApiTypes.TCreatePoliciesBody, + input: SdkApiTypes.TCreatePoliciesBody ): Promise => { if (!this.stamper) { return undefined; @@ -1438,11 +1438,11 @@ export class TurnkeySDKClientBase { createPolicy = async ( input: SdkApiTypes.TCreatePolicyBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -1458,12 +1458,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_CREATE_POLICY_V3", }, "createPolicyResult", - stampWith, + stampWith ); }; stampCreatePolicy = async ( - input: SdkApiTypes.TCreatePolicyBody, + input: SdkApiTypes.TCreatePolicyBody ): Promise => { if (!this.stamper) { return undefined; @@ -1480,11 +1480,11 @@ export class TurnkeySDKClientBase { createPrivateKeyTag = async ( input: SdkApiTypes.TCreatePrivateKeyTagBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -1500,12 +1500,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_CREATE_PRIVATE_KEY_TAG", }, "createPrivateKeyTagResult", - stampWith, + stampWith ); }; stampCreatePrivateKeyTag = async ( - input: SdkApiTypes.TCreatePrivateKeyTagBody, + input: SdkApiTypes.TCreatePrivateKeyTagBody ): Promise => { if (!this.stamper) { return undefined; @@ -1523,11 +1523,11 @@ export class TurnkeySDKClientBase { createPrivateKeys = async ( input: SdkApiTypes.TCreatePrivateKeysBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -1543,12 +1543,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_CREATE_PRIVATE_KEYS_V2", }, "createPrivateKeysResultV2", - stampWith, + stampWith ); }; stampCreatePrivateKeys = async ( - input: SdkApiTypes.TCreatePrivateKeysBody, + input: SdkApiTypes.TCreatePrivateKeysBody ): Promise => { if (!this.stamper) { return undefined; @@ -1566,11 +1566,11 @@ export class TurnkeySDKClientBase { createReadOnlySession = async ( input: SdkApiTypes.TCreateReadOnlySessionBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -1586,12 +1586,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_CREATE_READ_ONLY_SESSION", }, "createReadOnlySessionResult", - stampWith, + stampWith ); }; stampCreateReadOnlySession = async ( - input: SdkApiTypes.TCreateReadOnlySessionBody, + input: SdkApiTypes.TCreateReadOnlySessionBody ): Promise => { if (!this.stamper) { return undefined; @@ -1609,11 +1609,11 @@ export class TurnkeySDKClientBase { createReadWriteSession = async ( input: SdkApiTypes.TCreateReadWriteSessionBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -1629,12 +1629,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_CREATE_READ_WRITE_SESSION_V2", }, "createReadWriteSessionResultV2", - stampWith, + stampWith ); }; stampCreateReadWriteSession = async ( - input: SdkApiTypes.TCreateReadWriteSessionBody, + input: SdkApiTypes.TCreateReadWriteSessionBody ): Promise => { if (!this.stamper) { return undefined; @@ -1652,11 +1652,11 @@ export class TurnkeySDKClientBase { createSubOrganization = async ( input: SdkApiTypes.TCreateSubOrganizationBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -1672,12 +1672,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_CREATE_SUB_ORGANIZATION_V7", }, "createSubOrganizationResultV7", - stampWith, + stampWith ); }; stampCreateSubOrganization = async ( - input: SdkApiTypes.TCreateSubOrganizationBody, + input: SdkApiTypes.TCreateSubOrganizationBody ): Promise => { if (!this.stamper) { return undefined; @@ -1695,11 +1695,11 @@ export class TurnkeySDKClientBase { createUserTag = async ( input: SdkApiTypes.TCreateUserTagBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -1715,12 +1715,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_CREATE_USER_TAG", }, "createUserTagResult", - stampWith, + stampWith ); }; stampCreateUserTag = async ( - input: SdkApiTypes.TCreateUserTagBody, + input: SdkApiTypes.TCreateUserTagBody ): Promise => { if (!this.stamper) { return undefined; @@ -1738,11 +1738,11 @@ export class TurnkeySDKClientBase { createUsers = async ( input: SdkApiTypes.TCreateUsersBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -1758,12 +1758,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_CREATE_USERS_V3", }, "createUsersResult", - stampWith, + stampWith ); }; stampCreateUsers = async ( - input: SdkApiTypes.TCreateUsersBody, + input: SdkApiTypes.TCreateUsersBody ): Promise => { if (!this.stamper) { return undefined; @@ -1780,11 +1780,11 @@ export class TurnkeySDKClientBase { createWallet = async ( input: SdkApiTypes.TCreateWalletBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -1800,12 +1800,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_CREATE_WALLET", }, "createWalletResult", - stampWith, + stampWith ); }; stampCreateWallet = async ( - input: SdkApiTypes.TCreateWalletBody, + input: SdkApiTypes.TCreateWalletBody ): Promise => { if (!this.stamper) { return undefined; @@ -1822,11 +1822,11 @@ export class TurnkeySDKClientBase { createWalletAccounts = async ( input: SdkApiTypes.TCreateWalletAccountsBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -1842,12 +1842,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_CREATE_WALLET_ACCOUNTS", }, "createWalletAccountsResult", - stampWith, + stampWith ); }; stampCreateWalletAccounts = async ( - input: SdkApiTypes.TCreateWalletAccountsBody, + input: SdkApiTypes.TCreateWalletAccountsBody ): Promise => { if (!this.stamper) { return undefined; @@ -1865,11 +1865,11 @@ export class TurnkeySDKClientBase { deleteApiKeys = async ( input: SdkApiTypes.TDeleteApiKeysBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -1885,12 +1885,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_DELETE_API_KEYS", }, "deleteApiKeysResult", - stampWith, + stampWith ); }; stampDeleteApiKeys = async ( - input: SdkApiTypes.TDeleteApiKeysBody, + input: SdkApiTypes.TDeleteApiKeysBody ): Promise => { if (!this.stamper) { return undefined; @@ -1908,11 +1908,11 @@ export class TurnkeySDKClientBase { deleteAuthenticators = async ( input: SdkApiTypes.TDeleteAuthenticatorsBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -1928,12 +1928,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_DELETE_AUTHENTICATORS", }, "deleteAuthenticatorsResult", - stampWith, + stampWith ); }; stampDeleteAuthenticators = async ( - input: SdkApiTypes.TDeleteAuthenticatorsBody, + input: SdkApiTypes.TDeleteAuthenticatorsBody ): Promise => { if (!this.stamper) { return undefined; @@ -1951,11 +1951,11 @@ export class TurnkeySDKClientBase { deleteInvitation = async ( input: SdkApiTypes.TDeleteInvitationBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -1971,12 +1971,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_DELETE_INVITATION", }, "deleteInvitationResult", - stampWith, + stampWith ); }; stampDeleteInvitation = async ( - input: SdkApiTypes.TDeleteInvitationBody, + input: SdkApiTypes.TDeleteInvitationBody ): Promise => { if (!this.stamper) { return undefined; @@ -1994,11 +1994,11 @@ export class TurnkeySDKClientBase { deleteOauthProviders = async ( input: SdkApiTypes.TDeleteOauthProvidersBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -2014,12 +2014,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_DELETE_OAUTH_PROVIDERS", }, "deleteOauthProvidersResult", - stampWith, + stampWith ); }; stampDeleteOauthProviders = async ( - input: SdkApiTypes.TDeleteOauthProvidersBody, + input: SdkApiTypes.TDeleteOauthProvidersBody ): Promise => { if (!this.stamper) { return undefined; @@ -2037,11 +2037,11 @@ export class TurnkeySDKClientBase { deletePolicy = async ( input: SdkApiTypes.TDeletePolicyBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -2057,12 +2057,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_DELETE_POLICY", }, "deletePolicyResult", - stampWith, + stampWith ); }; stampDeletePolicy = async ( - input: SdkApiTypes.TDeletePolicyBody, + input: SdkApiTypes.TDeletePolicyBody ): Promise => { if (!this.stamper) { return undefined; @@ -2079,11 +2079,11 @@ export class TurnkeySDKClientBase { deletePrivateKeyTags = async ( input: SdkApiTypes.TDeletePrivateKeyTagsBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -2099,12 +2099,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_DELETE_PRIVATE_KEY_TAGS", }, "deletePrivateKeyTagsResult", - stampWith, + stampWith ); }; stampDeletePrivateKeyTags = async ( - input: SdkApiTypes.TDeletePrivateKeyTagsBody, + input: SdkApiTypes.TDeletePrivateKeyTagsBody ): Promise => { if (!this.stamper) { return undefined; @@ -2122,11 +2122,11 @@ export class TurnkeySDKClientBase { deletePrivateKeys = async ( input: SdkApiTypes.TDeletePrivateKeysBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -2142,12 +2142,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_DELETE_PRIVATE_KEYS", }, "deletePrivateKeysResult", - stampWith, + stampWith ); }; stampDeletePrivateKeys = async ( - input: SdkApiTypes.TDeletePrivateKeysBody, + input: SdkApiTypes.TDeletePrivateKeysBody ): Promise => { if (!this.stamper) { return undefined; @@ -2165,11 +2165,11 @@ export class TurnkeySDKClientBase { deleteSubOrganization = async ( input: SdkApiTypes.TDeleteSubOrganizationBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -2185,12 +2185,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_DELETE_SUB_ORGANIZATION", }, "deleteSubOrganizationResult", - stampWith, + stampWith ); }; stampDeleteSubOrganization = async ( - input: SdkApiTypes.TDeleteSubOrganizationBody, + input: SdkApiTypes.TDeleteSubOrganizationBody ): Promise => { if (!this.stamper) { return undefined; @@ -2208,11 +2208,11 @@ export class TurnkeySDKClientBase { deleteUserTags = async ( input: SdkApiTypes.TDeleteUserTagsBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -2228,12 +2228,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_DELETE_USER_TAGS", }, "deleteUserTagsResult", - stampWith, + stampWith ); }; stampDeleteUserTags = async ( - input: SdkApiTypes.TDeleteUserTagsBody, + input: SdkApiTypes.TDeleteUserTagsBody ): Promise => { if (!this.stamper) { return undefined; @@ -2251,11 +2251,11 @@ export class TurnkeySDKClientBase { deleteUsers = async ( input: SdkApiTypes.TDeleteUsersBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -2271,12 +2271,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_DELETE_USERS", }, "deleteUsersResult", - stampWith, + stampWith ); }; stampDeleteUsers = async ( - input: SdkApiTypes.TDeleteUsersBody, + input: SdkApiTypes.TDeleteUsersBody ): Promise => { if (!this.stamper) { return undefined; @@ -2293,11 +2293,11 @@ export class TurnkeySDKClientBase { deleteWallets = async ( input: SdkApiTypes.TDeleteWalletsBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -2313,12 +2313,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_DELETE_WALLETS", }, "deleteWalletsResult", - stampWith, + stampWith ); }; stampDeleteWallets = async ( - input: SdkApiTypes.TDeleteWalletsBody, + input: SdkApiTypes.TDeleteWalletsBody ): Promise => { if (!this.stamper) { return undefined; @@ -2335,11 +2335,11 @@ export class TurnkeySDKClientBase { emailAuth = async ( input: SdkApiTypes.TEmailAuthBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -2355,12 +2355,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_EMAIL_AUTH_V2", }, "emailAuthResult", - stampWith, + stampWith ); }; stampEmailAuth = async ( - input: SdkApiTypes.TEmailAuthBody, + input: SdkApiTypes.TEmailAuthBody ): Promise => { if (!this.stamper) { return undefined; @@ -2377,11 +2377,11 @@ export class TurnkeySDKClientBase { exportPrivateKey = async ( input: SdkApiTypes.TExportPrivateKeyBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -2397,12 +2397,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_EXPORT_PRIVATE_KEY", }, "exportPrivateKeyResult", - stampWith, + stampWith ); }; stampExportPrivateKey = async ( - input: SdkApiTypes.TExportPrivateKeyBody, + input: SdkApiTypes.TExportPrivateKeyBody ): Promise => { if (!this.stamper) { return undefined; @@ -2420,11 +2420,11 @@ export class TurnkeySDKClientBase { exportWallet = async ( input: SdkApiTypes.TExportWalletBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -2440,12 +2440,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_EXPORT_WALLET", }, "exportWalletResult", - stampWith, + stampWith ); }; stampExportWallet = async ( - input: SdkApiTypes.TExportWalletBody, + input: SdkApiTypes.TExportWalletBody ): Promise => { if (!this.stamper) { return undefined; @@ -2462,11 +2462,11 @@ export class TurnkeySDKClientBase { exportWalletAccount = async ( input: SdkApiTypes.TExportWalletAccountBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -2482,12 +2482,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_EXPORT_WALLET_ACCOUNT", }, "exportWalletAccountResult", - stampWith, + stampWith ); }; stampExportWalletAccount = async ( - input: SdkApiTypes.TExportWalletAccountBody, + input: SdkApiTypes.TExportWalletAccountBody ): Promise => { if (!this.stamper) { return undefined; @@ -2505,11 +2505,11 @@ export class TurnkeySDKClientBase { importPrivateKey = async ( input: SdkApiTypes.TImportPrivateKeyBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -2525,12 +2525,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_IMPORT_PRIVATE_KEY", }, "importPrivateKeyResult", - stampWith, + stampWith ); }; stampImportPrivateKey = async ( - input: SdkApiTypes.TImportPrivateKeyBody, + input: SdkApiTypes.TImportPrivateKeyBody ): Promise => { if (!this.stamper) { return undefined; @@ -2548,11 +2548,11 @@ export class TurnkeySDKClientBase { importWallet = async ( input: SdkApiTypes.TImportWalletBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -2568,12 +2568,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_IMPORT_WALLET", }, "importWalletResult", - stampWith, + stampWith ); }; stampImportWallet = async ( - input: SdkApiTypes.TImportWalletBody, + input: SdkApiTypes.TImportWalletBody ): Promise => { if (!this.stamper) { return undefined; @@ -2590,11 +2590,11 @@ export class TurnkeySDKClientBase { initImportPrivateKey = async ( input: SdkApiTypes.TInitImportPrivateKeyBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -2610,12 +2610,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_INIT_IMPORT_PRIVATE_KEY", }, "initImportPrivateKeyResult", - stampWith, + stampWith ); }; stampInitImportPrivateKey = async ( - input: SdkApiTypes.TInitImportPrivateKeyBody, + input: SdkApiTypes.TInitImportPrivateKeyBody ): Promise => { if (!this.stamper) { return undefined; @@ -2633,11 +2633,11 @@ export class TurnkeySDKClientBase { initImportWallet = async ( input: SdkApiTypes.TInitImportWalletBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -2653,12 +2653,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_INIT_IMPORT_WALLET", }, "initImportWalletResult", - stampWith, + stampWith ); }; stampInitImportWallet = async ( - input: SdkApiTypes.TInitImportWalletBody, + input: SdkApiTypes.TInitImportWalletBody ): Promise => { if (!this.stamper) { return undefined; @@ -2676,11 +2676,11 @@ export class TurnkeySDKClientBase { initOtp = async ( input: SdkApiTypes.TInitOtpBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -2696,12 +2696,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_INIT_OTP", }, "initOtpResult", - stampWith, + stampWith ); }; stampInitOtp = async ( - input: SdkApiTypes.TInitOtpBody, + input: SdkApiTypes.TInitOtpBody ): Promise => { if (!this.stamper) { return undefined; @@ -2718,11 +2718,11 @@ export class TurnkeySDKClientBase { initOtpAuth = async ( input: SdkApiTypes.TInitOtpAuthBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -2738,12 +2738,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_INIT_OTP_AUTH_V2", }, "initOtpAuthResultV2", - stampWith, + stampWith ); }; stampInitOtpAuth = async ( - input: SdkApiTypes.TInitOtpAuthBody, + input: SdkApiTypes.TInitOtpAuthBody ): Promise => { if (!this.stamper) { return undefined; @@ -2760,11 +2760,11 @@ export class TurnkeySDKClientBase { initUserEmailRecovery = async ( input: SdkApiTypes.TInitUserEmailRecoveryBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -2780,12 +2780,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_INIT_USER_EMAIL_RECOVERY", }, "initUserEmailRecoveryResult", - stampWith, + stampWith ); }; stampInitUserEmailRecovery = async ( - input: SdkApiTypes.TInitUserEmailRecoveryBody, + input: SdkApiTypes.TInitUserEmailRecoveryBody ): Promise => { if (!this.stamper) { return undefined; @@ -2803,11 +2803,11 @@ export class TurnkeySDKClientBase { oauth = async ( input: SdkApiTypes.TOauthBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -2823,12 +2823,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_OAUTH", }, "oauthResult", - stampWith, + stampWith ); }; stampOauth = async ( - input: SdkApiTypes.TOauthBody, + input: SdkApiTypes.TOauthBody ): Promise => { if (!this.stamper) { return undefined; @@ -2845,11 +2845,11 @@ export class TurnkeySDKClientBase { oauthLogin = async ( input: SdkApiTypes.TOauthLoginBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -2865,12 +2865,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_OAUTH_LOGIN", }, "oauthLoginResult", - stampWith, + stampWith ); }; stampOauthLogin = async ( - input: SdkApiTypes.TOauthLoginBody, + input: SdkApiTypes.TOauthLoginBody ): Promise => { if (!this.stamper) { return undefined; @@ -2887,11 +2887,11 @@ export class TurnkeySDKClientBase { otpAuth = async ( input: SdkApiTypes.TOtpAuthBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -2907,12 +2907,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_OTP_AUTH", }, "otpAuthResult", - stampWith, + stampWith ); }; stampOtpAuth = async ( - input: SdkApiTypes.TOtpAuthBody, + input: SdkApiTypes.TOtpAuthBody ): Promise => { if (!this.stamper) { return undefined; @@ -2929,11 +2929,11 @@ export class TurnkeySDKClientBase { otpLogin = async ( input: SdkApiTypes.TOtpLoginBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -2949,12 +2949,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_OTP_LOGIN", }, "otpLoginResult", - stampWith, + stampWith ); }; stampOtpLogin = async ( - input: SdkApiTypes.TOtpLoginBody, + input: SdkApiTypes.TOtpLoginBody ): Promise => { if (!this.stamper) { return undefined; @@ -2971,11 +2971,11 @@ export class TurnkeySDKClientBase { recoverUser = async ( input: SdkApiTypes.TRecoverUserBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -2991,12 +2991,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_RECOVER_USER", }, "recoverUserResult", - stampWith, + stampWith ); }; stampRecoverUser = async ( - input: SdkApiTypes.TRecoverUserBody, + input: SdkApiTypes.TRecoverUserBody ): Promise => { if (!this.stamper) { return undefined; @@ -3013,11 +3013,11 @@ export class TurnkeySDKClientBase { rejectActivity = async ( input: SdkApiTypes.TRejectActivityBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); return this.activityDecision( @@ -3031,12 +3031,12 @@ export class TurnkeySDKClientBase { timestampMs: timestampMs ?? String(Date.now()), type: "ACTIVITY_TYPE_REJECT_ACTIVITY", }, - stampWith, + stampWith ); }; stampRejectActivity = async ( - input: SdkApiTypes.TRejectActivityBody, + input: SdkApiTypes.TRejectActivityBody ): Promise => { if (!this.stamper) { return undefined; @@ -3054,11 +3054,11 @@ export class TurnkeySDKClientBase { removeOrganizationFeature = async ( input: SdkApiTypes.TRemoveOrganizationFeatureBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -3074,12 +3074,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_REMOVE_ORGANIZATION_FEATURE", }, "removeOrganizationFeatureResult", - stampWith, + stampWith ); }; stampRemoveOrganizationFeature = async ( - input: SdkApiTypes.TRemoveOrganizationFeatureBody, + input: SdkApiTypes.TRemoveOrganizationFeatureBody ): Promise => { if (!this.stamper) { return undefined; @@ -3097,11 +3097,11 @@ export class TurnkeySDKClientBase { setOrganizationFeature = async ( input: SdkApiTypes.TSetOrganizationFeatureBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -3117,12 +3117,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_SET_ORGANIZATION_FEATURE", }, "setOrganizationFeatureResult", - stampWith, + stampWith ); }; stampSetOrganizationFeature = async ( - input: SdkApiTypes.TSetOrganizationFeatureBody, + input: SdkApiTypes.TSetOrganizationFeatureBody ): Promise => { if (!this.stamper) { return undefined; @@ -3140,11 +3140,11 @@ export class TurnkeySDKClientBase { signRawPayload = async ( input: SdkApiTypes.TSignRawPayloadBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -3160,12 +3160,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_SIGN_RAW_PAYLOAD_V2", }, "signRawPayloadResult", - stampWith, + stampWith ); }; stampSignRawPayload = async ( - input: SdkApiTypes.TSignRawPayloadBody, + input: SdkApiTypes.TSignRawPayloadBody ): Promise => { if (!this.stamper) { return undefined; @@ -3183,11 +3183,11 @@ export class TurnkeySDKClientBase { signRawPayloads = async ( input: SdkApiTypes.TSignRawPayloadsBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -3203,12 +3203,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_SIGN_RAW_PAYLOADS", }, "signRawPayloadsResult", - stampWith, + stampWith ); }; stampSignRawPayloads = async ( - input: SdkApiTypes.TSignRawPayloadsBody, + input: SdkApiTypes.TSignRawPayloadsBody ): Promise => { if (!this.stamper) { return undefined; @@ -3226,11 +3226,11 @@ export class TurnkeySDKClientBase { signTransaction = async ( input: SdkApiTypes.TSignTransactionBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -3246,12 +3246,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_SIGN_TRANSACTION_V2", }, "signTransactionResult", - stampWith, + stampWith ); }; stampSignTransaction = async ( - input: SdkApiTypes.TSignTransactionBody, + input: SdkApiTypes.TSignTransactionBody ): Promise => { if (!this.stamper) { return undefined; @@ -3269,11 +3269,11 @@ export class TurnkeySDKClientBase { stampLogin = async ( input: SdkApiTypes.TStampLoginBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -3289,12 +3289,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_STAMP_LOGIN", }, "stampLoginResult", - stampWith, + stampWith ); }; stampStampLogin = async ( - input: SdkApiTypes.TStampLoginBody, + input: SdkApiTypes.TStampLoginBody ): Promise => { if (!this.stamper) { return undefined; @@ -3311,11 +3311,11 @@ export class TurnkeySDKClientBase { updatePolicy = async ( input: SdkApiTypes.TUpdatePolicyBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -3331,12 +3331,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_UPDATE_POLICY_V2", }, "updatePolicyResultV2", - stampWith, + stampWith ); }; stampUpdatePolicy = async ( - input: SdkApiTypes.TUpdatePolicyBody, + input: SdkApiTypes.TUpdatePolicyBody ): Promise => { if (!this.stamper) { return undefined; @@ -3353,11 +3353,11 @@ export class TurnkeySDKClientBase { updatePrivateKeyTag = async ( input: SdkApiTypes.TUpdatePrivateKeyTagBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -3373,12 +3373,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_UPDATE_PRIVATE_KEY_TAG", }, "updatePrivateKeyTagResult", - stampWith, + stampWith ); }; stampUpdatePrivateKeyTag = async ( - input: SdkApiTypes.TUpdatePrivateKeyTagBody, + input: SdkApiTypes.TUpdatePrivateKeyTagBody ): Promise => { if (!this.stamper) { return undefined; @@ -3396,11 +3396,11 @@ export class TurnkeySDKClientBase { updateRootQuorum = async ( input: SdkApiTypes.TUpdateRootQuorumBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -3416,12 +3416,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_UPDATE_ROOT_QUORUM", }, "updateRootQuorumResult", - stampWith, + stampWith ); }; stampUpdateRootQuorum = async ( - input: SdkApiTypes.TUpdateRootQuorumBody, + input: SdkApiTypes.TUpdateRootQuorumBody ): Promise => { if (!this.stamper) { return undefined; @@ -3439,11 +3439,11 @@ export class TurnkeySDKClientBase { updateUser = async ( input: SdkApiTypes.TUpdateUserBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -3459,12 +3459,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_UPDATE_USER", }, "updateUserResult", - stampWith, + stampWith ); }; stampUpdateUser = async ( - input: SdkApiTypes.TUpdateUserBody, + input: SdkApiTypes.TUpdateUserBody ): Promise => { if (!this.stamper) { return undefined; @@ -3481,11 +3481,11 @@ export class TurnkeySDKClientBase { updateUserTag = async ( input: SdkApiTypes.TUpdateUserTagBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -3501,12 +3501,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_UPDATE_USER_TAG", }, "updateUserTagResult", - stampWith, + stampWith ); }; stampUpdateUserTag = async ( - input: SdkApiTypes.TUpdateUserTagBody, + input: SdkApiTypes.TUpdateUserTagBody ): Promise => { if (!this.stamper) { return undefined; @@ -3524,11 +3524,11 @@ export class TurnkeySDKClientBase { updateWallet = async ( input: SdkApiTypes.TUpdateWalletBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -3544,12 +3544,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_UPDATE_WALLET", }, "updateWalletResult", - stampWith, + stampWith ); }; stampUpdateWallet = async ( - input: SdkApiTypes.TUpdateWalletBody, + input: SdkApiTypes.TUpdateWalletBody ): Promise => { if (!this.stamper) { return undefined; @@ -3566,11 +3566,11 @@ export class TurnkeySDKClientBase { verifyOtp = async ( input: SdkApiTypes.TVerifyOtpBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); @@ -3586,12 +3586,12 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_VERIFY_OTP", }, "verifyOtpResult", - stampWith, + stampWith ); }; stampVerifyOtp = async ( - input: SdkApiTypes.TVerifyOtpBody, + input: SdkApiTypes.TVerifyOtpBody ): Promise => { if (!this.stamper) { return undefined; @@ -3608,10 +3608,10 @@ export class TurnkeySDKClientBase { testRateLimits = async ( input: SdkApiTypes.TTestRateLimitsBody, - stampWith?: StamperType, + stampWith?: StamperType ): Promise => { let session = await this.storageManager?.getStorageValue( - StorageKey.Session, + SessionKey.DefaultSessionkey ); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -3623,12 +3623,12 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith, + stampWith ); }; stampTestRateLimits = async ( - input: SdkApiTypes.TTestRateLimitsBody, + input: SdkApiTypes.TTestRateLimitsBody ): Promise => { if (!this.stamper) { return undefined; diff --git a/packages/sdk-js/src/__stampers__/base.ts b/packages/sdk-js/src/__stampers__/base.ts new file mode 100644 index 000000000..d3ee2ff14 --- /dev/null +++ b/packages/sdk-js/src/__stampers__/base.ts @@ -0,0 +1,64 @@ +import { getPubKeyFromToken, isReactNative, isWeb } from "@utils"; +import { IndexedDbStamper } from "./web/stamper"; +import { StorageBase } from "../__storage__/base"; + +export interface StamperBase { + listKeyPairs(): Promise; + createKeyPair(externalKeyPair?: CryptoKeyPair): Promise; + deleteKeyPair(publicKeyHex: string): Promise; + sign(payload: string, publicKeyHex: string): Promise; + stamp( + payload: string, + publicKeyHex: string + ): Promise<{ stampHeaderName: string; stampHeaderValue: string }>; +} + +export class CrossPlatformApiKeyStamper { + private stamper!: StamperBase; + + constructor(private storageManager: StorageBase) { + if (isWeb()) { + this.stamper = new IndexedDbStamper(); + } else if (isReactNative()) { + //this.stamper = new ReactNativeKeychainStamper(); + } else { + throw new Error("Unsupported platform for API key stamper"); + } + } + + listKeyPairs(): Promise { + return this.stamper.listKeyPairs(); + } + + createKeyPair(externalKeyPair?: CryptoKeyPair): Promise { + return this.stamper.createKeyPair(externalKeyPair); + } + + deleteKeyPair(publicKeyHex: string): Promise { + return this.stamper.deleteKeyPair(publicKeyHex); + } + + async sign(payload: string): Promise { + const session = await this.storageManager.getActiveSession(); + console.log("Active session:", session); + console.log("Session token:", session?.token); + if (!session?.token) { + throw new Error("No active session or token available."); + } + const publicKey = getPubKeyFromToken(session.token); + return this.stamper.sign(payload, publicKey); + } + + async stamp( + payload: string + ): Promise<{ stampHeaderName: string; stampHeaderValue: string }> { + const session = await this.storageManager.getActiveSession(); + console.log("Active session:", session); + console.log("Session token:", session?.token); + if (!session?.token) { + throw new Error("No active session or token available."); + } + const publicKey = getPubKeyFromToken(session.token); + return this.stamper.stamp(payload, publicKey); + } +} diff --git a/packages/sdk-js/src/__stampers__/web/stamper.ts b/packages/sdk-js/src/__stampers__/web/stamper.ts new file mode 100644 index 000000000..f79c55c11 --- /dev/null +++ b/packages/sdk-js/src/__stampers__/web/stamper.ts @@ -0,0 +1,221 @@ +import { + uint8ArrayToHexString, + stringToBase64urlString, + pointEncode, +} from "@turnkey/encoding"; +import { StamperBase } from "../base"; + +const DB_NAME = "TurnkeyStamperDB"; +const DB_STORE = "KeyStore"; +const stampHeaderName = "X-Stamp"; + +function convertEcdsaIeee1363ToDer(ieee: Uint8Array): Uint8Array { + if (ieee.length % 2 != 0 || ieee.length == 0 || ieee.length > 132) { + throw new Error( + "Invalid IEEE P1363 signature encoding. Length: " + ieee.length + ); + } + const r = toUnsignedBigNum(ieee.subarray(0, ieee.length / 2)); + const s = toUnsignedBigNum(ieee.subarray(ieee.length / 2, ieee.length)); + let offset = 0; + const length = 1 + 1 + r.length + 1 + 1 + s.length; + let der: Uint8Array; + if (length >= 128) { + der = new Uint8Array(length + 3); + der[offset++] = 48; + der[offset++] = 128 + 1; + der[offset++] = length; + } else { + der = new Uint8Array(length + 2); + der[offset++] = 48; + der[offset++] = length; + } + der[offset++] = 2; + der[offset++] = r.length; + der.set(r, offset); + offset += r.length; + der[offset++] = 2; + der[offset++] = s.length; + der.set(s, offset); + return der; +} + +function toUnsignedBigNum(bytes: Uint8Array): Uint8Array { + let start = 0; + while (start < bytes.length && bytes[start] == 0) { + start++; + } + if (start == bytes.length) { + start = bytes.length - 1; + } + let extraZero = 0; + if ((bytes[start]! & 128) == 128) { + extraZero = 1; + } + const res = new Uint8Array(bytes.length - start + extraZero); + res.set(bytes.subarray(start), extraZero); + return res; +} + +export class IndexedDbStamper implements StamperBase { + constructor() { + if (typeof window === "undefined") { + throw new Error("IndexedDB is only available in the browser"); + } + } + + private async openDb(): Promise { + return new Promise((resolve, reject) => { + const request = indexedDB.open(DB_NAME, 1); + request.onupgradeneeded = (event) => { + const db = (event.target as IDBOpenDBRequest).result; + if (!db.objectStoreNames.contains(DB_STORE)) { + db.createObjectStore(DB_STORE); + } + }; + request.onsuccess = () => resolve(request.result); + request.onerror = () => reject(request.error); + }); + } + + private async storeKeyPair( + publicKeyHex: string, + privateKey: CryptoKey + ): Promise { + const db = await this.openDb(); + return new Promise((resolve, reject) => { + const tx = db.transaction(DB_STORE, "readwrite"); + const store = tx.objectStore(DB_STORE); + store.put(privateKey, publicKeyHex); + tx.oncomplete = () => { + db.close(); + resolve(); + }; + tx.onerror = () => reject(tx.error); + tx.onabort = () => reject(tx.error); + }); + } + + private async getPrivateKey(publicKeyHex: string): Promise { + const db = await this.openDb(); + return new Promise((resolve, reject) => { + const tx = db.transaction(DB_STORE, "readonly"); + const store = tx.objectStore(DB_STORE); + const request = store.get(publicKeyHex); + request.onsuccess = () => { + db.close(); + resolve(request.result || null); + }; + request.onerror = () => { + db.close(); + reject(request.error); + }; + }); + } + + async listKeyPairs(): Promise { + const db = await this.openDb(); + return new Promise((resolve, reject) => { + const tx = db.transaction(DB_STORE, "readonly"); + const store = tx.objectStore(DB_STORE); + const request = store.getAllKeys(); + request.onsuccess = () => { + db.close(); + resolve(request.result as string[]); + }; + request.onerror = () => { + db.close(); + reject(request.error); + }; + }); + } + + async createKeyPair(externalKeyPair?: CryptoKeyPair): Promise { + let privateKey: CryptoKey; + let publicKey: CryptoKey; + if (externalKeyPair) { + const extractable = (externalKeyPair.privateKey as any).extractable; + if (extractable !== false) { + throw new Error("Provided privateKey must be non-extractable."); + } + privateKey = externalKeyPair.privateKey; + publicKey = externalKeyPair.publicKey; + } else { + const keyPair = await crypto.subtle.generateKey( + { name: "ECDSA", namedCurve: "P-256" }, + false, + ["sign", "verify"] + ); + privateKey = keyPair.privateKey; + publicKey = keyPair.publicKey; + } + const rawPubKey = new Uint8Array( + await crypto.subtle.exportKey("raw", publicKey) + ); + const compressedPubKey = pointEncode(rawPubKey); + const compressedHex = uint8ArrayToHexString(compressedPubKey); + await this.storeKeyPair(compressedHex, privateKey); + return compressedHex; + } + + async deleteKeyPair(publicKeyHex: string): Promise { + const db = await this.openDb(); + return new Promise((resolve, reject) => { + const tx = db.transaction(DB_STORE, "readwrite"); + const store = tx.objectStore(DB_STORE); + store.delete(publicKeyHex); + tx.oncomplete = () => { + db.close(); + resolve(); + }; + tx.onerror = () => reject(tx.error); + }); + } + + async clear(): Promise { + const db = await this.openDb(); + return new Promise((resolve, reject) => { + const tx = db.transaction(DB_STORE, "readwrite"); + const store = tx.objectStore(DB_STORE); + store.clear(); + tx.oncomplete = () => { + db.close(); + resolve(); + }; + tx.onerror = () => reject(tx.error); + }); + } + + async sign(payload: string, publicKeyHex: string): Promise { + const privateKey = await this.getPrivateKey(publicKeyHex); + if (!privateKey) { + throw new Error("Key not found for publicKey: " + publicKeyHex); + } + const encodedPayload = new TextEncoder().encode(payload); + const signatureIeee1363 = await crypto.subtle.sign( + { name: "ECDSA", hash: { name: "SHA-256" } }, + privateKey, + encodedPayload + ); + const signatureDer = convertEcdsaIeee1363ToDer( + new Uint8Array(signatureIeee1363) + ); + return uint8ArrayToHexString(signatureDer); + } + + async stamp( + payload: string, + publicKeyHex: string + ): Promise<{ stampHeaderName: string; stampHeaderValue: string }> { + const signature = await this.sign(payload, publicKeyHex); + const stamp = { + publicKey: publicKeyHex, + scheme: "SIGNATURE_SCHEME_TK_API_P256", + signature, + }; + return { + stampHeaderName, + stampHeaderValue: stringToBase64urlString(JSON.stringify(stamp)), + }; + } +} diff --git a/packages/sdk-js/src/__storage__/base.ts b/packages/sdk-js/src/__storage__/base.ts index 15892a7cc..caaac9c9a 100644 --- a/packages/sdk-js/src/__storage__/base.ts +++ b/packages/sdk-js/src/__storage__/base.ts @@ -1,40 +1,45 @@ import { Session } from "@turnkey/sdk-types"; -import { AuthClient } from ".."; import { WebStorageManager } from "./web/storage"; import { isReactNative, isWeb } from "@utils"; -export enum StorageKey { - Session = "@turnkey/session/v2", - Client = "@turnkey/client", -} -export interface StorageValue { - [StorageKey.Session]: Session; - [StorageKey.Client]: AuthClient; // TODO (Amir): I don't think we need this +export enum SessionKey { + DefaultSessionkey = "@turnkey/session/v3", } export interface StorageBase { - getStorageValue( - key: K, - ): Promise; - setStorageValue( - storageKey: K, - storageValue: StorageValue[K], - ): Promise; - removeStorageValue(storageKey: K): Promise; - storeSession(session: Session): Promise; + getStorageValue(sessionKey: string): Promise; + + setStorageValue(sessionKey: string, storageValue: any): Promise; + + removeStorageValue(sessionKey: string): Promise; + + storeSession(session: Session, sessionKey?: string): Promise; + + getSession(sessionKey?: string): Promise; + + getActiveSessionKey(): Promise; + + getActiveSession(): Promise; + + listSessionKeys(): Promise; + + clearSession(sessionKey: string): Promise; + + clearAllSessions(): Promise; } export async function createStorageManager(): Promise { if (isReactNative()) { - try { - // Dynamic import to prevent bundling the native module in web environments - const { MobileStorageManager } = await import("./mobile/storage"); - return new MobileStorageManager(); - } catch (error) { - throw new Error( - `Failed to load native secure storage, falling back to memory storage: ${error}`, - ); - } + throw new Error("Not implemented for React Native yet."); + // try { + // // Dynamic import to prevent bundling the native module in web environments + // const { MobileStorageManager } = await import("./mobile/storage"); + // return new MobileStorageManager(); + // } catch (error) { + // throw new Error( + // `Failed to load native secure storage, falling back to memory storage: ${error}` + // ); + // } } else if (isWeb()) { return new WebStorageManager(); } else { diff --git a/packages/sdk-js/src/__storage__/mobile/storage.ts b/packages/sdk-js/src/__storage__/mobile/storage.ts index 282b89142..e90a014a6 100644 --- a/packages/sdk-js/src/__storage__/mobile/storage.ts +++ b/packages/sdk-js/src/__storage__/mobile/storage.ts @@ -1,58 +1,58 @@ -import type { Session } from "@turnkey/sdk-types"; +// import type { Session } from "@turnkey/sdk-types"; -import { StorageBase, StorageKey, StorageValue } from "../base"; +// import { StorageBase, StorageKey, StorageValue } from "../base"; -export class MobileStorageManager implements StorageBase { - Keychain = require("react-native-keychain"); +// export class MobileStorageManager implements StorageBase { +// Keychain = require("react-native-keychain"); - getStorageValue = async ( - storageKey: K, - ): Promise => { - try { - const result = await this.Keychain.getGenericPassword({ - service: storageKey, - }); +// getStorageValue = async ( +// storageKey: K, +// ): Promise => { +// try { +// const result = await this.Keychain.getGenericPassword({ +// service: storageKey, +// }); - if (result && result.password) { - return JSON.parse(result.password); - } - return undefined; - } catch (error) { - console.error("Error retrieving from Keychain:", error); - return undefined; - } - }; +// if (result && result.password) { +// return JSON.parse(result.password); +// } +// return undefined; +// } catch (error) { +// console.error("Error retrieving from Keychain:", error); +// return undefined; +// } +// }; - setStorageValue = async ( - storageKey: K, - storageValue: StorageValue[K], - ): Promise => { - try { - const result = await this.Keychain.setGenericPassword( - storageKey, - JSON.stringify(storageValue), - { service: storageKey }, - ); - return !!result; - } catch (error) { - console.error("Error storing in Keychain:", error); - return false; - } - }; +// setStorageValue = async ( +// storageKey: K, +// storageValue: StorageValue[K], +// ): Promise => { +// try { +// const result = await this.Keychain.setGenericPassword( +// storageKey, +// JSON.stringify(storageValue), +// { service: storageKey }, +// ); +// return !!result; +// } catch (error) { +// console.error("Error storing in Keychain:", error); +// return false; +// } +// }; - removeStorageValue = async ( - storageKey: K, - ): Promise => { - try { - await this.Keychain.resetGenericPassword({ - service: storageKey, - }); - } catch (error) { - console.error("Error removing from Keychain:", error); - } - }; +// removeStorageValue = async ( +// storageKey: K, +// ): Promise => { +// try { +// await this.Keychain.resetGenericPassword({ +// service: storageKey, +// }); +// } catch (error) { +// console.error("Error removing from Keychain:", error); +// } +// }; - storeSession = async (session: Session): Promise => { - return await this.setStorageValue(StorageKey.Session, session); - }; -} +// storeSession = async (session: Session): Promise => { +// return await this.setStorageValue(StorageKey.Session, session); +// }; +// } diff --git a/packages/sdk-js/src/__storage__/web/storage.ts b/packages/sdk-js/src/__storage__/web/storage.ts index 5662fba3f..ee3167846 100644 --- a/packages/sdk-js/src/__storage__/web/storage.ts +++ b/packages/sdk-js/src/__storage__/web/storage.ts @@ -1,33 +1,86 @@ import type { Session } from "@turnkey/sdk-types"; import WindowWrapper from "@polyfills/window"; - -import { StorageBase, StorageKey, StorageValue } from "../base"; +import { StorageBase, SessionKey } from "../base"; const browserStorage = WindowWrapper.localStorage; export class WebStorageManager implements StorageBase { - // TODO (Amir): try catch - getStorageValue = async ( - storageKey: K, - ): Promise => { - const storageItem = browserStorage.getItem(storageKey); - return storageItem ? JSON.parse(storageItem) : undefined; + private static SESSION_KEYS_KEY = "sessionKeys"; + private static ACTIVE_SESSION_KEY = "activeSessionKey"; + + getStorageValue = async (sessionKey: string): Promise => { + const item = browserStorage.getItem(sessionKey); + return item ? JSON.parse(item) : undefined; + }; + + setStorageValue = async ( + sessionKey: string, + storageValue: any + ): Promise => { + browserStorage.setItem(sessionKey, JSON.stringify(storageValue)); }; - setStorageValue = async ( - storageKey: K, - storageValue: StorageValue[K], - ): Promise => { - browserStorage.setItem(storageKey, JSON.stringify(storageValue)); + removeStorageValue = async (sessionKey: string): Promise => { + browserStorage.removeItem(sessionKey); }; - removeStorageValue = async ( - storageKey: K, + storeSession = async ( + session: Session, + sessionKey: string = SessionKey.DefaultSessionkey ): Promise => { - browserStorage.removeItem(storageKey); + await this.setStorageValue(sessionKey, session); + + // Ensure the session key is stored in the session keys list + const keys: string[] = + (await this.getStorageValue(WebStorageManager.SESSION_KEYS_KEY)) ?? []; + if (!keys.includes(sessionKey)) { + keys.push(sessionKey); + await this.setStorageValue(WebStorageManager.SESSION_KEYS_KEY, keys); + } + + // Set the active session key + await this.setStorageValue( + WebStorageManager.ACTIVE_SESSION_KEY, + sessionKey + ); + }; + + getSession = async ( + sessionKey: string = SessionKey.DefaultSessionkey + ): Promise => { + return this.getStorageValue(sessionKey); + }; + + getActiveSessionKey = async (): Promise => { + return this.getStorageValue(WebStorageManager.ACTIVE_SESSION_KEY); + }; + + getActiveSession = async (): Promise => { + const key = await this.getActiveSessionKey(); + return key ? this.getSession(key) : undefined; + }; + + listSessionKeys = async (): Promise => { + return ( + (await this.getStorageValue(WebStorageManager.SESSION_KEYS_KEY)) ?? [] + ); + }; + + clearSession = async (sessionKey: string): Promise => { + await this.removeStorageValue(sessionKey); + const keys = await this.listSessionKeys(); + const updated = keys.filter((k) => k !== sessionKey); + await this.setStorageValue(WebStorageManager.SESSION_KEYS_KEY, updated); + const active = await this.getActiveSessionKey(); + if (active === sessionKey) { + await this.removeStorageValue(WebStorageManager.ACTIVE_SESSION_KEY); + } }; - storeSession = async (session: Session): Promise => { - return await this.setStorageValue(StorageKey.Session, session); + clearAllSessions = async (): Promise => { + const keys = await this.listSessionKeys(); + await Promise.all(keys.map((k) => this.removeStorageValue(k))); + await this.removeStorageValue(WebStorageManager.SESSION_KEYS_KEY); + await this.removeStorageValue(WebStorageManager.ACTIVE_SESSION_KEY); }; } diff --git a/packages/sdk-js/src/__types__/base.ts b/packages/sdk-js/src/__types__/base.ts index 11f20721b..681fa5046 100644 --- a/packages/sdk-js/src/__types__/base.ts +++ b/packages/sdk-js/src/__types__/base.ts @@ -1,5 +1,5 @@ import type { TActivityId, TActivityStatus } from "@turnkey/http"; -import type { WalletInterface, WalletStamper } from "@turnkey/wallet-stamper"; +import type { WalletStamper } from "@turnkey/wallet-stamper"; import type { WebauthnStamper } from "@turnkey/webauthn-stamper"; import type { IndexedDbStamper } from "@turnkey/indexed-db-stamper"; import type { SessionType } from "@turnkey/sdk-types"; @@ -160,6 +160,7 @@ export interface LoginWithPasskeyParams { sessionType?: SessionType; expirationSeconds?: string | undefined; publicKey?: string; + sessionKey?: string | undefined; } export interface LoginWithWalletParams { diff --git a/packages/sdk-js/src/utils.ts b/packages/sdk-js/src/utils.ts index 5dfc507ab..f8468c363 100644 --- a/packages/sdk-js/src/utils.ts +++ b/packages/sdk-js/src/utils.ts @@ -1,6 +1,7 @@ import { Buffer } from "buffer"; import type { Session } from "@turnkey/sdk-types"; +import { jwtDecode } from "jwt-decode"; export const isReactNative = (): boolean => { return ( @@ -27,7 +28,7 @@ export const base64UrlEncode = (challenge: ArrayBuffer): string => { }; const hexByByte = Array.from({ length: 256 }, (_, i) => - i.toString(16).padStart(2, "0"), + i.toString(16).padStart(2, "0") ); export const bytesToHex = (bytes: Uint8Array): string => { @@ -69,3 +70,8 @@ export function parseSession(token: string | Session): Session { token: publicKey, }; } + +export function getPubKeyFromToken(token: string): string { + const { public_key } = jwtDecode(token) as any; + return public_key; +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 906119331..4756b4021 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2102,6 +2102,28 @@ importers: specifier: 5.3.0 version: 5.3.0(@babel/core@7.26.9)(@types/babel__core@7.20.5)(rollup@4.41.1) + packages/react-native-secure-storage-stamper: + dependencies: + '@turnkey/api-key-stamper': + specifier: workspace:* + version: link:../api-key-stamper + '@turnkey/encoding': + specifier: workspace:* + version: link:../encoding + react-native-keychain: + specifier: ^8.1.0 || ^9.2.2 || ^10.0.0 + version: 8.1.0 + devDependencies: + '@types/jest': + specifier: ^29.5.3 + version: 29.5.3 + jest: + specifier: ^29.7.0 + version: 29.7.0(@types/node@18.18.2) + ts-jest: + specifier: ^29.3.1 + version: 29.3.1(@babel/core@7.26.9)(@jest/types@29.4.3)(jest@29.7.0)(typescript@5.4.3) + packages/sdk-browser: dependencies: '@turnkey/api-key-stamper': @@ -2186,6 +2208,9 @@ importers: cross-fetch: specifier: ^3.1.5 version: 3.1.5 + jwt-decode: + specifier: 4.0.0 + version: 4.0.0 react-native-keychain: specifier: ^8.1.0 || ^9.2.2 || ^10.0.0 version: 8.1.0 From 62b038fe1a367b82b5dca7671f282f365722cc71 Mon Sep 17 00:00:00 2001 From: Amir Cheikh Date: Wed, 11 Jun 2025 13:30:10 -0400 Subject: [PATCH 005/184] Modified session storage. Added mobile storage manager --- packages/sdk-js/package.json | 6 +- packages/sdk-js/scripts/codegen.js | 41 +- packages/sdk-js/src/__clients__/core.ts | 72 +- .../src/__generated__/sdk-client-base.ts | 1581 +++++++++-------- packages/sdk-js/src/__stampers__/base.ts | 17 +- .../sdk-js/src/__stampers__/web/stamper.ts | 14 +- packages/sdk-js/src/__storage__/base.ts | 22 +- .../sdk-js/src/__storage__/mobile/storage.ts | 154 +- .../sdk-js/src/__storage__/web/storage.ts | 31 +- packages/sdk-js/src/__types__/base.ts | 4 +- packages/sdk-js/src/utils.ts | 10 +- pnpm-lock.yaml | 45 +- 12 files changed, 1051 insertions(+), 946 deletions(-) diff --git a/packages/sdk-js/package.json b/packages/sdk-js/package.json index 924748ccc..67039046c 100644 --- a/packages/sdk-js/package.json +++ b/packages/sdk-js/package.json @@ -39,11 +39,15 @@ "typescript": "5.4.3" }, "peerDependencies": { - "react-native-keychain": "^8.1.0 || ^9.2.2 || ^10.0.0" + "react-native-keychain": "^8.1.0 || ^9.2.2 || ^10.0.0", + "@react-native-async-storage/async-storage": "^2.2.0" }, "peerDependenciesMeta": { "react-native-keychain": { "optional": true + }, + "@react-native-async-storage/async-storage": { + "optional": true } }, "engines": { diff --git a/packages/sdk-js/scripts/codegen.js b/packages/sdk-js/scripts/codegen.js index a3327871a..a0bc9de2b 100644 --- a/packages/sdk-js/scripts/codegen.js +++ b/packages/sdk-js/scripts/codegen.js @@ -266,9 +266,7 @@ const generateSDKClientFromSwagger = async (swaggerSpec, targetPath) => { imports.push('import type * as SdkApiTypes from "./sdk_api_types";'); - imports.push( - 'import { StorageBase, StorageKey } from "../__storage__/base";', - ); + imports.push('import { StorageBase } from "../__storage__/base";'); imports.push('import { parseSession } from "../utils";'); imports.push('import { StamperType } from "../__types__/base";'); @@ -277,11 +275,8 @@ const generateSDKClientFromSwagger = async (swaggerSpec, targetPath) => { export class TurnkeySDKClientBase { config: TurnkeySDKClientConfig; - // Current active stamper - stamper?: TStamper | undefined; - // Store stampers - private indexedDBStamper?: TStamper | undefined; + private apiKeyStamper?: TStamper | undefined; private passkeyStamper?: TStamper | undefined; // Storage manager @@ -290,10 +285,8 @@ const generateSDKClientFromSwagger = async (swaggerSpec, targetPath) => { constructor(config: TurnkeySDKClientConfig) { this.config = config; - if (config.stamper) { - this.stamper = config.stamper; - // Store as default IndexedDB stamper - this.indexedDBStamper = config.stamper; + if (config.apiKeyStamper) { + this.apiKeyStamper = config.apiKeyStamper; } if (config.passkeyStamper) { this.passkeyStamper = config.passkeyStamper; @@ -304,15 +297,15 @@ const generateSDKClientFromSwagger = async (swaggerSpec, targetPath) => { } private getStamper(stampWith?: StamperType): TStamper | undefined { - if (!stampWith) return this.stamper; + if (!stampWith) return this.apiKeyStamper || this.passkeyStamper; switch (stampWith) { - case StamperType.IndexedDB: - return this.indexedDBStamper; + case StamperType.apiKey: + return this.apiKeyStamper; case StamperType.Passkey: return this.passkeyStamper; default: - return this.stamper; + return this.apiKeyStamper; } } @@ -462,7 +455,7 @@ const generateSDKClientFromSwagger = async (swaggerSpec, targetPath) => { ? " = {}" : "" }, stampWith?: StamperType): Promise => { - let session = await this.storageManager?.getStorageValue(StorageKey.Session); + let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request("${endpointPath}", { ...input, @@ -484,8 +477,8 @@ const generateSDKClientFromSwagger = async (swaggerSpec, targetPath) => { codeBuffer.push( `\n\t${methodName} = async (input: SdkApiTypes.${inputType}, stampWith?: StamperType): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue(StorageKey.Session); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command("${endpointPath}", { parameters: rest, @@ -500,8 +493,8 @@ const generateSDKClientFromSwagger = async (swaggerSpec, targetPath) => { codeBuffer.push( `\n\t${methodName} = async (input: SdkApiTypes.${inputType}, stampWith?: StamperType): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue(StorageKey.Session); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.activityDecision("${endpointPath}", { parameters: rest, @@ -516,13 +509,15 @@ const generateSDKClientFromSwagger = async (swaggerSpec, targetPath) => { } // generate a stamping method for each method codeBuffer.push( - `\n\tstamp${operationNameWithoutNamespace} = async (input: SdkApiTypes.${inputType}): Promise => { - if (!this.stamper) { + `\n\tstamp${operationNameWithoutNamespace} = async (input: SdkApiTypes.${inputType}, stampWith?: StamperType): Promise => { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "${endpointPath}"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, diff --git a/packages/sdk-js/src/__clients__/core.ts b/packages/sdk-js/src/__clients__/core.ts index 2af6d33c7..36b89d608 100644 --- a/packages/sdk-js/src/__clients__/core.ts +++ b/packages/sdk-js/src/__clients__/core.ts @@ -1,7 +1,7 @@ import { TurnkeySDKClientBase } from "../__generated__/sdk-client-base"; import { WebauthnStamper } from "@turnkey/webauthn-stamper"; import WindowWrapper from "@polyfills/window"; -import { SessionType, Session } from "@turnkey/sdk-types"; +import { SessionType } from "@turnkey/sdk-types"; import { LoginWithPasskeyParams, DEFAULT_SESSION_EXPIRATION_IN_SECONDS, @@ -11,7 +11,6 @@ import { import { base64UrlEncode, generateRandomBuffer, - getPubKeyFromToken, isReactNative, isWeb, } from "@utils"; @@ -43,7 +42,7 @@ export class TurnkeyClient { // Users can pass in their own stampers, or we will create them. Should we remove this? apiKeyStamper?: CrossPlatformApiKeyStamper, passkeyStamper?: WebauthnStamper, - mobilePasskeyStamper?: any // TODO: Add proper type + mobilePasskeyStamper?: any, // TODO: Add proper type ) { this.config = config; @@ -87,7 +86,7 @@ export class TurnkeyClient { // Initialize the HTTP client with the appropriate stampers this.httpClient = new TurnkeySDKClientBase({ - stamper: this.apiKeyStamper, + apiKeyStamper: this.apiKeyStamper, passkeyStamper: isWeb() ? this.passkeyStamper : this.mobilePasskeyStamper, storageManager: this.storageManager, ...this.config, @@ -100,7 +99,7 @@ export class TurnkeyClient { * @returns {Promise} */ createUserPasskey = async ( - config: Record = {} + config: Record = {}, ): Promise => { // TODO (Amir): Make this work for mobile as well const challenge = generateRandomBuffer(); @@ -166,32 +165,33 @@ export class TurnkeyClient { }; loginWithPasskey = async (params: LoginWithPasskeyParams): Promise => { + let generatedKeyPair = null; try { - const generatedPublicKey = await this.apiKeyStamper?.createKeyPair(); + generatedKeyPair = await this.apiKeyStamper?.createKeyPair(); const { sessionType = SessionType.READ_WRITE, - publicKey = generatedPublicKey, + publicKey = generatedKeyPair, expirationSeconds = DEFAULT_SESSION_EXPIRATION_IN_SECONDS, sessionKey = SessionKey.DefaultSessionkey, } = params; + // Create a read-only session if (sessionType === SessionType.READ_ONLY) { const readOnlySessionResult = await this.httpClient.createReadOnlySession({}, StamperType.Passkey); - const session: Session = { - sessionType: SessionType.READ_ONLY, - userId: readOnlySessionResult.userId, - organizationId: readOnlySessionResult.organizationId, - expiry: Number(readOnlySessionResult.sessionExpiry), - token: readOnlySessionResult.session, // Once we have api key session scopes this can change - }; - await this.storageManager.storeSession(session, sessionKey); + await this.storageManager.storeSession( + readOnlySessionResult.session, + sessionKey, + ); + // Key pair was successfully used, set to null to prevent cleanup + generatedKeyPair = null; + // Create a read-write session } else if (sessionType === SessionType.READ_WRITE) { if (!publicKey) { throw new Error( - "You must provide a publicKey to create a passkey read write session." + "You must provide a publicKey to create a passkey read write session.", ); } const sessionResponse = await this.httpClient.stampLogin( @@ -199,44 +199,38 @@ export class TurnkeyClient { publicKey, expirationSeconds, }, - StamperType.Passkey + StamperType.Passkey, ); // TODO (Amir): This should be done in a helper or something. It's very strange that we have to delete the key pair here const sessionToReplace = await this.storageManager.getSession(sessionKey); if (sessionToReplace) { - const pubkey = getPubKeyFromToken(sessionToReplace.token); - await this.apiKeyStamper?.deleteKeyPair(pubkey); + await this.apiKeyStamper?.deleteKeyPair(sessionToReplace.token); } await this.storageManager.storeSession( - { - /// THIS IS SO DUMB! - sessionType: SessionType.READ_WRITE, - expiry: Number(expirationSeconds), - token: sessionResponse.session, - } as any, - sessionKey + sessionResponse.session, + sessionKey, ); - - const whoamiResponse = await this.httpClient.getWhoami({}); - - const session: Session = { - // Note (Amir): Let's keep consistent with storing the actual session object rather than just the token - sessionType: SessionType.READ_ONLY, - userId: whoamiResponse.userId, - organizationId: whoamiResponse.organizationId, - expiry: Number(expirationSeconds), - token: sessionResponse.session, - }; - - await this.storageManager.storeSession(session, sessionKey); + // Key pair was successfully used, set to null to prevent cleanup + generatedKeyPair = null; } else { throw new Error(`Invalid session type passed: ${sessionType}`); } } catch (error) { throw new Error(`Unable to log in with the provided passkey: ${error}`); + } finally { + // Clean up the generated key pair if it wasn't successfully used + if (generatedKeyPair) { + try { + await this.apiKeyStamper?.deleteKeyPair(generatedKeyPair); + } catch (cleanupError) { + throw new Error( + `Failed to clean up generated key pair: ${cleanupError}`, + ); + } + } } }; } diff --git a/packages/sdk-js/src/__generated__/sdk-client-base.ts b/packages/sdk-js/src/__generated__/sdk-client-base.ts index 7f397d374..133589ae7 100644 --- a/packages/sdk-js/src/__generated__/sdk-client-base.ts +++ b/packages/sdk-js/src/__generated__/sdk-client-base.ts @@ -20,7 +20,7 @@ import { VERSION } from "../__generated__/version"; import type * as SdkApiTypes from "./sdk_api_types"; -import { StorageBase, SessionKey } from "../__storage__/base"; +import { StorageBase } from "../__storage__/base"; import { parseSession } from "../utils"; @@ -29,11 +29,8 @@ import { StamperType } from "../__types__/base"; export class TurnkeySDKClientBase { config: TurnkeySDKClientConfig; - // Current active stamper - stamper?: TStamper | undefined; - // Store stampers - private indexedDBStamper?: TStamper | undefined; + private apiKeyStamper?: TStamper | undefined; private passkeyStamper?: TStamper | undefined; // Storage manager @@ -42,10 +39,8 @@ export class TurnkeySDKClientBase { constructor(config: TurnkeySDKClientConfig) { this.config = config; - if (config.stamper) { - this.stamper = config.stamper; - // Store as default IndexedDB stamper - this.indexedDBStamper = config.stamper; + if (config.apiKeyStamper) { + this.apiKeyStamper = config.apiKeyStamper; } if (config.passkeyStamper) { this.passkeyStamper = config.passkeyStamper; @@ -56,22 +51,22 @@ export class TurnkeySDKClientBase { } private getStamper(stampWith?: StamperType): TStamper | undefined { - if (!stampWith) return this.stamper; + if (!stampWith) return this.apiKeyStamper || this.passkeyStamper; switch (stampWith) { - case StamperType.IndexedDB: - return this.indexedDBStamper; + case StamperType.apiKey: + return this.apiKeyStamper; case StamperType.Passkey: return this.passkeyStamper; default: - return this.stamper; + return this.apiKeyStamper; } } async request( url: string, body: TBodyType, - stampWith?: StamperType + stampWith?: StamperType, ): Promise { const fullUrl = this.config.apiBaseUrl + url; const stringifiedBody = JSON.stringify(body); @@ -117,7 +112,7 @@ export class TurnkeySDKClientBase { url: string, body: TBodyType, resultKey: string, - stampWith?: StamperType + stampWith?: StamperType, ): Promise { const pollingDuration = this.config.activityPoller?.intervalMs ?? 1000; const maxRetries = this.config.activityPoller?.numRetries ?? 3; @@ -145,7 +140,7 @@ export class TurnkeySDKClientBase { // Pass the stampWith parameter to getActivity const pollData = (await this.getActivity( pollBody, - stampWith + stampWith, )) as TActivityResponse; if (attempts > maxRetries) { @@ -156,7 +151,7 @@ export class TurnkeySDKClientBase { if ( !TERMINAL_ACTIVITY_STATUSES.includes( - pollData.activity.status as TActivityStatus + pollData.activity.status as TActivityStatus, ) ) { await sleep(pollingDuration); @@ -170,12 +165,12 @@ export class TurnkeySDKClientBase { const responseData = (await this.request( url, body, - stampWith + stampWith, )) as TActivityResponse; if ( !TERMINAL_ACTIVITY_STATUSES.includes( - responseData.activity.status as TActivityStatus + responseData.activity.status as TActivityStatus, ) ) { return pollStatus(responseData.activity.id); @@ -187,13 +182,13 @@ export class TurnkeySDKClientBase { async activityDecision( url: string, body: TBodyType, - stampWith?: StamperType + stampWith?: StamperType, ): Promise { // Use the specified stamper for this request const activityData = (await this.request( url, body, - stampWith + stampWith, )) as TActivityResponse; return { @@ -204,11 +199,9 @@ export class TurnkeySDKClientBase { getActivity = async ( input: SdkApiTypes.TGetActivityBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); + let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( "/public/v1/query/get_activity", @@ -219,19 +212,22 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith + stampWith, ); }; stampGetActivity = async ( - input: SdkApiTypes.TGetActivityBody + input: SdkApiTypes.TGetActivityBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/query/get_activity"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -241,11 +237,9 @@ export class TurnkeySDKClientBase { getApiKey = async ( input: SdkApiTypes.TGetApiKeyBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); + let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( "/public/v1/query/get_api_key", @@ -256,19 +250,22 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith + stampWith, ); }; stampGetApiKey = async ( - input: SdkApiTypes.TGetApiKeyBody + input: SdkApiTypes.TGetApiKeyBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/query/get_api_key"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -278,11 +275,9 @@ export class TurnkeySDKClientBase { getApiKeys = async ( input: SdkApiTypes.TGetApiKeysBody = {}, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); + let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( "/public/v1/query/get_api_keys", @@ -293,19 +288,22 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith + stampWith, ); }; stampGetApiKeys = async ( - input: SdkApiTypes.TGetApiKeysBody + input: SdkApiTypes.TGetApiKeysBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/query/get_api_keys"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -315,11 +313,9 @@ export class TurnkeySDKClientBase { getAttestationDocument = async ( input: SdkApiTypes.TGetAttestationDocumentBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); + let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( "/public/v1/query/get_attestation", @@ -330,19 +326,22 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith + stampWith, ); }; stampGetAttestationDocument = async ( - input: SdkApiTypes.TGetAttestationDocumentBody + input: SdkApiTypes.TGetAttestationDocumentBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/query/get_attestation"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -352,11 +351,9 @@ export class TurnkeySDKClientBase { getAuthenticator = async ( input: SdkApiTypes.TGetAuthenticatorBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); + let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( "/public/v1/query/get_authenticator", @@ -367,20 +364,23 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith + stampWith, ); }; stampGetAuthenticator = async ( - input: SdkApiTypes.TGetAuthenticatorBody + input: SdkApiTypes.TGetAuthenticatorBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/query/get_authenticator"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -390,11 +390,9 @@ export class TurnkeySDKClientBase { getAuthenticators = async ( input: SdkApiTypes.TGetAuthenticatorsBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); + let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( "/public/v1/query/get_authenticators", @@ -405,20 +403,23 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith + stampWith, ); }; stampGetAuthenticators = async ( - input: SdkApiTypes.TGetAuthenticatorsBody + input: SdkApiTypes.TGetAuthenticatorsBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/query/get_authenticators"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -428,11 +429,9 @@ export class TurnkeySDKClientBase { getOauthProviders = async ( input: SdkApiTypes.TGetOauthProvidersBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); + let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( "/public/v1/query/get_oauth_providers", @@ -443,20 +442,23 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith + stampWith, ); }; stampGetOauthProviders = async ( - input: SdkApiTypes.TGetOauthProvidersBody + input: SdkApiTypes.TGetOauthProvidersBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/query/get_oauth_providers"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -466,11 +468,9 @@ export class TurnkeySDKClientBase { getOrganization = async ( input: SdkApiTypes.TGetOrganizationBody = {}, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); + let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( "/public/v1/query/get_organization", @@ -481,20 +481,23 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith + stampWith, ); }; stampGetOrganization = async ( - input: SdkApiTypes.TGetOrganizationBody + input: SdkApiTypes.TGetOrganizationBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/query/get_organization"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -504,11 +507,9 @@ export class TurnkeySDKClientBase { getOrganizationConfigs = async ( input: SdkApiTypes.TGetOrganizationConfigsBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); + let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( "/public/v1/query/get_organization_configs", @@ -519,20 +520,23 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith + stampWith, ); }; stampGetOrganizationConfigs = async ( - input: SdkApiTypes.TGetOrganizationConfigsBody + input: SdkApiTypes.TGetOrganizationConfigsBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/query/get_organization_configs"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -542,11 +546,9 @@ export class TurnkeySDKClientBase { getPolicy = async ( input: SdkApiTypes.TGetPolicyBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); + let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( "/public/v1/query/get_policy", @@ -557,19 +559,22 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith + stampWith, ); }; stampGetPolicy = async ( - input: SdkApiTypes.TGetPolicyBody + input: SdkApiTypes.TGetPolicyBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/query/get_policy"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -579,11 +584,9 @@ export class TurnkeySDKClientBase { getPrivateKey = async ( input: SdkApiTypes.TGetPrivateKeyBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); + let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( "/public/v1/query/get_private_key", @@ -594,19 +597,22 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith + stampWith, ); }; stampGetPrivateKey = async ( - input: SdkApiTypes.TGetPrivateKeyBody + input: SdkApiTypes.TGetPrivateKeyBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/query/get_private_key"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -616,11 +622,9 @@ export class TurnkeySDKClientBase { getUser = async ( input: SdkApiTypes.TGetUserBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); + let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( "/public/v1/query/get_user", @@ -631,19 +635,22 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith + stampWith, ); }; stampGetUser = async ( - input: SdkApiTypes.TGetUserBody + input: SdkApiTypes.TGetUserBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/query/get_user"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -653,11 +660,9 @@ export class TurnkeySDKClientBase { getWallet = async ( input: SdkApiTypes.TGetWalletBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); + let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( "/public/v1/query/get_wallet", @@ -668,19 +673,22 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith + stampWith, ); }; stampGetWallet = async ( - input: SdkApiTypes.TGetWalletBody + input: SdkApiTypes.TGetWalletBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/query/get_wallet"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -690,11 +698,9 @@ export class TurnkeySDKClientBase { getWalletAccount = async ( input: SdkApiTypes.TGetWalletAccountBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); + let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( "/public/v1/query/get_wallet_account", @@ -705,20 +711,23 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith + stampWith, ); }; stampGetWalletAccount = async ( - input: SdkApiTypes.TGetWalletAccountBody + input: SdkApiTypes.TGetWalletAccountBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/query/get_wallet_account"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -728,11 +737,9 @@ export class TurnkeySDKClientBase { getActivities = async ( input: SdkApiTypes.TGetActivitiesBody = {}, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); + let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( "/public/v1/query/list_activities", @@ -743,19 +750,22 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith + stampWith, ); }; stampGetActivities = async ( - input: SdkApiTypes.TGetActivitiesBody + input: SdkApiTypes.TGetActivitiesBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/query/list_activities"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -765,11 +775,9 @@ export class TurnkeySDKClientBase { getPolicies = async ( input: SdkApiTypes.TGetPoliciesBody = {}, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); + let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( "/public/v1/query/list_policies", @@ -780,19 +788,22 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith + stampWith, ); }; stampGetPolicies = async ( - input: SdkApiTypes.TGetPoliciesBody + input: SdkApiTypes.TGetPoliciesBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/query/list_policies"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -802,11 +813,9 @@ export class TurnkeySDKClientBase { listPrivateKeyTags = async ( input: SdkApiTypes.TListPrivateKeyTagsBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); + let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( "/public/v1/query/list_private_key_tags", @@ -817,20 +826,23 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith + stampWith, ); }; stampListPrivateKeyTags = async ( - input: SdkApiTypes.TListPrivateKeyTagsBody + input: SdkApiTypes.TListPrivateKeyTagsBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/query/list_private_key_tags"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -840,11 +852,9 @@ export class TurnkeySDKClientBase { getPrivateKeys = async ( input: SdkApiTypes.TGetPrivateKeysBody = {}, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); + let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( "/public/v1/query/list_private_keys", @@ -855,20 +865,23 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith + stampWith, ); }; stampGetPrivateKeys = async ( - input: SdkApiTypes.TGetPrivateKeysBody + input: SdkApiTypes.TGetPrivateKeysBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/query/list_private_keys"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -878,11 +891,9 @@ export class TurnkeySDKClientBase { getSubOrgIds = async ( input: SdkApiTypes.TGetSubOrgIdsBody = {}, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); + let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( "/public/v1/query/list_suborgs", @@ -893,19 +904,22 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith + stampWith, ); }; stampGetSubOrgIds = async ( - input: SdkApiTypes.TGetSubOrgIdsBody + input: SdkApiTypes.TGetSubOrgIdsBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/query/list_suborgs"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -915,11 +929,9 @@ export class TurnkeySDKClientBase { listUserTags = async ( input: SdkApiTypes.TListUserTagsBody = {}, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); + let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( "/public/v1/query/list_user_tags", @@ -930,19 +942,22 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith + stampWith, ); }; stampListUserTags = async ( - input: SdkApiTypes.TListUserTagsBody + input: SdkApiTypes.TListUserTagsBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/query/list_user_tags"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -952,11 +967,9 @@ export class TurnkeySDKClientBase { getUsers = async ( input: SdkApiTypes.TGetUsersBody = {}, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); + let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( "/public/v1/query/list_users", @@ -967,19 +980,22 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith + stampWith, ); }; stampGetUsers = async ( - input: SdkApiTypes.TGetUsersBody + input: SdkApiTypes.TGetUsersBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/query/list_users"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -989,11 +1005,9 @@ export class TurnkeySDKClientBase { getVerifiedSubOrgIds = async ( input: SdkApiTypes.TGetVerifiedSubOrgIdsBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); + let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( "/public/v1/query/list_verified_suborgs", @@ -1004,20 +1018,23 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith + stampWith, ); }; stampGetVerifiedSubOrgIds = async ( - input: SdkApiTypes.TGetVerifiedSubOrgIdsBody + input: SdkApiTypes.TGetVerifiedSubOrgIdsBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/query/list_verified_suborgs"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -1027,11 +1044,9 @@ export class TurnkeySDKClientBase { getWalletAccounts = async ( input: SdkApiTypes.TGetWalletAccountsBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); + let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( "/public/v1/query/list_wallet_accounts", @@ -1042,20 +1057,23 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith + stampWith, ); }; stampGetWalletAccounts = async ( - input: SdkApiTypes.TGetWalletAccountsBody + input: SdkApiTypes.TGetWalletAccountsBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/query/list_wallet_accounts"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -1065,11 +1083,9 @@ export class TurnkeySDKClientBase { getWallets = async ( input: SdkApiTypes.TGetWalletsBody = {}, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); + let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( "/public/v1/query/list_wallets", @@ -1080,19 +1096,22 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith + stampWith, ); }; stampGetWallets = async ( - input: SdkApiTypes.TGetWalletsBody + input: SdkApiTypes.TGetWalletsBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/query/list_wallets"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -1102,11 +1121,9 @@ export class TurnkeySDKClientBase { getWhoami = async ( input: SdkApiTypes.TGetWhoamiBody = {}, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); + let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( "/public/v1/query/whoami", @@ -1117,19 +1134,22 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith + stampWith, ); }; stampGetWhoami = async ( - input: SdkApiTypes.TGetWhoamiBody + input: SdkApiTypes.TGetWhoamiBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/query/whoami"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -1139,13 +1159,11 @@ export class TurnkeySDKClientBase { approveActivity = async ( input: SdkApiTypes.TApproveActivityBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.activityDecision( "/public/v1/submit/approve_activity", { @@ -1157,20 +1175,23 @@ export class TurnkeySDKClientBase { timestampMs: timestampMs ?? String(Date.now()), type: "ACTIVITY_TYPE_APPROVE_ACTIVITY", }, - stampWith + stampWith, ); }; stampApproveActivity = async ( - input: SdkApiTypes.TApproveActivityBody + input: SdkApiTypes.TApproveActivityBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/approve_activity"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -1180,13 +1201,11 @@ export class TurnkeySDKClientBase { createApiKeys = async ( input: SdkApiTypes.TCreateApiKeysBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/create_api_keys", @@ -1200,20 +1219,23 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_CREATE_API_KEYS_V2", }, "createApiKeysResult", - stampWith + stampWith, ); }; stampCreateApiKeys = async ( - input: SdkApiTypes.TCreateApiKeysBody + input: SdkApiTypes.TCreateApiKeysBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/create_api_keys"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -1223,13 +1245,11 @@ export class TurnkeySDKClientBase { createApiOnlyUsers = async ( input: SdkApiTypes.TCreateApiOnlyUsersBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/create_api_only_users", @@ -1243,20 +1263,23 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_CREATE_API_ONLY_USERS", }, "createApiOnlyUsersResult", - stampWith + stampWith, ); }; stampCreateApiOnlyUsers = async ( - input: SdkApiTypes.TCreateApiOnlyUsersBody + input: SdkApiTypes.TCreateApiOnlyUsersBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/create_api_only_users"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -1266,13 +1289,11 @@ export class TurnkeySDKClientBase { createAuthenticators = async ( input: SdkApiTypes.TCreateAuthenticatorsBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/create_authenticators", @@ -1286,20 +1307,23 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_CREATE_AUTHENTICATORS_V2", }, "createAuthenticatorsResult", - stampWith + stampWith, ); }; stampCreateAuthenticators = async ( - input: SdkApiTypes.TCreateAuthenticatorsBody + input: SdkApiTypes.TCreateAuthenticatorsBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/create_authenticators"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -1309,13 +1333,11 @@ export class TurnkeySDKClientBase { createInvitations = async ( input: SdkApiTypes.TCreateInvitationsBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/create_invitations", @@ -1329,20 +1351,23 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_CREATE_INVITATIONS", }, "createInvitationsResult", - stampWith + stampWith, ); }; stampCreateInvitations = async ( - input: SdkApiTypes.TCreateInvitationsBody + input: SdkApiTypes.TCreateInvitationsBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/create_invitations"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -1352,13 +1377,11 @@ export class TurnkeySDKClientBase { createOauthProviders = async ( input: SdkApiTypes.TCreateOauthProvidersBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/create_oauth_providers", @@ -1372,20 +1395,23 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_CREATE_OAUTH_PROVIDERS", }, "createOauthProvidersResult", - stampWith + stampWith, ); }; stampCreateOauthProviders = async ( - input: SdkApiTypes.TCreateOauthProvidersBody + input: SdkApiTypes.TCreateOauthProvidersBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/create_oauth_providers"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -1395,13 +1421,11 @@ export class TurnkeySDKClientBase { createPolicies = async ( input: SdkApiTypes.TCreatePoliciesBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/create_policies", @@ -1415,20 +1439,23 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_CREATE_POLICIES", }, "createPoliciesResult", - stampWith + stampWith, ); }; stampCreatePolicies = async ( - input: SdkApiTypes.TCreatePoliciesBody + input: SdkApiTypes.TCreatePoliciesBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/create_policies"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -1438,13 +1465,11 @@ export class TurnkeySDKClientBase { createPolicy = async ( input: SdkApiTypes.TCreatePolicyBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/create_policy", @@ -1458,19 +1483,22 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_CREATE_POLICY_V3", }, "createPolicyResult", - stampWith + stampWith, ); }; stampCreatePolicy = async ( - input: SdkApiTypes.TCreatePolicyBody + input: SdkApiTypes.TCreatePolicyBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/create_policy"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -1480,13 +1508,11 @@ export class TurnkeySDKClientBase { createPrivateKeyTag = async ( input: SdkApiTypes.TCreatePrivateKeyTagBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/create_private_key_tag", @@ -1500,20 +1526,23 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_CREATE_PRIVATE_KEY_TAG", }, "createPrivateKeyTagResult", - stampWith + stampWith, ); }; stampCreatePrivateKeyTag = async ( - input: SdkApiTypes.TCreatePrivateKeyTagBody + input: SdkApiTypes.TCreatePrivateKeyTagBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/create_private_key_tag"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -1523,13 +1552,11 @@ export class TurnkeySDKClientBase { createPrivateKeys = async ( input: SdkApiTypes.TCreatePrivateKeysBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/create_private_keys", @@ -1543,20 +1570,23 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_CREATE_PRIVATE_KEYS_V2", }, "createPrivateKeysResultV2", - stampWith + stampWith, ); }; stampCreatePrivateKeys = async ( - input: SdkApiTypes.TCreatePrivateKeysBody + input: SdkApiTypes.TCreatePrivateKeysBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/create_private_keys"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -1566,13 +1596,11 @@ export class TurnkeySDKClientBase { createReadOnlySession = async ( input: SdkApiTypes.TCreateReadOnlySessionBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/create_read_only_session", @@ -1586,20 +1614,23 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_CREATE_READ_ONLY_SESSION", }, "createReadOnlySessionResult", - stampWith + stampWith, ); }; stampCreateReadOnlySession = async ( - input: SdkApiTypes.TCreateReadOnlySessionBody + input: SdkApiTypes.TCreateReadOnlySessionBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/create_read_only_session"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -1609,13 +1640,11 @@ export class TurnkeySDKClientBase { createReadWriteSession = async ( input: SdkApiTypes.TCreateReadWriteSessionBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/create_read_write_session", @@ -1629,20 +1658,23 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_CREATE_READ_WRITE_SESSION_V2", }, "createReadWriteSessionResultV2", - stampWith + stampWith, ); }; stampCreateReadWriteSession = async ( - input: SdkApiTypes.TCreateReadWriteSessionBody + input: SdkApiTypes.TCreateReadWriteSessionBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/create_read_write_session"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -1652,13 +1684,11 @@ export class TurnkeySDKClientBase { createSubOrganization = async ( input: SdkApiTypes.TCreateSubOrganizationBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/create_sub_organization", @@ -1672,20 +1702,23 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_CREATE_SUB_ORGANIZATION_V7", }, "createSubOrganizationResultV7", - stampWith + stampWith, ); }; stampCreateSubOrganization = async ( - input: SdkApiTypes.TCreateSubOrganizationBody + input: SdkApiTypes.TCreateSubOrganizationBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/create_sub_organization"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -1695,13 +1728,11 @@ export class TurnkeySDKClientBase { createUserTag = async ( input: SdkApiTypes.TCreateUserTagBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/create_user_tag", @@ -1715,20 +1746,23 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_CREATE_USER_TAG", }, "createUserTagResult", - stampWith + stampWith, ); }; stampCreateUserTag = async ( - input: SdkApiTypes.TCreateUserTagBody + input: SdkApiTypes.TCreateUserTagBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/create_user_tag"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -1738,13 +1772,11 @@ export class TurnkeySDKClientBase { createUsers = async ( input: SdkApiTypes.TCreateUsersBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/create_users", @@ -1758,19 +1790,22 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_CREATE_USERS_V3", }, "createUsersResult", - stampWith + stampWith, ); }; stampCreateUsers = async ( - input: SdkApiTypes.TCreateUsersBody + input: SdkApiTypes.TCreateUsersBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/create_users"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -1780,13 +1815,11 @@ export class TurnkeySDKClientBase { createWallet = async ( input: SdkApiTypes.TCreateWalletBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/create_wallet", @@ -1800,19 +1833,22 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_CREATE_WALLET", }, "createWalletResult", - stampWith + stampWith, ); }; stampCreateWallet = async ( - input: SdkApiTypes.TCreateWalletBody + input: SdkApiTypes.TCreateWalletBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/create_wallet"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -1822,13 +1858,11 @@ export class TurnkeySDKClientBase { createWalletAccounts = async ( input: SdkApiTypes.TCreateWalletAccountsBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/create_wallet_accounts", @@ -1842,20 +1876,23 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_CREATE_WALLET_ACCOUNTS", }, "createWalletAccountsResult", - stampWith + stampWith, ); }; stampCreateWalletAccounts = async ( - input: SdkApiTypes.TCreateWalletAccountsBody + input: SdkApiTypes.TCreateWalletAccountsBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/create_wallet_accounts"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -1865,13 +1902,11 @@ export class TurnkeySDKClientBase { deleteApiKeys = async ( input: SdkApiTypes.TDeleteApiKeysBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/delete_api_keys", @@ -1885,20 +1920,23 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_DELETE_API_KEYS", }, "deleteApiKeysResult", - stampWith + stampWith, ); }; stampDeleteApiKeys = async ( - input: SdkApiTypes.TDeleteApiKeysBody + input: SdkApiTypes.TDeleteApiKeysBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/delete_api_keys"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -1908,13 +1946,11 @@ export class TurnkeySDKClientBase { deleteAuthenticators = async ( input: SdkApiTypes.TDeleteAuthenticatorsBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/delete_authenticators", @@ -1928,20 +1964,23 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_DELETE_AUTHENTICATORS", }, "deleteAuthenticatorsResult", - stampWith + stampWith, ); }; stampDeleteAuthenticators = async ( - input: SdkApiTypes.TDeleteAuthenticatorsBody + input: SdkApiTypes.TDeleteAuthenticatorsBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/delete_authenticators"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -1951,13 +1990,11 @@ export class TurnkeySDKClientBase { deleteInvitation = async ( input: SdkApiTypes.TDeleteInvitationBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/delete_invitation", @@ -1971,20 +2008,23 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_DELETE_INVITATION", }, "deleteInvitationResult", - stampWith + stampWith, ); }; stampDeleteInvitation = async ( - input: SdkApiTypes.TDeleteInvitationBody + input: SdkApiTypes.TDeleteInvitationBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/delete_invitation"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -1994,13 +2034,11 @@ export class TurnkeySDKClientBase { deleteOauthProviders = async ( input: SdkApiTypes.TDeleteOauthProvidersBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/delete_oauth_providers", @@ -2014,20 +2052,23 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_DELETE_OAUTH_PROVIDERS", }, "deleteOauthProvidersResult", - stampWith + stampWith, ); }; stampDeleteOauthProviders = async ( - input: SdkApiTypes.TDeleteOauthProvidersBody + input: SdkApiTypes.TDeleteOauthProvidersBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/delete_oauth_providers"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -2037,13 +2078,11 @@ export class TurnkeySDKClientBase { deletePolicy = async ( input: SdkApiTypes.TDeletePolicyBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/delete_policy", @@ -2057,19 +2096,22 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_DELETE_POLICY", }, "deletePolicyResult", - stampWith + stampWith, ); }; stampDeletePolicy = async ( - input: SdkApiTypes.TDeletePolicyBody + input: SdkApiTypes.TDeletePolicyBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/delete_policy"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -2079,13 +2121,11 @@ export class TurnkeySDKClientBase { deletePrivateKeyTags = async ( input: SdkApiTypes.TDeletePrivateKeyTagsBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/delete_private_key_tags", @@ -2099,20 +2139,23 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_DELETE_PRIVATE_KEY_TAGS", }, "deletePrivateKeyTagsResult", - stampWith + stampWith, ); }; stampDeletePrivateKeyTags = async ( - input: SdkApiTypes.TDeletePrivateKeyTagsBody + input: SdkApiTypes.TDeletePrivateKeyTagsBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/delete_private_key_tags"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -2122,13 +2165,11 @@ export class TurnkeySDKClientBase { deletePrivateKeys = async ( input: SdkApiTypes.TDeletePrivateKeysBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/delete_private_keys", @@ -2142,20 +2183,23 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_DELETE_PRIVATE_KEYS", }, "deletePrivateKeysResult", - stampWith + stampWith, ); }; stampDeletePrivateKeys = async ( - input: SdkApiTypes.TDeletePrivateKeysBody + input: SdkApiTypes.TDeletePrivateKeysBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/delete_private_keys"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -2165,13 +2209,11 @@ export class TurnkeySDKClientBase { deleteSubOrganization = async ( input: SdkApiTypes.TDeleteSubOrganizationBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/delete_sub_organization", @@ -2185,20 +2227,23 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_DELETE_SUB_ORGANIZATION", }, "deleteSubOrganizationResult", - stampWith + stampWith, ); }; stampDeleteSubOrganization = async ( - input: SdkApiTypes.TDeleteSubOrganizationBody + input: SdkApiTypes.TDeleteSubOrganizationBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/delete_sub_organization"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -2208,13 +2253,11 @@ export class TurnkeySDKClientBase { deleteUserTags = async ( input: SdkApiTypes.TDeleteUserTagsBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/delete_user_tags", @@ -2228,20 +2271,23 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_DELETE_USER_TAGS", }, "deleteUserTagsResult", - stampWith + stampWith, ); }; stampDeleteUserTags = async ( - input: SdkApiTypes.TDeleteUserTagsBody + input: SdkApiTypes.TDeleteUserTagsBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/delete_user_tags"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -2251,13 +2297,11 @@ export class TurnkeySDKClientBase { deleteUsers = async ( input: SdkApiTypes.TDeleteUsersBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/delete_users", @@ -2271,19 +2315,22 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_DELETE_USERS", }, "deleteUsersResult", - stampWith + stampWith, ); }; stampDeleteUsers = async ( - input: SdkApiTypes.TDeleteUsersBody + input: SdkApiTypes.TDeleteUsersBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/delete_users"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -2293,13 +2340,11 @@ export class TurnkeySDKClientBase { deleteWallets = async ( input: SdkApiTypes.TDeleteWalletsBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/delete_wallets", @@ -2313,19 +2358,22 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_DELETE_WALLETS", }, "deleteWalletsResult", - stampWith + stampWith, ); }; stampDeleteWallets = async ( - input: SdkApiTypes.TDeleteWalletsBody + input: SdkApiTypes.TDeleteWalletsBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/delete_wallets"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -2335,13 +2383,11 @@ export class TurnkeySDKClientBase { emailAuth = async ( input: SdkApiTypes.TEmailAuthBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/email_auth", @@ -2355,19 +2401,22 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_EMAIL_AUTH_V2", }, "emailAuthResult", - stampWith + stampWith, ); }; stampEmailAuth = async ( - input: SdkApiTypes.TEmailAuthBody + input: SdkApiTypes.TEmailAuthBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/email_auth"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -2377,13 +2426,11 @@ export class TurnkeySDKClientBase { exportPrivateKey = async ( input: SdkApiTypes.TExportPrivateKeyBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/export_private_key", @@ -2397,20 +2444,23 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_EXPORT_PRIVATE_KEY", }, "exportPrivateKeyResult", - stampWith + stampWith, ); }; stampExportPrivateKey = async ( - input: SdkApiTypes.TExportPrivateKeyBody + input: SdkApiTypes.TExportPrivateKeyBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/export_private_key"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -2420,13 +2470,11 @@ export class TurnkeySDKClientBase { exportWallet = async ( input: SdkApiTypes.TExportWalletBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/export_wallet", @@ -2440,19 +2488,22 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_EXPORT_WALLET", }, "exportWalletResult", - stampWith + stampWith, ); }; stampExportWallet = async ( - input: SdkApiTypes.TExportWalletBody + input: SdkApiTypes.TExportWalletBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/export_wallet"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -2462,13 +2513,11 @@ export class TurnkeySDKClientBase { exportWalletAccount = async ( input: SdkApiTypes.TExportWalletAccountBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/export_wallet_account", @@ -2482,20 +2531,23 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_EXPORT_WALLET_ACCOUNT", }, "exportWalletAccountResult", - stampWith + stampWith, ); }; stampExportWalletAccount = async ( - input: SdkApiTypes.TExportWalletAccountBody + input: SdkApiTypes.TExportWalletAccountBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/export_wallet_account"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -2505,13 +2557,11 @@ export class TurnkeySDKClientBase { importPrivateKey = async ( input: SdkApiTypes.TImportPrivateKeyBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/import_private_key", @@ -2525,20 +2575,23 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_IMPORT_PRIVATE_KEY", }, "importPrivateKeyResult", - stampWith + stampWith, ); }; stampImportPrivateKey = async ( - input: SdkApiTypes.TImportPrivateKeyBody + input: SdkApiTypes.TImportPrivateKeyBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/import_private_key"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -2548,13 +2601,11 @@ export class TurnkeySDKClientBase { importWallet = async ( input: SdkApiTypes.TImportWalletBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/import_wallet", @@ -2568,19 +2619,22 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_IMPORT_WALLET", }, "importWalletResult", - stampWith + stampWith, ); }; stampImportWallet = async ( - input: SdkApiTypes.TImportWalletBody + input: SdkApiTypes.TImportWalletBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/import_wallet"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -2590,13 +2644,11 @@ export class TurnkeySDKClientBase { initImportPrivateKey = async ( input: SdkApiTypes.TInitImportPrivateKeyBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/init_import_private_key", @@ -2610,20 +2662,23 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_INIT_IMPORT_PRIVATE_KEY", }, "initImportPrivateKeyResult", - stampWith + stampWith, ); }; stampInitImportPrivateKey = async ( - input: SdkApiTypes.TInitImportPrivateKeyBody + input: SdkApiTypes.TInitImportPrivateKeyBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/init_import_private_key"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -2633,13 +2688,11 @@ export class TurnkeySDKClientBase { initImportWallet = async ( input: SdkApiTypes.TInitImportWalletBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/init_import_wallet", @@ -2653,20 +2706,23 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_INIT_IMPORT_WALLET", }, "initImportWalletResult", - stampWith + stampWith, ); }; stampInitImportWallet = async ( - input: SdkApiTypes.TInitImportWalletBody + input: SdkApiTypes.TInitImportWalletBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/init_import_wallet"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -2676,13 +2732,11 @@ export class TurnkeySDKClientBase { initOtp = async ( input: SdkApiTypes.TInitOtpBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/init_otp", @@ -2696,19 +2750,22 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_INIT_OTP", }, "initOtpResult", - stampWith + stampWith, ); }; stampInitOtp = async ( - input: SdkApiTypes.TInitOtpBody + input: SdkApiTypes.TInitOtpBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/init_otp"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -2718,13 +2775,11 @@ export class TurnkeySDKClientBase { initOtpAuth = async ( input: SdkApiTypes.TInitOtpAuthBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/init_otp_auth", @@ -2738,19 +2793,22 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_INIT_OTP_AUTH_V2", }, "initOtpAuthResultV2", - stampWith + stampWith, ); }; stampInitOtpAuth = async ( - input: SdkApiTypes.TInitOtpAuthBody + input: SdkApiTypes.TInitOtpAuthBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/init_otp_auth"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -2760,13 +2818,11 @@ export class TurnkeySDKClientBase { initUserEmailRecovery = async ( input: SdkApiTypes.TInitUserEmailRecoveryBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/init_user_email_recovery", @@ -2780,20 +2836,23 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_INIT_USER_EMAIL_RECOVERY", }, "initUserEmailRecoveryResult", - stampWith + stampWith, ); }; stampInitUserEmailRecovery = async ( - input: SdkApiTypes.TInitUserEmailRecoveryBody + input: SdkApiTypes.TInitUserEmailRecoveryBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/init_user_email_recovery"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -2803,13 +2862,11 @@ export class TurnkeySDKClientBase { oauth = async ( input: SdkApiTypes.TOauthBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/oauth", @@ -2823,19 +2880,22 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_OAUTH", }, "oauthResult", - stampWith + stampWith, ); }; stampOauth = async ( - input: SdkApiTypes.TOauthBody + input: SdkApiTypes.TOauthBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/oauth"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -2845,13 +2905,11 @@ export class TurnkeySDKClientBase { oauthLogin = async ( input: SdkApiTypes.TOauthLoginBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/oauth_login", @@ -2865,19 +2923,22 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_OAUTH_LOGIN", }, "oauthLoginResult", - stampWith + stampWith, ); }; stampOauthLogin = async ( - input: SdkApiTypes.TOauthLoginBody + input: SdkApiTypes.TOauthLoginBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/oauth_login"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -2887,13 +2948,11 @@ export class TurnkeySDKClientBase { otpAuth = async ( input: SdkApiTypes.TOtpAuthBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/otp_auth", @@ -2907,19 +2966,22 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_OTP_AUTH", }, "otpAuthResult", - stampWith + stampWith, ); }; stampOtpAuth = async ( - input: SdkApiTypes.TOtpAuthBody + input: SdkApiTypes.TOtpAuthBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/otp_auth"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -2929,13 +2991,11 @@ export class TurnkeySDKClientBase { otpLogin = async ( input: SdkApiTypes.TOtpLoginBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/otp_login", @@ -2949,19 +3009,22 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_OTP_LOGIN", }, "otpLoginResult", - stampWith + stampWith, ); }; stampOtpLogin = async ( - input: SdkApiTypes.TOtpLoginBody + input: SdkApiTypes.TOtpLoginBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/otp_login"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -2971,13 +3034,11 @@ export class TurnkeySDKClientBase { recoverUser = async ( input: SdkApiTypes.TRecoverUserBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/recover_user", @@ -2991,19 +3052,22 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_RECOVER_USER", }, "recoverUserResult", - stampWith + stampWith, ); }; stampRecoverUser = async ( - input: SdkApiTypes.TRecoverUserBody + input: SdkApiTypes.TRecoverUserBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/recover_user"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -3013,13 +3077,11 @@ export class TurnkeySDKClientBase { rejectActivity = async ( input: SdkApiTypes.TRejectActivityBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.activityDecision( "/public/v1/submit/reject_activity", { @@ -3031,20 +3093,23 @@ export class TurnkeySDKClientBase { timestampMs: timestampMs ?? String(Date.now()), type: "ACTIVITY_TYPE_REJECT_ACTIVITY", }, - stampWith + stampWith, ); }; stampRejectActivity = async ( - input: SdkApiTypes.TRejectActivityBody + input: SdkApiTypes.TRejectActivityBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/reject_activity"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -3054,13 +3119,11 @@ export class TurnkeySDKClientBase { removeOrganizationFeature = async ( input: SdkApiTypes.TRemoveOrganizationFeatureBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/remove_organization_feature", @@ -3074,20 +3137,23 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_REMOVE_ORGANIZATION_FEATURE", }, "removeOrganizationFeatureResult", - stampWith + stampWith, ); }; stampRemoveOrganizationFeature = async ( - input: SdkApiTypes.TRemoveOrganizationFeatureBody + input: SdkApiTypes.TRemoveOrganizationFeatureBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/remove_organization_feature"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -3097,13 +3163,11 @@ export class TurnkeySDKClientBase { setOrganizationFeature = async ( input: SdkApiTypes.TSetOrganizationFeatureBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/set_organization_feature", @@ -3117,20 +3181,23 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_SET_ORGANIZATION_FEATURE", }, "setOrganizationFeatureResult", - stampWith + stampWith, ); }; stampSetOrganizationFeature = async ( - input: SdkApiTypes.TSetOrganizationFeatureBody + input: SdkApiTypes.TSetOrganizationFeatureBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/set_organization_feature"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -3140,13 +3207,11 @@ export class TurnkeySDKClientBase { signRawPayload = async ( input: SdkApiTypes.TSignRawPayloadBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/sign_raw_payload", @@ -3160,20 +3225,23 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_SIGN_RAW_PAYLOAD_V2", }, "signRawPayloadResult", - stampWith + stampWith, ); }; stampSignRawPayload = async ( - input: SdkApiTypes.TSignRawPayloadBody + input: SdkApiTypes.TSignRawPayloadBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/sign_raw_payload"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -3183,13 +3251,11 @@ export class TurnkeySDKClientBase { signRawPayloads = async ( input: SdkApiTypes.TSignRawPayloadsBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/sign_raw_payloads", @@ -3203,20 +3269,23 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_SIGN_RAW_PAYLOADS", }, "signRawPayloadsResult", - stampWith + stampWith, ); }; stampSignRawPayloads = async ( - input: SdkApiTypes.TSignRawPayloadsBody + input: SdkApiTypes.TSignRawPayloadsBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/sign_raw_payloads"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -3226,13 +3295,11 @@ export class TurnkeySDKClientBase { signTransaction = async ( input: SdkApiTypes.TSignTransactionBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/sign_transaction", @@ -3246,20 +3313,23 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_SIGN_TRANSACTION_V2", }, "signTransactionResult", - stampWith + stampWith, ); }; stampSignTransaction = async ( - input: SdkApiTypes.TSignTransactionBody + input: SdkApiTypes.TSignTransactionBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/sign_transaction"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -3269,13 +3339,11 @@ export class TurnkeySDKClientBase { stampLogin = async ( input: SdkApiTypes.TStampLoginBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/stamp_login", @@ -3289,19 +3357,22 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_STAMP_LOGIN", }, "stampLoginResult", - stampWith + stampWith, ); }; stampStampLogin = async ( - input: SdkApiTypes.TStampLoginBody + input: SdkApiTypes.TStampLoginBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/stamp_login"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -3311,13 +3382,11 @@ export class TurnkeySDKClientBase { updatePolicy = async ( input: SdkApiTypes.TUpdatePolicyBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/update_policy", @@ -3331,19 +3400,22 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_UPDATE_POLICY_V2", }, "updatePolicyResultV2", - stampWith + stampWith, ); }; stampUpdatePolicy = async ( - input: SdkApiTypes.TUpdatePolicyBody + input: SdkApiTypes.TUpdatePolicyBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/update_policy"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -3353,13 +3425,11 @@ export class TurnkeySDKClientBase { updatePrivateKeyTag = async ( input: SdkApiTypes.TUpdatePrivateKeyTagBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/update_private_key_tag", @@ -3373,20 +3443,23 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_UPDATE_PRIVATE_KEY_TAG", }, "updatePrivateKeyTagResult", - stampWith + stampWith, ); }; stampUpdatePrivateKeyTag = async ( - input: SdkApiTypes.TUpdatePrivateKeyTagBody + input: SdkApiTypes.TUpdatePrivateKeyTagBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/update_private_key_tag"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -3396,13 +3469,11 @@ export class TurnkeySDKClientBase { updateRootQuorum = async ( input: SdkApiTypes.TUpdateRootQuorumBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/update_root_quorum", @@ -3416,20 +3487,23 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_UPDATE_ROOT_QUORUM", }, "updateRootQuorumResult", - stampWith + stampWith, ); }; stampUpdateRootQuorum = async ( - input: SdkApiTypes.TUpdateRootQuorumBody + input: SdkApiTypes.TUpdateRootQuorumBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/update_root_quorum"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -3439,13 +3513,11 @@ export class TurnkeySDKClientBase { updateUser = async ( input: SdkApiTypes.TUpdateUserBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/update_user", @@ -3459,19 +3531,22 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_UPDATE_USER", }, "updateUserResult", - stampWith + stampWith, ); }; stampUpdateUser = async ( - input: SdkApiTypes.TUpdateUserBody + input: SdkApiTypes.TUpdateUserBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/update_user"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -3481,13 +3556,11 @@ export class TurnkeySDKClientBase { updateUserTag = async ( input: SdkApiTypes.TUpdateUserTagBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/update_user_tag", @@ -3501,20 +3574,23 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_UPDATE_USER_TAG", }, "updateUserTagResult", - stampWith + stampWith, ); }; stampUpdateUserTag = async ( - input: SdkApiTypes.TUpdateUserTagBody + input: SdkApiTypes.TUpdateUserTagBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/update_user_tag"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -3524,13 +3600,11 @@ export class TurnkeySDKClientBase { updateWallet = async ( input: SdkApiTypes.TUpdateWalletBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/update_wallet", @@ -3544,19 +3618,22 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_UPDATE_WALLET", }, "updateWalletResult", - stampWith + stampWith, ); }; stampUpdateWallet = async ( - input: SdkApiTypes.TUpdateWalletBody + input: SdkApiTypes.TUpdateWalletBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/update_wallet"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -3566,13 +3643,11 @@ export class TurnkeySDKClientBase { verifyOtp = async ( input: SdkApiTypes.TVerifyOtpBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { const { organizationId, timestampMs, ...rest } = input; - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); - session = parseSession(session!); + let session = await this.storageManager?.getActiveSession(); + session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.command( "/public/v1/submit/verify_otp", @@ -3586,19 +3661,22 @@ export class TurnkeySDKClientBase { type: "ACTIVITY_TYPE_VERIFY_OTP", }, "verifyOtpResult", - stampWith + stampWith, ); }; stampVerifyOtp = async ( - input: SdkApiTypes.TVerifyOtpBody + input: SdkApiTypes.TVerifyOtpBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/public/v1/submit/verify_otp"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, @@ -3608,11 +3686,9 @@ export class TurnkeySDKClientBase { testRateLimits = async ( input: SdkApiTypes.TTestRateLimitsBody, - stampWith?: StamperType + stampWith?: StamperType, ): Promise => { - let session = await this.storageManager?.getStorageValue( - SessionKey.DefaultSessionkey - ); + let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( "/tkhq/api/v1/test_rate_limits", @@ -3623,19 +3699,22 @@ export class TurnkeySDKClientBase { session?.organizationId ?? this.config.organizationId, }, - stampWith + stampWith, ); }; stampTestRateLimits = async ( - input: SdkApiTypes.TTestRateLimitsBody + input: SdkApiTypes.TTestRateLimitsBody, + stampWith?: StamperType, ): Promise => { - if (!this.stamper) { + const activeStamper = this.getStamper(stampWith); + if (!activeStamper) { return undefined; } + const fullUrl = this.config.apiBaseUrl + "/tkhq/api/v1/test_rate_limits"; const body = JSON.stringify(input); - const stamp = await this.stamper.stamp(body); + const stamp = await activeStamper.stamp(body); return { body: body, stamp: stamp, diff --git a/packages/sdk-js/src/__stampers__/base.ts b/packages/sdk-js/src/__stampers__/base.ts index d3ee2ff14..d6c7a0374 100644 --- a/packages/sdk-js/src/__stampers__/base.ts +++ b/packages/sdk-js/src/__stampers__/base.ts @@ -1,4 +1,4 @@ -import { getPubKeyFromToken, isReactNative, isWeb } from "@utils"; +import { isReactNative, isWeb } from "@utils"; import { IndexedDbStamper } from "./web/stamper"; import { StorageBase } from "../__storage__/base"; @@ -9,7 +9,7 @@ export interface StamperBase { sign(payload: string, publicKeyHex: string): Promise; stamp( payload: string, - publicKeyHex: string + publicKeyHex: string, ): Promise<{ stampHeaderName: string; stampHeaderValue: string }>; } @@ -41,24 +41,21 @@ export class CrossPlatformApiKeyStamper { async sign(payload: string): Promise { const session = await this.storageManager.getActiveSession(); console.log("Active session:", session); - console.log("Session token:", session?.token); - if (!session?.token) { + if (!session) { throw new Error("No active session or token available."); } - const publicKey = getPubKeyFromToken(session.token); - return this.stamper.sign(payload, publicKey); + return this.stamper.sign(payload, session.token); } async stamp( - payload: string + payload: string, ): Promise<{ stampHeaderName: string; stampHeaderValue: string }> { const session = await this.storageManager.getActiveSession(); console.log("Active session:", session); console.log("Session token:", session?.token); - if (!session?.token) { + if (!session) { throw new Error("No active session or token available."); } - const publicKey = getPubKeyFromToken(session.token); - return this.stamper.stamp(payload, publicKey); + return this.stamper.stamp(payload, session.token); } } diff --git a/packages/sdk-js/src/__stampers__/web/stamper.ts b/packages/sdk-js/src/__stampers__/web/stamper.ts index f79c55c11..52a606c77 100644 --- a/packages/sdk-js/src/__stampers__/web/stamper.ts +++ b/packages/sdk-js/src/__stampers__/web/stamper.ts @@ -12,7 +12,7 @@ const stampHeaderName = "X-Stamp"; function convertEcdsaIeee1363ToDer(ieee: Uint8Array): Uint8Array { if (ieee.length % 2 != 0 || ieee.length == 0 || ieee.length > 132) { throw new Error( - "Invalid IEEE P1363 signature encoding. Length: " + ieee.length + "Invalid IEEE P1363 signature encoding. Length: " + ieee.length, ); } const r = toUnsignedBigNum(ieee.subarray(0, ieee.length / 2)); @@ -80,7 +80,7 @@ export class IndexedDbStamper implements StamperBase { private async storeKeyPair( publicKeyHex: string, - privateKey: CryptoKey + privateKey: CryptoKey, ): Promise { const db = await this.openDb(); return new Promise((resolve, reject) => { @@ -144,13 +144,13 @@ export class IndexedDbStamper implements StamperBase { const keyPair = await crypto.subtle.generateKey( { name: "ECDSA", namedCurve: "P-256" }, false, - ["sign", "verify"] + ["sign", "verify"], ); privateKey = keyPair.privateKey; publicKey = keyPair.publicKey; } const rawPubKey = new Uint8Array( - await crypto.subtle.exportKey("raw", publicKey) + await crypto.subtle.exportKey("raw", publicKey), ); const compressedPubKey = pointEncode(rawPubKey); const compressedHex = uint8ArrayToHexString(compressedPubKey); @@ -195,17 +195,17 @@ export class IndexedDbStamper implements StamperBase { const signatureIeee1363 = await crypto.subtle.sign( { name: "ECDSA", hash: { name: "SHA-256" } }, privateKey, - encodedPayload + encodedPayload, ); const signatureDer = convertEcdsaIeee1363ToDer( - new Uint8Array(signatureIeee1363) + new Uint8Array(signatureIeee1363), ); return uint8ArrayToHexString(signatureDer); } async stamp( payload: string, - publicKeyHex: string + publicKeyHex: string, ): Promise<{ stampHeaderName: string; stampHeaderValue: string }> { const signature = await this.sign(payload, publicKeyHex); const stamp = { diff --git a/packages/sdk-js/src/__storage__/base.ts b/packages/sdk-js/src/__storage__/base.ts index caaac9c9a..438167c1b 100644 --- a/packages/sdk-js/src/__storage__/base.ts +++ b/packages/sdk-js/src/__storage__/base.ts @@ -7,13 +7,14 @@ export enum SessionKey { } export interface StorageBase { + // These functions take in strings for sessions. This is just the JWT that is returned from Turnkey. getStorageValue(sessionKey: string): Promise; setStorageValue(sessionKey: string, storageValue: any): Promise; removeStorageValue(sessionKey: string): Promise; - storeSession(session: Session, sessionKey?: string): Promise; + storeSession(session: string, sessionKey?: string): Promise; getSession(sessionKey?: string): Promise; @@ -30,16 +31,15 @@ export interface StorageBase { export async function createStorageManager(): Promise { if (isReactNative()) { - throw new Error("Not implemented for React Native yet."); - // try { - // // Dynamic import to prevent bundling the native module in web environments - // const { MobileStorageManager } = await import("./mobile/storage"); - // return new MobileStorageManager(); - // } catch (error) { - // throw new Error( - // `Failed to load native secure storage, falling back to memory storage: ${error}` - // ); - // } + try { + // Dynamic import to prevent bundling the native module in web environments + const { MobileStorageManager } = await import("./mobile/storage"); + return new MobileStorageManager(); + } catch (error) { + throw new Error( + `Failed to load storage manager for react-native: ${error}`, + ); + } } else if (isWeb()) { return new WebStorageManager(); } else { diff --git a/packages/sdk-js/src/__storage__/mobile/storage.ts b/packages/sdk-js/src/__storage__/mobile/storage.ts index e90a014a6..fb9bdccde 100644 --- a/packages/sdk-js/src/__storage__/mobile/storage.ts +++ b/packages/sdk-js/src/__storage__/mobile/storage.ts @@ -1,58 +1,96 @@ -// import type { Session } from "@turnkey/sdk-types"; - -// import { StorageBase, StorageKey, StorageValue } from "../base"; - -// export class MobileStorageManager implements StorageBase { -// Keychain = require("react-native-keychain"); - -// getStorageValue = async ( -// storageKey: K, -// ): Promise => { -// try { -// const result = await this.Keychain.getGenericPassword({ -// service: storageKey, -// }); - -// if (result && result.password) { -// return JSON.parse(result.password); -// } -// return undefined; -// } catch (error) { -// console.error("Error retrieving from Keychain:", error); -// return undefined; -// } -// }; - -// setStorageValue = async ( -// storageKey: K, -// storageValue: StorageValue[K], -// ): Promise => { -// try { -// const result = await this.Keychain.setGenericPassword( -// storageKey, -// JSON.stringify(storageValue), -// { service: storageKey }, -// ); -// return !!result; -// } catch (error) { -// console.error("Error storing in Keychain:", error); -// return false; -// } -// }; - -// removeStorageValue = async ( -// storageKey: K, -// ): Promise => { -// try { -// await this.Keychain.resetGenericPassword({ -// service: storageKey, -// }); -// } catch (error) { -// console.error("Error removing from Keychain:", error); -// } -// }; - -// storeSession = async (session: Session): Promise => { -// return await this.setStorageValue(StorageKey.Session, session); -// }; -// } +import { StorageBase, SessionKey } from "../base"; +import { parseSession } from "@utils"; +import { Session } from "@turnkey/sdk-types"; + +let AsyncStorage: (typeof import("@react-native-async-storage/async-storage"))["default"]; + +try { + const mod = require("@react-native-async-storage/async-storage"); + AsyncStorage = mod.default ?? mod; +} catch { + throw new Error( + "Please install @react-native-async-storage/async-storage in your app to use MobileStorageManager", + ); +} + +export class MobileStorageManager implements StorageBase { + private static ALL_SESSION_KEYS = "@turnkey/all-session-keys"; + private static ACTIVE_SESSION_KEY = "@turnkey/active-session-key"; + + async getStorageValue(sessionKey: string): Promise { + const item = await AsyncStorage.getItem(sessionKey); + return item ? JSON.parse(item) : undefined; + } + + async setStorageValue(sessionKey: string, storageValue: any): Promise { + await AsyncStorage.setItem(sessionKey, JSON.stringify(storageValue)); + } + + async removeStorageValue(sessionKey: string): Promise { + await AsyncStorage.removeItem(sessionKey); + } + + async storeSession( + session: string, + sessionKey: string = SessionKey.DefaultSessionkey, + ): Promise { + const sessionWithMetadata = parseSession(session); + await this.setStorageValue(sessionKey, sessionWithMetadata); + + const raw = await this.getStorageValue( + MobileStorageManager.ALL_SESSION_KEYS, + ); + const keys: string[] = Array.isArray(raw) ? raw : []; + if (!keys.includes(sessionKey)) { + keys.push(sessionKey); + await this.setStorageValue(MobileStorageManager.ALL_SESSION_KEYS, keys); + } + + await this.setStorageValue( + MobileStorageManager.ACTIVE_SESSION_KEY, + sessionKey, + ); + } + + async getSession( + sessionKey: string = SessionKey.DefaultSessionkey, + ): Promise { + return this.getStorageValue(sessionKey); + } + + async getActiveSessionKey(): Promise { + return this.getStorageValue(MobileStorageManager.ACTIVE_SESSION_KEY); + } + + async getActiveSession(): Promise { + const key = await this.getActiveSessionKey(); + return key ? this.getSession(key) : undefined; + } + + async listSessionKeys(): Promise { + const raw = await this.getStorageValue( + MobileStorageManager.ALL_SESSION_KEYS, + ); + return Array.isArray(raw) ? raw : []; + } + + async clearSession(sessionKey: string): Promise { + await this.removeStorageValue(sessionKey); + + const keys = await this.listSessionKeys(); + const updated = keys.filter((k) => k !== sessionKey); + await this.setStorageValue(MobileStorageManager.ALL_SESSION_KEYS, updated); + + const active = await this.getActiveSessionKey(); + if (active === sessionKey) { + await this.removeStorageValue(MobileStorageManager.ACTIVE_SESSION_KEY); + } + } + + async clearAllSessions(): Promise { + const keys = await this.listSessionKeys(); + await Promise.all(keys.map((k) => AsyncStorage.removeItem(k))); + await this.removeStorageValue(MobileStorageManager.ALL_SESSION_KEYS); + await this.removeStorageValue(MobileStorageManager.ACTIVE_SESSION_KEY); + } +} diff --git a/packages/sdk-js/src/__storage__/web/storage.ts b/packages/sdk-js/src/__storage__/web/storage.ts index ee3167846..e35c4ee30 100644 --- a/packages/sdk-js/src/__storage__/web/storage.ts +++ b/packages/sdk-js/src/__storage__/web/storage.ts @@ -1,12 +1,13 @@ -import type { Session } from "@turnkey/sdk-types"; import WindowWrapper from "@polyfills/window"; import { StorageBase, SessionKey } from "../base"; +import { parseSession } from "@utils"; +import { Session } from "@turnkey/sdk-types"; const browserStorage = WindowWrapper.localStorage; export class WebStorageManager implements StorageBase { - private static SESSION_KEYS_KEY = "sessionKeys"; - private static ACTIVE_SESSION_KEY = "activeSessionKey"; + private static ALL_SESSION_KEYS = "@turnkey/all-session-keys"; + private static ACTIVE_SESSION_KEY = "@turnkey/active-session-key"; getStorageValue = async (sessionKey: string): Promise => { const item = browserStorage.getItem(sessionKey); @@ -15,7 +16,7 @@ export class WebStorageManager implements StorageBase { setStorageValue = async ( sessionKey: string, - storageValue: any + storageValue: any, ): Promise => { browserStorage.setItem(sessionKey, JSON.stringify(storageValue)); }; @@ -25,28 +26,30 @@ export class WebStorageManager implements StorageBase { }; storeSession = async ( - session: Session, - sessionKey: string = SessionKey.DefaultSessionkey + session: string, + sessionKey: string = SessionKey.DefaultSessionkey, ): Promise => { - await this.setStorageValue(sessionKey, session); + const sessionWithMetadata = parseSession(session); + + await this.setStorageValue(sessionKey, sessionWithMetadata); // Ensure the session key is stored in the session keys list const keys: string[] = - (await this.getStorageValue(WebStorageManager.SESSION_KEYS_KEY)) ?? []; + (await this.getStorageValue(WebStorageManager.ALL_SESSION_KEYS)) ?? []; if (!keys.includes(sessionKey)) { keys.push(sessionKey); - await this.setStorageValue(WebStorageManager.SESSION_KEYS_KEY, keys); + await this.setStorageValue(WebStorageManager.ALL_SESSION_KEYS, keys); } // Set the active session key await this.setStorageValue( WebStorageManager.ACTIVE_SESSION_KEY, - sessionKey + sessionKey, ); }; getSession = async ( - sessionKey: string = SessionKey.DefaultSessionkey + sessionKey: string = SessionKey.DefaultSessionkey, ): Promise => { return this.getStorageValue(sessionKey); }; @@ -62,7 +65,7 @@ export class WebStorageManager implements StorageBase { listSessionKeys = async (): Promise => { return ( - (await this.getStorageValue(WebStorageManager.SESSION_KEYS_KEY)) ?? [] + (await this.getStorageValue(WebStorageManager.ALL_SESSION_KEYS)) ?? [] ); }; @@ -70,7 +73,7 @@ export class WebStorageManager implements StorageBase { await this.removeStorageValue(sessionKey); const keys = await this.listSessionKeys(); const updated = keys.filter((k) => k !== sessionKey); - await this.setStorageValue(WebStorageManager.SESSION_KEYS_KEY, updated); + await this.setStorageValue(WebStorageManager.ALL_SESSION_KEYS, updated); const active = await this.getActiveSessionKey(); if (active === sessionKey) { await this.removeStorageValue(WebStorageManager.ACTIVE_SESSION_KEY); @@ -80,7 +83,7 @@ export class WebStorageManager implements StorageBase { clearAllSessions = async (): Promise => { const keys = await this.listSessionKeys(); await Promise.all(keys.map((k) => this.removeStorageValue(k))); - await this.removeStorageValue(WebStorageManager.SESSION_KEYS_KEY); + await this.removeStorageValue(WebStorageManager.ALL_SESSION_KEYS); await this.removeStorageValue(WebStorageManager.ACTIVE_SESSION_KEY); }; } diff --git a/packages/sdk-js/src/__types__/base.ts b/packages/sdk-js/src/__types__/base.ts index 681fa5046..f656dc655 100644 --- a/packages/sdk-js/src/__types__/base.ts +++ b/packages/sdk-js/src/__types__/base.ts @@ -105,7 +105,7 @@ export interface TurnkeySDKClientConfig { // TODO (Amir): Remove this in a user-facing config and add passkey and wallet configs activityPoller?: TActivityPollerConfig | undefined; - stamper?: never; + apiKeyStamper?: TStamper; passkeyStamper?: TStamper; storageManager?: StorageBase; readOnlySession?: string; @@ -183,6 +183,6 @@ export enum AuthClient { } export enum StamperType { - IndexedDB = "indexed-db", + apiKey = "api-key", Passkey = "passkey", } diff --git a/packages/sdk-js/src/utils.ts b/packages/sdk-js/src/utils.ts index f8468c363..de56b958b 100644 --- a/packages/sdk-js/src/utils.ts +++ b/packages/sdk-js/src/utils.ts @@ -1,7 +1,6 @@ import { Buffer } from "buffer"; import type { Session } from "@turnkey/sdk-types"; -import { jwtDecode } from "jwt-decode"; export const isReactNative = (): boolean => { return ( @@ -28,7 +27,7 @@ export const base64UrlEncode = (challenge: ArrayBuffer): string => { }; const hexByByte = Array.from({ length: 256 }, (_, i) => - i.toString(16).padStart(2, "0") + i.toString(16).padStart(2, "0"), ); export const bytesToHex = (bytes: Uint8Array): string => { @@ -67,11 +66,6 @@ export function parseSession(token: string | Session): Session { userId, organizationId, expiry: exp, - token: publicKey, + token: publicKey, // TODO (Amir): Should token be the JWT then add another field for publicKey? }; } - -export function getPubKeyFromToken(token: string): string { - const { public_key } = jwtDecode(token) as any; - return public_key; -} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4756b4021..c4a92f00f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2102,28 +2102,6 @@ importers: specifier: 5.3.0 version: 5.3.0(@babel/core@7.26.9)(@types/babel__core@7.20.5)(rollup@4.41.1) - packages/react-native-secure-storage-stamper: - dependencies: - '@turnkey/api-key-stamper': - specifier: workspace:* - version: link:../api-key-stamper - '@turnkey/encoding': - specifier: workspace:* - version: link:../encoding - react-native-keychain: - specifier: ^8.1.0 || ^9.2.2 || ^10.0.0 - version: 8.1.0 - devDependencies: - '@types/jest': - specifier: ^29.5.3 - version: 29.5.3 - jest: - specifier: ^29.7.0 - version: 29.7.0(@types/node@18.18.2) - ts-jest: - specifier: ^29.3.1 - version: 29.3.1(@babel/core@7.26.9)(@jest/types@29.4.3)(jest@29.7.0)(typescript@5.4.3) - packages/sdk-browser: dependencies: '@turnkey/api-key-stamper': @@ -2175,6 +2153,9 @@ importers: packages/sdk-js: dependencies: + '@react-native-async-storage/async-storage': + specifier: ^2.2.0 + version: 2.2.0(react-native@0.76.5) '@turnkey/api-key-stamper': specifier: workspace:* version: link:../api-key-stamper @@ -5181,7 +5162,20 @@ packages: peerDependencies: react-native: ^0.0.0-0 || >=0.60 <1.0 +<<<<<<< HEAD '@react-native/assets-registry@0.76.5': +======= + /@react-native-async-storage/async-storage@2.2.0(react-native@0.76.5): + resolution: {integrity: sha512-gvRvjR5JAaUZF8tv2Kcq/Gbt3JHwbKFYfmb445rhOj6NUMx3qPLixmDx5pZAyb9at1bYvJ4/eTUipU5aki45xw==} + peerDependencies: + react-native: ^0.0.0-0 || >=0.65 <1.0 + dependencies: + merge-options: 3.0.4 + react-native: 0.76.5(@babel/core@7.26.9)(@babel/preset-env@7.20.2)(@types/react@18.3.3)(react@18.3.1) + dev: false + + /@react-native/assets-registry@0.76.5: +>>>>>>> a1897f5f (Modified session storage. Added mobile storage manager) resolution: {integrity: sha512-MN5dasWo37MirVcKWuysRkRr4BjNc81SXwUtJYstwbn8oEkfnwR9DaqdDTo/hHOnTdhafffLIa2xOOHcjDIGEw==} engines: {node: '>=18'} @@ -10028,6 +10022,13 @@ packages: merge-options@3.0.4: resolution: {integrity: sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ==} engines: {node: '>=10'} +<<<<<<< HEAD +======= + requiresBuild: true + dependencies: + is-plain-obj: 2.1.0 + dev: false +>>>>>>> a1897f5f (Modified session storage. Added mobile storage manager) merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} From 1cb00809e8232d3e735fa32b8114163992ef023d Mon Sep 17 00:00:00 2001 From: Amir Cheikh Date: Wed, 11 Jun 2025 15:26:40 -0400 Subject: [PATCH 006/184] Mobile keychain stamper --- packages/sdk-js/src/__clients__/core.ts | 7 +- packages/sdk-js/src/__stampers__/base.ts | 34 +++++--- .../sdk-js/src/__stampers__/mobile/stamper.ts | 80 +++++++++++++++++++ .../sdk-js/src/__stampers__/web/stamper.ts | 4 +- packages/sdk-js/src/__storage__/base.ts | 2 +- 5 files changed, 111 insertions(+), 16 deletions(-) create mode 100644 packages/sdk-js/src/__stampers__/mobile/stamper.ts diff --git a/packages/sdk-js/src/__clients__/core.ts b/packages/sdk-js/src/__clients__/core.ts index 36b89d608..00872d011 100644 --- a/packages/sdk-js/src/__clients__/core.ts +++ b/packages/sdk-js/src/__clients__/core.ts @@ -26,11 +26,11 @@ export class TurnkeyClient { config: any; // Type TBD httpClient!: TurnkeySDKClientBase; - // public session?: Session | undefined; // TODO (Amir): Define session type + // public session?: Session | undefined; // TODO (Amir): Define session type. Or not maybe??? // public user?: any; // TODO (Amir): Define user type // public wallets?: any; // TODO (Amir): Define wallets type - private apiKeyStamper?: CrossPlatformApiKeyStamper | undefined; + apiKeyStamper?: CrossPlatformApiKeyStamper | undefined; // TODO (Amir): TEMPORARILY PUBLIC, MAKE PRIVATE LATER private passkeyStamper?: WebauthnStamper | undefined; private mobilePasskeyStamper?: any | undefined; // TODO (Amir): Implement proper type @@ -80,9 +80,12 @@ export class TurnkeyClient { } // Initialize storage manager + // TODO (Amir): StorageManager should be a class that extends StorageBase and has an init method this.storageManager = await createStorageManager(); + // Initialize the API key stamper this.apiKeyStamper = new CrossPlatformApiKeyStamper(this.storageManager); + await this.apiKeyStamper.init(); // Initialize the HTTP client with the appropriate stampers this.httpClient = new TurnkeySDKClientBase({ diff --git a/packages/sdk-js/src/__stampers__/base.ts b/packages/sdk-js/src/__stampers__/base.ts index d6c7a0374..dfbfa43b7 100644 --- a/packages/sdk-js/src/__stampers__/base.ts +++ b/packages/sdk-js/src/__stampers__/base.ts @@ -4,9 +4,11 @@ import { StorageBase } from "../__storage__/base"; export interface StamperBase { listKeyPairs(): Promise; - createKeyPair(externalKeyPair?: CryptoKeyPair): Promise; + createKeyPair( + externalKeyPair?: CryptoKeyPair | { publicKey: string; privateKey: string }, + ): Promise; deleteKeyPair(publicKeyHex: string): Promise; - sign(payload: string, publicKeyHex: string): Promise; + clearKeyPairs(): Promise; stamp( payload: string, publicKeyHex: string, @@ -17,20 +19,35 @@ export class CrossPlatformApiKeyStamper { private stamper!: StamperBase; constructor(private storageManager: StorageBase) { + // Use init method to set up the stamper based on the platform. It's async, so can't be done in the constructor. + } + + async init(): Promise { if (isWeb()) { this.stamper = new IndexedDbStamper(); } else if (isReactNative()) { - //this.stamper = new ReactNativeKeychainStamper(); + try { + // Dynamic import to prevent bundling the native module in web environments. + const { ReactNativeKeychainStamper } = await import("./mobile/stamper"); + this.stamper = new ReactNativeKeychainStamper(); + } catch (error) { + throw new Error( + `Failed to load storage manager for react-native: ${error}`, + ); + } } else { throw new Error("Unsupported platform for API key stamper"); } } listKeyPairs(): Promise { + // TODO (Amir): Wait, this doesn't show the private key, right? 0_0 return this.stamper.listKeyPairs(); } - createKeyPair(externalKeyPair?: CryptoKeyPair): Promise { + createKeyPair( + externalKeyPair?: CryptoKeyPair | { publicKey: string; privateKey: string }, + ): Promise { return this.stamper.createKeyPair(externalKeyPair); } @@ -38,13 +55,8 @@ export class CrossPlatformApiKeyStamper { return this.stamper.deleteKeyPair(publicKeyHex); } - async sign(payload: string): Promise { - const session = await this.storageManager.getActiveSession(); - console.log("Active session:", session); - if (!session) { - throw new Error("No active session or token available."); - } - return this.stamper.sign(payload, session.token); + clearKeyPairs?(): Promise { + return this.stamper.clearKeyPairs(); } async stamp( diff --git a/packages/sdk-js/src/__stampers__/mobile/stamper.ts b/packages/sdk-js/src/__stampers__/mobile/stamper.ts new file mode 100644 index 000000000..e3128c47b --- /dev/null +++ b/packages/sdk-js/src/__stampers__/mobile/stamper.ts @@ -0,0 +1,80 @@ +import { ApiKeyStamper } from "@turnkey/api-key-stamper"; +import { generateP256KeyPair } from "@turnkey/crypto"; +import { StamperBase } from "../base"; + +let Keychain: typeof import("react-native-keychain"); + +try { + Keychain = require("react-native-keychain"); +} catch { + throw new Error( + "Please install react-native-keychain in your app to use ReactNativeKeychainStamper", + ); +} + +export class ReactNativeKeychainStamper implements StamperBase { + async listKeyPairs(): Promise { + return await Keychain.getAllGenericPasswordServices(); + } + + async clearKeyPairs(): Promise { + const keys = await this.listKeyPairs(); + for (const key of keys) { + await this.deleteKeyPair(key); + } + } + async createKeyPair(externalKeyPair?: { + publicKey: string; + privateKey: string; + }): Promise { + let privateKey: string; + let publicKey: string; + + if (externalKeyPair) { + privateKey = externalKeyPair.privateKey; + publicKey = externalKeyPair.publicKey; + } else { + const pair = generateP256KeyPair(); + privateKey = pair.privateKey; + publicKey = pair.publicKey; + } + + // store in Keychain + await Keychain.setGenericPassword(publicKey, privateKey, { + service: publicKey, + }); + + return publicKey; + } + + async deleteKeyPair(publicKeyHex: string): Promise { + await Keychain.resetGenericPassword({ + service: publicKeyHex, + }); + } + + private async getPrivateKey(publicKeyHex: string): Promise { + const creds = await Keychain.getGenericPassword({ + service: publicKeyHex, + }); + if (!creds) return null; + + return creds.password; + } + + async stamp( + payload: string, + publicKeyHex: string, + ): Promise<{ stampHeaderName: string; stampHeaderValue: string }> { + const privateKey = await this.getPrivateKey(publicKeyHex); + if (!privateKey) { + throw new Error(`No private key found for public key: ${publicKeyHex}`); + } + const stamper = new ApiKeyStamper({ + apiPublicKey: publicKeyHex, + apiPrivateKey: privateKey, + }); + const { stampHeaderName, stampHeaderValue } = await stamper.stamp(payload); + return { stampHeaderName, stampHeaderValue }; + } +} diff --git a/packages/sdk-js/src/__stampers__/web/stamper.ts b/packages/sdk-js/src/__stampers__/web/stamper.ts index 52a606c77..f8034e4f5 100644 --- a/packages/sdk-js/src/__stampers__/web/stamper.ts +++ b/packages/sdk-js/src/__stampers__/web/stamper.ts @@ -172,7 +172,7 @@ export class IndexedDbStamper implements StamperBase { }); } - async clear(): Promise { + async clearKeyPairs(): Promise { const db = await this.openDb(); return new Promise((resolve, reject) => { const tx = db.transaction(DB_STORE, "readwrite"); @@ -186,7 +186,7 @@ export class IndexedDbStamper implements StamperBase { }); } - async sign(payload: string, publicKeyHex: string): Promise { + private async sign(payload: string, publicKeyHex: string): Promise { const privateKey = await this.getPrivateKey(publicKeyHex); if (!privateKey) { throw new Error("Key not found for publicKey: " + publicKeyHex); diff --git a/packages/sdk-js/src/__storage__/base.ts b/packages/sdk-js/src/__storage__/base.ts index 438167c1b..cfa695a70 100644 --- a/packages/sdk-js/src/__storage__/base.ts +++ b/packages/sdk-js/src/__storage__/base.ts @@ -28,7 +28,7 @@ export interface StorageBase { clearAllSessions(): Promise; } - +// TODO (Amir): Turn this into a class that extends StorageBase and make an init function. See stamper export async function createStorageManager(): Promise { if (isReactNative()) { try { From c78b1a6f1a52c0144c386d9e9ba682f3aa1b34d7 Mon Sep 17 00:00:00 2001 From: Amir Cheikh Date: Thu, 12 Jun 2025 17:00:45 -0400 Subject: [PATCH 007/184] Cross platform passkey stamper --- examples/with-sdk-js/src/app/page.tsx | 24 ++- packages/sdk-js/package.json | 9 +- packages/sdk-js/src/__clients__/core.ts | 133 +++--------- .../sdk-js/src/__stampers__/{ => api}/base.ts | 20 +- .../__stampers__/{ => api}/mobile/stamper.ts | 10 +- .../src/__stampers__/{ => api}/web/stamper.ts | 10 +- .../sdk-js/src/__stampers__/passkey/base.ts | 193 ++++++++++++++++++ packages/sdk-js/src/__types__/base.ts | 5 + pnpm-lock.yaml | 15 ++ 9 files changed, 286 insertions(+), 133 deletions(-) rename packages/sdk-js/src/__stampers__/{ => api}/base.ts (80%) rename packages/sdk-js/src/__stampers__/{ => api}/mobile/stamper.ts (89%) rename packages/sdk-js/src/__stampers__/{ => api}/web/stamper.ts (96%) create mode 100644 packages/sdk-js/src/__stampers__/passkey/base.ts diff --git a/examples/with-sdk-js/src/app/page.tsx b/examples/with-sdk-js/src/app/page.tsx index a3c92479e..dce1b5dc3 100644 --- a/examples/with-sdk-js/src/app/page.tsx +++ b/examples/with-sdk-js/src/app/page.tsx @@ -30,9 +30,12 @@ export default function AuthPage() { initializeClient(); }, []); - const passkey = async () => { + const createPasskey = async () => { + await client?.createPasskey({}); + }; + + const logInWithPasskey = async () => { await client?.loginWithPasskey({}); - //const resp = await client?.httpClient.getWhoami({}, StamperType.Passkey); }; const indexedDB = async () => { const resp = await client?.httpClient.getWhoami({}); @@ -65,11 +68,22 @@ export default function AuthPage() { color: "white", }} > - IndexedDB + GetWhoami with IndexedDB + ); diff --git a/packages/sdk-js/package.json b/packages/sdk-js/package.json index 67039046c..d6d961b55 100644 --- a/packages/sdk-js/package.json +++ b/packages/sdk-js/package.json @@ -32,7 +32,8 @@ "bs58check": "3.0.1", "jwt-decode": "4.0.0", "buffer": "^6.0.3", - "cross-fetch": "^3.1.5" + "cross-fetch": "^3.1.5", + "uuid": "^11.1.0" }, "devDependencies": { "glob": "^8.0.3", @@ -40,7 +41,8 @@ }, "peerDependencies": { "react-native-keychain": "^8.1.0 || ^9.2.2 || ^10.0.0", - "@react-native-async-storage/async-storage": "^2.2.0" + "@react-native-async-storage/async-storage": "^2.2.0", + "@turnkey/react-native-passkey-stamper": "workspace:*" }, "peerDependenciesMeta": { "react-native-keychain": { @@ -48,6 +50,9 @@ }, "@react-native-async-storage/async-storage": { "optional": true + }, + "@turnkey/react-native-passkey-stamper": { + "optional": true } }, "engines": { diff --git a/packages/sdk-js/src/__clients__/core.ts b/packages/sdk-js/src/__clients__/core.ts index 00872d011..c2687cc10 100644 --- a/packages/sdk-js/src/__clients__/core.ts +++ b/packages/sdk-js/src/__clients__/core.ts @@ -1,12 +1,11 @@ import { TurnkeySDKClientBase } from "../__generated__/sdk-client-base"; -import { WebauthnStamper } from "@turnkey/webauthn-stamper"; -import WindowWrapper from "@polyfills/window"; import { SessionType } from "@turnkey/sdk-types"; import { LoginWithPasskeyParams, DEFAULT_SESSION_EXPIRATION_IN_SECONDS, Passkey, StamperType, + CreatePasskeyParams, } from "@types"; // AHHHH, SDK-TYPES import { base64UrlEncode, @@ -20,7 +19,8 @@ import { StorageBase, SessionKey, } from "../__storage__/base"; -import { CrossPlatformApiKeyStamper } from "../__stampers__/base"; +import { CrossPlatformApiKeyStamper } from "../__stampers__/api/base"; +import { CrossPlatformPasskeyStamper } from "../__stampers__/passkey/base"; export class TurnkeyClient { config: any; // Type TBD @@ -31,9 +31,7 @@ export class TurnkeyClient { // public wallets?: any; // TODO (Amir): Define wallets type apiKeyStamper?: CrossPlatformApiKeyStamper | undefined; // TODO (Amir): TEMPORARILY PUBLIC, MAKE PRIVATE LATER - private passkeyStamper?: WebauthnStamper | undefined; - private mobilePasskeyStamper?: any | undefined; // TODO (Amir): Implement proper type - + private passkeyStamper?: CrossPlatformPasskeyStamper | undefined; storageManager!: StorageBase; constructor( @@ -41,44 +39,18 @@ export class TurnkeyClient { // Users can pass in their own stampers, or we will create them. Should we remove this? apiKeyStamper?: CrossPlatformApiKeyStamper, - passkeyStamper?: WebauthnStamper, - mobilePasskeyStamper?: any, // TODO: Add proper type + passkeyStamper?: CrossPlatformPasskeyStamper, ) { this.config = config; // Just store any explicitly provided stampers this.apiKeyStamper = apiKeyStamper; this.passkeyStamper = passkeyStamper; - this.mobilePasskeyStamper = mobilePasskeyStamper; // Actual initialization will happen in init() } async init() { - // Initialize platform-specific stampers - if (isWeb()) { - if (!this.passkeyStamper) { - this.passkeyStamper = new WebauthnStamper({ - rpId: - this.config?.passkeyConfig?.rpId ?? WindowWrapper.location.hostname, - ...(this.config?.passkeyConfig?.timeout !== undefined && { - timeout: this.config?.passkeyConfig?.timeout, - }), - ...(this.config?.passkeyConfig?.userVerification !== undefined && { - userVerification: this.config?.passkeyConfig?.userVerification, - }), - ...(this.config?.passkeyConfig?.allowCredentials !== undefined && { - allowCredentials: this.config?.passkeyConfig?.allowCredentials, - }), - }); - } - } else if (isReactNative()) { - if (!this.mobilePasskeyStamper) { - // TODO: Initialize mobilePasskeyStamper - // this.mobilePasskeyStamper = new MobilePasskeyStamper(); - } - } - // Initialize storage manager // TODO (Amir): StorageManager should be a class that extends StorageBase and has an init method this.storageManager = await createStorageManager(); @@ -87,84 +59,41 @@ export class TurnkeyClient { this.apiKeyStamper = new CrossPlatformApiKeyStamper(this.storageManager); await this.apiKeyStamper.init(); + this.passkeyStamper = new CrossPlatformPasskeyStamper( + this.config.passkeyConfig, + ); + await this.passkeyStamper.init(); + // Initialize the HTTP client with the appropriate stampers this.httpClient = new TurnkeySDKClientBase({ apiKeyStamper: this.apiKeyStamper, - passkeyStamper: isWeb() ? this.passkeyStamper : this.mobilePasskeyStamper, + passkeyStamper: this.passkeyStamper, storageManager: this.storageManager, ...this.config, }); } - /** - * Create a passkey for an end-user, taking care of various lower-level details. - * - * @returns {Promise} - */ - createUserPasskey = async ( - config: Record = {}, - ): Promise => { - // TODO (Amir): Make this work for mobile as well - const challenge = generateRandomBuffer(); - const encodedChallenge = base64UrlEncode(challenge); - const authenticatorUserId = generateRandomBuffer(); - - // WebAuthn credential options options can be found here: - // https://www.w3.org/TR/webauthn-2/#sctn-sample-registration - // - // All pubkey algorithms can be found here: https://www.iana.org/assignments/cose/cose.xhtml#algorithms - // Turnkey only supports ES256 (-7) and RS256 (-257) - // - // The pubkey type only supports one value, "public-key" - // See https://www.w3.org/TR/webauthn-2/#enumdef-publickeycredentialtype for more details - // TODO: consider un-nesting these config params - const webauthnConfig: CredentialCreationOptions = { - publicKey: { - rp: { - id: config.publicKey?.rp?.id ?? this.passkeyStamper?.rpId, - name: config.publicKey?.rp?.name ?? "", - }, - challenge: config.publicKey?.challenge ?? challenge, - pubKeyCredParams: config.publicKey?.pubKeyCredParams ?? [ - { - type: "public-key", - alg: -7, - }, - { - type: "public-key", - alg: -257, + createPasskey = async (params: CreatePasskeyParams): Promise => { + try { + const { name = "A Passkey", displayName = "A Passkey" } = params; + if (isWeb()) { + this.passkeyStamper?.createWebPasskey({ + publicKey: { + user: { + name, + displayName, + }, }, - ], - user: { - id: config.publicKey?.user?.id ?? authenticatorUserId, - name: config.publicKey?.user?.name ?? "Default User", - displayName: config.publicKey?.user?.displayName ?? "Default User", - }, - authenticatorSelection: { - authenticatorAttachment: - config.publicKey?.authenticatorSelection?.authenticatorAttachment ?? - undefined, // default to empty - requireResidentKey: - config.publicKey?.authenticatorSelection?.requireResidentKey ?? - true, - residentKey: - config.publicKey?.authenticatorSelection?.residentKey ?? "required", - userVerification: - config.publicKey?.authenticatorSelection?.userVerification ?? - this.passkeyStamper?.userVerification ?? - "preferred", - }, - }, - }; - - const attestation = await getWebAuthnAttestation(webauthnConfig); - - return { - encodedChallenge: config.publicKey?.challenge - ? base64UrlEncode(config.publicKey?.challenge) - : encodedChallenge, - attestation, - }; + }); + } else if (isReactNative()) { + this.passkeyStamper?.createReactNativePasskey({ + name, + displayName, + }); + } + } catch (error) { + throw new Error(`Failed to create passkey: ${error}`); + } }; loginWithPasskey = async (params: LoginWithPasskeyParams): Promise => { diff --git a/packages/sdk-js/src/__stampers__/base.ts b/packages/sdk-js/src/__stampers__/api/base.ts similarity index 80% rename from packages/sdk-js/src/__stampers__/base.ts rename to packages/sdk-js/src/__stampers__/api/base.ts index dfbfa43b7..96367d33b 100644 --- a/packages/sdk-js/src/__stampers__/base.ts +++ b/packages/sdk-js/src/__stampers__/api/base.ts @@ -1,22 +1,20 @@ import { isReactNative, isWeb } from "@utils"; import { IndexedDbStamper } from "./web/stamper"; -import { StorageBase } from "../__storage__/base"; +import { StorageBase } from "../../__storage__/base"; +import { TStamp, TStamper } from "@types"; -export interface StamperBase { +export interface ApiKeyStamperBase { listKeyPairs(): Promise; createKeyPair( externalKeyPair?: CryptoKeyPair | { publicKey: string; privateKey: string }, ): Promise; deleteKeyPair(publicKeyHex: string): Promise; clearKeyPairs(): Promise; - stamp( - payload: string, - publicKeyHex: string, - ): Promise<{ stampHeaderName: string; stampHeaderValue: string }>; + stamp(payload: string, publicKeyHex: string): Promise; } -export class CrossPlatformApiKeyStamper { - private stamper!: StamperBase; +export class CrossPlatformApiKeyStamper implements TStamper { + private stamper!: ApiKeyStamperBase; constructor(private storageManager: StorageBase) { // Use init method to set up the stamper based on the platform. It's async, so can't be done in the constructor. @@ -32,7 +30,7 @@ export class CrossPlatformApiKeyStamper { this.stamper = new ReactNativeKeychainStamper(); } catch (error) { throw new Error( - `Failed to load storage manager for react-native: ${error}`, + `Failed to load keychain stamper for react-native: ${error}`, ); } } else { @@ -59,9 +57,7 @@ export class CrossPlatformApiKeyStamper { return this.stamper.clearKeyPairs(); } - async stamp( - payload: string, - ): Promise<{ stampHeaderName: string; stampHeaderValue: string }> { + async stamp(payload: string): Promise { const session = await this.storageManager.getActiveSession(); console.log("Active session:", session); console.log("Session token:", session?.token); diff --git a/packages/sdk-js/src/__stampers__/mobile/stamper.ts b/packages/sdk-js/src/__stampers__/api/mobile/stamper.ts similarity index 89% rename from packages/sdk-js/src/__stampers__/mobile/stamper.ts rename to packages/sdk-js/src/__stampers__/api/mobile/stamper.ts index e3128c47b..b00de57a7 100644 --- a/packages/sdk-js/src/__stampers__/mobile/stamper.ts +++ b/packages/sdk-js/src/__stampers__/api/mobile/stamper.ts @@ -1,6 +1,7 @@ import { ApiKeyStamper } from "@turnkey/api-key-stamper"; import { generateP256KeyPair } from "@turnkey/crypto"; -import { StamperBase } from "../base"; +import { ApiKeyStamperBase } from "../base"; +import { TStamp } from "@types"; let Keychain: typeof import("react-native-keychain"); @@ -12,7 +13,7 @@ try { ); } -export class ReactNativeKeychainStamper implements StamperBase { +export class ReactNativeKeychainStamper implements ApiKeyStamperBase { async listKeyPairs(): Promise { return await Keychain.getAllGenericPasswordServices(); } @@ -62,10 +63,7 @@ export class ReactNativeKeychainStamper implements StamperBase { return creds.password; } - async stamp( - payload: string, - publicKeyHex: string, - ): Promise<{ stampHeaderName: string; stampHeaderValue: string }> { + async stamp(payload: string, publicKeyHex: string): Promise { const privateKey = await this.getPrivateKey(publicKeyHex); if (!privateKey) { throw new Error(`No private key found for public key: ${publicKeyHex}`); diff --git a/packages/sdk-js/src/__stampers__/web/stamper.ts b/packages/sdk-js/src/__stampers__/api/web/stamper.ts similarity index 96% rename from packages/sdk-js/src/__stampers__/web/stamper.ts rename to packages/sdk-js/src/__stampers__/api/web/stamper.ts index f8034e4f5..bbefe40cb 100644 --- a/packages/sdk-js/src/__stampers__/web/stamper.ts +++ b/packages/sdk-js/src/__stampers__/api/web/stamper.ts @@ -3,7 +3,8 @@ import { stringToBase64urlString, pointEncode, } from "@turnkey/encoding"; -import { StamperBase } from "../base"; +import { ApiKeyStamperBase } from "../base"; +import { TStamp } from "@types"; const DB_NAME = "TurnkeyStamperDB"; const DB_STORE = "KeyStore"; @@ -57,7 +58,7 @@ function toUnsignedBigNum(bytes: Uint8Array): Uint8Array { return res; } -export class IndexedDbStamper implements StamperBase { +export class IndexedDbStamper implements ApiKeyStamperBase { constructor() { if (typeof window === "undefined") { throw new Error("IndexedDB is only available in the browser"); @@ -203,10 +204,7 @@ export class IndexedDbStamper implements StamperBase { return uint8ArrayToHexString(signatureDer); } - async stamp( - payload: string, - publicKeyHex: string, - ): Promise<{ stampHeaderName: string; stampHeaderValue: string }> { + async stamp(payload: string, publicKeyHex: string): Promise { const signature = await this.sign(payload, publicKeyHex); const stamp = { publicKey: publicKeyHex, diff --git a/packages/sdk-js/src/__stampers__/passkey/base.ts b/packages/sdk-js/src/__stampers__/passkey/base.ts new file mode 100644 index 000000000..516e872da --- /dev/null +++ b/packages/sdk-js/src/__stampers__/passkey/base.ts @@ -0,0 +1,193 @@ +import { + base64UrlEncode, + generateRandomBuffer, + isReactNative, + isWeb, +} from "@utils"; +import { Passkey, TStamp, TStamper } from "@types"; +import { WebauthnStamper } from "@turnkey/webauthn-stamper"; +import { uint8ArrayToHexString } from "@turnkey/encoding"; +import { getWebAuthnAttestation, TurnkeyApiTypes } from "@turnkey/http"; +import { v4 as uuidv4 } from "uuid"; + +let PasskeyStamperModule: typeof import("@turnkey/react-native-passkey-stamper"); + +// TODO (Amir) This would be nice in sdk-types +export type TPasskeyStamperConfig = { + // The RPID ("Relying Party ID") for your app. This is automatically determined in web environments based on the current hostname. + // See https://github.com/f-23/react-native-passkey?tab=readme-ov-file#configuration to set this up for react-native. + rpId: string; + + // Optional timeout value in milliseconds. Defaults to 5 minutes. + timeout?: number; + + // Optional override for UV flag. Defaults to "preferred". + userVerification?: UserVerificationRequirement; + + // Optional list of credentials to pass. Defaults to empty. + allowCredentials?: PublicKeyCredentialDescriptor[]; + + // The below options do not exist in the WebauthnStamper: + + // Optional name for the Relying Party (RP). This is used in the passkey creation flow on mobile. + rpName?: string; + + // Option to force security passkeys on native platforms + withSecurityKey?: boolean; + + // Option to force platform passkeys on native platforms + withPlatformKey?: boolean; + + // Optional extensions. Defaults to empty. + extensions?: Record; +}; + +export type TurnkeyAuthenticatorParams = + TurnkeyApiTypes["v1AuthenticatorParamsV2"]; + +export class CrossPlatformPasskeyStamper implements TStamper { + private stamper!: TStamper; + private config: TPasskeyStamperConfig; + + constructor(config: TPasskeyStamperConfig) { + // Use init method to set up the stamper based on the platform. It's async, so can't be done in the constructor. + this.config = config; + } + + async init(): Promise { + if (isWeb()) { + const { default: WindowWrapper } = await import("@polyfills/window"); // TODO (Amir): Why did I do this? + this.stamper = new WebauthnStamper({ + ...this.config, + rpId: this.config.rpId ?? WindowWrapper.location.hostname, + }); + } else if (isReactNative()) { + try { + // Dynamic import to prevent bundling the native module in web environments. + let PasskeyStamper; + try { + PasskeyStamperModule = require("@turnkey/react-native-passkey-stamper"); + PasskeyStamper = PasskeyStamperModule.PasskeyStamper; + } catch { + throw new Error( + "Please install react-native-passkeys and @turnkey/react-native-passkey-stamper in your app to use passkeys.", + ); + } + + this.stamper = new PasskeyStamper({ + ...this.config, + allowCredentials: this.config.allowCredentials?.map((cred) => ({ + id: uint8ArrayToHexString(cred.id as Uint8Array), + type: cred.type, + transports: cred.transports, + })) as any, + }); + } catch (error) { + throw new Error( + `Failed to load passkey stamper for react-native: ${error}`, + ); + } + } else { + throw new Error("Unsupported platform for passkey stamper"); + } + } + + async stamp(payload: string): Promise { + return await this.stamper.stamp(payload); + } + + /** + * Create a passkey for an end-user, taking care of various lower-level details. + * + * @returns {Promise} + */ + createWebPasskey = async ( + config: Record = {}, + ): Promise => { + const challenge = generateRandomBuffer(); + const encodedChallenge = base64UrlEncode(challenge); + const authenticatorUserId = generateRandomBuffer(); + + // WebAuthn credential options options can be found here: + // https://www.w3.org/TR/webauthn-2/#sctn-sample-registration + // + // All pubkey algorithms can be found here: https://www.iana.org/assignments/cose/cose.xhtml#algorithms + // Turnkey only supports ES256 (-7) and RS256 (-257) + // + // The pubkey type only supports one value, "public-key" + // See https://www.w3.org/TR/webauthn-2/#enumdef-publickeycredentialtype for more details + // TODO: consider un-nesting these config params + const webauthnConfig: CredentialCreationOptions = { + publicKey: { + rp: { + id: config.publicKey?.rp?.id ?? this.config.rpId, + name: config.publicKey?.rp?.name ?? "", + }, + challenge: config.publicKey?.challenge ?? challenge, + pubKeyCredParams: config.publicKey?.pubKeyCredParams ?? [ + { + type: "public-key", + alg: -7, + }, + { + type: "public-key", + alg: -257, + }, + ], + user: { + id: config.publicKey?.user?.id ?? authenticatorUserId, + name: config.publicKey?.user?.name ?? "Default User", + displayName: config.publicKey?.user?.displayName ?? "Default User", + }, + authenticatorSelection: { + authenticatorAttachment: + config.publicKey?.authenticatorSelection?.authenticatorAttachment ?? + undefined, // default to empty + requireResidentKey: + config.publicKey?.authenticatorSelection?.requireResidentKey ?? + true, + residentKey: + config.publicKey?.authenticatorSelection?.residentKey ?? "required", + userVerification: + config.publicKey?.authenticatorSelection?.userVerification ?? + "preferred", + }, + }, + }; + + const attestation = await getWebAuthnAttestation(webauthnConfig); + + return { + encodedChallenge: config.publicKey?.challenge + ? base64UrlEncode(config.publicKey?.challenge) + : encodedChallenge, + attestation, + }; + }; + + createReactNativePasskey = async ( + config: Record = {}, + ): Promise => { + const { name, displayName } = config; + const { createPasskey } = PasskeyStamperModule; + + if (!createPasskey) { + throw new Error( + "Ensure you have @turnkey/react-native-passkey-stamper installed and linked correctly. Are you not on React Native?", + ); + } + + return await createPasskey({ + rp: { + id: this.config.rpId, + name: this.config.rpName ?? "Turnkey", + }, + user: { + id: uuidv4(), + name, + displayName, + }, + authenticatorName: "End-User Passkey", + }); + }; +} diff --git a/packages/sdk-js/src/__types__/base.ts b/packages/sdk-js/src/__types__/base.ts index f656dc655..5fac1881b 100644 --- a/packages/sdk-js/src/__types__/base.ts +++ b/packages/sdk-js/src/__types__/base.ts @@ -145,6 +145,11 @@ export interface PasskeyClientParams { allowCredentials?: PublicKeyCredentialDescriptor[]; } +export interface CreatePasskeyParams { + name?: string; + displayName?: string; +} + export interface RefreshSessionParams { sessionType: SessionType; expirationSeconds?: string | undefined; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c4a92f00f..5d583910f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2171,6 +2171,9 @@ importers: '@turnkey/indexed-db-stamper': specifier: workspace:* version: link:../indexed-db-stamper + '@turnkey/react-native-passkey-stamper': + specifier: workspace:* + version: link:../react-native-passkey-stamper '@turnkey/sdk-types': specifier: workspace:* version: link:../sdk-types @@ -2195,6 +2198,9 @@ importers: react-native-keychain: specifier: ^8.1.0 || ^9.2.2 || ^10.0.0 version: 8.1.0 + uuid: + specifier: ^11.1.0 + version: 11.1.0 devDependencies: glob: specifier: ^8.0.3 @@ -12513,7 +12519,16 @@ packages: resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} engines: {node: '>= 0.4.0'} +<<<<<<< HEAD uuid@8.3.2: +======= + /uuid@11.1.0: + resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} + hasBin: true + dev: false + + /uuid@8.3.2: +>>>>>>> 9c374d1c (Cross platform passkey stamper) resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} hasBin: true From 69bf98d34837b03aa57eeb48ea038f5f477a8cf3 Mon Sep 17 00:00:00 2001 From: Ethan Konkolowicz Date: Thu, 12 Jun 2025 15:17:16 -0400 Subject: [PATCH 008/184] added swagger type gen to sdk-types --- packages/sdk-types/scripts/codegen.js | 152 + packages/sdk-types/src/__generated__/types.ts | 3054 +++++ .../src/__inputs__/public_api.swagger.json | 9880 +++++++++++++++++ .../src/__inputs__/public_api.types.ts | 4714 ++++++++ packages/sdk-types/src/index.ts | 1 + 5 files changed, 17801 insertions(+) create mode 100644 packages/sdk-types/scripts/codegen.js create mode 100644 packages/sdk-types/src/__generated__/types.ts create mode 100644 packages/sdk-types/src/__inputs__/public_api.swagger.json create mode 100644 packages/sdk-types/src/__inputs__/public_api.types.ts diff --git a/packages/sdk-types/scripts/codegen.js b/packages/sdk-types/scripts/codegen.js new file mode 100644 index 000000000..d96f9c968 --- /dev/null +++ b/packages/sdk-types/scripts/codegen.js @@ -0,0 +1,152 @@ +const fs = require("fs"); +const path = require("path"); + +// Paths +const swaggerPath = path.resolve( + __dirname, + "../src/__inputs__/public_api.swagger.json", +); +const typesPath = path.resolve( + __dirname, + "../src/__inputs__/public_api.types.ts", +); +const outputPath = path.resolve(__dirname, "../src/__generated__/types.ts"); + +// Helper: Convert Swagger type to TS type +/** + * @param {string} type + * @param {object} schema + * @returns {string} + */ +function swaggerTypeToTs(type, schema) { + if (type === "integer" || type === "number") return "number"; + if (type === "boolean") return "boolean"; + if (type === "string") return "string"; + if (type === "array") { + if (schema.items) { + if (schema.items.$ref) { + return refToTs(schema.items.$ref) + "[]"; + } else if (schema.items.type) { + return swaggerTypeToTs(schema.items.type, schema.items) + "[]"; + } + } + return "any[]"; + } + if (type === "object") { + if (schema?.properties) return "{ [key: string]: any }"; + return "Record"; + } + return "any"; +} + +/** + * @param {string} name + * @returns {string} + */ +function stripVersionPrefix(name) { + return name.replace(/^v\d+/, ""); +} + +/** + * @param {string} ref + * @returns {string} + */ +function refToTs(ref) { + // "#/definitions/v1GetAuthenticatorRequest" -> "GetAuthenticatorRequest" + return stripVersionPrefix(ref.replace(/^#\/definitions\//, "")); +} + +/** + * @param {string} name + * @returns {boolean} + */ +function isValidIdentifier(name) { + return /^[$A-Z_][0-9A-Z_$]*$/i.test(name); +} + +/** + * @param {string} name + * @param {object} def + * @returns {string} + */ +function generateTsType(name, def) { + const cleanName = stripVersionPrefix(name); + if ( + def.type === "object" && + (def.properties || def.additionalProperties !== undefined) + ) { + let out = `export type ${cleanName} = {\n`; + if (def.properties) { + for (const [prop, schema] of Object.entries(def.properties)) { + const required = def.required && def.required.includes(prop) ? "" : "?"; + let type = "any"; + if (schema.$ref) { + type = refToTs(schema.$ref); + } else if (schema.type) { + type = swaggerTypeToTs(schema.type, schema); + } + const desc = schema.description + ? ` /** ${schema.description} */\n` + : ""; + // Quote property if not a valid identifier + const propName = isValidIdentifier(prop) ? prop : `"${prop}"`; + out += `${desc} ${propName}${required}: ${type};\n`; + } + } + // If additionalProperties is present, allow arbitrary keys + if (def.additionalProperties !== undefined) { + out += ` [key: string]: any;\n`; + } + out += "};\n"; + return out; + } + // enums + if (def.type === "string" && def.enum) { + return `export type ${cleanName} =\n ${def.enum.map((e) => `"${e}"`).join(" |\n ")};\n`; + } + // fallback + return `export type ${cleanName} = any;\n`; +} + +function main() { + // 1. Load files + const swagger = JSON.parse(fs.readFileSync(swaggerPath, "utf8")); + const typesSrc = fs.readFileSync(typesPath, "utf8"); + + // 2. Extract type definitions from types file (very basic, just for demo) + const typeDefRegex = /export type (\w+) = ([^;]+);/g; + const interfaceDefRegex = /export type (\w+) = {([^}]+)}/g; + + let match; + const typeDefs = {}; + while ((match = typeDefRegex.exec(typesSrc))) { + typeDefs[match[1]] = match[2].trim(); + } + while ((match = interfaceDefRegex.exec(typesSrc))) { + typeDefs[match[1]] = `{${match[2]}}`; + } + + // 3. Generate base types from swagger definitions + let output = `// AUTO-GENERATED FILE. DO NOT EDIT.\n// Generated by codegen.js\n\n`; + + // --- Base Types --- + output += `// --- Base Types from Swagger Definitions ---\n`; + for (const [defName, def] of Object.entries(swagger.definitions)) { + // Only parse object and enum types + if ( + (def.type === "object" && def.properties) || + (def.type === "string" && def.enum) + ) { + output += generateTsType(defName, def) + "\n"; + } else { + output += `export type ${stripVersionPrefix(defName)} = any;\n`; + } + } + + // 5. Write output + fs.writeFileSync(outputPath, output); + + console.log(`Nice types generated at ${outputPath}`); +} + +main(); diff --git a/packages/sdk-types/src/__generated__/types.ts b/packages/sdk-types/src/__generated__/types.ts new file mode 100644 index 000000000..c20359b01 --- /dev/null +++ b/packages/sdk-types/src/__generated__/types.ts @@ -0,0 +1,3054 @@ +// AUTO-GENERATED FILE. DO NOT EDIT. +// Generated by codegen.js + +// --- Base Types from Swagger Definitions --- +export type apiApiKeyParams = { + /** Human-readable name for an API Key. */ + apiKeyName: string; + /** The public component of a cryptographic key pair used to sign messages and transactions. */ + publicKey: string; + /** Optional window (in seconds) indicating how long the API Key should last. */ + expirationSeconds?: string; +}; + +export type billingActivateBillingTierIntent = { + /** The product that the customer wants to subscribe to. */ + productId: string; +}; + +export type billingActivateBillingTierResult = { + /** The id of the product being subscribed to. */ + productId: string; +}; + +export type billingDeletePaymentMethodIntent = { + /** The payment method that the customer wants to remove. */ + paymentMethodId: string; +}; + +export type billingDeletePaymentMethodResult = { + /** The payment method that was removed. */ + paymentMethodId: string; +}; + +export type billingSetPaymentMethodIntent = { + /** The account number of the customer's credit card. */ + number: string; + /** The verification digits of the customer's credit card. */ + cvv: string; + /** The month that the credit card expires. */ + expiryMonth: string; + /** The year that the credit card expires. */ + expiryYear: string; + /** The email that will receive invoices for the credit card. */ + cardHolderEmail: string; + /** The name associated with the credit card. */ + cardHolderName: string; +}; + +export type billingSetPaymentMethodIntentV2 = { + /** The id of the payment method that was created clientside. */ + paymentMethodId: string; + /** The email that will receive invoices for the credit card. */ + cardHolderEmail: string; + /** The name associated with the credit card. */ + cardHolderName: string; +}; + +export type billingSetPaymentMethodResult = { + /** The last four digits of the credit card added. */ + lastFour: string; + /** The name associated with the payment method. */ + cardHolderName: string; + /** The email address associated with the payment method. */ + cardHolderEmail: string; +}; + +export type datav1Tag = { + /** Unique identifier for a given Tag. */ + tagId: string; + /** Human-readable name for a Tag. */ + tagName: string; + tagType: TagType; + createdAt: externaldatav1Timestamp; + updatedAt: externaldatav1Timestamp; +}; + +export type externaldatav1Address = { + format?: AddressFormat; + address?: string; +}; + +export type externaldatav1Credential = { + /** The public component of a cryptographic key pair used to sign messages and transactions. */ + publicKey: string; + type: CredentialType; +}; + +export type externaldatav1Quorum = { + /** Count of unique approvals required to meet quorum. */ + threshold: number; + /** Unique identifiers of quorum set members. */ + userIds: string[]; +}; + +export type externaldatav1Timestamp = { + seconds: string; + nanos: string; +}; + +export type immutableactivityv1Address = { + format?: AddressFormat; + address?: string; +}; + +export type protobufAny = { + "@type"?: string; + [key: string]: any; +}; + +export type rpcStatus = { + code?: number; + message?: string; + details?: protobufAny[]; +}; + +export type AcceptInvitationIntent = { + /** Unique identifier for a given Invitation object. */ + invitationId: string; + /** Unique identifier for a given User. */ + userId: string; + /** WebAuthN hardware devices that can be used to log in to the Turnkey web app. */ + authenticator: AuthenticatorParams; +}; + +export type AcceptInvitationIntentV2 = { + /** Unique identifier for a given Invitation object. */ + invitationId: string; + /** Unique identifier for a given User. */ + userId: string; + /** WebAuthN hardware devices that can be used to log in to the Turnkey web app. */ + authenticator: AuthenticatorParamsV2; +}; + +export type AcceptInvitationResult = { + /** Unique identifier for a given Invitation. */ + invitationId: string; + /** Unique identifier for a given User. */ + userId: string; +}; + +export type AccessType = + | "ACCESS_TYPE_WEB" + | "ACCESS_TYPE_API" + | "ACCESS_TYPE_ALL"; + +export type Activity = { + /** Unique identifier for a given Activity object. */ + id: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + /** The current processing status of a specified Activity. */ + status: ActivityStatus; + /** Type of Activity, such as Add User, or Sign Transaction. */ + type: ActivityType; + /** Intent object crafted by Turnkey based on the user request, used to assess the permissibility of an action. */ + intent: Intent; + /** Result of the intended action. */ + result: Result; + /** A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. */ + votes: Vote[]; + /** An artifact verifying a User's action. */ + fingerprint: string; + canApprove: boolean; + canReject: boolean; + createdAt: externaldatav1Timestamp; + updatedAt: externaldatav1Timestamp; + /** Failure reason of the intended action. */ + failure?: rpcStatus; +}; + +export type ActivityResponse = { + /** An action that can that can be taken within the Turnkey infrastructure. */ + activity: Activity; +}; + +export type ActivityStatus = + | "ACTIVITY_STATUS_CREATED" + | "ACTIVITY_STATUS_PENDING" + | "ACTIVITY_STATUS_COMPLETED" + | "ACTIVITY_STATUS_FAILED" + | "ACTIVITY_STATUS_CONSENSUS_NEEDED" + | "ACTIVITY_STATUS_REJECTED"; + +export type ActivityType = + | "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"; + +export type AddressFormat = + | "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"; + +export type ApiKey = { + /** A User credential that can be used to authenticate to Turnkey. */ + credential: externaldatav1Credential; + /** Unique identifier for a given API Key. */ + apiKeyId: string; + /** Human-readable name for an API Key. */ + apiKeyName: string; + createdAt: externaldatav1Timestamp; + updatedAt: externaldatav1Timestamp; + /** Optional window (in seconds) indicating how long the API Key should last. */ + expirationSeconds?: string; +}; + +export type ApiKeyCurve = + | "API_KEY_CURVE_P256" + | "API_KEY_CURVE_SECP256K1" + | "API_KEY_CURVE_ED25519"; + +export type ApiKeyParamsV2 = { + /** Human-readable name for an API Key. */ + apiKeyName: string; + /** The public component of a cryptographic key pair used to sign messages and transactions. */ + publicKey: string; + /** The curve type to be used for processing API key signatures. */ + curveType: ApiKeyCurve; + /** Optional window (in seconds) indicating how long the API Key should last. */ + expirationSeconds?: string; +}; + +export type ApiOnlyUserParams = { + /** The name of the new API-only User. */ + userName: string; + /** The email address for this API-only User (optional). */ + userEmail?: string; + /** A list of tags assigned to the new API-only User. This field, if not needed, should be an empty array in your request body. */ + userTags: string[]; + /** A list of API Key parameters. This field, if not needed, should be an empty array in your request body. */ + apiKeys: apiApiKeyParams[]; +}; + +export type ApproveActivityIntent = { + /** An artifact verifying a User's action. */ + fingerprint: string; +}; + +export type ApproveActivityRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: ApproveActivityIntent; +}; + +export type Attestation = { + /** The cbor encoded then base64 url encoded id of the credential. */ + credentialId: string; + /** A base64 url encoded payload containing metadata about the signing context and the challenge. */ + clientDataJson: string; + /** A base64 url encoded payload containing authenticator data and any attestation the webauthn provider chooses. */ + attestationObject: string; + /** The type of authenticator transports. */ + transports: AuthenticatorTransport[]; +}; + +export type Authenticator = { + /** Types of transports that may be used by an Authenticator (e.g., USB, NFC, BLE). */ + transports: AuthenticatorTransport[]; + attestationType: string; + /** Identifier indicating the type of the Security Key. */ + aaguid: string; + /** Unique identifier for a WebAuthn credential. */ + credentialId: string; + /** The type of Authenticator device. */ + model: string; + /** A User credential that can be used to authenticate to Turnkey. */ + credential: externaldatav1Credential; + /** Unique identifier for a given Authenticator. */ + authenticatorId: string; + /** Human-readable name for an Authenticator. */ + authenticatorName: string; + createdAt: externaldatav1Timestamp; + updatedAt: externaldatav1Timestamp; +}; + +export type AuthenticatorAttestationResponse = { + clientDataJson: string; + attestationObject: string; + transports?: AuthenticatorTransport[]; + authenticatorAttachment?: string; +}; + +export type AuthenticatorParams = { + /** Human-readable name for an Authenticator. */ + authenticatorName: string; + /** Unique identifier for a given User. */ + userId: string; + attestation: PublicKeyCredentialWithAttestation; + /** Challenge presented for authentication purposes. */ + challenge: string; +}; + +export type AuthenticatorParamsV2 = { + /** Human-readable name for an Authenticator. */ + authenticatorName: string; + /** Challenge presented for authentication purposes. */ + challenge: string; + /** The attestation that proves custody of the authenticator and provides metadata about it. */ + attestation: Attestation; +}; + +export type AuthenticatorTransport = + | "AUTHENTICATOR_TRANSPORT_BLE" + | "AUTHENTICATOR_TRANSPORT_INTERNAL" + | "AUTHENTICATOR_TRANSPORT_NFC" + | "AUTHENTICATOR_TRANSPORT_USB" + | "AUTHENTICATOR_TRANSPORT_HYBRID"; + +export type Config = { + features?: Feature[]; + quorum?: externaldatav1Quorum; +}; + +export type CreateApiKeysIntent = { + /** A list of API Keys. */ + apiKeys: apiApiKeyParams[]; + /** Unique identifier for a given User. */ + userId: string; +}; + +export type CreateApiKeysIntentV2 = { + /** A list of API Keys. */ + apiKeys: ApiKeyParamsV2[]; + /** Unique identifier for a given User. */ + userId: string; +}; + +export type CreateApiKeysRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: CreateApiKeysIntentV2; +}; + +export type CreateApiKeysResult = { + /** A list of API Key IDs. */ + apiKeyIds: string[]; +}; + +export type CreateApiOnlyUsersIntent = { + /** A list of API-only Users to create. */ + apiOnlyUsers: ApiOnlyUserParams[]; +}; + +export type CreateApiOnlyUsersRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: CreateApiOnlyUsersIntent; +}; + +export type CreateApiOnlyUsersResult = { + /** A list of API-only User IDs. */ + userIds: string[]; +}; + +export type CreateAuthenticatorsIntent = { + /** A list of Authenticators. */ + authenticators: AuthenticatorParams[]; + /** Unique identifier for a given User. */ + userId: string; +}; + +export type CreateAuthenticatorsIntentV2 = { + /** A list of Authenticators. */ + authenticators: AuthenticatorParamsV2[]; + /** Unique identifier for a given User. */ + userId: string; +}; + +export type CreateAuthenticatorsRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: CreateAuthenticatorsIntentV2; +}; + +export type CreateAuthenticatorsResult = { + /** A list of Authenticator IDs. */ + authenticatorIds: string[]; +}; + +export type CreateInvitationsIntent = { + /** A list of Invitations. */ + invitations: InvitationParams[]; +}; + +export type CreateInvitationsRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: CreateInvitationsIntent; +}; + +export type CreateInvitationsResult = { + /** A list of Invitation IDs */ + invitationIds: string[]; +}; + +export type CreateOauthProvidersIntent = { + /** The ID of the User to add an Oauth provider to */ + userId: string; + /** A list of Oauth providers. */ + oauthProviders: OauthProviderParams[]; +}; + +export type CreateOauthProvidersRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: CreateOauthProvidersIntent; +}; + +export type CreateOauthProvidersResult = { + /** A list of unique identifiers for Oauth Providers */ + providerIds: string[]; +}; + +export type CreateOrganizationIntent = { + /** Human-readable name for an Organization. */ + organizationName: string; + /** The root user's email address. */ + rootEmail: string; + /** The root user's Authenticator. */ + rootAuthenticator: AuthenticatorParams; + /** Unique identifier for the root user object. */ + rootUserId?: string; +}; + +export type CreateOrganizationIntentV2 = { + /** Human-readable name for an Organization. */ + organizationName: string; + /** The root user's email address. */ + rootEmail: string; + /** The root user's Authenticator. */ + rootAuthenticator: AuthenticatorParamsV2; + /** Unique identifier for the root user object. */ + rootUserId?: string; +}; + +export type CreateOrganizationResult = { + /** Unique identifier for a given Organization. */ + organizationId: string; +}; + +export type CreatePoliciesIntent = { + /** An array of policy intents to be created. */ + policies: CreatePolicyIntentV3[]; +}; + +export type CreatePoliciesRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: CreatePoliciesIntent; +}; + +export type CreatePoliciesResult = { + /** A list of unique identifiers for the created policies. */ + policyIds: string[]; +}; + +export type CreatePolicyIntent = { + /** Human-readable name for a Policy. */ + policyName: string; + /** A list of simple functions each including a subject, target and boolean. See Policy Engine Language section for additional details. */ + selectors: Selector[]; + /** The instruction to DENY or ALLOW a particular activity following policy selector(s). */ + effect: Effect; + notes?: string; +}; + +export type CreatePolicyIntentV2 = { + /** Human-readable name for a Policy. */ + policyName: string; + /** A list of simple functions each including a subject, target and boolean. See Policy Engine Language section for additional details. */ + selectors: SelectorV2[]; + /** Whether to ALLOW or DENY requests that match the condition and consensus requirements. */ + effect: Effect; + notes?: string; +}; + +export type CreatePolicyIntentV3 = { + /** Human-readable name for a Policy. */ + policyName: string; + /** The instruction to DENY or ALLOW an activity. */ + effect: Effect; + /** The condition expression that triggers the Effect */ + condition?: string; + /** The consensus expression that triggers the Effect */ + consensus?: string; + notes?: string; +}; + +export type CreatePolicyRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: CreatePolicyIntentV3; +}; + +export type CreatePolicyResult = { + /** Unique identifier for a given Policy. */ + policyId: string; +}; + +export type CreatePrivateKeyTagIntent = { + /** Human-readable name for a Private Key Tag. */ + privateKeyTagName: string; + /** A list of Private Key IDs. */ + privateKeyIds: string[]; +}; + +export type CreatePrivateKeyTagRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: CreatePrivateKeyTagIntent; +}; + +export type CreatePrivateKeyTagResult = { + /** Unique identifier for a given Private Key Tag. */ + privateKeyTagId: string; + /** A list of Private Key IDs. */ + privateKeyIds: string[]; +}; + +export type CreatePrivateKeysIntent = { + /** A list of Private Keys. */ + privateKeys: PrivateKeyParams[]; +}; + +export type CreatePrivateKeysIntentV2 = { + /** A list of Private Keys. */ + privateKeys: PrivateKeyParams[]; +}; + +export type CreatePrivateKeysRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: CreatePrivateKeysIntentV2; +}; + +export type CreatePrivateKeysResult = { + /** A list of Private Key IDs. */ + privateKeyIds: string[]; +}; + +export type CreatePrivateKeysResultV2 = { + /** A list of Private Key IDs and addresses. */ + privateKeys: PrivateKeyResult[]; +}; + +export type CreateReadOnlySessionIntent = any; +export type CreateReadOnlySessionRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: CreateReadOnlySessionIntent; +}; + +export type CreateReadOnlySessionResult = { + /** Unique identifier for a given Organization. If the request is being made by a user and their Sub-Organization ID is unknown, this can be the Parent Organization ID. However, using the Sub-Organization ID is preferred due to performance reasons. */ + organizationId: string; + /** Human-readable name for an Organization. */ + organizationName: string; + /** Unique identifier for a given User. */ + userId: string; + /** Human-readable name for a User. */ + username: string; + /** String representing a read only session */ + session: string; + /** UTC timestamp in seconds representing the expiry time for the read only session. */ + sessionExpiry: string; +}; + +export type CreateReadWriteSessionIntent = { + /** Client-side public key generated by the user, to which the read write session bundle (credentials) will be encrypted. */ + targetPublicKey: string; + /** Email of the user to create a read write session for */ + email: string; + /** Optional human-readable name for an API Key. If none provided, default to Read Write Session - */ + apiKeyName?: string; + /** Expiration window (in seconds) indicating how long the API key is valid for. If not provided, a default of 15 minutes will be used. */ + expirationSeconds?: string; +}; + +export type CreateReadWriteSessionIntentV2 = { + /** Client-side public key generated by the user, to which the read write session bundle (credentials) will be encrypted. */ + targetPublicKey: string; + /** Unique identifier for a given User. */ + userId?: string; + /** Optional human-readable name for an API Key. If none provided, default to Read Write Session - */ + apiKeyName?: string; + /** Expiration window (in seconds) indicating how long the API key is valid for. If not provided, a default of 15 minutes will be used. */ + expirationSeconds?: string; + /** Invalidate all other previously generated ReadWriteSession API keys */ + invalidateExisting?: boolean; +}; + +export type CreateReadWriteSessionRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: CreateReadWriteSessionIntentV2; +}; + +export type CreateReadWriteSessionResult = { + /** Unique identifier for a given Organization. If the request is being made by a user and their Sub-Organization ID is unknown, this can be the Parent Organization ID. However, using the Sub-Organization ID is preferred due to performance reasons. */ + organizationId: string; + /** Human-readable name for an Organization. */ + organizationName: string; + /** Unique identifier for a given User. */ + userId: string; + /** Human-readable name for a User. */ + username: string; + /** Unique identifier for the created API key. */ + apiKeyId: string; + /** HPKE encrypted credential bundle */ + credentialBundle: string; +}; + +export type CreateReadWriteSessionResultV2 = { + /** Unique identifier for a given Organization. If the request is being made by a user and their Sub-Organization ID is unknown, this can be the Parent Organization ID. However, using the Sub-Organization ID is preferred due to performance reasons. */ + organizationId: string; + /** Human-readable name for an Organization. */ + organizationName: string; + /** Unique identifier for a given User. */ + userId: string; + /** Human-readable name for a User. */ + username: string; + /** Unique identifier for the created API key. */ + apiKeyId: string; + /** HPKE encrypted credential bundle */ + credentialBundle: string; +}; + +export type CreateSubOrganizationIntent = { + /** Name for this sub-organization */ + name: string; + /** Root User authenticator for this new sub-organization */ + rootAuthenticator: AuthenticatorParamsV2; +}; + +export type CreateSubOrganizationIntentV2 = { + /** Name for this sub-organization */ + subOrganizationName: string; + /** Root users to create within this sub-organization */ + rootUsers: RootUserParams[]; + /** The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users */ + rootQuorumThreshold: number; +}; + +export type CreateSubOrganizationIntentV3 = { + /** Name for this sub-organization */ + subOrganizationName: string; + /** Root users to create within this sub-organization */ + rootUsers: RootUserParams[]; + /** The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users */ + rootQuorumThreshold: number; + /** A list of Private Keys. */ + privateKeys: PrivateKeyParams[]; +}; + +export type CreateSubOrganizationIntentV4 = { + /** Name for this sub-organization */ + subOrganizationName: string; + /** Root users to create within this sub-organization */ + rootUsers: RootUserParams[]; + /** The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users */ + rootQuorumThreshold: number; + /** The wallet to create for the sub-organization */ + wallet?: WalletParams; + /** Disable email recovery for the sub-organization */ + disableEmailRecovery?: boolean; + /** Disable email auth for the sub-organization */ + disableEmailAuth?: boolean; +}; + +export type CreateSubOrganizationIntentV5 = { + /** Name for this sub-organization */ + subOrganizationName: string; + /** Root users to create within this sub-organization */ + rootUsers: RootUserParamsV2[]; + /** The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users */ + rootQuorumThreshold: number; + /** The wallet to create for the sub-organization */ + wallet?: WalletParams; + /** Disable email recovery for the sub-organization */ + disableEmailRecovery?: boolean; + /** Disable email auth for the sub-organization */ + disableEmailAuth?: boolean; +}; + +export type CreateSubOrganizationIntentV6 = { + /** Name for this sub-organization */ + subOrganizationName: string; + /** Root users to create within this sub-organization */ + rootUsers: RootUserParamsV3[]; + /** The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users */ + rootQuorumThreshold: number; + /** The wallet to create for the sub-organization */ + wallet?: WalletParams; + /** Disable email recovery for the sub-organization */ + disableEmailRecovery?: boolean; + /** Disable email auth for the sub-organization */ + disableEmailAuth?: boolean; +}; + +export type CreateSubOrganizationIntentV7 = { + /** Name for this sub-organization */ + subOrganizationName: string; + /** Root users to create within this sub-organization */ + rootUsers: RootUserParamsV4[]; + /** The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users */ + rootQuorumThreshold: number; + /** The wallet to create for the sub-organization */ + wallet?: WalletParams; + /** Disable email recovery for the sub-organization */ + disableEmailRecovery?: boolean; + /** Disable email auth for the sub-organization */ + disableEmailAuth?: boolean; + /** Disable OTP SMS auth for the sub-organization */ + disableSmsAuth?: boolean; + /** Disable OTP email auth for the sub-organization */ + disableOtpEmailAuth?: boolean; +}; + +export type CreateSubOrganizationRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: CreateSubOrganizationIntentV7; +}; + +export type CreateSubOrganizationResult = { + subOrganizationId: string; + rootUserIds?: string[]; +}; + +export type CreateSubOrganizationResultV3 = { + subOrganizationId: string; + /** A list of Private Key IDs and addresses. */ + privateKeys: PrivateKeyResult[]; + rootUserIds?: string[]; +}; + +export type CreateSubOrganizationResultV4 = { + subOrganizationId: string; + wallet?: WalletResult; + rootUserIds?: string[]; +}; + +export type CreateSubOrganizationResultV5 = { + subOrganizationId: string; + wallet?: WalletResult; + rootUserIds?: string[]; +}; + +export type CreateSubOrganizationResultV6 = { + subOrganizationId: string; + wallet?: WalletResult; + rootUserIds?: string[]; +}; + +export type CreateSubOrganizationResultV7 = { + subOrganizationId: string; + wallet?: WalletResult; + rootUserIds?: string[]; +}; + +export type CreateUserTagIntent = { + /** Human-readable name for a User Tag. */ + userTagName: string; + /** A list of User IDs. */ + userIds: string[]; +}; + +export type CreateUserTagRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: CreateUserTagIntent; +}; + +export type CreateUserTagResult = { + /** Unique identifier for a given User Tag. */ + userTagId: string; + /** A list of User IDs. */ + userIds: string[]; +}; + +export type CreateUsersIntent = { + /** A list of Users. */ + users: UserParams[]; +}; + +export type CreateUsersIntentV2 = { + /** A list of Users. */ + users: UserParamsV2[]; +}; + +export type CreateUsersIntentV3 = { + /** A list of Users. */ + users: UserParamsV3[]; +}; + +export type CreateUsersRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: CreateUsersIntentV3; +}; + +export type CreateUsersResult = { + /** A list of User IDs. */ + userIds: string[]; +}; + +export type CreateWalletAccountsIntent = { + /** Unique identifier for a given Wallet. */ + walletId: string; + /** A list of wallet Accounts. */ + accounts: WalletAccountParams[]; +}; + +export type CreateWalletAccountsRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: CreateWalletAccountsIntent; +}; + +export type CreateWalletAccountsResult = { + /** A list of derived addresses. */ + addresses: string[]; +}; + +export type CreateWalletIntent = { + /** Human-readable name for a Wallet. */ + walletName: string; + /** A list of wallet Accounts. This field, if not needed, should be an empty array in your request body. */ + accounts: WalletAccountParams[]; + /** Length of mnemonic to generate the Wallet seed. Defaults to 12. Accepted values: 12, 15, 18, 21, 24. */ + mnemonicLength?: number; +}; + +export type CreateWalletRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: CreateWalletIntent; +}; + +export type CreateWalletResult = { + /** Unique identifier for a Wallet. */ + walletId: string; + /** A list of account addresses. */ + addresses: string[]; +}; + +export type CredPropsAuthenticationExtensionsClientOutputs = { + rk: boolean; +}; + +export type CredentialType = + | "CREDENTIAL_TYPE_WEBAUTHN_AUTHENTICATOR" + | "CREDENTIAL_TYPE_API_KEY_P256" + | "CREDENTIAL_TYPE_RECOVER_USER_KEY_P256" + | "CREDENTIAL_TYPE_API_KEY_SECP256K1" + | "CREDENTIAL_TYPE_EMAIL_AUTH_KEY_P256" + | "CREDENTIAL_TYPE_API_KEY_ED25519" + | "CREDENTIAL_TYPE_OTP_AUTH_KEY_P256" + | "CREDENTIAL_TYPE_READ_WRITE_SESSION_KEY_P256" + | "CREDENTIAL_TYPE_OAUTH_KEY_P256" + | "CREDENTIAL_TYPE_LOGIN"; + +export type Curve = "CURVE_SECP256K1" | "CURVE_ED25519"; + +export type DeleteApiKeysIntent = { + /** Unique identifier for a given User. */ + userId: string; + /** A list of API Key IDs. */ + apiKeyIds: string[]; +}; + +export type DeleteApiKeysRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: DeleteApiKeysIntent; +}; + +export type DeleteApiKeysResult = { + /** A list of API Key IDs. */ + apiKeyIds: string[]; +}; + +export type DeleteAuthenticatorsIntent = { + /** Unique identifier for a given User. */ + userId: string; + /** A list of Authenticator IDs. */ + authenticatorIds: string[]; +}; + +export type DeleteAuthenticatorsRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: DeleteAuthenticatorsIntent; +}; + +export type DeleteAuthenticatorsResult = { + /** Unique identifier for a given Authenticator. */ + authenticatorIds: string[]; +}; + +export type DeleteInvitationIntent = { + /** Unique identifier for a given Invitation object. */ + invitationId: string; +}; + +export type DeleteInvitationRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: DeleteInvitationIntent; +}; + +export type DeleteInvitationResult = { + /** Unique identifier for a given Invitation. */ + invitationId: string; +}; + +export type DeleteOauthProvidersIntent = { + /** The ID of the User to remove an Oauth provider from */ + userId: string; + /** Unique identifier for a given Provider. */ + providerIds: string[]; +}; + +export type DeleteOauthProvidersRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: DeleteOauthProvidersIntent; +}; + +export type DeleteOauthProvidersResult = { + /** A list of unique identifiers for Oauth Providers */ + providerIds: string[]; +}; + +export type DeleteOrganizationIntent = { + /** Unique identifier for a given Organization. */ + organizationId: string; +}; + +export type DeleteOrganizationResult = { + /** Unique identifier for a given Organization. */ + organizationId: string; +}; + +export type DeletePolicyIntent = { + /** Unique identifier for a given Policy. */ + policyId: string; +}; + +export type DeletePolicyRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: DeletePolicyIntent; +}; + +export type DeletePolicyResult = { + /** Unique identifier for a given Policy. */ + policyId: string; +}; + +export type DeletePrivateKeyTagsIntent = { + /** A list of Private Key Tag IDs. */ + privateKeyTagIds: string[]; +}; + +export type DeletePrivateKeyTagsRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: DeletePrivateKeyTagsIntent; +}; + +export type DeletePrivateKeyTagsResult = { + /** A list of Private Key Tag IDs. */ + privateKeyTagIds: string[]; + /** A list of Private Key IDs. */ + privateKeyIds: string[]; +}; + +export type DeletePrivateKeysIntent = { + /** List of unique identifiers for private keys within an organization */ + privateKeyIds: string[]; + /** Optional parameter for deleting the private keys, even if any have not been previously exported. If they have been exported, this field is ignored. */ + deleteWithoutExport?: boolean; +}; + +export type DeletePrivateKeysRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: DeletePrivateKeysIntent; +}; + +export type DeletePrivateKeysResult = { + /** A list of private key unique identifiers that were removed */ + privateKeyIds: string[]; +}; + +export type DeleteSubOrganizationIntent = { + /** Sub-organization deletion, by default, requires associated wallets and private keys to be exported for security reasons. Set this boolean to true to force sub-organization deletion even if some wallets or private keys within it have not been exported yet. Default: false. */ + deleteWithoutExport?: boolean; +}; + +export type DeleteSubOrganizationRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: DeleteSubOrganizationIntent; +}; + +export type DeleteSubOrganizationResult = { + /** Unique identifier of the sub organization that was removed */ + subOrganizationUuid: string; +}; + +export type DeleteUserTagsIntent = { + /** A list of User Tag IDs. */ + userTagIds: string[]; +}; + +export type DeleteUserTagsRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: DeleteUserTagsIntent; +}; + +export type DeleteUserTagsResult = { + /** A list of User Tag IDs. */ + userTagIds: string[]; + /** A list of User IDs. */ + userIds: string[]; +}; + +export type DeleteUsersIntent = { + /** A list of User IDs. */ + userIds: string[]; +}; + +export type DeleteUsersRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: DeleteUsersIntent; +}; + +export type DeleteUsersResult = { + /** A list of User IDs. */ + userIds: string[]; +}; + +export type DeleteWalletsIntent = { + /** List of unique identifiers for wallets within an organization */ + walletIds: string[]; + /** Optional parameter for deleting the wallets, even if any have not been previously exported. If they have been exported, this field is ignored. */ + deleteWithoutExport?: boolean; +}; + +export type DeleteWalletsRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: DeleteWalletsIntent; +}; + +export type DeleteWalletsResult = { + /** A list of wallet unique identifiers that were removed */ + walletIds: string[]; +}; + +export type DisablePrivateKeyIntent = { + /** Unique identifier for a given Private Key. */ + privateKeyId: string; +}; + +export type DisablePrivateKeyResult = { + /** Unique identifier for a given Private Key. */ + privateKeyId: string; +}; + +export type Effect = "EFFECT_ALLOW" | "EFFECT_DENY"; + +export type EmailAuthIntent = { + /** Email of the authenticating user. */ + email: string; + /** Client-side public key generated by the user, to which the email auth bundle (credentials) will be encrypted. */ + targetPublicKey: string; + /** Optional human-readable name for an API Key. If none provided, default to Email Auth - */ + apiKeyName?: string; + /** Expiration window (in seconds) indicating how long the API key is valid for. If not provided, a default of 15 minutes will be used. */ + expirationSeconds?: string; + /** Optional parameters for customizing emails. If not provided, the default email will be used. */ + emailCustomization?: EmailCustomizationParams; + /** Invalidate all other previously generated Email Auth API keys */ + invalidateExisting?: boolean; + /** Optional custom email address from which to send the email */ + sendFromEmailAddress?: string; + /** Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications' */ + sendFromEmailSenderName?: string; + /** Optional custom email address to use as reply-to */ + replyToEmailAddress?: string; +}; + +export type EmailAuthIntentV2 = { + /** Email of the authenticating user. */ + email: string; + /** Client-side public key generated by the user, to which the email auth bundle (credentials) will be encrypted. */ + targetPublicKey: string; + /** Optional human-readable name for an API Key. If none provided, default to Email Auth - */ + apiKeyName?: string; + /** Expiration window (in seconds) indicating how long the API key is valid for. If not provided, a default of 15 minutes will be used. */ + expirationSeconds?: string; + /** Optional parameters for customizing emails. If not provided, the default email will be used. */ + emailCustomization?: EmailCustomizationParams; + /** Invalidate all other previously generated Email Auth API keys */ + invalidateExisting?: boolean; + /** Optional custom email address from which to send the email */ + sendFromEmailAddress?: string; + /** Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications' */ + sendFromEmailSenderName?: string; + /** Optional custom email address to use as reply-to */ + replyToEmailAddress?: string; +}; + +export type EmailAuthRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: EmailAuthIntentV2; +}; + +export type EmailAuthResult = { + /** Unique identifier for the authenticating User. */ + userId: string; + /** Unique identifier for the created API key. */ + apiKeyId: string; +}; + +export type EmailCustomizationParams = { + /** The name of the application. */ + appName?: string; + /** A URL pointing to a logo in PNG format. Note this logo will be resized to fit into 340px x 124px. */ + logoUrl?: string; + /** A template for the URL to be used in a magic link button, e.g. `https://dapp.xyz/%s`. The auth bundle will be interpolated into the `%s`. */ + magicLinkTemplate?: string; + /** JSON object containing key/value pairs to be used with custom templates. */ + templateVariables?: string; + /** Unique identifier for a given Email Template. If not specified, the default is the most recent Email Template. */ + templateId?: string; +}; + +export type ExportPrivateKeyIntent = { + /** Unique identifier for a given Private Key. */ + privateKeyId: string; + /** Client-side public key generated by the user, to which the export bundle will be encrypted. */ + targetPublicKey: string; +}; + +export type ExportPrivateKeyRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: ExportPrivateKeyIntent; +}; + +export type ExportPrivateKeyResult = { + /** Unique identifier for a given Private Key. */ + privateKeyId: string; + /** Export bundle containing a private key encrypted to the client's target public key. */ + exportBundle: string; +}; + +export type ExportWalletAccountIntent = { + /** Address to identify Wallet Account. */ + address: string; + /** Client-side public key generated by the user, to which the export bundle will be encrypted. */ + targetPublicKey: string; +}; + +export type ExportWalletAccountRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: ExportWalletAccountIntent; +}; + +export type ExportWalletAccountResult = { + /** Address to identify Wallet Account. */ + address: string; + /** Export bundle containing a private key encrypted by the client's target public key. */ + exportBundle: string; +}; + +export type ExportWalletIntent = { + /** Unique identifier for a given Wallet. */ + walletId: string; + /** Client-side public key generated by the user, to which the export bundle will be encrypted. */ + targetPublicKey: string; + /** The language of the mnemonic to export. Defaults to English. */ + language?: MnemonicLanguage; +}; + +export type ExportWalletRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: ExportWalletIntent; +}; + +export type ExportWalletResult = { + /** Unique identifier for a given Wallet. */ + walletId: string; + /** Export bundle containing a wallet mnemonic + optional newline passphrase encrypted by the client's target public key. */ + exportBundle: string; +}; + +export type Feature = { + name?: FeatureName; + value?: string; +}; + +export type FeatureName = + | "FEATURE_NAME_ROOT_USER_EMAIL_RECOVERY" + | "FEATURE_NAME_WEBAUTHN_ORIGINS" + | "FEATURE_NAME_EMAIL_AUTH" + | "FEATURE_NAME_EMAIL_RECOVERY" + | "FEATURE_NAME_WEBHOOK" + | "FEATURE_NAME_SMS_AUTH" + | "FEATURE_NAME_OTP_EMAIL_AUTH"; + +export type GetActivitiesRequest = { + /** Unique identifier for a given Organization. */ + organizationId: string; + /** Array of Activity Statuses filtering which Activities will be listed in the response. */ + filterByStatus?: ActivityStatus[]; + /** Parameters used for cursor-based pagination. */ + paginationOptions?: Pagination; + /** Array of Activity Types filtering which Activities will be listed in the response. */ + filterByType?: ActivityType[]; +}; + +export type GetActivitiesResponse = { + /** A list of Activities. */ + activities: Activity[]; +}; + +export type GetActivityRequest = { + /** Unique identifier for a given Organization. */ + organizationId: string; + /** Unique identifier for a given Activity object. */ + activityId: string; +}; + +export type GetApiKeyRequest = { + /** Unique identifier for a given Organization. */ + organizationId: string; + /** Unique identifier for a given API key. */ + apiKeyId: string; +}; + +export type GetApiKeyResponse = { + /** An API key. */ + apiKey: ApiKey; +}; + +export type GetApiKeysRequest = { + /** Unique identifier for a given Organization. */ + organizationId: string; + /** Unique identifier for a given User. */ + userId?: string; +}; + +export type GetApiKeysResponse = { + /** A list of API keys. */ + apiKeys: ApiKey[]; +}; + +export type GetAttestationDocumentRequest = { + /** Unique identifier for a given Organization. */ + organizationId: string; + /** The enclave type, one of: ump, notarizer, signer, evm-parser */ + enclaveType: string; +}; + +export type GetAttestationDocumentResponse = { + /** Raw (CBOR-encoded) attestation document */ + attestationDocument: string; +}; + +export type GetAuthenticatorRequest = { + /** Unique identifier for a given Organization. */ + organizationId: string; + /** Unique identifier for a given Authenticator. */ + authenticatorId: string; +}; + +export type GetAuthenticatorResponse = { + /** An authenticator. */ + authenticator: Authenticator; +}; + +export type GetAuthenticatorsRequest = { + /** Unique identifier for a given Organization. */ + organizationId: string; + /** Unique identifier for a given User. */ + userId: string; +}; + +export type GetAuthenticatorsResponse = { + /** A list of authenticators. */ + authenticators: Authenticator[]; +}; + +export type GetOauthProvidersRequest = { + /** Unique identifier for a given Organization. */ + organizationId: string; + /** Unique identifier for a given User. */ + userId?: string; +}; + +export type GetOauthProvidersResponse = { + /** A list of Oauth Providers */ + oauthProviders: OauthProvider[]; +}; + +export type GetOrganizationConfigsRequest = { + /** Unique identifier for a given Organization. */ + organizationId: string; +}; + +export type GetOrganizationConfigsResponse = { + /** Organization configs including quorum settings and organization features */ + configs: Config; +}; + +export type GetOrganizationRequest = { + /** Unique identifier for a given Organization. */ + organizationId: string; +}; + +export type GetOrganizationResponse = { + /** Object representing the full current and deleted / disabled collection of Users, Policies, Private Keys, and Invitations attributable to a particular Organization. */ + organizationData: OrganizationData; +}; + +export type GetPoliciesRequest = { + /** Unique identifier for a given Organization. */ + organizationId: string; +}; + +export type GetPoliciesResponse = { + /** A list of Policies. */ + policies: Policy[]; +}; + +export type GetPolicyRequest = { + /** Unique identifier for a given Organization. */ + organizationId: string; + /** Unique identifier for a given Policy. */ + policyId: string; +}; + +export type GetPolicyResponse = { + /** Object that codifies rules defining the actions that are permissible within an Organization. */ + policy: Policy; +}; + +export type GetPrivateKeyRequest = { + /** Unique identifier for a given Organization. */ + organizationId: string; + /** Unique identifier for a given Private Key. */ + privateKeyId: string; +}; + +export type GetPrivateKeyResponse = { + /** Cryptographic public/private key pair that can be used for cryptocurrency needs or more generalized encryption. */ + privateKey: PrivateKey; +}; + +export type GetPrivateKeysRequest = { + /** Unique identifier for a given Organization. */ + organizationId: string; +}; + +export type GetPrivateKeysResponse = { + /** A list of Private Keys. */ + privateKeys: PrivateKey[]; +}; + +export type GetSubOrgIdsRequest = { + /** Unique identifier for the parent Organization. This is used to find sub-organizations within it. */ + organizationId: string; + /** Specifies the type of filter to apply, i.e 'CREDENTIAL_ID', 'NAME', 'USERNAME', 'EMAIL', 'PHONE_NUMBER', 'OIDC_TOKEN' or 'PUBLIC_KEY' */ + filterType?: string; + /** The value of the filter to apply for the specified type. For example, a specific email or name string. */ + filterValue?: string; + /** Parameters used for cursor-based pagination. */ + paginationOptions?: Pagination; +}; + +export type GetSubOrgIdsResponse = { + /** List of unique identifiers for the matching sub-organizations. */ + organizationIds: string[]; +}; + +export type GetUserRequest = { + /** Unique identifier for a given Organization. */ + organizationId: string; + /** Unique identifier for a given User. */ + userId: string; +}; + +export type GetUserResponse = { + /** Web and/or API user within your Organization. */ + user: User; +}; + +export type GetUsersRequest = { + /** Unique identifier for a given Organization. */ + organizationId: string; +}; + +export type GetUsersResponse = { + /** A list of Users. */ + users: User[]; +}; + +export type GetVerifiedSubOrgIdsRequest = { + /** Unique identifier for the parent Organization. This is used to find sub-organizations within it. */ + organizationId: string; + /** Specifies the type of filter to apply, i.e 'EMAIL', 'PHONE_NUMBER' */ + filterType?: string; + /** The value of the filter to apply for the specified type. For example, a specific email or phone number string. */ + filterValue?: string; + /** Parameters used for cursor-based pagination. */ + paginationOptions?: Pagination; +}; + +export type GetVerifiedSubOrgIdsResponse = { + /** List of unique identifiers for the matching sub-organizations. */ + organizationIds: string[]; +}; + +export type GetWalletAccountRequest = { + /** Unique identifier for a given Organization. */ + organizationId: string; + /** Unique identifier for a given Wallet. */ + walletId: string; + /** Address corresponding to a Wallet Account. */ + address?: string; + /** Path corresponding to a Wallet Account. */ + path?: string; +}; + +export type GetWalletAccountResponse = { + /** The resulting Wallet Account. */ + account: WalletAccount; +}; + +export type GetWalletAccountsRequest = { + /** Unique identifier for a given Organization. */ + organizationId: string; + /** Unique identifier for a given Wallet. */ + walletId: string; + /** Parameters used for cursor-based pagination. */ + paginationOptions?: Pagination; +}; + +export type GetWalletAccountsResponse = { + /** A list of Accounts generated from a Wallet that share a common seed. */ + accounts: WalletAccount[]; +}; + +export type GetWalletRequest = { + /** Unique identifier for a given Organization. */ + organizationId: string; + /** Unique identifier for a given Wallet. */ + walletId: string; +}; + +export type GetWalletResponse = { + /** A collection of deterministically generated cryptographic public / private key pairs that share a common seed */ + wallet: Wallet; +}; + +export type GetWalletsRequest = { + /** Unique identifier for a given Organization. */ + organizationId: string; +}; + +export type GetWalletsResponse = { + /** A list of Wallets. */ + wallets: Wallet[]; +}; + +export type GetWhoamiRequest = { + /** 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. */ + organizationId: string; +}; + +export type GetWhoamiResponse = { + /** Unique identifier for a given Organization. */ + organizationId: string; + /** Human-readable name for an Organization. */ + organizationName: string; + /** Unique identifier for a given User. */ + userId: string; + /** Human-readable name for a User. */ + username: string; +}; + +export type HashFunction = + | "HASH_FUNCTION_NO_OP" + | "HASH_FUNCTION_SHA256" + | "HASH_FUNCTION_KECCAK256" + | "HASH_FUNCTION_NOT_APPLICABLE"; + +export type ImportPrivateKeyIntent = { + /** The ID of the User importing a Private Key. */ + userId: string; + /** Human-readable name for a Private Key. */ + privateKeyName: string; + /** Bundle containing a raw private key encrypted to the enclave's target public key. */ + encryptedBundle: string; + /** Cryptographic Curve used to generate a given Private Key. */ + curve: Curve; + /** Cryptocurrency-specific formats for a derived address (e.g., Ethereum). */ + addressFormats: AddressFormat[]; +}; + +export type ImportPrivateKeyRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: ImportPrivateKeyIntent; +}; + +export type ImportPrivateKeyResult = { + /** Unique identifier for a Private Key. */ + privateKeyId: string; + /** A list of addresses. */ + addresses: immutableactivityv1Address[]; +}; + +export type ImportWalletIntent = { + /** The ID of the User importing a Wallet. */ + userId: string; + /** Human-readable name for a Wallet. */ + walletName: string; + /** Bundle containing a wallet mnemonic encrypted to the enclave's target public key. */ + encryptedBundle: string; + /** A list of wallet Accounts. */ + accounts: WalletAccountParams[]; +}; + +export type ImportWalletRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: ImportWalletIntent; +}; + +export type ImportWalletResult = { + /** Unique identifier for a Wallet. */ + walletId: string; + /** A list of account addresses. */ + addresses: string[]; +}; + +export type InitImportPrivateKeyIntent = { + /** The ID of the User importing a Private Key. */ + userId: string; +}; + +export type InitImportPrivateKeyRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: InitImportPrivateKeyIntent; +}; + +export type InitImportPrivateKeyResult = { + /** Import bundle containing a public key and signature to use for importing client data. */ + importBundle: string; +}; + +export type InitImportWalletIntent = { + /** The ID of the User importing a Wallet. */ + userId: string; +}; + +export type InitImportWalletRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: InitImportWalletIntent; +}; + +export type InitImportWalletResult = { + /** Import bundle containing a public key and signature to use for importing client data. */ + importBundle: string; +}; + +export type InitOtpAuthIntent = { + /** Enum to specifiy whether to send OTP via SMS or email */ + otpType: string; + /** Email or phone number to send the OTP code to */ + contact: string; + /** Optional parameters for customizing emails. If not provided, the default email will be used. */ + emailCustomization?: EmailCustomizationParams; + /** Optional parameters for customizing SMS message. If not provided, the default sms message will be used. */ + smsCustomization?: SmsCustomizationParams; + /** 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. */ + userIdentifier?: string; + /** Optional custom email address from which to send the OTP email */ + sendFromEmailAddress?: string; + /** Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications' */ + sendFromEmailSenderName?: string; + /** Optional custom email address to use as reply-to */ + replyToEmailAddress?: string; +}; + +export type InitOtpAuthIntentV2 = { + /** Enum to specifiy whether to send OTP via SMS or email */ + otpType: string; + /** Email or phone number to send the OTP code to */ + contact: string; + /** Optional length of the OTP code. Default = 9 */ + otpLength?: number; + /** Optional parameters for customizing emails. If not provided, the default email will be used. */ + emailCustomization?: EmailCustomizationParams; + /** Optional parameters for customizing SMS message. If not provided, the default sms message will be used. */ + smsCustomization?: SmsCustomizationParams; + /** 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. */ + userIdentifier?: string; + /** Optional custom email address from which to send the OTP email */ + sendFromEmailAddress?: string; + /** Optional flag to specify if the OTP code should be alphanumeric (Crockford’s Base32). Default = true */ + alphanumeric?: boolean; + /** Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications' */ + sendFromEmailSenderName?: string; + /** Optional custom email address to use as reply-to */ + replyToEmailAddress?: string; +}; + +export type InitOtpAuthRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: InitOtpAuthIntentV2; +}; + +export type InitOtpAuthResult = { + /** Unique identifier for an OTP authentication */ + otpId: string; +}; + +export type InitOtpAuthResultV2 = { + /** Unique identifier for an OTP authentication */ + otpId: string; +}; + +export type InitOtpIntent = { + /** Whether to send OTP via SMS or email. Possible values: OTP_TYPE_SMS, OTP_TYPE_EMAIL */ + otpType: string; + /** Email or phone number to send the OTP code to */ + contact: string; + /** Optional length of the OTP code. Default = 9 */ + otpLength?: number; + /** Optional parameters for customizing emails. If not provided, the default email will be used. */ + emailCustomization?: EmailCustomizationParams; + /** Optional parameters for customizing SMS message. If not provided, the default sms message will be used. */ + smsCustomization?: SmsCustomizationParams; + /** 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. */ + userIdentifier?: string; + /** Optional custom email address from which to send the OTP email */ + sendFromEmailAddress?: string; + /** Optional flag to specify if the OTP code should be alphanumeric (Crockford’s Base32). Default = true */ + alphanumeric?: boolean; + /** Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications' */ + sendFromEmailSenderName?: string; + /** 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) */ + expirationSeconds?: string; + /** Optional custom email address to use as reply-to */ + replyToEmailAddress?: string; +}; + +export type InitOtpRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: InitOtpIntent; +}; + +export type InitOtpResult = { + /** Unique identifier for an OTP authentication */ + otpId: string; +}; + +export type InitUserEmailRecoveryIntent = { + /** Email of the user starting recovery */ + email: string; + /** Client-side public key generated by the user, to which the recovery bundle will be encrypted. */ + targetPublicKey: string; + /** Expiration window (in seconds) indicating how long the recovery credential is valid for. If not provided, a default of 15 minutes will be used. */ + expirationSeconds?: string; + /** Optional parameters for customizing emails. If not provided, the default email will be used. */ + emailCustomization?: EmailCustomizationParams; +}; + +export type InitUserEmailRecoveryRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: InitUserEmailRecoveryIntent; +}; + +export type InitUserEmailRecoveryResult = { + /** Unique identifier for the user being recovered. */ + userId: string; +}; + +export type Intent = { + createOrganizationIntent?: CreateOrganizationIntent; + createAuthenticatorsIntent?: CreateAuthenticatorsIntent; + createUsersIntent?: CreateUsersIntent; + createPrivateKeysIntent?: CreatePrivateKeysIntent; + signRawPayloadIntent?: SignRawPayloadIntent; + createInvitationsIntent?: CreateInvitationsIntent; + acceptInvitationIntent?: AcceptInvitationIntent; + createPolicyIntent?: CreatePolicyIntent; + disablePrivateKeyIntent?: DisablePrivateKeyIntent; + deleteUsersIntent?: DeleteUsersIntent; + deleteAuthenticatorsIntent?: DeleteAuthenticatorsIntent; + deleteInvitationIntent?: DeleteInvitationIntent; + deleteOrganizationIntent?: DeleteOrganizationIntent; + deletePolicyIntent?: DeletePolicyIntent; + createUserTagIntent?: CreateUserTagIntent; + deleteUserTagsIntent?: DeleteUserTagsIntent; + signTransactionIntent?: SignTransactionIntent; + createApiKeysIntent?: CreateApiKeysIntent; + deleteApiKeysIntent?: DeleteApiKeysIntent; + approveActivityIntent?: ApproveActivityIntent; + rejectActivityIntent?: RejectActivityIntent; + createPrivateKeyTagIntent?: CreatePrivateKeyTagIntent; + deletePrivateKeyTagsIntent?: DeletePrivateKeyTagsIntent; + createPolicyIntentV2?: CreatePolicyIntentV2; + setPaymentMethodIntent?: billingSetPaymentMethodIntent; + activateBillingTierIntent?: billingActivateBillingTierIntent; + deletePaymentMethodIntent?: billingDeletePaymentMethodIntent; + createPolicyIntentV3?: CreatePolicyIntentV3; + createApiOnlyUsersIntent?: CreateApiOnlyUsersIntent; + updateRootQuorumIntent?: UpdateRootQuorumIntent; + updateUserTagIntent?: UpdateUserTagIntent; + updatePrivateKeyTagIntent?: UpdatePrivateKeyTagIntent; + createAuthenticatorsIntentV2?: CreateAuthenticatorsIntentV2; + acceptInvitationIntentV2?: AcceptInvitationIntentV2; + createOrganizationIntentV2?: CreateOrganizationIntentV2; + createUsersIntentV2?: CreateUsersIntentV2; + createSubOrganizationIntent?: CreateSubOrganizationIntent; + createSubOrganizationIntentV2?: CreateSubOrganizationIntentV2; + updateAllowedOriginsIntent?: UpdateAllowedOriginsIntent; + createPrivateKeysIntentV2?: CreatePrivateKeysIntentV2; + updateUserIntent?: UpdateUserIntent; + updatePolicyIntent?: UpdatePolicyIntent; + setPaymentMethodIntentV2?: billingSetPaymentMethodIntentV2; + createSubOrganizationIntentV3?: CreateSubOrganizationIntentV3; + createWalletIntent?: CreateWalletIntent; + createWalletAccountsIntent?: CreateWalletAccountsIntent; + initUserEmailRecoveryIntent?: InitUserEmailRecoveryIntent; + recoverUserIntent?: RecoverUserIntent; + setOrganizationFeatureIntent?: SetOrganizationFeatureIntent; + removeOrganizationFeatureIntent?: RemoveOrganizationFeatureIntent; + signRawPayloadIntentV2?: SignRawPayloadIntentV2; + signTransactionIntentV2?: SignTransactionIntentV2; + exportPrivateKeyIntent?: ExportPrivateKeyIntent; + exportWalletIntent?: ExportWalletIntent; + createSubOrganizationIntentV4?: CreateSubOrganizationIntentV4; + emailAuthIntent?: EmailAuthIntent; + exportWalletAccountIntent?: ExportWalletAccountIntent; + initImportWalletIntent?: InitImportWalletIntent; + importWalletIntent?: ImportWalletIntent; + initImportPrivateKeyIntent?: InitImportPrivateKeyIntent; + importPrivateKeyIntent?: ImportPrivateKeyIntent; + createPoliciesIntent?: CreatePoliciesIntent; + signRawPayloadsIntent?: SignRawPayloadsIntent; + createReadOnlySessionIntent?: CreateReadOnlySessionIntent; + createOauthProvidersIntent?: CreateOauthProvidersIntent; + deleteOauthProvidersIntent?: DeleteOauthProvidersIntent; + createSubOrganizationIntentV5?: CreateSubOrganizationIntentV5; + oauthIntent?: OauthIntent; + createApiKeysIntentV2?: CreateApiKeysIntentV2; + createReadWriteSessionIntent?: CreateReadWriteSessionIntent; + emailAuthIntentV2?: EmailAuthIntentV2; + createSubOrganizationIntentV6?: CreateSubOrganizationIntentV6; + deletePrivateKeysIntent?: DeletePrivateKeysIntent; + deleteWalletsIntent?: DeleteWalletsIntent; + createReadWriteSessionIntentV2?: CreateReadWriteSessionIntentV2; + deleteSubOrganizationIntent?: DeleteSubOrganizationIntent; + initOtpAuthIntent?: InitOtpAuthIntent; + otpAuthIntent?: OtpAuthIntent; + createSubOrganizationIntentV7?: CreateSubOrganizationIntentV7; + updateWalletIntent?: UpdateWalletIntent; + updatePolicyIntentV2?: UpdatePolicyIntentV2; + createUsersIntentV3?: CreateUsersIntentV3; + initOtpAuthIntentV2?: InitOtpAuthIntentV2; + initOtpIntent?: InitOtpIntent; + verifyOtpIntent?: VerifyOtpIntent; + otpLoginIntent?: OtpLoginIntent; + stampLoginIntent?: StampLoginIntent; + oauthLoginIntent?: OauthLoginIntent; +}; + +export type Invitation = { + /** Unique identifier for a given Invitation object. */ + invitationId: string; + /** The name of the intended Invitation recipient. */ + receiverUserName: string; + /** The email address of the intended Invitation recipient. */ + receiverEmail: string; + /** A list of tags assigned to the Invitation recipient. */ + receiverUserTags: string[]; + /** The User's permissible access method(s). */ + accessType: AccessType; + /** The current processing status of a specified Invitation. */ + status: InvitationStatus; + createdAt: externaldatav1Timestamp; + updatedAt: externaldatav1Timestamp; + /** Unique identifier for the Sender of an Invitation. */ + senderUserId: string; +}; + +export type InvitationParams = { + /** The name of the intended Invitation recipient. */ + receiverUserName: string; + /** The email address of the intended Invitation recipient. */ + receiverUserEmail: string; + /** A list of tags assigned to the Invitation recipient. This field, if not needed, should be an empty array in your request body. */ + receiverUserTags: string[]; + /** The User's permissible access method(s). */ + accessType: AccessType; + /** Unique identifier for the Sender of an Invitation. */ + senderUserId: string; +}; + +export type InvitationStatus = + | "INVITATION_STATUS_CREATED" + | "INVITATION_STATUS_ACCEPTED" + | "INVITATION_STATUS_REVOKED"; + +export type ListPrivateKeyTagsRequest = { + /** Unique identifier for a given Organization. */ + organizationId: string; +}; + +export type ListPrivateKeyTagsResponse = { + /** A list of Private Key Tags */ + privateKeyTags: datav1Tag[]; +}; + +export type ListUserTagsRequest = { + /** Unique identifier for a given Organization. */ + organizationId: string; +}; + +export type ListUserTagsResponse = { + /** A list of User Tags */ + userTags: datav1Tag[]; +}; + +export type MnemonicLanguage = + | "MNEMONIC_LANGUAGE_ENGLISH" + | "MNEMONIC_LANGUAGE_SIMPLIFIED_CHINESE" + | "MNEMONIC_LANGUAGE_TRADITIONAL_CHINESE" + | "MNEMONIC_LANGUAGE_CZECH" + | "MNEMONIC_LANGUAGE_FRENCH" + | "MNEMONIC_LANGUAGE_ITALIAN" + | "MNEMONIC_LANGUAGE_JAPANESE" + | "MNEMONIC_LANGUAGE_KOREAN" + | "MNEMONIC_LANGUAGE_SPANISH"; + +export type NOOPCodegenAnchorResponse = { + stamp: WebAuthnStamp; +}; + +export type OauthIntent = { + /** Base64 encoded OIDC token */ + oidcToken: string; + /** Client-side public key generated by the user, to which the oauth bundle (credentials) will be encrypted. */ + targetPublicKey: string; + /** Optional human-readable name for an API Key. If none provided, default to Oauth - */ + apiKeyName?: string; + /** Expiration window (in seconds) indicating how long the API key is valid for. If not provided, a default of 15 minutes will be used. */ + expirationSeconds?: string; + /** Invalidate all other previously generated Oauth API keys */ + invalidateExisting?: boolean; +}; + +export type OauthLoginIntent = { + /** Base64 encoded OIDC token */ + oidcToken: string; + /** 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 */ + publicKey: string; + /** Expiration window (in seconds) indicating how long the Session is valid for. If not provided, a default of 15 minutes will be used. */ + expirationSeconds?: string; + /** Invalidate all other previously generated Login API keys */ + invalidateExisting?: boolean; +}; + +export type OauthLoginRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: OauthLoginIntent; +}; + +export type OauthLoginResult = { + /** Signed JWT containing an expiry, public key, session type, user id, and organization id */ + session: string; +}; + +export type OauthProvider = { + /** Unique identifier for an OAuth Provider */ + providerId: string; + /** Human-readable name to identify a Provider. */ + providerName: string; + /** The issuer of the token, typically a URL indicating the authentication server, e.g https://accounts.google.com */ + issuer: string; + /** Expected audience ('aud' attribute of the signed token) which represents the app ID */ + audience: string; + /** Expected subject ('sub' attribute of the signed token) which represents the user ID */ + subject: string; + createdAt: externaldatav1Timestamp; + updatedAt: externaldatav1Timestamp; +}; + +export type OauthProviderParams = { + /** Human-readable name to identify a Provider. */ + providerName: string; + /** Base64 encoded OIDC token */ + oidcToken: string; +}; + +export type OauthRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: OauthIntent; +}; + +export type OauthResult = { + /** Unique identifier for the authenticating User. */ + userId: string; + /** Unique identifier for the created API key. */ + apiKeyId: string; + /** HPKE encrypted credential bundle */ + credentialBundle: string; +}; + +export type Operator = + | "OPERATOR_EQUAL" + | "OPERATOR_MORE_THAN" + | "OPERATOR_MORE_THAN_OR_EQUAL" + | "OPERATOR_LESS_THAN" + | "OPERATOR_LESS_THAN_OR_EQUAL" + | "OPERATOR_CONTAINS" + | "OPERATOR_NOT_EQUAL" + | "OPERATOR_IN" + | "OPERATOR_NOT_IN" + | "OPERATOR_CONTAINS_ONE" + | "OPERATOR_CONTAINS_ALL"; + +export type OrganizationData = { + organizationId?: string; + name?: string; + users?: User[]; + policies?: Policy[]; + privateKeys?: PrivateKey[]; + invitations?: Invitation[]; + tags?: datav1Tag[]; + rootQuorum?: externaldatav1Quorum; + features?: Feature[]; + wallets?: Wallet[]; +}; + +export type OtpAuthIntent = { + /** ID representing the result of an init OTP activity. */ + otpId: string; + /** OTP sent out to a user's contact (email or SMS) */ + otpCode: string; + /** Client-side public key generated by the user, to which the OTP bundle (credentials) will be encrypted. */ + targetPublicKey: string; + /** Optional human-readable name for an API Key. If none provided, default to OTP Auth - */ + apiKeyName?: string; + /** Expiration window (in seconds) indicating how long the API key is valid for. If not provided, a default of 15 minutes will be used. */ + expirationSeconds?: string; + /** Invalidate all other previously generated OTP Auth API keys */ + invalidateExisting?: boolean; +}; + +export type OtpAuthRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: OtpAuthIntent; +}; + +export type OtpAuthResult = { + /** Unique identifier for the authenticating User. */ + userId: string; + /** Unique identifier for the created API key. */ + apiKeyId?: string; + /** HPKE encrypted credential bundle */ + credentialBundle?: string; +}; + +export type OtpLoginIntent = { + /** Signed JWT containing a unique id, expiry, verification type, contact */ + verificationToken: string; + /** Client-side public key generated by the user, which will be conditionally added to org data based on the validity of the verification token */ + publicKey: string; + /** Expiration window (in seconds) indicating how long the Session is valid for. If not provided, a default of 15 minutes will be used. */ + expirationSeconds?: string; + /** Invalidate all other previously generated Login API keys */ + invalidateExisting?: boolean; +}; + +export type OtpLoginRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: OtpLoginIntent; +}; + +export type OtpLoginResult = { + /** Signed JWT containing an expiry, public key, session type, user id, and organization id */ + session: string; +}; + +export type Pagination = { + /** A limit of the number of object to be returned, between 1 and 100. Defaults to 10. */ + limit?: string; + /** A pagination cursor. This is an object ID that enables you to fetch all objects before this ID. */ + before?: string; + /** A pagination cursor. This is an object ID that enables you to fetch all objects after this ID. */ + after?: string; +}; + +export type PathFormat = "PATH_FORMAT_BIP32"; + +export type PayloadEncoding = + | "PAYLOAD_ENCODING_HEXADECIMAL" + | "PAYLOAD_ENCODING_TEXT_UTF8"; + +export type Policy = { + /** Unique identifier for a given Policy. */ + policyId: string; + /** Human-readable name for a Policy. */ + policyName: string; + /** The instruction to DENY or ALLOW a particular activity following policy selector(s). */ + effect: Effect; + createdAt: externaldatav1Timestamp; + updatedAt: externaldatav1Timestamp; + /** Human-readable notes added by a User to describe a particular policy. */ + notes: string; + /** A consensus expression that evalutes to true or false. */ + consensus: string; + /** A condition expression that evalutes to true or false. */ + condition: string; +}; + +export type PrivateKey = { + /** Unique identifier for a given Private Key. */ + privateKeyId: string; + /** The public component of a cryptographic key pair used to sign messages and transactions. */ + publicKey: string; + /** Human-readable name for a Private Key. */ + privateKeyName: string; + /** Cryptographic Curve used to generate a given Private Key. */ + curve: Curve; + /** Derived cryptocurrency addresses for a given Private Key. */ + addresses: externaldatav1Address[]; + /** A list of Private Key Tag IDs. */ + privateKeyTags: string[]; + createdAt: externaldatav1Timestamp; + updatedAt: externaldatav1Timestamp; + /** True when a given Private Key is exported, false otherwise. */ + exported: boolean; + /** True when a given Private Key is imported, false otherwise. */ + imported: boolean; +}; + +export type PrivateKeyParams = { + /** Human-readable name for a Private Key. */ + privateKeyName: string; + /** Cryptographic Curve used to generate a given Private Key. */ + curve: Curve; + /** A list of Private Key Tag IDs. This field, if not needed, should be an empty array in your request body. */ + privateKeyTags: string[]; + /** Cryptocurrency-specific formats for a derived address (e.g., Ethereum). */ + addressFormats: AddressFormat[]; +}; + +export type PrivateKeyResult = { + privateKeyId?: string; + addresses?: immutableactivityv1Address[]; +}; + +export type PublicKeyCredentialWithAttestation = { + id: string; + type: string; + rawId: string; + authenticatorAttachment?: string; + response: AuthenticatorAttestationResponse; + clientExtensionResults: SimpleClientExtensionResults; +}; + +export type RecoverUserIntent = { + /** The new authenticator to register. */ + authenticator: AuthenticatorParamsV2; + /** Unique identifier for the user performing recovery. */ + userId: string; +}; + +export type RecoverUserRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: RecoverUserIntent; +}; + +export type RecoverUserResult = { + /** ID of the authenticator created. */ + authenticatorId: string[]; +}; + +export type RejectActivityIntent = { + /** An artifact verifying a User's action. */ + fingerprint: string; +}; + +export type RejectActivityRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: RejectActivityIntent; +}; + +export type RemoveOrganizationFeatureIntent = { + /** Name of the feature to remove */ + name: FeatureName; +}; + +export type RemoveOrganizationFeatureRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: RemoveOrganizationFeatureIntent; +}; + +export type RemoveOrganizationFeatureResult = { + /** Resulting list of organization features. */ + features: Feature[]; +}; + +export type Result = { + createOrganizationResult?: CreateOrganizationResult; + createAuthenticatorsResult?: CreateAuthenticatorsResult; + createUsersResult?: CreateUsersResult; + createPrivateKeysResult?: CreatePrivateKeysResult; + createInvitationsResult?: CreateInvitationsResult; + acceptInvitationResult?: AcceptInvitationResult; + signRawPayloadResult?: SignRawPayloadResult; + createPolicyResult?: CreatePolicyResult; + disablePrivateKeyResult?: DisablePrivateKeyResult; + deleteUsersResult?: DeleteUsersResult; + deleteAuthenticatorsResult?: DeleteAuthenticatorsResult; + deleteInvitationResult?: DeleteInvitationResult; + deleteOrganizationResult?: DeleteOrganizationResult; + deletePolicyResult?: DeletePolicyResult; + createUserTagResult?: CreateUserTagResult; + deleteUserTagsResult?: DeleteUserTagsResult; + signTransactionResult?: SignTransactionResult; + deleteApiKeysResult?: DeleteApiKeysResult; + createApiKeysResult?: CreateApiKeysResult; + createPrivateKeyTagResult?: CreatePrivateKeyTagResult; + deletePrivateKeyTagsResult?: DeletePrivateKeyTagsResult; + setPaymentMethodResult?: billingSetPaymentMethodResult; + activateBillingTierResult?: billingActivateBillingTierResult; + deletePaymentMethodResult?: billingDeletePaymentMethodResult; + createApiOnlyUsersResult?: CreateApiOnlyUsersResult; + updateRootQuorumResult?: UpdateRootQuorumResult; + updateUserTagResult?: UpdateUserTagResult; + updatePrivateKeyTagResult?: UpdatePrivateKeyTagResult; + createSubOrganizationResult?: CreateSubOrganizationResult; + updateAllowedOriginsResult?: UpdateAllowedOriginsResult; + createPrivateKeysResultV2?: CreatePrivateKeysResultV2; + updateUserResult?: UpdateUserResult; + updatePolicyResult?: UpdatePolicyResult; + createSubOrganizationResultV3?: CreateSubOrganizationResultV3; + createWalletResult?: CreateWalletResult; + createWalletAccountsResult?: CreateWalletAccountsResult; + initUserEmailRecoveryResult?: InitUserEmailRecoveryResult; + recoverUserResult?: RecoverUserResult; + setOrganizationFeatureResult?: SetOrganizationFeatureResult; + removeOrganizationFeatureResult?: RemoveOrganizationFeatureResult; + exportPrivateKeyResult?: ExportPrivateKeyResult; + exportWalletResult?: ExportWalletResult; + createSubOrganizationResultV4?: CreateSubOrganizationResultV4; + emailAuthResult?: EmailAuthResult; + exportWalletAccountResult?: ExportWalletAccountResult; + initImportWalletResult?: InitImportWalletResult; + importWalletResult?: ImportWalletResult; + initImportPrivateKeyResult?: InitImportPrivateKeyResult; + importPrivateKeyResult?: ImportPrivateKeyResult; + createPoliciesResult?: CreatePoliciesResult; + signRawPayloadsResult?: SignRawPayloadsResult; + createReadOnlySessionResult?: CreateReadOnlySessionResult; + createOauthProvidersResult?: CreateOauthProvidersResult; + deleteOauthProvidersResult?: DeleteOauthProvidersResult; + createSubOrganizationResultV5?: CreateSubOrganizationResultV5; + oauthResult?: OauthResult; + createReadWriteSessionResult?: CreateReadWriteSessionResult; + createSubOrganizationResultV6?: CreateSubOrganizationResultV6; + deletePrivateKeysResult?: DeletePrivateKeysResult; + deleteWalletsResult?: DeleteWalletsResult; + createReadWriteSessionResultV2?: CreateReadWriteSessionResultV2; + deleteSubOrganizationResult?: DeleteSubOrganizationResult; + initOtpAuthResult?: InitOtpAuthResult; + otpAuthResult?: OtpAuthResult; + createSubOrganizationResultV7?: CreateSubOrganizationResultV7; + updateWalletResult?: UpdateWalletResult; + updatePolicyResultV2?: UpdatePolicyResultV2; + initOtpAuthResultV2?: InitOtpAuthResultV2; + initOtpResult?: InitOtpResult; + verifyOtpResult?: VerifyOtpResult; + otpLoginResult?: OtpLoginResult; + stampLoginResult?: StampLoginResult; + oauthLoginResult?: OauthLoginResult; +}; + +export type RootUserParams = { + /** Human-readable name for a User. */ + userName: string; + /** The user's email address. */ + userEmail?: string; + /** A list of API Key parameters. This field, if not needed, should be an empty array in your request body. */ + apiKeys: apiApiKeyParams[]; + /** A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. */ + authenticators: AuthenticatorParamsV2[]; +}; + +export type RootUserParamsV2 = { + /** Human-readable name for a User. */ + userName: string; + /** The user's email address. */ + userEmail?: string; + /** A list of API Key parameters. This field, if not needed, should be an empty array in your request body. */ + apiKeys: apiApiKeyParams[]; + /** A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. */ + authenticators: AuthenticatorParamsV2[]; + /** A list of Oauth providers. This field, if not needed, should be an empty array in your request body. */ + oauthProviders: OauthProviderParams[]; +}; + +export type RootUserParamsV3 = { + /** Human-readable name for a User. */ + userName: string; + /** The user's email address. */ + userEmail?: string; + /** A list of API Key parameters. This field, if not needed, should be an empty array in your request body. */ + apiKeys: ApiKeyParamsV2[]; + /** A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. */ + authenticators: AuthenticatorParamsV2[]; + /** A list of Oauth providers. This field, if not needed, should be an empty array in your request body. */ + oauthProviders: OauthProviderParams[]; +}; + +export type RootUserParamsV4 = { + /** Human-readable name for a User. */ + userName: string; + /** The user's email address. */ + userEmail?: string; + /** The user's phone number in E.164 format e.g. +13214567890 */ + userPhoneNumber?: string; + /** A list of API Key parameters. This field, if not needed, should be an empty array in your request body. */ + apiKeys: ApiKeyParamsV2[]; + /** A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. */ + authenticators: AuthenticatorParamsV2[]; + /** A list of Oauth providers. This field, if not needed, should be an empty array in your request body. */ + oauthProviders: OauthProviderParams[]; +}; + +export type Selector = { + subject?: string; + operator?: Operator; + target?: string; +}; + +export type SelectorV2 = { + subject?: string; + operator?: Operator; + targets?: string[]; +}; + +export type SetOrganizationFeatureIntent = { + /** Name of the feature to set */ + name: FeatureName; + /** Optional value for the feature. Will override existing values if feature is already set. */ + value: string; +}; + +export type SetOrganizationFeatureRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: SetOrganizationFeatureIntent; +}; + +export type SetOrganizationFeatureResult = { + /** Resulting list of organization features. */ + features: Feature[]; +}; + +export type SignRawPayloadIntent = { + /** Unique identifier for a given Private Key. */ + privateKeyId: string; + /** Raw unsigned payload to be signed. */ + payload: string; + /** Encoding of the `payload` string. Turnkey uses this information to convert `payload` into bytes with the correct decoder (e.g. hex, utf8). */ + encoding: PayloadEncoding; + /** Hash function to apply to payload bytes before signing. This field must be set to HASH_FUNCTION_NOT_APPLICABLE for EdDSA/ed25519 signature requests; configurable payload hashing is not supported by RFC 8032. */ + hashFunction: HashFunction; +}; + +export type SignRawPayloadIntentV2 = { + /** A Wallet account address, Private Key address, or Private Key identifier. */ + signWith: string; + /** Raw unsigned payload to be signed. */ + payload: string; + /** Encoding of the `payload` string. Turnkey uses this information to convert `payload` into bytes with the correct decoder (e.g. hex, utf8). */ + encoding: PayloadEncoding; + /** Hash function to apply to payload bytes before signing. This field must be set to HASH_FUNCTION_NOT_APPLICABLE for EdDSA/ed25519 signature requests; configurable payload hashing is not supported by RFC 8032. */ + hashFunction: HashFunction; +}; + +export type SignRawPayloadRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: SignRawPayloadIntentV2; +}; + +export type SignRawPayloadResult = { + /** Component of an ECSDA signature. */ + r: string; + /** Component of an ECSDA signature. */ + s: string; + /** Component of an ECSDA signature. */ + v: string; +}; + +export type SignRawPayloadsIntent = { + /** A Wallet account address, Private Key address, or Private Key identifier. */ + signWith: string; + /** An array of raw unsigned payloads to be signed. */ + payloads: string[]; + /** Encoding of the `payload` string. Turnkey uses this information to convert `payload` into bytes with the correct decoder (e.g. hex, utf8). */ + encoding: PayloadEncoding; + /** Hash function to apply to payload bytes before signing. This field must be set to HASH_FUNCTION_NOT_APPLICABLE for EdDSA/ed25519 signature requests; configurable payload hashing is not supported by RFC 8032. */ + hashFunction: HashFunction; +}; + +export type SignRawPayloadsRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: SignRawPayloadsIntent; +}; + +export type SignRawPayloadsResult = { + signatures?: SignRawPayloadResult[]; +}; + +export type SignTransactionIntent = { + /** Unique identifier for a given Private Key. */ + privateKeyId: string; + /** Raw unsigned transaction to be signed by a particular Private Key. */ + unsignedTransaction: string; + type: TransactionType; +}; + +export type SignTransactionIntentV2 = { + /** A Wallet account address, Private Key address, or Private Key identifier. */ + signWith: string; + /** Raw unsigned transaction to be signed */ + unsignedTransaction: string; + type: TransactionType; +}; + +export type SignTransactionRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: SignTransactionIntentV2; +}; + +export type SignTransactionResult = { + signedTransaction: string; +}; + +export type SimpleClientExtensionResults = { + appid?: boolean; + appidExclude?: boolean; + credProps?: CredPropsAuthenticationExtensionsClientOutputs; +}; + +export type SmsCustomizationParams = { + /** Template containing references to .OtpCode i.e Your OTP is {{.OtpCode}} */ + template?: string; +}; + +export type StampLoginIntent = { + /** Client-side public key generated by the user, which will be conditionally added to org data based on the passkey stamp associated with this request */ + publicKey: string; + /** Expiration window (in seconds) indicating how long the Session is valid for. If not provided, a default of 15 minutes will be used. */ + expirationSeconds?: string; + /** Invalidate all other previously generated Login API keys */ + invalidateExisting?: boolean; +}; + +export type StampLoginRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: StampLoginIntent; +}; + +export type StampLoginResult = { + /** Signed JWT containing an expiry, public key, session type, user id, and organization id */ + session: string; +}; + +export type TagType = "TAG_TYPE_USER" | "TAG_TYPE_PRIVATE_KEY"; + +export type TestRateLimitsRequest = { + /** 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. */ + organizationId: string; + /** Whether or not to set a limit on this request. */ + isSetLimit: boolean; + /** Rate limit to set for org, if is_set_limit is set to true */ + limit: number; +}; + +export type TestRateLimitsResponse = any; +export type TransactionType = + | "TRANSACTION_TYPE_ETHEREUM" + | "TRANSACTION_TYPE_SOLANA" + | "TRANSACTION_TYPE_TRON"; + +export type UpdateAllowedOriginsIntent = { + /** Additional origins requests are allowed from besides Turnkey origins */ + allowedOrigins: string[]; +}; + +export type UpdateAllowedOriginsResult = any; +export type UpdatePolicyIntent = { + /** Unique identifier for a given Policy. */ + policyId: string; + /** Human-readable name for a Policy. */ + policyName?: string; + /** The instruction to DENY or ALLOW an activity (optional). */ + policyEffect?: Effect; + /** The condition expression that triggers the Effect (optional). */ + policyCondition?: string; + /** The consensus expression that triggers the Effect (optional). */ + policyConsensus?: string; + /** Accompanying notes for a Policy (optional). */ + policyNotes?: string; +}; + +export type UpdatePolicyIntentV2 = { + /** Unique identifier for a given Policy. */ + policyId: string; + /** Human-readable name for a Policy. */ + policyName?: string; + /** The instruction to DENY or ALLOW an activity (optional). */ + policyEffect?: Effect; + /** The condition expression that triggers the Effect (optional). */ + policyCondition?: string; + /** The consensus expression that triggers the Effect (optional). */ + policyConsensus?: string; + /** Accompanying notes for a Policy (optional). */ + policyNotes?: string; +}; + +export type UpdatePolicyRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: UpdatePolicyIntentV2; +}; + +export type UpdatePolicyResult = { + /** Unique identifier for a given Policy. */ + policyId: string; +}; + +export type UpdatePolicyResultV2 = { + /** Unique identifier for a given Policy. */ + policyId: string; +}; + +export type UpdatePrivateKeyTagIntent = { + /** Unique identifier for a given Private Key Tag. */ + privateKeyTagId: string; + /** The new, human-readable name for the tag with the given ID. */ + newPrivateKeyTagName?: string; + /** A list of Private Keys IDs to add this tag to. */ + addPrivateKeyIds: string[]; + /** A list of Private Key IDs to remove this tag from. */ + removePrivateKeyIds: string[]; +}; + +export type UpdatePrivateKeyTagRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: UpdatePrivateKeyTagIntent; +}; + +export type UpdatePrivateKeyTagResult = { + /** Unique identifier for a given Private Key Tag. */ + privateKeyTagId: string; +}; + +export type UpdateRootQuorumIntent = { + /** The threshold of unique approvals to reach quorum. */ + threshold: number; + /** The unique identifiers of users who comprise the quorum set. */ + userIds: string[]; +}; + +export type UpdateRootQuorumRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: UpdateRootQuorumIntent; +}; + +export type UpdateRootQuorumResult = any; +export type UpdateUserIntent = { + /** Unique identifier for a given User. */ + userId: string; + /** Human-readable name for a User. */ + userName?: string; + /** The user's email address. */ + userEmail?: string; + /** An updated list of User Tags to apply to this User. This field, if not needed, should be an empty array in your request body. */ + userTagIds?: string[]; + /** The user's phone number in E.164 format e.g. +13214567890 */ + userPhoneNumber?: string; +}; + +export type UpdateUserRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: UpdateUserIntent; +}; + +export type UpdateUserResult = { + /** A User ID. */ + userId: string; +}; + +export type UpdateUserTagIntent = { + /** Unique identifier for a given User Tag. */ + userTagId: string; + /** The new, human-readable name for the tag with the given ID. */ + newUserTagName?: string; + /** A list of User IDs to add this tag to. */ + addUserIds: string[]; + /** A list of User IDs to remove this tag from. */ + removeUserIds: string[]; +}; + +export type UpdateUserTagRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: UpdateUserTagIntent; +}; + +export type UpdateUserTagResult = { + /** Unique identifier for a given User Tag. */ + userTagId: string; +}; + +export type UpdateWalletIntent = { + /** Unique identifier for a given Wallet. */ + walletId: string; + /** Human-readable name for a Wallet. */ + walletName?: string; +}; + +export type UpdateWalletRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: UpdateWalletIntent; +}; + +export type UpdateWalletResult = { + /** A Wallet ID. */ + walletId: string; +}; + +export type User = { + /** Unique identifier for a given User. */ + userId: string; + /** Human-readable name for a User. */ + userName: string; + /** The user's email address. */ + userEmail?: string; + /** The user's phone number in E.164 format e.g. +13214567890 */ + userPhoneNumber?: string; + /** A list of Authenticator parameters. */ + authenticators: Authenticator[]; + /** A list of API Key parameters. This field, if not needed, should be an empty array in your request body. */ + apiKeys: ApiKey[]; + /** A list of User Tag IDs. */ + userTags: string[]; + /** A list of Oauth Providers. */ + oauthProviders: OauthProvider[]; + createdAt: externaldatav1Timestamp; + updatedAt: externaldatav1Timestamp; +}; + +export type UserParams = { + /** Human-readable name for a User. */ + userName: string; + /** The user's email address. */ + userEmail?: string; + /** The User's permissible access method(s). */ + accessType: AccessType; + /** A list of API Key parameters. This field, if not needed, should be an empty array in your request body. */ + apiKeys: apiApiKeyParams[]; + /** A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. */ + authenticators: AuthenticatorParams[]; + /** A list of User Tag IDs. This field, if not needed, should be an empty array in your request body. */ + userTags: string[]; +}; + +export type UserParamsV2 = { + /** Human-readable name for a User. */ + userName: string; + /** The user's email address. */ + userEmail?: string; + /** A list of API Key parameters. This field, if not needed, should be an empty array in your request body. */ + apiKeys: apiApiKeyParams[]; + /** A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. */ + authenticators: AuthenticatorParamsV2[]; + /** A list of User Tag IDs. This field, if not needed, should be an empty array in your request body. */ + userTags: string[]; +}; + +export type UserParamsV3 = { + /** Human-readable name for a User. */ + userName: string; + /** The user's email address. */ + userEmail?: string; + /** The user's phone number in E.164 format e.g. +13214567890 */ + userPhoneNumber?: string; + /** A list of API Key parameters. This field, if not needed, should be an empty array in your request body. */ + apiKeys: ApiKeyParamsV2[]; + /** A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. */ + authenticators: AuthenticatorParamsV2[]; + /** A list of Oauth providers. This field, if not needed, should be an empty array in your request body. */ + oauthProviders: OauthProviderParams[]; + /** A list of User Tag IDs. This field, if not needed, should be an empty array in your request body. */ + userTags: string[]; +}; + +export type VerifyOtpIntent = { + /** ID representing the result of an init OTP activity. */ + otpId: string; + /** OTP sent out to a user's contact (email or SMS) */ + otpCode: string; + /** Expiration window (in seconds) indicating how long the verification token is valid for. If not provided, a default of 1 hour will be used. Maximum value is 86400 seconds (24 hours) */ + expirationSeconds?: string; +}; + +export type VerifyOtpRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: VerifyOtpIntent; +}; + +export type VerifyOtpResult = { + /** Signed JWT containing a unique id, expiry, verification type, contact. Verification status of a user is updated when the token is consumed (in OTP_LOGIN requests) */ + verificationToken: string; +}; + +export type Vote = { + /** Unique identifier for a given Vote object. */ + id: string; + /** Unique identifier for a given User. */ + userId: string; + /** Web and/or API user within your Organization. */ + user: User; + /** Unique identifier for a given Activity object. */ + activityId: string; + selection: string; + /** The raw message being signed within a Vote. */ + message: string; + /** The public component of a cryptographic key pair used to sign messages and transactions. */ + publicKey: string; + /** The signature applied to a particular vote. */ + signature: string; + /** Method used to produce a signature. */ + scheme: string; + createdAt: externaldatav1Timestamp; +}; + +export type Wallet = { + /** Unique identifier for a given Wallet. */ + walletId: string; + /** Human-readable name for a Wallet. */ + walletName: string; + createdAt: externaldatav1Timestamp; + updatedAt: externaldatav1Timestamp; + /** True when a given Wallet is exported, false otherwise. */ + exported: boolean; + /** True when a given Wallet is imported, false otherwise. */ + imported: boolean; +}; + +export type WalletAccount = { + /** Unique identifier for a given Wallet Account. */ + walletAccountId: string; + /** The Organization the Account belongs to. */ + organizationId: string; + /** The Wallet the Account was derived from. */ + walletId: string; + /** Cryptographic curve used to generate the Account. */ + curve: Curve; + /** Path format used to generate the Account. */ + pathFormat: PathFormat; + /** Path used to generate the Account. */ + path: string; + /** Address format used to generate the Account. */ + addressFormat: AddressFormat; + /** Address generated using the Wallet seed and Account parameters. */ + address: string; + createdAt: externaldatav1Timestamp; + updatedAt: externaldatav1Timestamp; + /** The public component of this wallet account's underlying cryptographic key pair. */ + publicKey?: string; +}; + +export type WalletAccountParams = { + /** Cryptographic curve used to generate a wallet Account. */ + curve: Curve; + /** Path format used to generate a wallet Account. */ + pathFormat: PathFormat; + /** Path used to generate a wallet Account. */ + path: string; + /** Address format used to generate a wallet Acccount. */ + addressFormat: AddressFormat; +}; + +export type WalletParams = { + /** Human-readable name for a Wallet. */ + walletName: string; + /** A list of wallet Accounts. This field, if not needed, should be an empty array in your request body. */ + accounts: WalletAccountParams[]; + /** Length of mnemonic to generate the Wallet seed. Defaults to 12. Accepted values: 12, 15, 18, 21, 24. */ + mnemonicLength?: number; +}; + +export type WalletResult = { + walletId: string; + /** A list of account addresses. */ + addresses: string[]; +}; + +export type WebAuthnStamp = { + /** A base64 url encoded Unique identifier for a given credential. */ + credentialId: string; + /** A base64 encoded payload containing metadata about the signing context and the challenge. */ + clientDataJson: string; + /** A base64 encoded payload containing metadata about the authenticator. */ + authenticatorData: string; + /** The base64 url encoded signature bytes contained within the WebAuthn assertion response. */ + signature: string; +}; diff --git a/packages/sdk-types/src/__inputs__/public_api.swagger.json b/packages/sdk-types/src/__inputs__/public_api.swagger.json new file mode 100644 index 000000000..b5e0170ad --- /dev/null +++ b/packages/sdk-types/src/__inputs__/public_api.swagger.json @@ -0,0 +1,9880 @@ +{ + "swagger": "2.0", + "info": { + "title": "API Reference", + "description": "Review our [API Introduction](../api-introduction) to get started.", + "version": "1.0", + "contact": {} + }, + "tags": [ + { + "name": "PublicApiService" + }, + { + "name": "Organizations", + "description": "An Organization is the highest level of hierarchy in Turnkey. It can contain many Users, Private Keys, and Policies managed by a Root Quorum. The Root Quorum consists of a set of Users with a consensus threshold. This consensus threshold must be reached by Quorum members in order for any actions to take place.\n\nSee [Root Quorum](../concepts/users/root-quorum) for more information" + }, + { + "name": "Invitations", + "description": "Invitations allow you to invite Users into your Organization via email. Alternatively, Users can be added directly without an Invitation if their ApiKey or Authenticator credentials are known ahead of time.\n\nSee [Users](./api#tag/Users) for more information" + }, + { + "name": "Policies", + "description": "Policies allow for deep customization of the security of your Organization. They can be used to grant permissions or restrict usage of Users and Private Keys. The Policy Engine analyzes all of your Policies on each request to determine whether an Activity is allowed.\n\nSee [Policy Overview](../managing-policies/overview) for more information" + }, + { + "name": "Wallets", + "description": "Wallets contain collections of deterministically generated cryptographic public / private key pairs that share a common seed. Turnkey securely holds the common seed, but only you can access it. In most cases, Wallets should be preferred over Private Keys since they can be represented by a mnemonic phrase, used across a variety of cryptographic curves, and can derive many addresses.\n\nDerived addresses can be used to create digital signatures using the corresponding underlying private key. See [Signing](./api#tag/Signing) for more information" + }, + { + "name": "Signing", + "description": "Signers allow you to create digital signatures. Signatures are used to validate the authenticity and integrity of a digital message. Turnkey makes it easy to produce signatures by allowing you to sign with an address. If Turnkey doesn't yet support an address format you need, you can generate and sign with the public key instead by using the address format `ADDRESS_FORMAT_COMPRESSED`." + }, + { + "name": "Private Keys", + "description": "Private Keys are cryptographic public / private key pairs that can be used for cryptocurrency needs or more generalized encryption. Turnkey securely holds all private key materials for you, but only you can access them.\n\nThe Private Key ID or any derived address can be used to create digital signatures. See [Signing](./api#tag/Signing) for more information" + }, + { + "name": "Private Key Tags", + "description": "Private Key Tags allow you to easily group and permission Private Keys through Policies." + }, + { + "name": "Users", + "description": "Users are responsible for any action taken within an Organization. They can have ApiKey or Auuthenticator credentials, allowing you to onboard teammates to the Organization, or create API-only Users to run as part of your infrastructure." + }, + { + "name": "User Tags", + "description": "User Key Tags allow you to easily group and permission Users through Policies." + }, + { + "name": "Authenticators", + "description": "Authenticators are WebAuthN hardware devices, such as a Macbook TouchID or Yubikey, that can be used to authenticate requests." + }, + { + "name": "API Keys", + "description": "API Keys are used to authenticate requests\n\nSee our [CLI](https://github.com/tkhq/tkcli) for instructions on generating API Keys" + }, + { + "name": "Activities", + "description": "Activities encapsulate all the possible actions that can be taken with Turnkey. Some examples include adding a new user, creating a private key, and signing a transaction.\n\nActivities that modify your Organization are processed asynchronously. To confirm processing is complete and retrieve the Activity results, these activities must be polled until that status has been updated to a finalized state: `COMPLETED` when the activity is successful or `FAILED` when the activity has failed" + }, + { + "name": "Consensus", + "description": "Policies can enforce consensus requirements for Activities. For example, adding a new user requires two admins to approve the request.\n\nActivities that have been proposed, but don't yet meet the Consesnsus requirements will have the status: `REQUIRES_CONSENSUS`. Activities in this state can be approved or rejected using the unique fingerprint generated when an Activity is created." + } + ], + "host": "api.turnkey.com", + "schemes": ["https"], + "consumes": ["application/json"], + "produces": ["application/json"], + "paths": { + "/public/v1/query/get_activity": { + "post": { + "summary": "Get Activity", + "description": "Get details about an Activity", + "operationId": "PublicApiService_GetActivity", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1GetActivityRequest" + } + } + ], + "tags": ["Activities"] + } + }, + "/public/v1/query/get_api_key": { + "post": { + "summary": "Get API key", + "description": "Get details about an API key", + "operationId": "PublicApiService_GetApiKey", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetApiKeyResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1GetApiKeyRequest" + } + } + ], + "tags": ["API keys"] + } + }, + "/public/v1/query/get_api_keys": { + "post": { + "summary": "Get API keys", + "description": "Get details about API keys for a user", + "operationId": "PublicApiService_GetApiKeys", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetApiKeysResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1GetApiKeysRequest" + } + } + ], + "tags": ["API keys"] + } + }, + "/public/v1/query/get_attestation": { + "post": { + "summary": "Attestation", + "description": "Get the attestation document corresponding to an enclave.", + "operationId": "PublicApiService_GetAttestationDocument", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetAttestationDocumentResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1GetAttestationDocumentRequest" + } + } + ], + "tags": ["Attestation"] + } + }, + "/public/v1/query/get_authenticator": { + "post": { + "summary": "Get Authenticator", + "description": "Get details about an authenticator", + "operationId": "PublicApiService_GetAuthenticator", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetAuthenticatorResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1GetAuthenticatorRequest" + } + } + ], + "tags": ["Authenticators"] + } + }, + "/public/v1/query/get_authenticators": { + "post": { + "summary": "Get Authenticators", + "description": "Get details about authenticators for a user", + "operationId": "PublicApiService_GetAuthenticators", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetAuthenticatorsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1GetAuthenticatorsRequest" + } + } + ], + "tags": ["Authenticators"] + } + }, + "/public/v1/query/get_oauth_providers": { + "post": { + "summary": "Get Oauth providers", + "description": "Get details about Oauth providers for a user", + "operationId": "PublicApiService_GetOauthProviders", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetOauthProvidersResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1GetOauthProvidersRequest" + } + } + ], + "tags": ["User Auth"] + } + }, + "/public/v1/query/get_organization": { + "post": { + "summary": "Get Organization", + "description": "Get details about an Organization", + "operationId": "PublicApiService_GetOrganization", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetOrganizationResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1GetOrganizationRequest" + } + } + ], + "tags": ["Organizations"] + } + }, + "/public/v1/query/get_organization_configs": { + "post": { + "summary": "Get Configs", + "description": "Get quorum settings and features for an organization", + "operationId": "PublicApiService_GetOrganizationConfigs", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetOrganizationConfigsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1GetOrganizationConfigsRequest" + } + } + ], + "tags": ["Organizations"] + } + }, + "/public/v1/query/get_policy": { + "post": { + "summary": "Get Policy", + "description": "Get details about a Policy", + "operationId": "PublicApiService_GetPolicy", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetPolicyResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1GetPolicyRequest" + } + } + ], + "tags": ["Policies"] + } + }, + "/public/v1/query/get_private_key": { + "post": { + "summary": "Get Private Key", + "description": "Get details about a Private Key", + "operationId": "PublicApiService_GetPrivateKey", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetPrivateKeyResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1GetPrivateKeyRequest" + } + } + ], + "tags": ["Private Keys"] + } + }, + "/public/v1/query/get_user": { + "post": { + "summary": "Get User", + "description": "Get details about a User", + "operationId": "PublicApiService_GetUser", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetUserResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1GetUserRequest" + } + } + ], + "tags": ["Users"] + } + }, + "/public/v1/query/get_wallet": { + "post": { + "summary": "Get Wallet", + "description": "Get details about a Wallet", + "operationId": "PublicApiService_GetWallet", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetWalletResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1GetWalletRequest" + } + } + ], + "tags": ["Wallets"] + } + }, + "/public/v1/query/get_wallet_account": { + "post": { + "summary": "Get Wallet Account", + "description": "Get a single wallet account", + "operationId": "PublicApiService_GetWalletAccount", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetWalletAccountResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1GetWalletAccountRequest" + } + } + ], + "tags": ["Wallets"] + } + }, + "/public/v1/query/list_activities": { + "post": { + "summary": "List Activities", + "description": "List all Activities within an Organization", + "operationId": "PublicApiService_GetActivities", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetActivitiesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1GetActivitiesRequest" + } + } + ], + "tags": ["Activities"] + } + }, + "/public/v1/query/list_policies": { + "post": { + "summary": "List Policies", + "description": "List all Policies within an Organization", + "operationId": "PublicApiService_GetPolicies", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetPoliciesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1GetPoliciesRequest" + } + } + ], + "tags": ["Policies"] + } + }, + "/public/v1/query/list_private_key_tags": { + "post": { + "summary": "List Private Key Tags", + "description": "List all Private Key Tags within an Organization", + "operationId": "PublicApiService_ListPrivateKeyTags", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ListPrivateKeyTagsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1ListPrivateKeyTagsRequest" + } + } + ], + "tags": ["Private Key Tags"] + } + }, + "/public/v1/query/list_private_keys": { + "post": { + "summary": "List Private Keys", + "description": "List all Private Keys within an Organization", + "operationId": "PublicApiService_GetPrivateKeys", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetPrivateKeysResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1GetPrivateKeysRequest" + } + } + ], + "tags": ["Private Keys"] + } + }, + "/public/v1/query/list_suborgs": { + "post": { + "summary": "Get Suborgs", + "description": "Get all suborg IDs associated given a parent org ID and an optional filter.", + "operationId": "PublicApiService_GetSubOrgIds", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetSubOrgIdsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1GetSubOrgIdsRequest" + } + } + ], + "tags": ["Organizations"] + } + }, + "/public/v1/query/list_user_tags": { + "post": { + "summary": "List User Tags", + "description": "List all User Tags within an Organization", + "operationId": "PublicApiService_ListUserTags", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ListUserTagsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1ListUserTagsRequest" + } + } + ], + "tags": ["User Tags"] + } + }, + "/public/v1/query/list_users": { + "post": { + "summary": "List Users", + "description": "List all Users within an Organization", + "operationId": "PublicApiService_GetUsers", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetUsersResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1GetUsersRequest" + } + } + ], + "tags": ["Users"] + } + }, + "/public/v1/query/list_verified_suborgs": { + "post": { + "summary": "Get Verified Suborgs", + "description": "Get all email or phone verified suborg IDs associated given a parent org ID.", + "operationId": "PublicApiService_GetVerifiedSubOrgIds", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetVerifiedSubOrgIdsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1GetVerifiedSubOrgIdsRequest" + } + } + ], + "tags": ["Organizations"] + } + }, + "/public/v1/query/list_wallet_accounts": { + "post": { + "summary": "List Wallets Accounts", + "description": "List all Accounts within a Wallet", + "operationId": "PublicApiService_GetWalletAccounts", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetWalletAccountsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1GetWalletAccountsRequest" + } + } + ], + "tags": ["Wallets"] + } + }, + "/public/v1/query/list_wallets": { + "post": { + "summary": "List Wallets", + "description": "List all Wallets within an Organization", + "operationId": "PublicApiService_GetWallets", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetWalletsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1GetWalletsRequest" + } + } + ], + "tags": ["Wallets"] + } + }, + "/public/v1/query/whoami": { + "post": { + "summary": "Who am I?", + "description": "Get basic information about your current API or WebAuthN user and their organization. Affords Sub-Organization look ups via Parent Organization for WebAuthN or API key users.", + "operationId": "PublicApiService_GetWhoami", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetWhoamiResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1GetWhoamiRequest" + } + } + ], + "tags": ["Sessions"] + } + }, + "/public/v1/submit/approve_activity": { + "post": { + "summary": "Approve Activity", + "description": "Approve an Activity", + "operationId": "PublicApiService_ApproveActivity", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1ApproveActivityRequest" + } + } + ], + "tags": ["Consensus"] + } + }, + "/public/v1/submit/create_api_keys": { + "post": { + "summary": "Create API Keys", + "description": "Add api keys to an existing User", + "operationId": "PublicApiService_CreateApiKeys", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1CreateApiKeysRequest" + } + } + ], + "tags": ["API Keys"] + } + }, + "/public/v1/submit/create_api_only_users": { + "post": { + "summary": "Create API-only Users", + "description": "Create API-only Users in an existing Organization", + "operationId": "PublicApiService_CreateApiOnlyUsers", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1CreateApiOnlyUsersRequest" + } + } + ], + "tags": ["Users"] + } + }, + "/public/v1/submit/create_authenticators": { + "post": { + "summary": "Create Authenticators", + "description": "Create Authenticators to authenticate requests to Turnkey", + "operationId": "PublicApiService_CreateAuthenticators", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1CreateAuthenticatorsRequest" + } + } + ], + "tags": ["Authenticators"] + } + }, + "/public/v1/submit/create_invitations": { + "post": { + "summary": "Create Invitations", + "description": "Create Invitations to join an existing Organization", + "operationId": "PublicApiService_CreateInvitations", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1CreateInvitationsRequest" + } + } + ], + "tags": ["Invitations"] + } + }, + "/public/v1/submit/create_oauth_providers": { + "post": { + "summary": "Create Oauth Providers", + "description": "Creates Oauth providers for a specified user - BETA", + "operationId": "PublicApiService_CreateOauthProviders", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1CreateOauthProvidersRequest" + } + } + ], + "tags": ["User Auth"] + } + }, + "/public/v1/submit/create_policies": { + "post": { + "summary": "Create Policies", + "description": "Create new Policies", + "operationId": "PublicApiService_CreatePolicies", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1CreatePoliciesRequest" + } + } + ], + "tags": ["Policies"] + } + }, + "/public/v1/submit/create_policy": { + "post": { + "summary": "Create Policy", + "description": "Create a new Policy", + "operationId": "PublicApiService_CreatePolicy", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1CreatePolicyRequest" + } + } + ], + "tags": ["Policies"] + } + }, + "/public/v1/submit/create_private_key_tag": { + "post": { + "summary": "Create Private Key Tag", + "description": "Create a private key tag and add it to private keys.", + "operationId": "PublicApiService_CreatePrivateKeyTag", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1CreatePrivateKeyTagRequest" + } + } + ], + "tags": ["Private Key Tags"] + } + }, + "/public/v1/submit/create_private_keys": { + "post": { + "summary": "Create Private Keys", + "description": "Create new Private Keys", + "operationId": "PublicApiService_CreatePrivateKeys", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1CreatePrivateKeysRequest" + } + } + ], + "tags": ["Private Keys"] + } + }, + "/public/v1/submit/create_read_only_session": { + "post": { + "summary": "Create Read Only Session", + "description": "Create a read only session for a user (valid for 1 hour)", + "operationId": "PublicApiService_CreateReadOnlySession", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1CreateReadOnlySessionRequest" + } + } + ], + "tags": ["Sessions"] + } + }, + "/public/v1/submit/create_read_write_session": { + "post": { + "summary": "Create Read Write Session", + "description": "Create a read write session for a user", + "operationId": "PublicApiService_CreateReadWriteSession", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1CreateReadWriteSessionRequest" + } + } + ], + "tags": ["Sessions"] + } + }, + "/public/v1/submit/create_sub_organization": { + "post": { + "summary": "Create Sub-Organization", + "description": "Create a new Sub-Organization", + "operationId": "PublicApiService_CreateSubOrganization", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1CreateSubOrganizationRequest" + } + } + ], + "tags": ["Organizations"] + } + }, + "/public/v1/submit/create_user_tag": { + "post": { + "summary": "Create User Tag", + "description": "Create a user tag and add it to users.", + "operationId": "PublicApiService_CreateUserTag", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1CreateUserTagRequest" + } + } + ], + "tags": ["User Tags"] + } + }, + "/public/v1/submit/create_users": { + "post": { + "summary": "Create Users", + "description": "Create Users in an existing Organization", + "operationId": "PublicApiService_CreateUsers", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1CreateUsersRequest" + } + } + ], + "tags": ["Users"] + } + }, + "/public/v1/submit/create_wallet": { + "post": { + "summary": "Create Wallet", + "description": "Create a Wallet and derive addresses", + "operationId": "PublicApiService_CreateWallet", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1CreateWalletRequest" + } + } + ], + "tags": ["Wallets"] + } + }, + "/public/v1/submit/create_wallet_accounts": { + "post": { + "summary": "Create Wallet Accounts", + "description": "Derive additional addresses using an existing wallet", + "operationId": "PublicApiService_CreateWalletAccounts", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1CreateWalletAccountsRequest" + } + } + ], + "tags": ["Wallets"] + } + }, + "/public/v1/submit/delete_api_keys": { + "post": { + "summary": "Delete API Keys", + "description": "Remove api keys from a User", + "operationId": "PublicApiService_DeleteApiKeys", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1DeleteApiKeysRequest" + } + } + ], + "tags": ["API Keys"] + } + }, + "/public/v1/submit/delete_authenticators": { + "post": { + "summary": "Delete Authenticators", + "description": "Remove authenticators from a User", + "operationId": "PublicApiService_DeleteAuthenticators", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1DeleteAuthenticatorsRequest" + } + } + ], + "tags": ["Authenticators"] + } + }, + "/public/v1/submit/delete_invitation": { + "post": { + "summary": "Delete Invitation", + "description": "Delete an existing Invitation", + "operationId": "PublicApiService_DeleteInvitation", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1DeleteInvitationRequest" + } + } + ], + "tags": ["Invitations"] + } + }, + "/public/v1/submit/delete_oauth_providers": { + "post": { + "summary": "Delete Oauth Providers", + "description": "Removes Oauth providers for a specified user - BETA", + "operationId": "PublicApiService_DeleteOauthProviders", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1DeleteOauthProvidersRequest" + } + } + ], + "tags": ["User Auth"] + } + }, + "/public/v1/submit/delete_policy": { + "post": { + "summary": "Delete Policy", + "description": "Delete an existing Policy", + "operationId": "PublicApiService_DeletePolicy", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1DeletePolicyRequest" + } + } + ], + "tags": ["Policies"] + } + }, + "/public/v1/submit/delete_private_key_tags": { + "post": { + "summary": "Delete Private Key Tags", + "description": "Delete Private Key Tags within an Organization", + "operationId": "PublicApiService_DeletePrivateKeyTags", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1DeletePrivateKeyTagsRequest" + } + } + ], + "tags": ["Private Key Tags"] + } + }, + "/public/v1/submit/delete_private_keys": { + "post": { + "summary": "Delete Private Keys", + "description": "Deletes private keys for an organization", + "operationId": "PublicApiService_DeletePrivateKeys", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1DeletePrivateKeysRequest" + } + } + ], + "tags": ["Private Keys"] + } + }, + "/public/v1/submit/delete_sub_organization": { + "post": { + "summary": "Delete Sub Organization", + "description": "Deletes a sub organization", + "operationId": "PublicApiService_DeleteSubOrganization", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1DeleteSubOrganizationRequest" + } + } + ], + "tags": ["Organizations"] + } + }, + "/public/v1/submit/delete_user_tags": { + "post": { + "summary": "Delete User Tags", + "description": "Delete User Tags within an Organization", + "operationId": "PublicApiService_DeleteUserTags", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1DeleteUserTagsRequest" + } + } + ], + "tags": ["User Tags"] + } + }, + "/public/v1/submit/delete_users": { + "post": { + "summary": "Delete Users", + "description": "Delete Users within an Organization", + "operationId": "PublicApiService_DeleteUsers", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1DeleteUsersRequest" + } + } + ], + "tags": ["Users"] + } + }, + "/public/v1/submit/delete_wallets": { + "post": { + "summary": "Delete Wallets", + "description": "Deletes wallets for an organization", + "operationId": "PublicApiService_DeleteWallets", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1DeleteWalletsRequest" + } + } + ], + "tags": ["Wallets"] + } + }, + "/public/v1/submit/email_auth": { + "post": { + "summary": "Perform Email Auth", + "description": "Authenticate a user via Email", + "operationId": "PublicApiService_EmailAuth", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1EmailAuthRequest" + } + } + ], + "tags": ["User Auth"] + } + }, + "/public/v1/submit/export_private_key": { + "post": { + "summary": "Export Private Key", + "description": "Exports a Private Key", + "operationId": "PublicApiService_ExportPrivateKey", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1ExportPrivateKeyRequest" + } + } + ], + "tags": ["Private Keys"] + } + }, + "/public/v1/submit/export_wallet": { + "post": { + "summary": "Export Wallet", + "description": "Exports a Wallet", + "operationId": "PublicApiService_ExportWallet", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1ExportWalletRequest" + } + } + ], + "tags": ["Wallets"] + } + }, + "/public/v1/submit/export_wallet_account": { + "post": { + "summary": "Export Wallet Account", + "description": "Exports a Wallet Account", + "operationId": "PublicApiService_ExportWalletAccount", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1ExportWalletAccountRequest" + } + } + ], + "tags": ["Wallets"] + } + }, + "/public/v1/submit/import_private_key": { + "post": { + "summary": "Import Private Key", + "description": "Imports a private key", + "operationId": "PublicApiService_ImportPrivateKey", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1ImportPrivateKeyRequest" + } + } + ], + "tags": ["Private Keys"] + } + }, + "/public/v1/submit/import_wallet": { + "post": { + "summary": "Import Wallet", + "description": "Imports a wallet", + "operationId": "PublicApiService_ImportWallet", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1ImportWalletRequest" + } + } + ], + "tags": ["Wallets"] + } + }, + "/public/v1/submit/init_import_private_key": { + "post": { + "summary": "Init Import Private Key", + "description": "Initializes a new private key import", + "operationId": "PublicApiService_InitImportPrivateKey", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1InitImportPrivateKeyRequest" + } + } + ], + "tags": ["Private Keys"] + } + }, + "/public/v1/submit/init_import_wallet": { + "post": { + "summary": "Init Import Wallet", + "description": "Initializes a new wallet import", + "operationId": "PublicApiService_InitImportWallet", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1InitImportWalletRequest" + } + } + ], + "tags": ["Wallets"] + } + }, + "/public/v1/submit/init_otp": { + "post": { + "summary": "Init Generic OTP", + "description": "Initiate a Generic OTP activity", + "operationId": "PublicApiService_InitOtp", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1InitOtpRequest" + } + } + ], + "tags": ["User Verification"] + } + }, + "/public/v1/submit/init_otp_auth": { + "post": { + "summary": "Init OTP auth", + "description": "Initiate an OTP auth activity", + "operationId": "PublicApiService_InitOtpAuth", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1InitOtpAuthRequest" + } + } + ], + "tags": ["User Auth"] + } + }, + "/public/v1/submit/init_user_email_recovery": { + "post": { + "summary": "Init Email Recovery", + "description": "Initializes a new email recovery", + "operationId": "PublicApiService_InitUserEmailRecovery", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1InitUserEmailRecoveryRequest" + } + } + ], + "tags": ["User Recovery"] + } + }, + "/public/v1/submit/oauth": { + "post": { + "summary": "Oauth", + "description": "Authenticate a user with an Oidc token (Oauth) - BETA", + "operationId": "PublicApiService_Oauth", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1OauthRequest" + } + } + ], + "tags": ["User Auth"] + } + }, + "/public/v1/submit/oauth_login": { + "post": { + "summary": "Login with Oauth", + "description": "Create an Oauth session for a user", + "operationId": "PublicApiService_OauthLogin", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1OauthLoginRequest" + } + } + ], + "tags": ["Sessions"] + } + }, + "/public/v1/submit/otp_auth": { + "post": { + "summary": "OTP auth", + "description": "Authenticate a user with an OTP code sent via email or SMS", + "operationId": "PublicApiService_OtpAuth", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1OtpAuthRequest" + } + } + ], + "tags": ["User Auth"] + } + }, + "/public/v1/submit/otp_login": { + "post": { + "summary": "Login with OTP", + "description": "Create an OTP session for a user", + "operationId": "PublicApiService_OtpLogin", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1OtpLoginRequest" + } + } + ], + "tags": ["Sessions"] + } + }, + "/public/v1/submit/recover_user": { + "post": { + "summary": "Recover a user", + "description": "Completes the process of recovering a user by adding an authenticator", + "operationId": "PublicApiService_RecoverUser", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1RecoverUserRequest" + } + } + ], + "tags": ["User Recovery"] + } + }, + "/public/v1/submit/reject_activity": { + "post": { + "summary": "Reject Activity", + "description": "Reject an Activity", + "operationId": "PublicApiService_RejectActivity", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1RejectActivityRequest" + } + } + ], + "tags": ["Consensus"] + } + }, + "/public/v1/submit/remove_organization_feature": { + "post": { + "summary": "Remove Organization Feature", + "description": "Removes an organization feature. This activity must be approved by the current root quorum.", + "operationId": "PublicApiService_RemoveOrganizationFeature", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1RemoveOrganizationFeatureRequest" + } + } + ], + "tags": ["Features"] + } + }, + "/public/v1/submit/set_organization_feature": { + "post": { + "summary": "Set Organization Feature", + "description": "Sets an organization feature. This activity must be approved by the current root quorum.", + "operationId": "PublicApiService_SetOrganizationFeature", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1SetOrganizationFeatureRequest" + } + } + ], + "tags": ["Features"] + } + }, + "/public/v1/submit/sign_raw_payload": { + "post": { + "summary": "Sign Raw Payload", + "description": "Sign a raw payload", + "operationId": "PublicApiService_SignRawPayload", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1SignRawPayloadRequest" + } + } + ], + "tags": ["Signing"] + } + }, + "/public/v1/submit/sign_raw_payloads": { + "post": { + "summary": "Sign Raw Payloads", + "description": "Sign multiple raw payloads with the same signing parameters", + "operationId": "PublicApiService_SignRawPayloads", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1SignRawPayloadsRequest" + } + } + ], + "tags": ["Signing"] + } + }, + "/public/v1/submit/sign_transaction": { + "post": { + "summary": "Sign Transaction", + "description": "Sign a transaction", + "operationId": "PublicApiService_SignTransaction", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1SignTransactionRequest" + } + } + ], + "tags": ["Signing"] + } + }, + "/public/v1/submit/stamp_login": { + "post": { + "summary": "Login with a Stamp", + "description": "Create a session for a user through stamping client side (api key, wallet client, or passkey client)", + "operationId": "PublicApiService_StampLogin", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1StampLoginRequest" + } + } + ], + "tags": ["Sessions"] + } + }, + "/public/v1/submit/update_policy": { + "post": { + "summary": "Update Policy", + "description": "Update an existing Policy", + "operationId": "PublicApiService_UpdatePolicy", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1UpdatePolicyRequest" + } + } + ], + "tags": ["Policies"] + } + }, + "/public/v1/submit/update_private_key_tag": { + "post": { + "summary": "Update Private Key Tag", + "description": "Update human-readable name or associated private keys. Note that this activity is atomic: all of the updates will succeed at once, or all of them will fail.", + "operationId": "PublicApiService_UpdatePrivateKeyTag", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1UpdatePrivateKeyTagRequest" + } + } + ], + "tags": ["Private Key Tags"] + } + }, + "/public/v1/submit/update_root_quorum": { + "post": { + "summary": "Update Root Quorum", + "description": "Set the threshold and members of the root quorum. This activity must be approved by the current root quorum.", + "operationId": "PublicApiService_UpdateRootQuorum", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1UpdateRootQuorumRequest" + } + } + ], + "tags": ["Organizations"] + } + }, + "/public/v1/submit/update_user": { + "post": { + "summary": "Update User", + "description": "Update a User in an existing Organization", + "operationId": "PublicApiService_UpdateUser", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1UpdateUserRequest" + } + } + ], + "tags": ["Users"] + } + }, + "/public/v1/submit/update_user_tag": { + "post": { + "summary": "Update User Tag", + "description": "Update human-readable name or associated users. Note that this activity is atomic: all of the updates will succeed at once, or all of them will fail.", + "operationId": "PublicApiService_UpdateUserTag", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1UpdateUserTagRequest" + } + } + ], + "tags": ["User Tags"] + } + }, + "/public/v1/submit/update_wallet": { + "post": { + "summary": "Update Wallet", + "description": "Update a wallet for an organization", + "operationId": "PublicApiService_UpdateWallet", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1UpdateWalletRequest" + } + } + ], + "tags": ["Wallets"] + } + }, + "/public/v1/submit/verify_otp": { + "post": { + "summary": "Verify Generic OTP", + "description": "Verify a Generic OTP", + "operationId": "PublicApiService_VerifyOtp", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1VerifyOtpRequest" + } + } + ], + "tags": ["User Verification"] + } + }, + "/tkhq/api/v1/noop-codegen-anchor": { + "post": { + "operationId": "PublicApiService_NOOPCodegenAnchor", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1NOOPCodegenAnchorResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "tags": ["PublicApiService"] + } + }, + "/tkhq/api/v1/test_rate_limits": { + "post": { + "summary": "Test Rate Limit", + "description": "Set a rate local rate limit just on the current endpoint, for purposes of testing with Vivosuite", + "operationId": "PublicApiService_TestRateLimits", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1TestRateLimitsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1TestRateLimitsRequest" + } + } + ], + "tags": ["RateLimit"] + } + } + }, + "definitions": { + "apiApiKeyParams": { + "type": "object", + "properties": { + "apiKeyName": { + "type": "string", + "description": "Human-readable name for an API Key." + }, + "publicKey": { + "type": "string", + "description": "The public component of a cryptographic key pair used to sign messages and transactions." + }, + "expirationSeconds": { + "type": "string", + "description": "Optional window (in seconds) indicating how long the API Key should last." + } + }, + "required": ["apiKeyName", "publicKey"] + }, + "billingActivateBillingTierIntent": { + "type": "object", + "properties": { + "productId": { + "type": "string", + "description": "The product that the customer wants to subscribe to." + } + }, + "required": ["productId"] + }, + "billingActivateBillingTierResult": { + "type": "object", + "properties": { + "productId": { + "type": "string", + "description": "The id of the product being subscribed to." + } + }, + "required": ["productId"] + }, + "billingDeletePaymentMethodIntent": { + "type": "object", + "properties": { + "paymentMethodId": { + "type": "string", + "description": "The payment method that the customer wants to remove." + } + }, + "required": ["paymentMethodId"] + }, + "billingDeletePaymentMethodResult": { + "type": "object", + "properties": { + "paymentMethodId": { + "type": "string", + "description": "The payment method that was removed." + } + }, + "required": ["paymentMethodId"] + }, + "billingSetPaymentMethodIntent": { + "type": "object", + "properties": { + "number": { + "type": "string", + "description": "The account number of the customer's credit card." + }, + "cvv": { + "type": "string", + "description": "The verification digits of the customer's credit card." + }, + "expiryMonth": { + "type": "string", + "description": "The month that the credit card expires." + }, + "expiryYear": { + "type": "string", + "description": "The year that the credit card expires." + }, + "cardHolderEmail": { + "type": "string", + "description": "The email that will receive invoices for the credit card." + }, + "cardHolderName": { + "type": "string", + "description": "The name associated with the credit card." + } + }, + "required": [ + "number", + "cvv", + "expiryMonth", + "expiryYear", + "cardHolderEmail", + "cardHolderName" + ] + }, + "billingSetPaymentMethodIntentV2": { + "type": "object", + "properties": { + "paymentMethodId": { + "type": "string", + "description": "The id of the payment method that was created clientside." + }, + "cardHolderEmail": { + "type": "string", + "description": "The email that will receive invoices for the credit card." + }, + "cardHolderName": { + "type": "string", + "description": "The name associated with the credit card." + } + }, + "required": ["paymentMethodId", "cardHolderEmail", "cardHolderName"] + }, + "billingSetPaymentMethodResult": { + "type": "object", + "properties": { + "lastFour": { + "type": "string", + "description": "The last four digits of the credit card added." + }, + "cardHolderName": { + "type": "string", + "description": "The name associated with the payment method." + }, + "cardHolderEmail": { + "type": "string", + "description": "The email address associated with the payment method." + } + }, + "required": ["lastFour", "cardHolderName", "cardHolderEmail"] + }, + "datav1Tag": { + "type": "object", + "properties": { + "tagId": { + "type": "string", + "description": "Unique identifier for a given Tag." + }, + "tagName": { + "type": "string", + "description": "Human-readable name for a Tag." + }, + "tagType": { + "$ref": "#/definitions/v1TagType" + }, + "createdAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + }, + "updatedAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + } + }, + "required": ["tagId", "tagName", "tagType", "createdAt", "updatedAt"] + }, + "externaldatav1Address": { + "type": "object", + "properties": { + "format": { + "$ref": "#/definitions/v1AddressFormat" + }, + "address": { + "type": "string" + } + } + }, + "externaldatav1Credential": { + "type": "object", + "properties": { + "publicKey": { + "type": "string", + "description": "The public component of a cryptographic key pair used to sign messages and transactions." + }, + "type": { + "$ref": "#/definitions/v1CredentialType" + } + }, + "required": ["publicKey", "type"] + }, + "externaldatav1Quorum": { + "type": "object", + "properties": { + "threshold": { + "type": "integer", + "format": "int32", + "description": "Count of unique approvals required to meet quorum." + }, + "userIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Unique identifiers of quorum set members." + } + }, + "required": ["threshold", "userIds"] + }, + "externaldatav1Timestamp": { + "type": "object", + "properties": { + "seconds": { + "type": "string" + }, + "nanos": { + "type": "string" + } + }, + "required": ["seconds", "nanos"] + }, + "immutableactivityv1Address": { + "type": "object", + "properties": { + "format": { + "$ref": "#/definitions/v1AddressFormat" + }, + "address": { + "type": "string" + } + } + }, + "protobufAny": { + "type": "object", + "properties": { + "@type": { + "type": "string" + } + }, + "additionalProperties": {} + }, + "rpcStatus": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/protobufAny" + } + } + } + }, + "v1AcceptInvitationIntent": { + "type": "object", + "properties": { + "invitationId": { + "type": "string", + "description": "Unique identifier for a given Invitation object." + }, + "userId": { + "type": "string", + "description": "Unique identifier for a given User." + }, + "authenticator": { + "$ref": "#/definitions/v1AuthenticatorParams", + "description": "WebAuthN hardware devices that can be used to log in to the Turnkey web app." + } + }, + "required": ["invitationId", "userId", "authenticator"] + }, + "v1AcceptInvitationIntentV2": { + "type": "object", + "properties": { + "invitationId": { + "type": "string", + "description": "Unique identifier for a given Invitation object." + }, + "userId": { + "type": "string", + "description": "Unique identifier for a given User." + }, + "authenticator": { + "$ref": "#/definitions/v1AuthenticatorParamsV2", + "description": "WebAuthN hardware devices that can be used to log in to the Turnkey web app." + } + }, + "required": ["invitationId", "userId", "authenticator"] + }, + "v1AcceptInvitationResult": { + "type": "object", + "properties": { + "invitationId": { + "type": "string", + "description": "Unique identifier for a given Invitation." + }, + "userId": { + "type": "string", + "description": "Unique identifier for a given User." + } + }, + "required": ["invitationId", "userId"] + }, + "v1AccessType": { + "type": "string", + "enum": ["ACCESS_TYPE_WEB", "ACCESS_TYPE_API", "ACCESS_TYPE_ALL"] + }, + "v1Activity": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "Unique identifier for a given Activity object." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "status": { + "$ref": "#/definitions/v1ActivityStatus", + "description": "The current processing status of a specified Activity." + }, + "type": { + "$ref": "#/definitions/v1ActivityType", + "description": "Type of Activity, such as Add User, or Sign Transaction." + }, + "intent": { + "$ref": "#/definitions/v1Intent", + "description": "Intent object crafted by Turnkey based on the user request, used to assess the permissibility of an action." + }, + "result": { + "$ref": "#/definitions/v1Result", + "description": "Result of the intended action." + }, + "votes": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1Vote" + }, + "description": "A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata." + }, + "fingerprint": { + "type": "string", + "description": "An artifact verifying a User's action." + }, + "canApprove": { + "type": "boolean" + }, + "canReject": { + "type": "boolean" + }, + "createdAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + }, + "updatedAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + }, + "failure": { + "$ref": "#/definitions/rpcStatus", + "description": "Failure reason of the intended action." + } + }, + "required": [ + "id", + "organizationId", + "status", + "type", + "intent", + "result", + "votes", + "fingerprint", + "canApprove", + "canReject", + "createdAt", + "updatedAt" + ] + }, + "v1ActivityResponse": { + "type": "object", + "properties": { + "activity": { + "$ref": "#/definitions/v1Activity", + "description": "An action that can that can be taken within the Turnkey infrastructure." + } + }, + "required": ["activity"] + }, + "v1ActivityStatus": { + "type": "string", + "enum": [ + "ACTIVITY_STATUS_CREATED", + "ACTIVITY_STATUS_PENDING", + "ACTIVITY_STATUS_COMPLETED", + "ACTIVITY_STATUS_FAILED", + "ACTIVITY_STATUS_CONSENSUS_NEEDED", + "ACTIVITY_STATUS_REJECTED" + ] + }, + "v1ActivityType": { + "type": "string", + "enum": [ + "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" + ] + }, + "v1AddressFormat": { + "type": "string", + "enum": [ + "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" + ] + }, + "v1ApiKey": { + "type": "object", + "properties": { + "credential": { + "$ref": "#/definitions/externaldatav1Credential", + "description": "A User credential that can be used to authenticate to Turnkey." + }, + "apiKeyId": { + "type": "string", + "description": "Unique identifier for a given API Key." + }, + "apiKeyName": { + "type": "string", + "description": "Human-readable name for an API Key." + }, + "createdAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + }, + "updatedAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + }, + "expirationSeconds": { + "type": "string", + "format": "uint64", + "description": "Optional window (in seconds) indicating how long the API Key should last." + } + }, + "required": [ + "credential", + "apiKeyId", + "apiKeyName", + "createdAt", + "updatedAt" + ] + }, + "v1ApiKeyCurve": { + "type": "string", + "enum": [ + "API_KEY_CURVE_P256", + "API_KEY_CURVE_SECP256K1", + "API_KEY_CURVE_ED25519" + ] + }, + "v1ApiKeyParamsV2": { + "type": "object", + "properties": { + "apiKeyName": { + "type": "string", + "description": "Human-readable name for an API Key." + }, + "publicKey": { + "type": "string", + "description": "The public component of a cryptographic key pair used to sign messages and transactions." + }, + "curveType": { + "$ref": "#/definitions/v1ApiKeyCurve", + "description": "The curve type to be used for processing API key signatures." + }, + "expirationSeconds": { + "type": "string", + "description": "Optional window (in seconds) indicating how long the API Key should last." + } + }, + "required": ["apiKeyName", "publicKey", "curveType"] + }, + "v1ApiOnlyUserParams": { + "type": "object", + "properties": { + "userName": { + "type": "string", + "description": "The name of the new API-only User." + }, + "userEmail": { + "type": "string", + "description": "The email address for this API-only User (optional)." + }, + "userTags": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of tags assigned to the new API-only User. This field, if not needed, should be an empty array in your request body." + }, + "apiKeys": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/apiApiKeyParams" + }, + "description": "A list of API Key parameters. This field, if not needed, should be an empty array in your request body." + } + }, + "required": ["userName", "userTags", "apiKeys"] + }, + "v1ApproveActivityIntent": { + "type": "object", + "properties": { + "fingerprint": { + "type": "string", + "description": "An artifact verifying a User's action." + } + }, + "required": ["fingerprint"] + }, + "v1ApproveActivityRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_APPROVE_ACTIVITY"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1ApproveActivityIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1Attestation": { + "type": "object", + "properties": { + "credentialId": { + "type": "string", + "description": "The cbor encoded then base64 url encoded id of the credential." + }, + "clientDataJson": { + "type": "string", + "description": "A base64 url encoded payload containing metadata about the signing context and the challenge." + }, + "attestationObject": { + "type": "string", + "description": "A base64 url encoded payload containing authenticator data and any attestation the webauthn provider chooses." + }, + "transports": { + "type": "array", + "items": { + "$ref": "#/definitions/v1AuthenticatorTransport" + }, + "description": "The type of authenticator transports." + } + }, + "required": [ + "credentialId", + "clientDataJson", + "attestationObject", + "transports" + ] + }, + "v1Authenticator": { + "type": "object", + "properties": { + "transports": { + "type": "array", + "items": { + "$ref": "#/definitions/v1AuthenticatorTransport" + }, + "description": "Types of transports that may be used by an Authenticator (e.g., USB, NFC, BLE)." + }, + "attestationType": { + "type": "string" + }, + "aaguid": { + "type": "string", + "description": "Identifier indicating the type of the Security Key." + }, + "credentialId": { + "type": "string", + "description": "Unique identifier for a WebAuthn credential." + }, + "model": { + "type": "string", + "description": "The type of Authenticator device." + }, + "credential": { + "$ref": "#/definitions/externaldatav1Credential", + "description": "A User credential that can be used to authenticate to Turnkey." + }, + "authenticatorId": { + "type": "string", + "description": "Unique identifier for a given Authenticator." + }, + "authenticatorName": { + "type": "string", + "description": "Human-readable name for an Authenticator." + }, + "createdAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + }, + "updatedAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + } + }, + "required": [ + "transports", + "attestationType", + "aaguid", + "credentialId", + "model", + "credential", + "authenticatorId", + "authenticatorName", + "createdAt", + "updatedAt" + ] + }, + "v1AuthenticatorAttestationResponse": { + "type": "object", + "properties": { + "clientDataJson": { + "type": "string" + }, + "attestationObject": { + "type": "string" + }, + "transports": { + "type": "array", + "items": { + "$ref": "#/definitions/v1AuthenticatorTransport" + } + }, + "authenticatorAttachment": { + "type": "string", + "enum": ["cross-platform", "platform"], + "x-nullable": true + } + }, + "required": ["clientDataJson", "attestationObject"] + }, + "v1AuthenticatorParams": { + "type": "object", + "properties": { + "authenticatorName": { + "type": "string", + "description": "Human-readable name for an Authenticator." + }, + "userId": { + "type": "string", + "description": "Unique identifier for a given User." + }, + "attestation": { + "$ref": "#/definitions/v1PublicKeyCredentialWithAttestation" + }, + "challenge": { + "type": "string", + "description": "Challenge presented for authentication purposes." + } + }, + "required": ["authenticatorName", "userId", "attestation", "challenge"] + }, + "v1AuthenticatorParamsV2": { + "type": "object", + "properties": { + "authenticatorName": { + "type": "string", + "description": "Human-readable name for an Authenticator." + }, + "challenge": { + "type": "string", + "description": "Challenge presented for authentication purposes." + }, + "attestation": { + "$ref": "#/definitions/v1Attestation", + "description": "The attestation that proves custody of the authenticator and provides metadata about it." + } + }, + "required": ["authenticatorName", "challenge", "attestation"] + }, + "v1AuthenticatorTransport": { + "type": "string", + "enum": [ + "AUTHENTICATOR_TRANSPORT_BLE", + "AUTHENTICATOR_TRANSPORT_INTERNAL", + "AUTHENTICATOR_TRANSPORT_NFC", + "AUTHENTICATOR_TRANSPORT_USB", + "AUTHENTICATOR_TRANSPORT_HYBRID" + ] + }, + "v1Config": { + "type": "object", + "properties": { + "features": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1Feature" + } + }, + "quorum": { + "$ref": "#/definitions/externaldatav1Quorum" + } + } + }, + "v1CreateApiKeysIntent": { + "type": "object", + "properties": { + "apiKeys": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/apiApiKeyParams" + }, + "description": "A list of API Keys." + }, + "userId": { + "type": "string", + "description": "Unique identifier for a given User." + } + }, + "required": ["apiKeys", "userId"] + }, + "v1CreateApiKeysIntentV2": { + "type": "object", + "properties": { + "apiKeys": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1ApiKeyParamsV2" + }, + "description": "A list of API Keys." + }, + "userId": { + "type": "string", + "description": "Unique identifier for a given User." + } + }, + "required": ["apiKeys", "userId"] + }, + "v1CreateApiKeysRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_CREATE_API_KEYS_V2"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1CreateApiKeysIntentV2" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1CreateApiKeysResult": { + "type": "object", + "properties": { + "apiKeyIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of API Key IDs." + } + }, + "required": ["apiKeyIds"] + }, + "v1CreateApiOnlyUsersIntent": { + "type": "object", + "properties": { + "apiOnlyUsers": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1ApiOnlyUserParams" + }, + "description": "A list of API-only Users to create." + } + }, + "required": ["apiOnlyUsers"] + }, + "v1CreateApiOnlyUsersRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_CREATE_API_ONLY_USERS"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1CreateApiOnlyUsersIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1CreateApiOnlyUsersResult": { + "type": "object", + "properties": { + "userIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of API-only User IDs." + } + }, + "required": ["userIds"] + }, + "v1CreateAuthenticatorsIntent": { + "type": "object", + "properties": { + "authenticators": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1AuthenticatorParams" + }, + "description": "A list of Authenticators." + }, + "userId": { + "type": "string", + "description": "Unique identifier for a given User." + } + }, + "required": ["authenticators", "userId"] + }, + "v1CreateAuthenticatorsIntentV2": { + "type": "object", + "properties": { + "authenticators": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1AuthenticatorParamsV2" + }, + "description": "A list of Authenticators." + }, + "userId": { + "type": "string", + "description": "Unique identifier for a given User." + } + }, + "required": ["authenticators", "userId"] + }, + "v1CreateAuthenticatorsRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_CREATE_AUTHENTICATORS_V2"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1CreateAuthenticatorsIntentV2" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1CreateAuthenticatorsResult": { + "type": "object", + "properties": { + "authenticatorIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of Authenticator IDs." + } + }, + "required": ["authenticatorIds"] + }, + "v1CreateInvitationsIntent": { + "type": "object", + "properties": { + "invitations": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1InvitationParams" + }, + "description": "A list of Invitations." + } + }, + "required": ["invitations"] + }, + "v1CreateInvitationsRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_CREATE_INVITATIONS"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1CreateInvitationsIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1CreateInvitationsResult": { + "type": "object", + "properties": { + "invitationIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of Invitation IDs" + } + }, + "required": ["invitationIds"] + }, + "v1CreateOauthProvidersIntent": { + "type": "object", + "properties": { + "userId": { + "type": "string", + "description": "The ID of the User to add an Oauth provider to" + }, + "oauthProviders": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1OauthProviderParams" + }, + "description": "A list of Oauth providers." + } + }, + "required": ["userId", "oauthProviders"] + }, + "v1CreateOauthProvidersRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_CREATE_OAUTH_PROVIDERS"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1CreateOauthProvidersIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1CreateOauthProvidersResult": { + "type": "object", + "properties": { + "providerIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of unique identifiers for Oauth Providers" + } + }, + "required": ["providerIds"] + }, + "v1CreateOrganizationIntent": { + "type": "object", + "properties": { + "organizationName": { + "type": "string", + "description": "Human-readable name for an Organization." + }, + "rootEmail": { + "type": "string", + "description": "The root user's email address." + }, + "rootAuthenticator": { + "$ref": "#/definitions/v1AuthenticatorParams", + "description": "The root user's Authenticator." + }, + "rootUserId": { + "type": "string", + "description": "Unique identifier for the root user object." + } + }, + "required": ["organizationName", "rootEmail", "rootAuthenticator"] + }, + "v1CreateOrganizationIntentV2": { + "type": "object", + "properties": { + "organizationName": { + "type": "string", + "description": "Human-readable name for an Organization." + }, + "rootEmail": { + "type": "string", + "description": "The root user's email address." + }, + "rootAuthenticator": { + "$ref": "#/definitions/v1AuthenticatorParamsV2", + "description": "The root user's Authenticator." + }, + "rootUserId": { + "type": "string", + "description": "Unique identifier for the root user object." + } + }, + "required": ["organizationName", "rootEmail", "rootAuthenticator"] + }, + "v1CreateOrganizationResult": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + } + }, + "required": ["organizationId"] + }, + "v1CreatePoliciesIntent": { + "type": "object", + "properties": { + "policies": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1CreatePolicyIntentV3" + }, + "description": "An array of policy intents to be created." + } + }, + "required": ["policies"] + }, + "v1CreatePoliciesRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_CREATE_POLICIES"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1CreatePoliciesIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1CreatePoliciesResult": { + "type": "object", + "properties": { + "policyIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of unique identifiers for the created policies." + } + }, + "required": ["policyIds"] + }, + "v1CreatePolicyIntent": { + "type": "object", + "properties": { + "policyName": { + "type": "string", + "description": "Human-readable name for a Policy." + }, + "selectors": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1Selector" + }, + "description": "A list of simple functions each including a subject, target and boolean. See Policy Engine Language section for additional details." + }, + "effect": { + "$ref": "#/definitions/v1Effect", + "description": "The instruction to DENY or ALLOW a particular activity following policy selector(s)." + }, + "notes": { + "type": "string" + } + }, + "required": ["policyName", "selectors", "effect"] + }, + "v1CreatePolicyIntentV2": { + "type": "object", + "properties": { + "policyName": { + "type": "string", + "description": "Human-readable name for a Policy." + }, + "selectors": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1SelectorV2" + }, + "description": "A list of simple functions each including a subject, target and boolean. See Policy Engine Language section for additional details." + }, + "effect": { + "$ref": "#/definitions/v1Effect", + "description": "Whether to ALLOW or DENY requests that match the condition and consensus requirements." + }, + "notes": { + "type": "string" + } + }, + "required": ["policyName", "selectors", "effect"] + }, + "v1CreatePolicyIntentV3": { + "type": "object", + "properties": { + "policyName": { + "type": "string", + "description": "Human-readable name for a Policy." + }, + "effect": { + "$ref": "#/definitions/v1Effect", + "description": "The instruction to DENY or ALLOW an activity." + }, + "condition": { + "type": "string", + "description": "The condition expression that triggers the Effect" + }, + "consensus": { + "type": "string", + "description": "The consensus expression that triggers the Effect" + }, + "notes": { + "type": "string" + } + }, + "required": ["policyName", "effect"] + }, + "v1CreatePolicyRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_CREATE_POLICY_V3"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1CreatePolicyIntentV3" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1CreatePolicyResult": { + "type": "object", + "properties": { + "policyId": { + "type": "string", + "description": "Unique identifier for a given Policy." + } + }, + "required": ["policyId"] + }, + "v1CreatePrivateKeyTagIntent": { + "type": "object", + "properties": { + "privateKeyTagName": { + "type": "string", + "description": "Human-readable name for a Private Key Tag." + }, + "privateKeyIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of Private Key IDs." + } + }, + "required": ["privateKeyTagName", "privateKeyIds"] + }, + "v1CreatePrivateKeyTagRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_CREATE_PRIVATE_KEY_TAG"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1CreatePrivateKeyTagIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1CreatePrivateKeyTagResult": { + "type": "object", + "properties": { + "privateKeyTagId": { + "type": "string", + "description": "Unique identifier for a given Private Key Tag." + }, + "privateKeyIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of Private Key IDs." + } + }, + "required": ["privateKeyTagId", "privateKeyIds"] + }, + "v1CreatePrivateKeysIntent": { + "type": "object", + "properties": { + "privateKeys": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1PrivateKeyParams" + }, + "description": "A list of Private Keys." + } + }, + "required": ["privateKeys"] + }, + "v1CreatePrivateKeysIntentV2": { + "type": "object", + "properties": { + "privateKeys": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1PrivateKeyParams" + }, + "description": "A list of Private Keys." + } + }, + "required": ["privateKeys"] + }, + "v1CreatePrivateKeysRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_CREATE_PRIVATE_KEYS_V2"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1CreatePrivateKeysIntentV2" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1CreatePrivateKeysResult": { + "type": "object", + "properties": { + "privateKeyIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of Private Key IDs." + } + }, + "required": ["privateKeyIds"] + }, + "v1CreatePrivateKeysResultV2": { + "type": "object", + "properties": { + "privateKeys": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1PrivateKeyResult" + }, + "description": "A list of Private Key IDs and addresses." + } + }, + "required": ["privateKeys"] + }, + "v1CreateReadOnlySessionIntent": { + "type": "object" + }, + "v1CreateReadOnlySessionRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_CREATE_READ_ONLY_SESSION"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1CreateReadOnlySessionIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1CreateReadOnlySessionResult": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization. If the request is being made by a user and their Sub-Organization ID is unknown, this can be the Parent Organization ID. However, using the Sub-Organization ID is preferred due to performance reasons." + }, + "organizationName": { + "type": "string", + "description": "Human-readable name for an Organization." + }, + "userId": { + "type": "string", + "description": "Unique identifier for a given User." + }, + "username": { + "type": "string", + "description": "Human-readable name for a User." + }, + "session": { + "type": "string", + "description": "String representing a read only session" + }, + "sessionExpiry": { + "type": "string", + "format": "uint64", + "description": "UTC timestamp in seconds representing the expiry time for the read only session." + } + }, + "required": [ + "organizationId", + "organizationName", + "userId", + "username", + "session", + "sessionExpiry" + ] + }, + "v1CreateReadWriteSessionIntent": { + "type": "object", + "properties": { + "targetPublicKey": { + "type": "string", + "description": "Client-side public key generated by the user, to which the read write session bundle (credentials) will be encrypted." + }, + "email": { + "type": "string", + "description": "Email of the user to create a read write session for" + }, + "apiKeyName": { + "type": "string", + "description": "Optional human-readable name for an API Key. If none provided, default to Read Write Session - \u003cTimestamp\u003e" + }, + "expirationSeconds": { + "type": "string", + "description": "Expiration window (in seconds) indicating how long the API key is valid for. If not provided, a default of 15 minutes will be used." + } + }, + "required": ["targetPublicKey", "email"] + }, + "v1CreateReadWriteSessionIntentV2": { + "type": "object", + "properties": { + "targetPublicKey": { + "type": "string", + "description": "Client-side public key generated by the user, to which the read write session bundle (credentials) will be encrypted." + }, + "userId": { + "type": "string", + "description": "Unique identifier for a given User." + }, + "apiKeyName": { + "type": "string", + "description": "Optional human-readable name for an API Key. If none provided, default to Read Write Session - \u003cTimestamp\u003e" + }, + "expirationSeconds": { + "type": "string", + "description": "Expiration window (in seconds) indicating how long the API key is valid for. If not provided, a default of 15 minutes will be used." + }, + "invalidateExisting": { + "type": "boolean", + "description": "Invalidate all other previously generated ReadWriteSession API keys" + } + }, + "required": ["targetPublicKey"] + }, + "v1CreateReadWriteSessionRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_CREATE_READ_WRITE_SESSION_V2"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1CreateReadWriteSessionIntentV2" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1CreateReadWriteSessionResult": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization. If the request is being made by a user and their Sub-Organization ID is unknown, this can be the Parent Organization ID. However, using the Sub-Organization ID is preferred due to performance reasons." + }, + "organizationName": { + "type": "string", + "description": "Human-readable name for an Organization." + }, + "userId": { + "type": "string", + "description": "Unique identifier for a given User." + }, + "username": { + "type": "string", + "description": "Human-readable name for a User." + }, + "apiKeyId": { + "type": "string", + "description": "Unique identifier for the created API key." + }, + "credentialBundle": { + "type": "string", + "description": "HPKE encrypted credential bundle" + } + }, + "required": [ + "organizationId", + "organizationName", + "userId", + "username", + "apiKeyId", + "credentialBundle" + ] + }, + "v1CreateReadWriteSessionResultV2": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization. If the request is being made by a user and their Sub-Organization ID is unknown, this can be the Parent Organization ID. However, using the Sub-Organization ID is preferred due to performance reasons." + }, + "organizationName": { + "type": "string", + "description": "Human-readable name for an Organization." + }, + "userId": { + "type": "string", + "description": "Unique identifier for a given User." + }, + "username": { + "type": "string", + "description": "Human-readable name for a User." + }, + "apiKeyId": { + "type": "string", + "description": "Unique identifier for the created API key." + }, + "credentialBundle": { + "type": "string", + "description": "HPKE encrypted credential bundle" + } + }, + "required": [ + "organizationId", + "organizationName", + "userId", + "username", + "apiKeyId", + "credentialBundle" + ] + }, + "v1CreateSubOrganizationIntent": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Name for this sub-organization" + }, + "rootAuthenticator": { + "$ref": "#/definitions/v1AuthenticatorParamsV2", + "description": "Root User authenticator for this new sub-organization" + } + }, + "required": ["name", "rootAuthenticator"] + }, + "v1CreateSubOrganizationIntentV2": { + "type": "object", + "properties": { + "subOrganizationName": { + "type": "string", + "description": "Name for this sub-organization" + }, + "rootUsers": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1RootUserParams" + }, + "description": "Root users to create within this sub-organization" + }, + "rootQuorumThreshold": { + "type": "integer", + "format": "int32", + "description": "The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users" + } + }, + "required": ["subOrganizationName", "rootUsers", "rootQuorumThreshold"] + }, + "v1CreateSubOrganizationIntentV3": { + "type": "object", + "properties": { + "subOrganizationName": { + "type": "string", + "description": "Name for this sub-organization" + }, + "rootUsers": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1RootUserParams" + }, + "description": "Root users to create within this sub-organization" + }, + "rootQuorumThreshold": { + "type": "integer", + "format": "int32", + "description": "The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users" + }, + "privateKeys": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1PrivateKeyParams" + }, + "description": "A list of Private Keys." + } + }, + "required": [ + "subOrganizationName", + "rootUsers", + "rootQuorumThreshold", + "privateKeys" + ] + }, + "v1CreateSubOrganizationIntentV4": { + "type": "object", + "properties": { + "subOrganizationName": { + "type": "string", + "description": "Name for this sub-organization" + }, + "rootUsers": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1RootUserParams" + }, + "description": "Root users to create within this sub-organization" + }, + "rootQuorumThreshold": { + "type": "integer", + "format": "int32", + "description": "The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users" + }, + "wallet": { + "$ref": "#/definitions/v1WalletParams", + "description": "The wallet to create for the sub-organization" + }, + "disableEmailRecovery": { + "type": "boolean", + "description": "Disable email recovery for the sub-organization" + }, + "disableEmailAuth": { + "type": "boolean", + "description": "Disable email auth for the sub-organization" + } + }, + "required": ["subOrganizationName", "rootUsers", "rootQuorumThreshold"] + }, + "v1CreateSubOrganizationIntentV5": { + "type": "object", + "properties": { + "subOrganizationName": { + "type": "string", + "description": "Name for this sub-organization" + }, + "rootUsers": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1RootUserParamsV2" + }, + "description": "Root users to create within this sub-organization" + }, + "rootQuorumThreshold": { + "type": "integer", + "format": "int32", + "description": "The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users" + }, + "wallet": { + "$ref": "#/definitions/v1WalletParams", + "description": "The wallet to create for the sub-organization" + }, + "disableEmailRecovery": { + "type": "boolean", + "description": "Disable email recovery for the sub-organization" + }, + "disableEmailAuth": { + "type": "boolean", + "description": "Disable email auth for the sub-organization" + } + }, + "required": ["subOrganizationName", "rootUsers", "rootQuorumThreshold"] + }, + "v1CreateSubOrganizationIntentV6": { + "type": "object", + "properties": { + "subOrganizationName": { + "type": "string", + "description": "Name for this sub-organization" + }, + "rootUsers": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1RootUserParamsV3" + }, + "description": "Root users to create within this sub-organization" + }, + "rootQuorumThreshold": { + "type": "integer", + "format": "int32", + "description": "The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users" + }, + "wallet": { + "$ref": "#/definitions/v1WalletParams", + "description": "The wallet to create for the sub-organization" + }, + "disableEmailRecovery": { + "type": "boolean", + "description": "Disable email recovery for the sub-organization" + }, + "disableEmailAuth": { + "type": "boolean", + "description": "Disable email auth for the sub-organization" + } + }, + "required": ["subOrganizationName", "rootUsers", "rootQuorumThreshold"] + }, + "v1CreateSubOrganizationIntentV7": { + "type": "object", + "properties": { + "subOrganizationName": { + "type": "string", + "description": "Name for this sub-organization" + }, + "rootUsers": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1RootUserParamsV4" + }, + "description": "Root users to create within this sub-organization" + }, + "rootQuorumThreshold": { + "type": "integer", + "format": "int32", + "description": "The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users" + }, + "wallet": { + "$ref": "#/definitions/v1WalletParams", + "description": "The wallet to create for the sub-organization" + }, + "disableEmailRecovery": { + "type": "boolean", + "description": "Disable email recovery for the sub-organization" + }, + "disableEmailAuth": { + "type": "boolean", + "description": "Disable email auth for the sub-organization" + }, + "disableSmsAuth": { + "type": "boolean", + "description": "Disable OTP SMS auth for the sub-organization" + }, + "disableOtpEmailAuth": { + "type": "boolean", + "description": "Disable OTP email auth for the sub-organization" + } + }, + "required": ["subOrganizationName", "rootUsers", "rootQuorumThreshold"] + }, + "v1CreateSubOrganizationRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_CREATE_SUB_ORGANIZATION_V7"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1CreateSubOrganizationIntentV7" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1CreateSubOrganizationResult": { + "type": "object", + "properties": { + "subOrganizationId": { + "type": "string" + }, + "rootUserIds": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": ["subOrganizationId"] + }, + "v1CreateSubOrganizationResultV3": { + "type": "object", + "properties": { + "subOrganizationId": { + "type": "string" + }, + "privateKeys": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1PrivateKeyResult" + }, + "description": "A list of Private Key IDs and addresses." + }, + "rootUserIds": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": ["subOrganizationId", "privateKeys"] + }, + "v1CreateSubOrganizationResultV4": { + "type": "object", + "properties": { + "subOrganizationId": { + "type": "string" + }, + "wallet": { + "$ref": "#/definitions/v1WalletResult" + }, + "rootUserIds": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": ["subOrganizationId"] + }, + "v1CreateSubOrganizationResultV5": { + "type": "object", + "properties": { + "subOrganizationId": { + "type": "string" + }, + "wallet": { + "$ref": "#/definitions/v1WalletResult" + }, + "rootUserIds": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": ["subOrganizationId"] + }, + "v1CreateSubOrganizationResultV6": { + "type": "object", + "properties": { + "subOrganizationId": { + "type": "string" + }, + "wallet": { + "$ref": "#/definitions/v1WalletResult" + }, + "rootUserIds": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": ["subOrganizationId"] + }, + "v1CreateSubOrganizationResultV7": { + "type": "object", + "properties": { + "subOrganizationId": { + "type": "string" + }, + "wallet": { + "$ref": "#/definitions/v1WalletResult" + }, + "rootUserIds": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": ["subOrganizationId"] + }, + "v1CreateUserTagIntent": { + "type": "object", + "properties": { + "userTagName": { + "type": "string", + "description": "Human-readable name for a User Tag." + }, + "userIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of User IDs." + } + }, + "required": ["userTagName", "userIds"] + }, + "v1CreateUserTagRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_CREATE_USER_TAG"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1CreateUserTagIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1CreateUserTagResult": { + "type": "object", + "properties": { + "userTagId": { + "type": "string", + "description": "Unique identifier for a given User Tag." + }, + "userIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of User IDs." + } + }, + "required": ["userTagId", "userIds"] + }, + "v1CreateUsersIntent": { + "type": "object", + "properties": { + "users": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1UserParams" + }, + "description": "A list of Users." + } + }, + "required": ["users"] + }, + "v1CreateUsersIntentV2": { + "type": "object", + "properties": { + "users": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1UserParamsV2" + }, + "description": "A list of Users." + } + }, + "required": ["users"] + }, + "v1CreateUsersIntentV3": { + "type": "object", + "properties": { + "users": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1UserParamsV3" + }, + "description": "A list of Users." + } + }, + "required": ["users"] + }, + "v1CreateUsersRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_CREATE_USERS_V3"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1CreateUsersIntentV3" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1CreateUsersResult": { + "type": "object", + "properties": { + "userIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of User IDs." + } + }, + "required": ["userIds"] + }, + "v1CreateWalletAccountsIntent": { + "type": "object", + "properties": { + "walletId": { + "type": "string", + "description": "Unique identifier for a given Wallet." + }, + "accounts": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1WalletAccountParams" + }, + "description": "A list of wallet Accounts." + } + }, + "required": ["walletId", "accounts"] + }, + "v1CreateWalletAccountsRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_CREATE_WALLET_ACCOUNTS"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1CreateWalletAccountsIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1CreateWalletAccountsResult": { + "type": "object", + "properties": { + "addresses": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of derived addresses." + } + }, + "required": ["addresses"] + }, + "v1CreateWalletIntent": { + "type": "object", + "properties": { + "walletName": { + "type": "string", + "description": "Human-readable name for a Wallet." + }, + "accounts": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1WalletAccountParams" + }, + "description": "A list of wallet Accounts. This field, if not needed, should be an empty array in your request body." + }, + "mnemonicLength": { + "type": "integer", + "format": "int32", + "description": "Length of mnemonic to generate the Wallet seed. Defaults to 12. Accepted values: 12, 15, 18, 21, 24." + } + }, + "required": ["walletName", "accounts"] + }, + "v1CreateWalletRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_CREATE_WALLET"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1CreateWalletIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1CreateWalletResult": { + "type": "object", + "properties": { + "walletId": { + "type": "string", + "description": "Unique identifier for a Wallet." + }, + "addresses": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of account addresses." + } + }, + "required": ["walletId", "addresses"] + }, + "v1CredPropsAuthenticationExtensionsClientOutputs": { + "type": "object", + "properties": { + "rk": { + "type": "boolean" + } + }, + "required": ["rk"] + }, + "v1CredentialType": { + "type": "string", + "enum": [ + "CREDENTIAL_TYPE_WEBAUTHN_AUTHENTICATOR", + "CREDENTIAL_TYPE_API_KEY_P256", + "CREDENTIAL_TYPE_RECOVER_USER_KEY_P256", + "CREDENTIAL_TYPE_API_KEY_SECP256K1", + "CREDENTIAL_TYPE_EMAIL_AUTH_KEY_P256", + "CREDENTIAL_TYPE_API_KEY_ED25519", + "CREDENTIAL_TYPE_OTP_AUTH_KEY_P256", + "CREDENTIAL_TYPE_READ_WRITE_SESSION_KEY_P256", + "CREDENTIAL_TYPE_OAUTH_KEY_P256", + "CREDENTIAL_TYPE_LOGIN" + ] + }, + "v1Curve": { + "type": "string", + "enum": ["CURVE_SECP256K1", "CURVE_ED25519"] + }, + "v1DeleteApiKeysIntent": { + "type": "object", + "properties": { + "userId": { + "type": "string", + "description": "Unique identifier for a given User." + }, + "apiKeyIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of API Key IDs." + } + }, + "required": ["userId", "apiKeyIds"] + }, + "v1DeleteApiKeysRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_DELETE_API_KEYS"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1DeleteApiKeysIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1DeleteApiKeysResult": { + "type": "object", + "properties": { + "apiKeyIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of API Key IDs." + } + }, + "required": ["apiKeyIds"] + }, + "v1DeleteAuthenticatorsIntent": { + "type": "object", + "properties": { + "userId": { + "type": "string", + "description": "Unique identifier for a given User." + }, + "authenticatorIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of Authenticator IDs." + } + }, + "required": ["userId", "authenticatorIds"] + }, + "v1DeleteAuthenticatorsRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_DELETE_AUTHENTICATORS"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1DeleteAuthenticatorsIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1DeleteAuthenticatorsResult": { + "type": "object", + "properties": { + "authenticatorIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Unique identifier for a given Authenticator." + } + }, + "required": ["authenticatorIds"] + }, + "v1DeleteInvitationIntent": { + "type": "object", + "properties": { + "invitationId": { + "type": "string", + "description": "Unique identifier for a given Invitation object." + } + }, + "required": ["invitationId"] + }, + "v1DeleteInvitationRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_DELETE_INVITATION"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1DeleteInvitationIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1DeleteInvitationResult": { + "type": "object", + "properties": { + "invitationId": { + "type": "string", + "description": "Unique identifier for a given Invitation." + } + }, + "required": ["invitationId"] + }, + "v1DeleteOauthProvidersIntent": { + "type": "object", + "properties": { + "userId": { + "type": "string", + "description": "The ID of the User to remove an Oauth provider from" + }, + "providerIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Unique identifier for a given Provider." + } + }, + "required": ["userId", "providerIds"] + }, + "v1DeleteOauthProvidersRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_DELETE_OAUTH_PROVIDERS"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1DeleteOauthProvidersIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1DeleteOauthProvidersResult": { + "type": "object", + "properties": { + "providerIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of unique identifiers for Oauth Providers" + } + }, + "required": ["providerIds"] + }, + "v1DeleteOrganizationIntent": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + } + }, + "required": ["organizationId"] + }, + "v1DeleteOrganizationResult": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + } + }, + "required": ["organizationId"] + }, + "v1DeletePolicyIntent": { + "type": "object", + "properties": { + "policyId": { + "type": "string", + "description": "Unique identifier for a given Policy." + } + }, + "required": ["policyId"] + }, + "v1DeletePolicyRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_DELETE_POLICY"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1DeletePolicyIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1DeletePolicyResult": { + "type": "object", + "properties": { + "policyId": { + "type": "string", + "description": "Unique identifier for a given Policy." + } + }, + "required": ["policyId"] + }, + "v1DeletePrivateKeyTagsIntent": { + "type": "object", + "properties": { + "privateKeyTagIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of Private Key Tag IDs." + } + }, + "required": ["privateKeyTagIds"] + }, + "v1DeletePrivateKeyTagsRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_DELETE_PRIVATE_KEY_TAGS"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1DeletePrivateKeyTagsIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1DeletePrivateKeyTagsResult": { + "type": "object", + "properties": { + "privateKeyTagIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of Private Key Tag IDs." + }, + "privateKeyIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of Private Key IDs." + } + }, + "required": ["privateKeyTagIds", "privateKeyIds"] + }, + "v1DeletePrivateKeysIntent": { + "type": "object", + "properties": { + "privateKeyIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "List of unique identifiers for private keys within an organization" + }, + "deleteWithoutExport": { + "type": "boolean", + "description": "Optional parameter for deleting the private keys, even if any have not been previously exported. If they have been exported, this field is ignored." + } + }, + "required": ["privateKeyIds"] + }, + "v1DeletePrivateKeysRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_DELETE_PRIVATE_KEYS"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1DeletePrivateKeysIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1DeletePrivateKeysResult": { + "type": "object", + "properties": { + "privateKeyIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of private key unique identifiers that were removed" + } + }, + "required": ["privateKeyIds"] + }, + "v1DeleteSubOrganizationIntent": { + "type": "object", + "properties": { + "deleteWithoutExport": { + "type": "boolean", + "description": "Sub-organization deletion, by default, requires associated wallets and private keys to be exported for security reasons. Set this boolean to true to force sub-organization deletion even if some wallets or private keys within it have not been exported yet. Default: false." + } + } + }, + "v1DeleteSubOrganizationRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_DELETE_SUB_ORGANIZATION"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1DeleteSubOrganizationIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1DeleteSubOrganizationResult": { + "type": "object", + "properties": { + "subOrganizationUuid": { + "type": "string", + "description": "Unique identifier of the sub organization that was removed" + } + }, + "required": ["subOrganizationUuid"] + }, + "v1DeleteUserTagsIntent": { + "type": "object", + "properties": { + "userTagIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of User Tag IDs." + } + }, + "required": ["userTagIds"] + }, + "v1DeleteUserTagsRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_DELETE_USER_TAGS"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1DeleteUserTagsIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1DeleteUserTagsResult": { + "type": "object", + "properties": { + "userTagIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of User Tag IDs." + }, + "userIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of User IDs." + } + }, + "required": ["userTagIds", "userIds"] + }, + "v1DeleteUsersIntent": { + "type": "object", + "properties": { + "userIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of User IDs." + } + }, + "required": ["userIds"] + }, + "v1DeleteUsersRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_DELETE_USERS"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1DeleteUsersIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1DeleteUsersResult": { + "type": "object", + "properties": { + "userIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of User IDs." + } + }, + "required": ["userIds"] + }, + "v1DeleteWalletsIntent": { + "type": "object", + "properties": { + "walletIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "List of unique identifiers for wallets within an organization" + }, + "deleteWithoutExport": { + "type": "boolean", + "description": "Optional parameter for deleting the wallets, even if any have not been previously exported. If they have been exported, this field is ignored." + } + }, + "required": ["walletIds"] + }, + "v1DeleteWalletsRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_DELETE_WALLETS"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1DeleteWalletsIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1DeleteWalletsResult": { + "type": "object", + "properties": { + "walletIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of wallet unique identifiers that were removed" + } + }, + "required": ["walletIds"] + }, + "v1DisablePrivateKeyIntent": { + "type": "object", + "properties": { + "privateKeyId": { + "type": "string", + "description": "Unique identifier for a given Private Key." + } + }, + "required": ["privateKeyId"] + }, + "v1DisablePrivateKeyResult": { + "type": "object", + "properties": { + "privateKeyId": { + "type": "string", + "description": "Unique identifier for a given Private Key." + } + }, + "required": ["privateKeyId"] + }, + "v1Effect": { + "type": "string", + "enum": ["EFFECT_ALLOW", "EFFECT_DENY"] + }, + "v1EmailAuthIntent": { + "type": "object", + "properties": { + "email": { + "type": "string", + "description": "Email of the authenticating user." + }, + "targetPublicKey": { + "type": "string", + "description": "Client-side public key generated by the user, to which the email auth bundle (credentials) will be encrypted." + }, + "apiKeyName": { + "type": "string", + "description": "Optional human-readable name for an API Key. If none provided, default to Email Auth - \u003cTimestamp\u003e" + }, + "expirationSeconds": { + "type": "string", + "description": "Expiration window (in seconds) indicating how long the API key is valid for. If not provided, a default of 15 minutes will be used." + }, + "emailCustomization": { + "$ref": "#/definitions/v1EmailCustomizationParams", + "description": "Optional parameters for customizing emails. If not provided, the default email will be used." + }, + "invalidateExisting": { + "type": "boolean", + "description": "Invalidate all other previously generated Email Auth API keys" + }, + "sendFromEmailAddress": { + "type": "string", + "description": "Optional custom email address from which to send the email" + }, + "sendFromEmailSenderName": { + "type": "string", + "description": "Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications'" + }, + "replyToEmailAddress": { + "type": "string", + "description": "Optional custom email address to use as reply-to" + } + }, + "required": ["email", "targetPublicKey"] + }, + "v1EmailAuthIntentV2": { + "type": "object", + "properties": { + "email": { + "type": "string", + "description": "Email of the authenticating user." + }, + "targetPublicKey": { + "type": "string", + "description": "Client-side public key generated by the user, to which the email auth bundle (credentials) will be encrypted." + }, + "apiKeyName": { + "type": "string", + "description": "Optional human-readable name for an API Key. If none provided, default to Email Auth - \u003cTimestamp\u003e" + }, + "expirationSeconds": { + "type": "string", + "description": "Expiration window (in seconds) indicating how long the API key is valid for. If not provided, a default of 15 minutes will be used." + }, + "emailCustomization": { + "$ref": "#/definitions/v1EmailCustomizationParams", + "description": "Optional parameters for customizing emails. If not provided, the default email will be used." + }, + "invalidateExisting": { + "type": "boolean", + "description": "Invalidate all other previously generated Email Auth API keys" + }, + "sendFromEmailAddress": { + "type": "string", + "description": "Optional custom email address from which to send the email" + }, + "sendFromEmailSenderName": { + "type": "string", + "description": "Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications'" + }, + "replyToEmailAddress": { + "type": "string", + "description": "Optional custom email address to use as reply-to" + } + }, + "required": ["email", "targetPublicKey"] + }, + "v1EmailAuthRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_EMAIL_AUTH_V2"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1EmailAuthIntentV2" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1EmailAuthResult": { + "type": "object", + "properties": { + "userId": { + "type": "string", + "description": "Unique identifier for the authenticating User." + }, + "apiKeyId": { + "type": "string", + "description": "Unique identifier for the created API key." + } + }, + "required": ["userId", "apiKeyId"] + }, + "v1EmailCustomizationParams": { + "type": "object", + "properties": { + "appName": { + "type": "string", + "description": "The name of the application." + }, + "logoUrl": { + "type": "string", + "description": "A URL pointing to a logo in PNG format. Note this logo will be resized to fit into 340px x 124px." + }, + "magicLinkTemplate": { + "type": "string", + "description": "A template for the URL to be used in a magic link button, e.g. `https://dapp.xyz/%s`. The auth bundle will be interpolated into the `%s`." + }, + "templateVariables": { + "type": "string", + "description": "JSON object containing key/value pairs to be used with custom templates." + }, + "templateId": { + "type": "string", + "description": "Unique identifier for a given Email Template. If not specified, the default is the most recent Email Template." + } + } + }, + "v1ExportPrivateKeyIntent": { + "type": "object", + "properties": { + "privateKeyId": { + "type": "string", + "description": "Unique identifier for a given Private Key." + }, + "targetPublicKey": { + "type": "string", + "description": "Client-side public key generated by the user, to which the export bundle will be encrypted." + } + }, + "required": ["privateKeyId", "targetPublicKey"] + }, + "v1ExportPrivateKeyRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_EXPORT_PRIVATE_KEY"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1ExportPrivateKeyIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1ExportPrivateKeyResult": { + "type": "object", + "properties": { + "privateKeyId": { + "type": "string", + "description": "Unique identifier for a given Private Key." + }, + "exportBundle": { + "type": "string", + "description": "Export bundle containing a private key encrypted to the client's target public key." + } + }, + "required": ["privateKeyId", "exportBundle"] + }, + "v1ExportWalletAccountIntent": { + "type": "object", + "properties": { + "address": { + "type": "string", + "description": "Address to identify Wallet Account." + }, + "targetPublicKey": { + "type": "string", + "description": "Client-side public key generated by the user, to which the export bundle will be encrypted." + } + }, + "required": ["address", "targetPublicKey"] + }, + "v1ExportWalletAccountRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_EXPORT_WALLET_ACCOUNT"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1ExportWalletAccountIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1ExportWalletAccountResult": { + "type": "object", + "properties": { + "address": { + "type": "string", + "description": "Address to identify Wallet Account." + }, + "exportBundle": { + "type": "string", + "description": "Export bundle containing a private key encrypted by the client's target public key." + } + }, + "required": ["address", "exportBundle"] + }, + "v1ExportWalletIntent": { + "type": "object", + "properties": { + "walletId": { + "type": "string", + "description": "Unique identifier for a given Wallet." + }, + "targetPublicKey": { + "type": "string", + "description": "Client-side public key generated by the user, to which the export bundle will be encrypted." + }, + "language": { + "$ref": "#/definitions/v1MnemonicLanguage", + "description": "The language of the mnemonic to export. Defaults to English." + } + }, + "required": ["walletId", "targetPublicKey"] + }, + "v1ExportWalletRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_EXPORT_WALLET"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1ExportWalletIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1ExportWalletResult": { + "type": "object", + "properties": { + "walletId": { + "type": "string", + "description": "Unique identifier for a given Wallet." + }, + "exportBundle": { + "type": "string", + "description": "Export bundle containing a wallet mnemonic + optional newline passphrase encrypted by the client's target public key." + } + }, + "required": ["walletId", "exportBundle"] + }, + "v1Feature": { + "type": "object", + "properties": { + "name": { + "$ref": "#/definitions/v1FeatureName" + }, + "value": { + "type": "string" + } + } + }, + "v1FeatureName": { + "type": "string", + "enum": [ + "FEATURE_NAME_ROOT_USER_EMAIL_RECOVERY", + "FEATURE_NAME_WEBAUTHN_ORIGINS", + "FEATURE_NAME_EMAIL_AUTH", + "FEATURE_NAME_EMAIL_RECOVERY", + "FEATURE_NAME_WEBHOOK", + "FEATURE_NAME_SMS_AUTH", + "FEATURE_NAME_OTP_EMAIL_AUTH" + ] + }, + "v1GetActivitiesRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "filterByStatus": { + "type": "array", + "items": { + "$ref": "#/definitions/v1ActivityStatus" + }, + "description": "Array of Activity Statuses filtering which Activities will be listed in the response." + }, + "paginationOptions": { + "$ref": "#/definitions/v1Pagination", + "description": "Parameters used for cursor-based pagination." + }, + "filterByType": { + "type": "array", + "items": { + "$ref": "#/definitions/v1ActivityType" + }, + "description": "Array of Activity Types filtering which Activities will be listed in the response." + } + }, + "required": ["organizationId"] + }, + "v1GetActivitiesResponse": { + "type": "object", + "properties": { + "activities": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1Activity" + }, + "description": "A list of Activities." + } + }, + "required": ["activities"] + }, + "v1GetActivityRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "activityId": { + "type": "string", + "description": "Unique identifier for a given Activity object." + } + }, + "required": ["organizationId", "activityId"] + }, + "v1GetApiKeyRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "apiKeyId": { + "type": "string", + "description": "Unique identifier for a given API key." + } + }, + "required": ["organizationId", "apiKeyId"] + }, + "v1GetApiKeyResponse": { + "type": "object", + "properties": { + "apiKey": { + "$ref": "#/definitions/v1ApiKey", + "description": "An API key." + } + }, + "required": ["apiKey"] + }, + "v1GetApiKeysRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "userId": { + "type": "string", + "description": "Unique identifier for a given User." + } + }, + "required": ["organizationId"] + }, + "v1GetApiKeysResponse": { + "type": "object", + "properties": { + "apiKeys": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1ApiKey" + }, + "description": "A list of API keys." + } + }, + "required": ["apiKeys"] + }, + "v1GetAttestationDocumentRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "enclaveType": { + "type": "string", + "description": "The enclave type, one of: ump, notarizer, signer, evm-parser" + } + }, + "required": ["organizationId", "enclaveType"] + }, + "v1GetAttestationDocumentResponse": { + "type": "object", + "properties": { + "attestationDocument": { + "type": "string", + "format": "byte", + "description": "Raw (CBOR-encoded) attestation document" + } + }, + "required": ["attestationDocument"] + }, + "v1GetAuthenticatorRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "authenticatorId": { + "type": "string", + "description": "Unique identifier for a given Authenticator." + } + }, + "required": ["organizationId", "authenticatorId"] + }, + "v1GetAuthenticatorResponse": { + "type": "object", + "properties": { + "authenticator": { + "$ref": "#/definitions/v1Authenticator", + "description": "An authenticator." + } + }, + "required": ["authenticator"] + }, + "v1GetAuthenticatorsRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "userId": { + "type": "string", + "description": "Unique identifier for a given User." + } + }, + "required": ["organizationId", "userId"] + }, + "v1GetAuthenticatorsResponse": { + "type": "object", + "properties": { + "authenticators": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1Authenticator" + }, + "description": "A list of authenticators." + } + }, + "required": ["authenticators"] + }, + "v1GetOauthProvidersRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "userId": { + "type": "string", + "description": "Unique identifier for a given User." + } + }, + "required": ["organizationId"] + }, + "v1GetOauthProvidersResponse": { + "type": "object", + "properties": { + "oauthProviders": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1OauthProvider" + }, + "description": "A list of Oauth Providers" + } + }, + "required": ["oauthProviders"] + }, + "v1GetOrganizationConfigsRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + } + }, + "required": ["organizationId"] + }, + "v1GetOrganizationConfigsResponse": { + "type": "object", + "properties": { + "configs": { + "$ref": "#/definitions/v1Config", + "description": "Organization configs including quorum settings and organization features" + } + }, + "required": ["configs"] + }, + "v1GetOrganizationRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + } + }, + "required": ["organizationId"] + }, + "v1GetOrganizationResponse": { + "type": "object", + "properties": { + "organizationData": { + "$ref": "#/definitions/v1OrganizationData", + "description": "Object representing the full current and deleted / disabled collection of Users, Policies, Private Keys, and Invitations attributable to a particular Organization." + } + }, + "required": ["organizationData"] + }, + "v1GetPoliciesRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + } + }, + "required": ["organizationId"] + }, + "v1GetPoliciesResponse": { + "type": "object", + "properties": { + "policies": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1Policy" + }, + "description": "A list of Policies." + } + }, + "required": ["policies"] + }, + "v1GetPolicyRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "policyId": { + "type": "string", + "description": "Unique identifier for a given Policy." + } + }, + "required": ["organizationId", "policyId"] + }, + "v1GetPolicyResponse": { + "type": "object", + "properties": { + "policy": { + "$ref": "#/definitions/v1Policy", + "description": "Object that codifies rules defining the actions that are permissible within an Organization." + } + }, + "required": ["policy"] + }, + "v1GetPrivateKeyRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "privateKeyId": { + "type": "string", + "description": "Unique identifier for a given Private Key." + } + }, + "required": ["organizationId", "privateKeyId"] + }, + "v1GetPrivateKeyResponse": { + "type": "object", + "properties": { + "privateKey": { + "$ref": "#/definitions/v1PrivateKey", + "description": "Cryptographic public/private key pair that can be used for cryptocurrency needs or more generalized encryption." + } + }, + "required": ["privateKey"] + }, + "v1GetPrivateKeysRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + } + }, + "required": ["organizationId"] + }, + "v1GetPrivateKeysResponse": { + "type": "object", + "properties": { + "privateKeys": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1PrivateKey" + }, + "description": "A list of Private Keys." + } + }, + "required": ["privateKeys"] + }, + "v1GetSubOrgIdsRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for the parent Organization. This is used to find sub-organizations within it." + }, + "filterType": { + "type": "string", + "description": "Specifies the type of filter to apply, i.e 'CREDENTIAL_ID', 'NAME', 'USERNAME', 'EMAIL', 'PHONE_NUMBER', 'OIDC_TOKEN' or 'PUBLIC_KEY'" + }, + "filterValue": { + "type": "string", + "description": "The value of the filter to apply for the specified type. For example, a specific email or name string." + }, + "paginationOptions": { + "$ref": "#/definitions/v1Pagination", + "description": "Parameters used for cursor-based pagination." + } + }, + "required": ["organizationId"] + }, + "v1GetSubOrgIdsResponse": { + "type": "object", + "properties": { + "organizationIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "List of unique identifiers for the matching sub-organizations." + } + }, + "required": ["organizationIds"] + }, + "v1GetUserRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "userId": { + "type": "string", + "description": "Unique identifier for a given User." + } + }, + "required": ["organizationId", "userId"] + }, + "v1GetUserResponse": { + "type": "object", + "properties": { + "user": { + "$ref": "#/definitions/v1User", + "description": "Web and/or API user within your Organization." + } + }, + "required": ["user"] + }, + "v1GetUsersRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + } + }, + "required": ["organizationId"] + }, + "v1GetUsersResponse": { + "type": "object", + "properties": { + "users": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1User" + }, + "description": "A list of Users." + } + }, + "required": ["users"] + }, + "v1GetVerifiedSubOrgIdsRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for the parent Organization. This is used to find sub-organizations within it." + }, + "filterType": { + "type": "string", + "description": "Specifies the type of filter to apply, i.e 'EMAIL', 'PHONE_NUMBER'" + }, + "filterValue": { + "type": "string", + "description": "The value of the filter to apply for the specified type. For example, a specific email or phone number string." + }, + "paginationOptions": { + "$ref": "#/definitions/v1Pagination", + "description": "Parameters used for cursor-based pagination." + } + }, + "required": ["organizationId"] + }, + "v1GetVerifiedSubOrgIdsResponse": { + "type": "object", + "properties": { + "organizationIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "List of unique identifiers for the matching sub-organizations." + } + }, + "required": ["organizationIds"] + }, + "v1GetWalletAccountRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "walletId": { + "type": "string", + "description": "Unique identifier for a given Wallet." + }, + "address": { + "type": "string", + "description": "Address corresponding to a Wallet Account." + }, + "path": { + "type": "string", + "description": "Path corresponding to a Wallet Account." + } + }, + "required": ["organizationId", "walletId"] + }, + "v1GetWalletAccountResponse": { + "type": "object", + "properties": { + "account": { + "$ref": "#/definitions/v1WalletAccount", + "description": "The resulting Wallet Account." + } + }, + "required": ["account"] + }, + "v1GetWalletAccountsRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "walletId": { + "type": "string", + "description": "Unique identifier for a given Wallet." + }, + "paginationOptions": { + "$ref": "#/definitions/v1Pagination", + "description": "Parameters used for cursor-based pagination." + } + }, + "required": ["organizationId", "walletId"] + }, + "v1GetWalletAccountsResponse": { + "type": "object", + "properties": { + "accounts": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1WalletAccount" + }, + "description": "A list of Accounts generated from a Wallet that share a common seed." + } + }, + "required": ["accounts"] + }, + "v1GetWalletRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "walletId": { + "type": "string", + "description": "Unique identifier for a given Wallet." + } + }, + "required": ["organizationId", "walletId"] + }, + "v1GetWalletResponse": { + "type": "object", + "properties": { + "wallet": { + "$ref": "#/definitions/v1Wallet", + "description": "A collection of deterministically generated cryptographic public / private key pairs that share a common seed" + } + }, + "required": ["wallet"] + }, + "v1GetWalletsRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + } + }, + "required": ["organizationId"] + }, + "v1GetWalletsResponse": { + "type": "object", + "properties": { + "wallets": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1Wallet" + }, + "description": "A list of Wallets." + } + }, + "required": ["wallets"] + }, + "v1GetWhoamiRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "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." + } + }, + "required": ["organizationId"] + }, + "v1GetWhoamiResponse": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "organizationName": { + "type": "string", + "description": "Human-readable name for an Organization." + }, + "userId": { + "type": "string", + "description": "Unique identifier for a given User." + }, + "username": { + "type": "string", + "description": "Human-readable name for a User." + } + }, + "required": ["organizationId", "organizationName", "userId", "username"] + }, + "v1HashFunction": { + "type": "string", + "enum": [ + "HASH_FUNCTION_NO_OP", + "HASH_FUNCTION_SHA256", + "HASH_FUNCTION_KECCAK256", + "HASH_FUNCTION_NOT_APPLICABLE" + ] + }, + "v1ImportPrivateKeyIntent": { + "type": "object", + "properties": { + "userId": { + "type": "string", + "description": "The ID of the User importing a Private Key." + }, + "privateKeyName": { + "type": "string", + "description": "Human-readable name for a Private Key." + }, + "encryptedBundle": { + "type": "string", + "description": "Bundle containing a raw private key encrypted to the enclave's target public key." + }, + "curve": { + "$ref": "#/definitions/v1Curve", + "description": "Cryptographic Curve used to generate a given Private Key." + }, + "addressFormats": { + "type": "array", + "items": { + "$ref": "#/definitions/v1AddressFormat" + }, + "description": "Cryptocurrency-specific formats for a derived address (e.g., Ethereum)." + } + }, + "required": [ + "userId", + "privateKeyName", + "encryptedBundle", + "curve", + "addressFormats" + ] + }, + "v1ImportPrivateKeyRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_IMPORT_PRIVATE_KEY"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1ImportPrivateKeyIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1ImportPrivateKeyResult": { + "type": "object", + "properties": { + "privateKeyId": { + "type": "string", + "description": "Unique identifier for a Private Key." + }, + "addresses": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/immutableactivityv1Address" + }, + "description": "A list of addresses." + } + }, + "required": ["privateKeyId", "addresses"] + }, + "v1ImportWalletIntent": { + "type": "object", + "properties": { + "userId": { + "type": "string", + "description": "The ID of the User importing a Wallet." + }, + "walletName": { + "type": "string", + "description": "Human-readable name for a Wallet." + }, + "encryptedBundle": { + "type": "string", + "description": "Bundle containing a wallet mnemonic encrypted to the enclave's target public key." + }, + "accounts": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1WalletAccountParams" + }, + "description": "A list of wallet Accounts." + } + }, + "required": ["userId", "walletName", "encryptedBundle", "accounts"] + }, + "v1ImportWalletRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_IMPORT_WALLET"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1ImportWalletIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1ImportWalletResult": { + "type": "object", + "properties": { + "walletId": { + "type": "string", + "description": "Unique identifier for a Wallet." + }, + "addresses": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of account addresses." + } + }, + "required": ["walletId", "addresses"] + }, + "v1InitImportPrivateKeyIntent": { + "type": "object", + "properties": { + "userId": { + "type": "string", + "description": "The ID of the User importing a Private Key." + } + }, + "required": ["userId"] + }, + "v1InitImportPrivateKeyRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_INIT_IMPORT_PRIVATE_KEY"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1InitImportPrivateKeyIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1InitImportPrivateKeyResult": { + "type": "object", + "properties": { + "importBundle": { + "type": "string", + "description": "Import bundle containing a public key and signature to use for importing client data." + } + }, + "required": ["importBundle"] + }, + "v1InitImportWalletIntent": { + "type": "object", + "properties": { + "userId": { + "type": "string", + "description": "The ID of the User importing a Wallet." + } + }, + "required": ["userId"] + }, + "v1InitImportWalletRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_INIT_IMPORT_WALLET"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1InitImportWalletIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1InitImportWalletResult": { + "type": "object", + "properties": { + "importBundle": { + "type": "string", + "description": "Import bundle containing a public key and signature to use for importing client data." + } + }, + "required": ["importBundle"] + }, + "v1InitOtpAuthIntent": { + "type": "object", + "properties": { + "otpType": { + "type": "string", + "description": "Enum to specifiy whether to send OTP via SMS or email" + }, + "contact": { + "type": "string", + "description": "Email or phone number to send the OTP code to" + }, + "emailCustomization": { + "$ref": "#/definitions/v1EmailCustomizationParams", + "description": "Optional parameters for customizing emails. If not provided, the default email will be used." + }, + "smsCustomization": { + "$ref": "#/definitions/v1SmsCustomizationParams", + "description": "Optional parameters for customizing SMS message. If not provided, the default sms message will be used." + }, + "userIdentifier": { + "type": "string", + "description": "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." + }, + "sendFromEmailAddress": { + "type": "string", + "description": "Optional custom email address from which to send the OTP email" + }, + "sendFromEmailSenderName": { + "type": "string", + "description": "Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications'" + }, + "replyToEmailAddress": { + "type": "string", + "description": "Optional custom email address to use as reply-to" + } + }, + "required": ["otpType", "contact"] + }, + "v1InitOtpAuthIntentV2": { + "type": "object", + "properties": { + "otpType": { + "type": "string", + "description": "Enum to specifiy whether to send OTP via SMS or email" + }, + "contact": { + "type": "string", + "description": "Email or phone number to send the OTP code to" + }, + "otpLength": { + "type": "integer", + "format": "int32", + "description": "Optional length of the OTP code. Default = 9" + }, + "emailCustomization": { + "$ref": "#/definitions/v1EmailCustomizationParams", + "description": "Optional parameters for customizing emails. If not provided, the default email will be used." + }, + "smsCustomization": { + "$ref": "#/definitions/v1SmsCustomizationParams", + "description": "Optional parameters for customizing SMS message. If not provided, the default sms message will be used." + }, + "userIdentifier": { + "type": "string", + "description": "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." + }, + "sendFromEmailAddress": { + "type": "string", + "description": "Optional custom email address from which to send the OTP email" + }, + "alphanumeric": { + "type": "boolean", + "description": "Optional flag to specify if the OTP code should be alphanumeric (Crockford’s Base32). Default = true" + }, + "sendFromEmailSenderName": { + "type": "string", + "description": "Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications'" + }, + "replyToEmailAddress": { + "type": "string", + "description": "Optional custom email address to use as reply-to" + } + }, + "required": ["otpType", "contact"] + }, + "v1InitOtpAuthRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_INIT_OTP_AUTH_V2"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1InitOtpAuthIntentV2" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1InitOtpAuthResult": { + "type": "object", + "properties": { + "otpId": { + "type": "string", + "description": "Unique identifier for an OTP authentication" + } + }, + "required": ["otpId"] + }, + "v1InitOtpAuthResultV2": { + "type": "object", + "properties": { + "otpId": { + "type": "string", + "description": "Unique identifier for an OTP authentication" + } + }, + "required": ["otpId"] + }, + "v1InitOtpIntent": { + "type": "object", + "properties": { + "otpType": { + "type": "string", + "description": "Whether to send OTP via SMS or email. Possible values: OTP_TYPE_SMS, OTP_TYPE_EMAIL" + }, + "contact": { + "type": "string", + "description": "Email or phone number to send the OTP code to" + }, + "otpLength": { + "type": "integer", + "format": "int32", + "description": "Optional length of the OTP code. Default = 9" + }, + "emailCustomization": { + "$ref": "#/definitions/v1EmailCustomizationParams", + "description": "Optional parameters for customizing emails. If not provided, the default email will be used." + }, + "smsCustomization": { + "$ref": "#/definitions/v1SmsCustomizationParams", + "description": "Optional parameters for customizing SMS message. If not provided, the default sms message will be used." + }, + "userIdentifier": { + "type": "string", + "description": "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." + }, + "sendFromEmailAddress": { + "type": "string", + "description": "Optional custom email address from which to send the OTP email" + }, + "alphanumeric": { + "type": "boolean", + "description": "Optional flag to specify if the OTP code should be alphanumeric (Crockford’s Base32). Default = true" + }, + "sendFromEmailSenderName": { + "type": "string", + "description": "Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications'" + }, + "expirationSeconds": { + "type": "string", + "description": "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)" + }, + "replyToEmailAddress": { + "type": "string", + "description": "Optional custom email address to use as reply-to" + } + }, + "required": ["otpType", "contact"] + }, + "v1InitOtpRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_INIT_OTP"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1InitOtpIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1InitOtpResult": { + "type": "object", + "properties": { + "otpId": { + "type": "string", + "description": "Unique identifier for an OTP authentication" + } + }, + "required": ["otpId"] + }, + "v1InitUserEmailRecoveryIntent": { + "type": "object", + "properties": { + "email": { + "type": "string", + "description": "Email of the user starting recovery" + }, + "targetPublicKey": { + "type": "string", + "description": "Client-side public key generated by the user, to which the recovery bundle will be encrypted." + }, + "expirationSeconds": { + "type": "string", + "description": "Expiration window (in seconds) indicating how long the recovery credential is valid for. If not provided, a default of 15 minutes will be used." + }, + "emailCustomization": { + "$ref": "#/definitions/v1EmailCustomizationParams", + "description": "Optional parameters for customizing emails. If not provided, the default email will be used." + } + }, + "required": ["email", "targetPublicKey"] + }, + "v1InitUserEmailRecoveryRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_INIT_USER_EMAIL_RECOVERY"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1InitUserEmailRecoveryIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1InitUserEmailRecoveryResult": { + "type": "object", + "properties": { + "userId": { + "type": "string", + "description": "Unique identifier for the user being recovered." + } + }, + "required": ["userId"] + }, + "v1Intent": { + "type": "object", + "properties": { + "createOrganizationIntent": { + "$ref": "#/definitions/v1CreateOrganizationIntent" + }, + "createAuthenticatorsIntent": { + "$ref": "#/definitions/v1CreateAuthenticatorsIntent" + }, + "createUsersIntent": { + "$ref": "#/definitions/v1CreateUsersIntent" + }, + "createPrivateKeysIntent": { + "$ref": "#/definitions/v1CreatePrivateKeysIntent" + }, + "signRawPayloadIntent": { + "$ref": "#/definitions/v1SignRawPayloadIntent" + }, + "createInvitationsIntent": { + "$ref": "#/definitions/v1CreateInvitationsIntent" + }, + "acceptInvitationIntent": { + "$ref": "#/definitions/v1AcceptInvitationIntent" + }, + "createPolicyIntent": { + "$ref": "#/definitions/v1CreatePolicyIntent" + }, + "disablePrivateKeyIntent": { + "$ref": "#/definitions/v1DisablePrivateKeyIntent" + }, + "deleteUsersIntent": { + "$ref": "#/definitions/v1DeleteUsersIntent" + }, + "deleteAuthenticatorsIntent": { + "$ref": "#/definitions/v1DeleteAuthenticatorsIntent" + }, + "deleteInvitationIntent": { + "$ref": "#/definitions/v1DeleteInvitationIntent" + }, + "deleteOrganizationIntent": { + "$ref": "#/definitions/v1DeleteOrganizationIntent" + }, + "deletePolicyIntent": { + "$ref": "#/definitions/v1DeletePolicyIntent" + }, + "createUserTagIntent": { + "$ref": "#/definitions/v1CreateUserTagIntent" + }, + "deleteUserTagsIntent": { + "$ref": "#/definitions/v1DeleteUserTagsIntent" + }, + "signTransactionIntent": { + "$ref": "#/definitions/v1SignTransactionIntent" + }, + "createApiKeysIntent": { + "$ref": "#/definitions/v1CreateApiKeysIntent" + }, + "deleteApiKeysIntent": { + "$ref": "#/definitions/v1DeleteApiKeysIntent" + }, + "approveActivityIntent": { + "$ref": "#/definitions/v1ApproveActivityIntent" + }, + "rejectActivityIntent": { + "$ref": "#/definitions/v1RejectActivityIntent" + }, + "createPrivateKeyTagIntent": { + "$ref": "#/definitions/v1CreatePrivateKeyTagIntent" + }, + "deletePrivateKeyTagsIntent": { + "$ref": "#/definitions/v1DeletePrivateKeyTagsIntent" + }, + "createPolicyIntentV2": { + "$ref": "#/definitions/v1CreatePolicyIntentV2" + }, + "setPaymentMethodIntent": { + "$ref": "#/definitions/billingSetPaymentMethodIntent" + }, + "activateBillingTierIntent": { + "$ref": "#/definitions/billingActivateBillingTierIntent" + }, + "deletePaymentMethodIntent": { + "$ref": "#/definitions/billingDeletePaymentMethodIntent" + }, + "createPolicyIntentV3": { + "$ref": "#/definitions/v1CreatePolicyIntentV3" + }, + "createApiOnlyUsersIntent": { + "$ref": "#/definitions/v1CreateApiOnlyUsersIntent" + }, + "updateRootQuorumIntent": { + "$ref": "#/definitions/v1UpdateRootQuorumIntent" + }, + "updateUserTagIntent": { + "$ref": "#/definitions/v1UpdateUserTagIntent" + }, + "updatePrivateKeyTagIntent": { + "$ref": "#/definitions/v1UpdatePrivateKeyTagIntent" + }, + "createAuthenticatorsIntentV2": { + "$ref": "#/definitions/v1CreateAuthenticatorsIntentV2" + }, + "acceptInvitationIntentV2": { + "$ref": "#/definitions/v1AcceptInvitationIntentV2" + }, + "createOrganizationIntentV2": { + "$ref": "#/definitions/v1CreateOrganizationIntentV2" + }, + "createUsersIntentV2": { + "$ref": "#/definitions/v1CreateUsersIntentV2" + }, + "createSubOrganizationIntent": { + "$ref": "#/definitions/v1CreateSubOrganizationIntent" + }, + "createSubOrganizationIntentV2": { + "$ref": "#/definitions/v1CreateSubOrganizationIntentV2" + }, + "updateAllowedOriginsIntent": { + "$ref": "#/definitions/v1UpdateAllowedOriginsIntent" + }, + "createPrivateKeysIntentV2": { + "$ref": "#/definitions/v1CreatePrivateKeysIntentV2" + }, + "updateUserIntent": { + "$ref": "#/definitions/v1UpdateUserIntent" + }, + "updatePolicyIntent": { + "$ref": "#/definitions/v1UpdatePolicyIntent" + }, + "setPaymentMethodIntentV2": { + "$ref": "#/definitions/billingSetPaymentMethodIntentV2" + }, + "createSubOrganizationIntentV3": { + "$ref": "#/definitions/v1CreateSubOrganizationIntentV3" + }, + "createWalletIntent": { + "$ref": "#/definitions/v1CreateWalletIntent" + }, + "createWalletAccountsIntent": { + "$ref": "#/definitions/v1CreateWalletAccountsIntent" + }, + "initUserEmailRecoveryIntent": { + "$ref": "#/definitions/v1InitUserEmailRecoveryIntent" + }, + "recoverUserIntent": { + "$ref": "#/definitions/v1RecoverUserIntent" + }, + "setOrganizationFeatureIntent": { + "$ref": "#/definitions/v1SetOrganizationFeatureIntent" + }, + "removeOrganizationFeatureIntent": { + "$ref": "#/definitions/v1RemoveOrganizationFeatureIntent" + }, + "signRawPayloadIntentV2": { + "$ref": "#/definitions/v1SignRawPayloadIntentV2" + }, + "signTransactionIntentV2": { + "$ref": "#/definitions/v1SignTransactionIntentV2" + }, + "exportPrivateKeyIntent": { + "$ref": "#/definitions/v1ExportPrivateKeyIntent" + }, + "exportWalletIntent": { + "$ref": "#/definitions/v1ExportWalletIntent" + }, + "createSubOrganizationIntentV4": { + "$ref": "#/definitions/v1CreateSubOrganizationIntentV4" + }, + "emailAuthIntent": { + "$ref": "#/definitions/v1EmailAuthIntent" + }, + "exportWalletAccountIntent": { + "$ref": "#/definitions/v1ExportWalletAccountIntent" + }, + "initImportWalletIntent": { + "$ref": "#/definitions/v1InitImportWalletIntent" + }, + "importWalletIntent": { + "$ref": "#/definitions/v1ImportWalletIntent" + }, + "initImportPrivateKeyIntent": { + "$ref": "#/definitions/v1InitImportPrivateKeyIntent" + }, + "importPrivateKeyIntent": { + "$ref": "#/definitions/v1ImportPrivateKeyIntent" + }, + "createPoliciesIntent": { + "$ref": "#/definitions/v1CreatePoliciesIntent" + }, + "signRawPayloadsIntent": { + "$ref": "#/definitions/v1SignRawPayloadsIntent" + }, + "createReadOnlySessionIntent": { + "$ref": "#/definitions/v1CreateReadOnlySessionIntent" + }, + "createOauthProvidersIntent": { + "$ref": "#/definitions/v1CreateOauthProvidersIntent" + }, + "deleteOauthProvidersIntent": { + "$ref": "#/definitions/v1DeleteOauthProvidersIntent" + }, + "createSubOrganizationIntentV5": { + "$ref": "#/definitions/v1CreateSubOrganizationIntentV5" + }, + "oauthIntent": { + "$ref": "#/definitions/v1OauthIntent" + }, + "createApiKeysIntentV2": { + "$ref": "#/definitions/v1CreateApiKeysIntentV2" + }, + "createReadWriteSessionIntent": { + "$ref": "#/definitions/v1CreateReadWriteSessionIntent" + }, + "emailAuthIntentV2": { + "$ref": "#/definitions/v1EmailAuthIntentV2" + }, + "createSubOrganizationIntentV6": { + "$ref": "#/definitions/v1CreateSubOrganizationIntentV6" + }, + "deletePrivateKeysIntent": { + "$ref": "#/definitions/v1DeletePrivateKeysIntent" + }, + "deleteWalletsIntent": { + "$ref": "#/definitions/v1DeleteWalletsIntent" + }, + "createReadWriteSessionIntentV2": { + "$ref": "#/definitions/v1CreateReadWriteSessionIntentV2" + }, + "deleteSubOrganizationIntent": { + "$ref": "#/definitions/v1DeleteSubOrganizationIntent" + }, + "initOtpAuthIntent": { + "$ref": "#/definitions/v1InitOtpAuthIntent" + }, + "otpAuthIntent": { + "$ref": "#/definitions/v1OtpAuthIntent" + }, + "createSubOrganizationIntentV7": { + "$ref": "#/definitions/v1CreateSubOrganizationIntentV7" + }, + "updateWalletIntent": { + "$ref": "#/definitions/v1UpdateWalletIntent" + }, + "updatePolicyIntentV2": { + "$ref": "#/definitions/v1UpdatePolicyIntentV2" + }, + "createUsersIntentV3": { + "$ref": "#/definitions/v1CreateUsersIntentV3" + }, + "initOtpAuthIntentV2": { + "$ref": "#/definitions/v1InitOtpAuthIntentV2" + }, + "initOtpIntent": { + "$ref": "#/definitions/v1InitOtpIntent" + }, + "verifyOtpIntent": { + "$ref": "#/definitions/v1VerifyOtpIntent" + }, + "otpLoginIntent": { + "$ref": "#/definitions/v1OtpLoginIntent" + }, + "stampLoginIntent": { + "$ref": "#/definitions/v1StampLoginIntent" + }, + "oauthLoginIntent": { + "$ref": "#/definitions/v1OauthLoginIntent" + } + } + }, + "v1Invitation": { + "type": "object", + "properties": { + "invitationId": { + "type": "string", + "description": "Unique identifier for a given Invitation object." + }, + "receiverUserName": { + "type": "string", + "description": "The name of the intended Invitation recipient." + }, + "receiverEmail": { + "type": "string", + "description": "The email address of the intended Invitation recipient." + }, + "receiverUserTags": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of tags assigned to the Invitation recipient." + }, + "accessType": { + "$ref": "#/definitions/v1AccessType", + "description": "The User's permissible access method(s)." + }, + "status": { + "$ref": "#/definitions/v1InvitationStatus", + "description": "The current processing status of a specified Invitation." + }, + "createdAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + }, + "updatedAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + }, + "senderUserId": { + "type": "string", + "description": "Unique identifier for the Sender of an Invitation." + } + }, + "required": [ + "invitationId", + "receiverUserName", + "receiverEmail", + "receiverUserTags", + "accessType", + "status", + "createdAt", + "updatedAt", + "senderUserId" + ] + }, + "v1InvitationParams": { + "type": "object", + "properties": { + "receiverUserName": { + "type": "string", + "description": "The name of the intended Invitation recipient." + }, + "receiverUserEmail": { + "type": "string", + "description": "The email address of the intended Invitation recipient." + }, + "receiverUserTags": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of tags assigned to the Invitation recipient. This field, if not needed, should be an empty array in your request body." + }, + "accessType": { + "$ref": "#/definitions/v1AccessType", + "description": "The User's permissible access method(s)." + }, + "senderUserId": { + "type": "string", + "description": "Unique identifier for the Sender of an Invitation." + } + }, + "required": [ + "receiverUserName", + "receiverUserEmail", + "receiverUserTags", + "accessType", + "senderUserId" + ] + }, + "v1InvitationStatus": { + "type": "string", + "enum": [ + "INVITATION_STATUS_CREATED", + "INVITATION_STATUS_ACCEPTED", + "INVITATION_STATUS_REVOKED" + ] + }, + "v1ListPrivateKeyTagsRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + } + }, + "required": ["organizationId"] + }, + "v1ListPrivateKeyTagsResponse": { + "type": "object", + "properties": { + "privateKeyTags": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/datav1Tag" + }, + "description": "A list of Private Key Tags" + } + }, + "required": ["privateKeyTags"] + }, + "v1ListUserTagsRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + } + }, + "required": ["organizationId"] + }, + "v1ListUserTagsResponse": { + "type": "object", + "properties": { + "userTags": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/datav1Tag" + }, + "description": "A list of User Tags" + } + }, + "required": ["userTags"] + }, + "v1MnemonicLanguage": { + "type": "string", + "enum": [ + "MNEMONIC_LANGUAGE_ENGLISH", + "MNEMONIC_LANGUAGE_SIMPLIFIED_CHINESE", + "MNEMONIC_LANGUAGE_TRADITIONAL_CHINESE", + "MNEMONIC_LANGUAGE_CZECH", + "MNEMONIC_LANGUAGE_FRENCH", + "MNEMONIC_LANGUAGE_ITALIAN", + "MNEMONIC_LANGUAGE_JAPANESE", + "MNEMONIC_LANGUAGE_KOREAN", + "MNEMONIC_LANGUAGE_SPANISH" + ] + }, + "v1NOOPCodegenAnchorResponse": { + "type": "object", + "properties": { + "stamp": { + "$ref": "#/definitions/v1WebAuthnStamp" + } + }, + "required": ["stamp"] + }, + "v1OauthIntent": { + "type": "object", + "properties": { + "oidcToken": { + "type": "string", + "description": "Base64 encoded OIDC token" + }, + "targetPublicKey": { + "type": "string", + "description": "Client-side public key generated by the user, to which the oauth bundle (credentials) will be encrypted." + }, + "apiKeyName": { + "type": "string", + "description": "Optional human-readable name for an API Key. If none provided, default to Oauth - \u003cTimestamp\u003e" + }, + "expirationSeconds": { + "type": "string", + "description": "Expiration window (in seconds) indicating how long the API key is valid for. If not provided, a default of 15 minutes will be used." + }, + "invalidateExisting": { + "type": "boolean", + "description": "Invalidate all other previously generated Oauth API keys" + } + }, + "required": ["oidcToken", "targetPublicKey"] + }, + "v1OauthLoginIntent": { + "type": "object", + "properties": { + "oidcToken": { + "type": "string", + "description": "Base64 encoded OIDC token" + }, + "publicKey": { + "type": "string", + "description": "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" + }, + "expirationSeconds": { + "type": "string", + "description": "Expiration window (in seconds) indicating how long the Session is valid for. If not provided, a default of 15 minutes will be used." + }, + "invalidateExisting": { + "type": "boolean", + "description": "Invalidate all other previously generated Login API keys" + } + }, + "required": ["oidcToken", "publicKey"] + }, + "v1OauthLoginRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_OAUTH_LOGIN"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1OauthLoginIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1OauthLoginResult": { + "type": "object", + "properties": { + "session": { + "type": "string", + "description": "Signed JWT containing an expiry, public key, session type, user id, and organization id" + } + }, + "required": ["session"] + }, + "v1OauthProvider": { + "type": "object", + "properties": { + "providerId": { + "type": "string", + "description": "Unique identifier for an OAuth Provider" + }, + "providerName": { + "type": "string", + "description": "Human-readable name to identify a Provider." + }, + "issuer": { + "type": "string", + "description": "The issuer of the token, typically a URL indicating the authentication server, e.g https://accounts.google.com" + }, + "audience": { + "type": "string", + "description": "Expected audience ('aud' attribute of the signed token) which represents the app ID" + }, + "subject": { + "type": "string", + "description": "Expected subject ('sub' attribute of the signed token) which represents the user ID" + }, + "createdAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + }, + "updatedAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + } + }, + "required": [ + "providerId", + "providerName", + "issuer", + "audience", + "subject", + "createdAt", + "updatedAt" + ] + }, + "v1OauthProviderParams": { + "type": "object", + "properties": { + "providerName": { + "type": "string", + "description": "Human-readable name to identify a Provider." + }, + "oidcToken": { + "type": "string", + "description": "Base64 encoded OIDC token" + } + }, + "required": ["providerName", "oidcToken"] + }, + "v1OauthRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_OAUTH"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1OauthIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1OauthResult": { + "type": "object", + "properties": { + "userId": { + "type": "string", + "description": "Unique identifier for the authenticating User." + }, + "apiKeyId": { + "type": "string", + "description": "Unique identifier for the created API key." + }, + "credentialBundle": { + "type": "string", + "description": "HPKE encrypted credential bundle" + } + }, + "required": ["userId", "apiKeyId", "credentialBundle"] + }, + "v1Operator": { + "type": "string", + "enum": [ + "OPERATOR_EQUAL", + "OPERATOR_MORE_THAN", + "OPERATOR_MORE_THAN_OR_EQUAL", + "OPERATOR_LESS_THAN", + "OPERATOR_LESS_THAN_OR_EQUAL", + "OPERATOR_CONTAINS", + "OPERATOR_NOT_EQUAL", + "OPERATOR_IN", + "OPERATOR_NOT_IN", + "OPERATOR_CONTAINS_ONE", + "OPERATOR_CONTAINS_ALL" + ] + }, + "v1OrganizationData": { + "type": "object", + "properties": { + "organizationId": { + "type": "string" + }, + "name": { + "type": "string" + }, + "users": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1User" + } + }, + "policies": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1Policy" + } + }, + "privateKeys": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1PrivateKey" + } + }, + "invitations": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1Invitation" + } + }, + "tags": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/datav1Tag" + } + }, + "rootQuorum": { + "$ref": "#/definitions/externaldatav1Quorum" + }, + "features": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1Feature" + } + }, + "wallets": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1Wallet" + } + } + } + }, + "v1OtpAuthIntent": { + "type": "object", + "properties": { + "otpId": { + "type": "string", + "description": "ID representing the result of an init OTP activity." + }, + "otpCode": { + "type": "string", + "description": "OTP sent out to a user's contact (email or SMS)" + }, + "targetPublicKey": { + "type": "string", + "description": "Client-side public key generated by the user, to which the OTP bundle (credentials) will be encrypted." + }, + "apiKeyName": { + "type": "string", + "description": "Optional human-readable name for an API Key. If none provided, default to OTP Auth - \u003cTimestamp\u003e" + }, + "expirationSeconds": { + "type": "string", + "description": "Expiration window (in seconds) indicating how long the API key is valid for. If not provided, a default of 15 minutes will be used." + }, + "invalidateExisting": { + "type": "boolean", + "description": "Invalidate all other previously generated OTP Auth API keys" + } + }, + "required": ["otpId", "otpCode", "targetPublicKey"] + }, + "v1OtpAuthRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_OTP_AUTH"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1OtpAuthIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1OtpAuthResult": { + "type": "object", + "properties": { + "userId": { + "type": "string", + "description": "Unique identifier for the authenticating User." + }, + "apiKeyId": { + "type": "string", + "description": "Unique identifier for the created API key." + }, + "credentialBundle": { + "type": "string", + "description": "HPKE encrypted credential bundle" + } + }, + "required": ["userId"] + }, + "v1OtpLoginIntent": { + "type": "object", + "properties": { + "verificationToken": { + "type": "string", + "description": "Signed JWT containing a unique id, expiry, verification type, contact" + }, + "publicKey": { + "type": "string", + "description": "Client-side public key generated by the user, which will be conditionally added to org data based on the validity of the verification token" + }, + "expirationSeconds": { + "type": "string", + "description": "Expiration window (in seconds) indicating how long the Session is valid for. If not provided, a default of 15 minutes will be used." + }, + "invalidateExisting": { + "type": "boolean", + "description": "Invalidate all other previously generated Login API keys" + } + }, + "required": ["verificationToken", "publicKey"] + }, + "v1OtpLoginRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_OTP_LOGIN"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1OtpLoginIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1OtpLoginResult": { + "type": "object", + "properties": { + "session": { + "type": "string", + "description": "Signed JWT containing an expiry, public key, session type, user id, and organization id" + } + }, + "required": ["session"] + }, + "v1Pagination": { + "type": "object", + "properties": { + "limit": { + "type": "string", + "description": "A limit of the number of object to be returned, between 1 and 100. Defaults to 10." + }, + "before": { + "type": "string", + "description": "A pagination cursor. This is an object ID that enables you to fetch all objects before this ID." + }, + "after": { + "type": "string", + "description": "A pagination cursor. This is an object ID that enables you to fetch all objects after this ID." + } + } + }, + "v1PathFormat": { + "type": "string", + "enum": ["PATH_FORMAT_BIP32"] + }, + "v1PayloadEncoding": { + "type": "string", + "enum": ["PAYLOAD_ENCODING_HEXADECIMAL", "PAYLOAD_ENCODING_TEXT_UTF8"] + }, + "v1Policy": { + "type": "object", + "properties": { + "policyId": { + "type": "string", + "description": "Unique identifier for a given Policy." + }, + "policyName": { + "type": "string", + "description": "Human-readable name for a Policy." + }, + "effect": { + "$ref": "#/definitions/v1Effect", + "description": "The instruction to DENY or ALLOW a particular activity following policy selector(s)." + }, + "createdAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + }, + "updatedAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + }, + "notes": { + "type": "string", + "description": "Human-readable notes added by a User to describe a particular policy." + }, + "consensus": { + "type": "string", + "description": "A consensus expression that evalutes to true or false." + }, + "condition": { + "type": "string", + "description": "A condition expression that evalutes to true or false." + } + }, + "required": [ + "policyId", + "policyName", + "effect", + "createdAt", + "updatedAt", + "notes", + "consensus", + "condition" + ] + }, + "v1PrivateKey": { + "type": "object", + "properties": { + "privateKeyId": { + "type": "string", + "description": "Unique identifier for a given Private Key." + }, + "publicKey": { + "type": "string", + "description": "The public component of a cryptographic key pair used to sign messages and transactions." + }, + "privateKeyName": { + "type": "string", + "description": "Human-readable name for a Private Key." + }, + "curve": { + "$ref": "#/definitions/v1Curve", + "description": "Cryptographic Curve used to generate a given Private Key." + }, + "addresses": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/externaldatav1Address" + }, + "description": "Derived cryptocurrency addresses for a given Private Key." + }, + "privateKeyTags": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of Private Key Tag IDs." + }, + "createdAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + }, + "updatedAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + }, + "exported": { + "type": "boolean", + "description": "True when a given Private Key is exported, false otherwise." + }, + "imported": { + "type": "boolean", + "description": "True when a given Private Key is imported, false otherwise." + } + }, + "required": [ + "privateKeyId", + "publicKey", + "privateKeyName", + "curve", + "addresses", + "privateKeyTags", + "createdAt", + "updatedAt", + "exported", + "imported" + ] + }, + "v1PrivateKeyParams": { + "type": "object", + "properties": { + "privateKeyName": { + "type": "string", + "description": "Human-readable name for a Private Key." + }, + "curve": { + "$ref": "#/definitions/v1Curve", + "description": "Cryptographic Curve used to generate a given Private Key." + }, + "privateKeyTags": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of Private Key Tag IDs. This field, if not needed, should be an empty array in your request body." + }, + "addressFormats": { + "type": "array", + "items": { + "$ref": "#/definitions/v1AddressFormat" + }, + "description": "Cryptocurrency-specific formats for a derived address (e.g., Ethereum)." + } + }, + "required": [ + "privateKeyName", + "curve", + "privateKeyTags", + "addressFormats" + ] + }, + "v1PrivateKeyResult": { + "type": "object", + "properties": { + "privateKeyId": { + "type": "string" + }, + "addresses": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/immutableactivityv1Address" + } + } + } + }, + "v1PublicKeyCredentialWithAttestation": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "type": { + "type": "string", + "enum": ["public-key"] + }, + "rawId": { + "type": "string" + }, + "authenticatorAttachment": { + "type": "string", + "enum": ["cross-platform", "platform"], + "x-nullable": true + }, + "response": { + "$ref": "#/definitions/v1AuthenticatorAttestationResponse" + }, + "clientExtensionResults": { + "$ref": "#/definitions/v1SimpleClientExtensionResults" + } + }, + "required": ["id", "type", "rawId", "response", "clientExtensionResults"] + }, + "v1RecoverUserIntent": { + "type": "object", + "properties": { + "authenticator": { + "$ref": "#/definitions/v1AuthenticatorParamsV2", + "description": "The new authenticator to register." + }, + "userId": { + "type": "string", + "description": "Unique identifier for the user performing recovery." + } + }, + "required": ["authenticator", "userId"] + }, + "v1RecoverUserRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_RECOVER_USER"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1RecoverUserIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1RecoverUserResult": { + "type": "object", + "properties": { + "authenticatorId": { + "type": "array", + "items": { + "type": "string" + }, + "description": "ID of the authenticator created." + } + }, + "required": ["authenticatorId"] + }, + "v1RejectActivityIntent": { + "type": "object", + "properties": { + "fingerprint": { + "type": "string", + "description": "An artifact verifying a User's action." + } + }, + "required": ["fingerprint"] + }, + "v1RejectActivityRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_REJECT_ACTIVITY"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1RejectActivityIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1RemoveOrganizationFeatureIntent": { + "type": "object", + "properties": { + "name": { + "$ref": "#/definitions/v1FeatureName", + "description": "Name of the feature to remove" + } + }, + "required": ["name"] + }, + "v1RemoveOrganizationFeatureRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_REMOVE_ORGANIZATION_FEATURE"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1RemoveOrganizationFeatureIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1RemoveOrganizationFeatureResult": { + "type": "object", + "properties": { + "features": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1Feature" + }, + "description": "Resulting list of organization features." + } + }, + "required": ["features"] + }, + "v1Result": { + "type": "object", + "properties": { + "createOrganizationResult": { + "$ref": "#/definitions/v1CreateOrganizationResult" + }, + "createAuthenticatorsResult": { + "$ref": "#/definitions/v1CreateAuthenticatorsResult" + }, + "createUsersResult": { + "$ref": "#/definitions/v1CreateUsersResult" + }, + "createPrivateKeysResult": { + "$ref": "#/definitions/v1CreatePrivateKeysResult" + }, + "createInvitationsResult": { + "$ref": "#/definitions/v1CreateInvitationsResult" + }, + "acceptInvitationResult": { + "$ref": "#/definitions/v1AcceptInvitationResult" + }, + "signRawPayloadResult": { + "$ref": "#/definitions/v1SignRawPayloadResult" + }, + "createPolicyResult": { + "$ref": "#/definitions/v1CreatePolicyResult" + }, + "disablePrivateKeyResult": { + "$ref": "#/definitions/v1DisablePrivateKeyResult" + }, + "deleteUsersResult": { + "$ref": "#/definitions/v1DeleteUsersResult" + }, + "deleteAuthenticatorsResult": { + "$ref": "#/definitions/v1DeleteAuthenticatorsResult" + }, + "deleteInvitationResult": { + "$ref": "#/definitions/v1DeleteInvitationResult" + }, + "deleteOrganizationResult": { + "$ref": "#/definitions/v1DeleteOrganizationResult" + }, + "deletePolicyResult": { + "$ref": "#/definitions/v1DeletePolicyResult" + }, + "createUserTagResult": { + "$ref": "#/definitions/v1CreateUserTagResult" + }, + "deleteUserTagsResult": { + "$ref": "#/definitions/v1DeleteUserTagsResult" + }, + "signTransactionResult": { + "$ref": "#/definitions/v1SignTransactionResult" + }, + "deleteApiKeysResult": { + "$ref": "#/definitions/v1DeleteApiKeysResult" + }, + "createApiKeysResult": { + "$ref": "#/definitions/v1CreateApiKeysResult" + }, + "createPrivateKeyTagResult": { + "$ref": "#/definitions/v1CreatePrivateKeyTagResult" + }, + "deletePrivateKeyTagsResult": { + "$ref": "#/definitions/v1DeletePrivateKeyTagsResult" + }, + "setPaymentMethodResult": { + "$ref": "#/definitions/billingSetPaymentMethodResult" + }, + "activateBillingTierResult": { + "$ref": "#/definitions/billingActivateBillingTierResult" + }, + "deletePaymentMethodResult": { + "$ref": "#/definitions/billingDeletePaymentMethodResult" + }, + "createApiOnlyUsersResult": { + "$ref": "#/definitions/v1CreateApiOnlyUsersResult" + }, + "updateRootQuorumResult": { + "$ref": "#/definitions/v1UpdateRootQuorumResult" + }, + "updateUserTagResult": { + "$ref": "#/definitions/v1UpdateUserTagResult" + }, + "updatePrivateKeyTagResult": { + "$ref": "#/definitions/v1UpdatePrivateKeyTagResult" + }, + "createSubOrganizationResult": { + "$ref": "#/definitions/v1CreateSubOrganizationResult" + }, + "updateAllowedOriginsResult": { + "$ref": "#/definitions/v1UpdateAllowedOriginsResult" + }, + "createPrivateKeysResultV2": { + "$ref": "#/definitions/v1CreatePrivateKeysResultV2" + }, + "updateUserResult": { + "$ref": "#/definitions/v1UpdateUserResult" + }, + "updatePolicyResult": { + "$ref": "#/definitions/v1UpdatePolicyResult" + }, + "createSubOrganizationResultV3": { + "$ref": "#/definitions/v1CreateSubOrganizationResultV3" + }, + "createWalletResult": { + "$ref": "#/definitions/v1CreateWalletResult" + }, + "createWalletAccountsResult": { + "$ref": "#/definitions/v1CreateWalletAccountsResult" + }, + "initUserEmailRecoveryResult": { + "$ref": "#/definitions/v1InitUserEmailRecoveryResult" + }, + "recoverUserResult": { + "$ref": "#/definitions/v1RecoverUserResult" + }, + "setOrganizationFeatureResult": { + "$ref": "#/definitions/v1SetOrganizationFeatureResult" + }, + "removeOrganizationFeatureResult": { + "$ref": "#/definitions/v1RemoveOrganizationFeatureResult" + }, + "exportPrivateKeyResult": { + "$ref": "#/definitions/v1ExportPrivateKeyResult" + }, + "exportWalletResult": { + "$ref": "#/definitions/v1ExportWalletResult" + }, + "createSubOrganizationResultV4": { + "$ref": "#/definitions/v1CreateSubOrganizationResultV4" + }, + "emailAuthResult": { + "$ref": "#/definitions/v1EmailAuthResult" + }, + "exportWalletAccountResult": { + "$ref": "#/definitions/v1ExportWalletAccountResult" + }, + "initImportWalletResult": { + "$ref": "#/definitions/v1InitImportWalletResult" + }, + "importWalletResult": { + "$ref": "#/definitions/v1ImportWalletResult" + }, + "initImportPrivateKeyResult": { + "$ref": "#/definitions/v1InitImportPrivateKeyResult" + }, + "importPrivateKeyResult": { + "$ref": "#/definitions/v1ImportPrivateKeyResult" + }, + "createPoliciesResult": { + "$ref": "#/definitions/v1CreatePoliciesResult" + }, + "signRawPayloadsResult": { + "$ref": "#/definitions/v1SignRawPayloadsResult" + }, + "createReadOnlySessionResult": { + "$ref": "#/definitions/v1CreateReadOnlySessionResult" + }, + "createOauthProvidersResult": { + "$ref": "#/definitions/v1CreateOauthProvidersResult" + }, + "deleteOauthProvidersResult": { + "$ref": "#/definitions/v1DeleteOauthProvidersResult" + }, + "createSubOrganizationResultV5": { + "$ref": "#/definitions/v1CreateSubOrganizationResultV5" + }, + "oauthResult": { + "$ref": "#/definitions/v1OauthResult" + }, + "createReadWriteSessionResult": { + "$ref": "#/definitions/v1CreateReadWriteSessionResult" + }, + "createSubOrganizationResultV6": { + "$ref": "#/definitions/v1CreateSubOrganizationResultV6" + }, + "deletePrivateKeysResult": { + "$ref": "#/definitions/v1DeletePrivateKeysResult" + }, + "deleteWalletsResult": { + "$ref": "#/definitions/v1DeleteWalletsResult" + }, + "createReadWriteSessionResultV2": { + "$ref": "#/definitions/v1CreateReadWriteSessionResultV2" + }, + "deleteSubOrganizationResult": { + "$ref": "#/definitions/v1DeleteSubOrganizationResult" + }, + "initOtpAuthResult": { + "$ref": "#/definitions/v1InitOtpAuthResult" + }, + "otpAuthResult": { + "$ref": "#/definitions/v1OtpAuthResult" + }, + "createSubOrganizationResultV7": { + "$ref": "#/definitions/v1CreateSubOrganizationResultV7" + }, + "updateWalletResult": { + "$ref": "#/definitions/v1UpdateWalletResult" + }, + "updatePolicyResultV2": { + "$ref": "#/definitions/v1UpdatePolicyResultV2" + }, + "initOtpAuthResultV2": { + "$ref": "#/definitions/v1InitOtpAuthResultV2" + }, + "initOtpResult": { + "$ref": "#/definitions/v1InitOtpResult" + }, + "verifyOtpResult": { + "$ref": "#/definitions/v1VerifyOtpResult" + }, + "otpLoginResult": { + "$ref": "#/definitions/v1OtpLoginResult" + }, + "stampLoginResult": { + "$ref": "#/definitions/v1StampLoginResult" + }, + "oauthLoginResult": { + "$ref": "#/definitions/v1OauthLoginResult" + } + } + }, + "v1RootUserParams": { + "type": "object", + "properties": { + "userName": { + "type": "string", + "description": "Human-readable name for a User." + }, + "userEmail": { + "type": "string", + "description": "The user's email address." + }, + "apiKeys": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/apiApiKeyParams" + }, + "description": "A list of API Key parameters. This field, if not needed, should be an empty array in your request body." + }, + "authenticators": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1AuthenticatorParamsV2" + }, + "description": "A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body." + } + }, + "required": ["userName", "apiKeys", "authenticators"] + }, + "v1RootUserParamsV2": { + "type": "object", + "properties": { + "userName": { + "type": "string", + "description": "Human-readable name for a User." + }, + "userEmail": { + "type": "string", + "description": "The user's email address." + }, + "apiKeys": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/apiApiKeyParams" + }, + "description": "A list of API Key parameters. This field, if not needed, should be an empty array in your request body." + }, + "authenticators": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1AuthenticatorParamsV2" + }, + "description": "A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body." + }, + "oauthProviders": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1OauthProviderParams" + }, + "description": "A list of Oauth providers. This field, if not needed, should be an empty array in your request body." + } + }, + "required": ["userName", "apiKeys", "authenticators", "oauthProviders"] + }, + "v1RootUserParamsV3": { + "type": "object", + "properties": { + "userName": { + "type": "string", + "description": "Human-readable name for a User." + }, + "userEmail": { + "type": "string", + "description": "The user's email address." + }, + "apiKeys": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1ApiKeyParamsV2" + }, + "description": "A list of API Key parameters. This field, if not needed, should be an empty array in your request body." + }, + "authenticators": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1AuthenticatorParamsV2" + }, + "description": "A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body." + }, + "oauthProviders": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1OauthProviderParams" + }, + "description": "A list of Oauth providers. This field, if not needed, should be an empty array in your request body." + } + }, + "required": ["userName", "apiKeys", "authenticators", "oauthProviders"] + }, + "v1RootUserParamsV4": { + "type": "object", + "properties": { + "userName": { + "type": "string", + "description": "Human-readable name for a User." + }, + "userEmail": { + "type": "string", + "description": "The user's email address." + }, + "userPhoneNumber": { + "type": "string", + "description": "The user's phone number in E.164 format e.g. +13214567890" + }, + "apiKeys": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1ApiKeyParamsV2" + }, + "description": "A list of API Key parameters. This field, if not needed, should be an empty array in your request body." + }, + "authenticators": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1AuthenticatorParamsV2" + }, + "description": "A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body." + }, + "oauthProviders": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1OauthProviderParams" + }, + "description": "A list of Oauth providers. This field, if not needed, should be an empty array in your request body." + } + }, + "required": ["userName", "apiKeys", "authenticators", "oauthProviders"] + }, + "v1Selector": { + "type": "object", + "properties": { + "subject": { + "type": "string" + }, + "operator": { + "$ref": "#/definitions/v1Operator" + }, + "target": { + "type": "string" + } + } + }, + "v1SelectorV2": { + "type": "object", + "properties": { + "subject": { + "type": "string" + }, + "operator": { + "$ref": "#/definitions/v1Operator" + }, + "targets": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "v1SetOrganizationFeatureIntent": { + "type": "object", + "properties": { + "name": { + "$ref": "#/definitions/v1FeatureName", + "description": "Name of the feature to set" + }, + "value": { + "type": "string", + "description": "Optional value for the feature. Will override existing values if feature is already set." + } + }, + "required": ["name", "value"] + }, + "v1SetOrganizationFeatureRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_SET_ORGANIZATION_FEATURE"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1SetOrganizationFeatureIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1SetOrganizationFeatureResult": { + "type": "object", + "properties": { + "features": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1Feature" + }, + "description": "Resulting list of organization features." + } + }, + "required": ["features"] + }, + "v1SignRawPayloadIntent": { + "type": "object", + "properties": { + "privateKeyId": { + "type": "string", + "description": "Unique identifier for a given Private Key." + }, + "payload": { + "type": "string", + "description": "Raw unsigned payload to be signed." + }, + "encoding": { + "$ref": "#/definitions/v1PayloadEncoding", + "description": "Encoding of the `payload` string. Turnkey uses this information to convert `payload` into bytes with the correct decoder (e.g. hex, utf8)." + }, + "hashFunction": { + "$ref": "#/definitions/v1HashFunction", + "description": "Hash function to apply to payload bytes before signing. This field must be set to HASH_FUNCTION_NOT_APPLICABLE for EdDSA/ed25519 signature requests; configurable payload hashing is not supported by RFC 8032." + } + }, + "required": ["privateKeyId", "payload", "encoding", "hashFunction"] + }, + "v1SignRawPayloadIntentV2": { + "type": "object", + "properties": { + "signWith": { + "type": "string", + "description": "A Wallet account address, Private Key address, or Private Key identifier." + }, + "payload": { + "type": "string", + "description": "Raw unsigned payload to be signed." + }, + "encoding": { + "$ref": "#/definitions/v1PayloadEncoding", + "description": "Encoding of the `payload` string. Turnkey uses this information to convert `payload` into bytes with the correct decoder (e.g. hex, utf8)." + }, + "hashFunction": { + "$ref": "#/definitions/v1HashFunction", + "description": "Hash function to apply to payload bytes before signing. This field must be set to HASH_FUNCTION_NOT_APPLICABLE for EdDSA/ed25519 signature requests; configurable payload hashing is not supported by RFC 8032." + } + }, + "required": ["signWith", "payload", "encoding", "hashFunction"] + }, + "v1SignRawPayloadRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_SIGN_RAW_PAYLOAD_V2"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1SignRawPayloadIntentV2" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1SignRawPayloadResult": { + "type": "object", + "properties": { + "r": { + "type": "string", + "description": "Component of an ECSDA signature." + }, + "s": { + "type": "string", + "description": "Component of an ECSDA signature." + }, + "v": { + "type": "string", + "description": "Component of an ECSDA signature." + } + }, + "required": ["r", "s", "v"] + }, + "v1SignRawPayloadsIntent": { + "type": "object", + "properties": { + "signWith": { + "type": "string", + "description": "A Wallet account address, Private Key address, or Private Key identifier." + }, + "payloads": { + "type": "array", + "items": { + "type": "string" + }, + "description": "An array of raw unsigned payloads to be signed." + }, + "encoding": { + "$ref": "#/definitions/v1PayloadEncoding", + "description": "Encoding of the `payload` string. Turnkey uses this information to convert `payload` into bytes with the correct decoder (e.g. hex, utf8)." + }, + "hashFunction": { + "$ref": "#/definitions/v1HashFunction", + "description": "Hash function to apply to payload bytes before signing. This field must be set to HASH_FUNCTION_NOT_APPLICABLE for EdDSA/ed25519 signature requests; configurable payload hashing is not supported by RFC 8032." + } + }, + "required": ["signWith", "payloads", "encoding", "hashFunction"] + }, + "v1SignRawPayloadsRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_SIGN_RAW_PAYLOADS"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1SignRawPayloadsIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1SignRawPayloadsResult": { + "type": "object", + "properties": { + "signatures": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1SignRawPayloadResult" + } + } + } + }, + "v1SignTransactionIntent": { + "type": "object", + "properties": { + "privateKeyId": { + "type": "string", + "description": "Unique identifier for a given Private Key." + }, + "unsignedTransaction": { + "type": "string", + "description": "Raw unsigned transaction to be signed by a particular Private Key." + }, + "type": { + "$ref": "#/definitions/v1TransactionType" + } + }, + "required": ["privateKeyId", "unsignedTransaction", "type"] + }, + "v1SignTransactionIntentV2": { + "type": "object", + "properties": { + "signWith": { + "type": "string", + "description": "A Wallet account address, Private Key address, or Private Key identifier." + }, + "unsignedTransaction": { + "type": "string", + "description": "Raw unsigned transaction to be signed" + }, + "type": { + "$ref": "#/definitions/v1TransactionType" + } + }, + "required": ["signWith", "unsignedTransaction", "type"] + }, + "v1SignTransactionRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_SIGN_TRANSACTION_V2"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1SignTransactionIntentV2" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1SignTransactionResult": { + "type": "object", + "properties": { + "signedTransaction": { + "type": "string" + } + }, + "required": ["signedTransaction"] + }, + "v1SimpleClientExtensionResults": { + "type": "object", + "properties": { + "appid": { + "type": "boolean" + }, + "appidExclude": { + "type": "boolean" + }, + "credProps": { + "$ref": "#/definitions/v1CredPropsAuthenticationExtensionsClientOutputs" + } + } + }, + "v1SmsCustomizationParams": { + "type": "object", + "properties": { + "template": { + "type": "string", + "description": "Template containing references to .OtpCode i.e Your OTP is {{.OtpCode}}" + } + } + }, + "v1StampLoginIntent": { + "type": "object", + "properties": { + "publicKey": { + "type": "string", + "description": "Client-side public key generated by the user, which will be conditionally added to org data based on the passkey stamp associated with this request" + }, + "expirationSeconds": { + "type": "string", + "description": "Expiration window (in seconds) indicating how long the Session is valid for. If not provided, a default of 15 minutes will be used." + }, + "invalidateExisting": { + "type": "boolean", + "description": "Invalidate all other previously generated Login API keys" + } + }, + "required": ["publicKey"] + }, + "v1StampLoginRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_STAMP_LOGIN"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1StampLoginIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1StampLoginResult": { + "type": "object", + "properties": { + "session": { + "type": "string", + "description": "Signed JWT containing an expiry, public key, session type, user id, and organization id" + } + }, + "required": ["session"] + }, + "v1TagType": { + "type": "string", + "enum": ["TAG_TYPE_USER", "TAG_TYPE_PRIVATE_KEY"] + }, + "v1TestRateLimitsRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "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." + }, + "isSetLimit": { + "type": "boolean", + "description": "Whether or not to set a limit on this request." + }, + "limit": { + "type": "integer", + "format": "int64", + "description": "Rate limit to set for org, if is_set_limit is set to true" + } + }, + "required": ["organizationId", "isSetLimit", "limit"] + }, + "v1TestRateLimitsResponse": { + "type": "object" + }, + "v1TransactionType": { + "type": "string", + "enum": [ + "TRANSACTION_TYPE_ETHEREUM", + "TRANSACTION_TYPE_SOLANA", + "TRANSACTION_TYPE_TRON" + ] + }, + "v1UpdateAllowedOriginsIntent": { + "type": "object", + "properties": { + "allowedOrigins": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Additional origins requests are allowed from besides Turnkey origins" + } + }, + "required": ["allowedOrigins"] + }, + "v1UpdateAllowedOriginsResult": { + "type": "object" + }, + "v1UpdatePolicyIntent": { + "type": "object", + "properties": { + "policyId": { + "type": "string", + "description": "Unique identifier for a given Policy." + }, + "policyName": { + "type": "string", + "description": "Human-readable name for a Policy." + }, + "policyEffect": { + "$ref": "#/definitions/v1Effect", + "description": "The instruction to DENY or ALLOW an activity (optional)." + }, + "policyCondition": { + "type": "string", + "description": "The condition expression that triggers the Effect (optional)." + }, + "policyConsensus": { + "type": "string", + "description": "The consensus expression that triggers the Effect (optional)." + }, + "policyNotes": { + "type": "string", + "description": "Accompanying notes for a Policy (optional)." + } + }, + "required": ["policyId"] + }, + "v1UpdatePolicyIntentV2": { + "type": "object", + "properties": { + "policyId": { + "type": "string", + "description": "Unique identifier for a given Policy." + }, + "policyName": { + "type": "string", + "description": "Human-readable name for a Policy." + }, + "policyEffect": { + "$ref": "#/definitions/v1Effect", + "description": "The instruction to DENY or ALLOW an activity (optional)." + }, + "policyCondition": { + "type": "string", + "description": "The condition expression that triggers the Effect (optional)." + }, + "policyConsensus": { + "type": "string", + "description": "The consensus expression that triggers the Effect (optional)." + }, + "policyNotes": { + "type": "string", + "description": "Accompanying notes for a Policy (optional)." + } + }, + "required": ["policyId"] + }, + "v1UpdatePolicyRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_UPDATE_POLICY_V2"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1UpdatePolicyIntentV2" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1UpdatePolicyResult": { + "type": "object", + "properties": { + "policyId": { + "type": "string", + "description": "Unique identifier for a given Policy." + } + }, + "required": ["policyId"] + }, + "v1UpdatePolicyResultV2": { + "type": "object", + "properties": { + "policyId": { + "type": "string", + "description": "Unique identifier for a given Policy." + } + }, + "required": ["policyId"] + }, + "v1UpdatePrivateKeyTagIntent": { + "type": "object", + "properties": { + "privateKeyTagId": { + "type": "string", + "description": "Unique identifier for a given Private Key Tag." + }, + "newPrivateKeyTagName": { + "type": "string", + "description": "The new, human-readable name for the tag with the given ID." + }, + "addPrivateKeyIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of Private Keys IDs to add this tag to." + }, + "removePrivateKeyIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of Private Key IDs to remove this tag from." + } + }, + "required": ["privateKeyTagId", "addPrivateKeyIds", "removePrivateKeyIds"] + }, + "v1UpdatePrivateKeyTagRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_UPDATE_PRIVATE_KEY_TAG"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1UpdatePrivateKeyTagIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1UpdatePrivateKeyTagResult": { + "type": "object", + "properties": { + "privateKeyTagId": { + "type": "string", + "description": "Unique identifier for a given Private Key Tag." + } + }, + "required": ["privateKeyTagId"] + }, + "v1UpdateRootQuorumIntent": { + "type": "object", + "properties": { + "threshold": { + "type": "integer", + "format": "int32", + "description": "The threshold of unique approvals to reach quorum." + }, + "userIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The unique identifiers of users who comprise the quorum set." + } + }, + "required": ["threshold", "userIds"] + }, + "v1UpdateRootQuorumRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_UPDATE_ROOT_QUORUM"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1UpdateRootQuorumIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1UpdateRootQuorumResult": { + "type": "object" + }, + "v1UpdateUserIntent": { + "type": "object", + "properties": { + "userId": { + "type": "string", + "description": "Unique identifier for a given User." + }, + "userName": { + "type": "string", + "description": "Human-readable name for a User." + }, + "userEmail": { + "type": "string", + "description": "The user's email address." + }, + "userTagIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "An updated list of User Tags to apply to this User. This field, if not needed, should be an empty array in your request body." + }, + "userPhoneNumber": { + "type": "string", + "description": "The user's phone number in E.164 format e.g. +13214567890" + } + }, + "required": ["userId"] + }, + "v1UpdateUserRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_UPDATE_USER"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1UpdateUserIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1UpdateUserResult": { + "type": "object", + "properties": { + "userId": { + "type": "string", + "description": "A User ID." + } + }, + "required": ["userId"] + }, + "v1UpdateUserTagIntent": { + "type": "object", + "properties": { + "userTagId": { + "type": "string", + "description": "Unique identifier for a given User Tag." + }, + "newUserTagName": { + "type": "string", + "description": "The new, human-readable name for the tag with the given ID." + }, + "addUserIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of User IDs to add this tag to." + }, + "removeUserIds": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of User IDs to remove this tag from." + } + }, + "required": ["userTagId", "addUserIds", "removeUserIds"] + }, + "v1UpdateUserTagRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_UPDATE_USER_TAG"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1UpdateUserTagIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1UpdateUserTagResult": { + "type": "object", + "properties": { + "userTagId": { + "type": "string", + "description": "Unique identifier for a given User Tag." + } + }, + "required": ["userTagId"] + }, + "v1UpdateWalletIntent": { + "type": "object", + "properties": { + "walletId": { + "type": "string", + "description": "Unique identifier for a given Wallet." + }, + "walletName": { + "type": "string", + "description": "Human-readable name for a Wallet." + } + }, + "required": ["walletId"] + }, + "v1UpdateWalletRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_UPDATE_WALLET"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1UpdateWalletIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1UpdateWalletResult": { + "type": "object", + "properties": { + "walletId": { + "type": "string", + "description": "A Wallet ID." + } + }, + "required": ["walletId"] + }, + "v1User": { + "type": "object", + "properties": { + "userId": { + "type": "string", + "description": "Unique identifier for a given User." + }, + "userName": { + "type": "string", + "description": "Human-readable name for a User." + }, + "userEmail": { + "type": "string", + "description": "The user's email address." + }, + "userPhoneNumber": { + "type": "string", + "description": "The user's phone number in E.164 format e.g. +13214567890" + }, + "authenticators": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1Authenticator" + }, + "description": "A list of Authenticator parameters." + }, + "apiKeys": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1ApiKey" + }, + "description": "A list of API Key parameters. This field, if not needed, should be an empty array in your request body." + }, + "userTags": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of User Tag IDs." + }, + "oauthProviders": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1OauthProvider" + }, + "description": "A list of Oauth Providers." + }, + "createdAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + }, + "updatedAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + } + }, + "required": [ + "userId", + "userName", + "authenticators", + "apiKeys", + "userTags", + "oauthProviders", + "createdAt", + "updatedAt" + ] + }, + "v1UserParams": { + "type": "object", + "properties": { + "userName": { + "type": "string", + "description": "Human-readable name for a User." + }, + "userEmail": { + "type": "string", + "description": "The user's email address." + }, + "accessType": { + "$ref": "#/definitions/v1AccessType", + "description": "The User's permissible access method(s)." + }, + "apiKeys": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/apiApiKeyParams" + }, + "description": "A list of API Key parameters. This field, if not needed, should be an empty array in your request body." + }, + "authenticators": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1AuthenticatorParams" + }, + "description": "A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body." + }, + "userTags": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of User Tag IDs. This field, if not needed, should be an empty array in your request body." + } + }, + "required": [ + "userName", + "accessType", + "apiKeys", + "authenticators", + "userTags" + ] + }, + "v1UserParamsV2": { + "type": "object", + "properties": { + "userName": { + "type": "string", + "description": "Human-readable name for a User." + }, + "userEmail": { + "type": "string", + "description": "The user's email address." + }, + "apiKeys": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/apiApiKeyParams" + }, + "description": "A list of API Key parameters. This field, if not needed, should be an empty array in your request body." + }, + "authenticators": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1AuthenticatorParamsV2" + }, + "description": "A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body." + }, + "userTags": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of User Tag IDs. This field, if not needed, should be an empty array in your request body." + } + }, + "required": ["userName", "apiKeys", "authenticators", "userTags"] + }, + "v1UserParamsV3": { + "type": "object", + "properties": { + "userName": { + "type": "string", + "description": "Human-readable name for a User." + }, + "userEmail": { + "type": "string", + "description": "The user's email address." + }, + "userPhoneNumber": { + "type": "string", + "description": "The user's phone number in E.164 format e.g. +13214567890" + }, + "apiKeys": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1ApiKeyParamsV2" + }, + "description": "A list of API Key parameters. This field, if not needed, should be an empty array in your request body." + }, + "authenticators": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1AuthenticatorParamsV2" + }, + "description": "A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body." + }, + "oauthProviders": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1OauthProviderParams" + }, + "description": "A list of Oauth providers. This field, if not needed, should be an empty array in your request body." + }, + "userTags": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of User Tag IDs. This field, if not needed, should be an empty array in your request body." + } + }, + "required": [ + "userName", + "apiKeys", + "authenticators", + "oauthProviders", + "userTags" + ] + }, + "v1VerifyOtpIntent": { + "type": "object", + "properties": { + "otpId": { + "type": "string", + "description": "ID representing the result of an init OTP activity." + }, + "otpCode": { + "type": "string", + "description": "OTP sent out to a user's contact (email or SMS)" + }, + "expirationSeconds": { + "type": "string", + "description": "Expiration window (in seconds) indicating how long the verification token is valid for. If not provided, a default of 1 hour will be used. Maximum value is 86400 seconds (24 hours)" + } + }, + "required": ["otpId", "otpCode"] + }, + "v1VerifyOtpRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_VERIFY_OTP"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1VerifyOtpIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1VerifyOtpResult": { + "type": "object", + "properties": { + "verificationToken": { + "type": "string", + "description": "Signed JWT containing a unique id, expiry, verification type, contact. Verification status of a user is updated when the token is consumed (in OTP_LOGIN requests)" + } + }, + "required": ["verificationToken"] + }, + "v1Vote": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "Unique identifier for a given Vote object." + }, + "userId": { + "type": "string", + "description": "Unique identifier for a given User." + }, + "user": { + "$ref": "#/definitions/v1User", + "description": "Web and/or API user within your Organization." + }, + "activityId": { + "type": "string", + "description": "Unique identifier for a given Activity object." + }, + "selection": { + "type": "string", + "enum": ["VOTE_SELECTION_APPROVED", "VOTE_SELECTION_REJECTED"] + }, + "message": { + "type": "string", + "description": "The raw message being signed within a Vote." + }, + "publicKey": { + "type": "string", + "description": "The public component of a cryptographic key pair used to sign messages and transactions." + }, + "signature": { + "type": "string", + "description": "The signature applied to a particular vote." + }, + "scheme": { + "type": "string", + "description": "Method used to produce a signature." + }, + "createdAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + } + }, + "required": [ + "id", + "userId", + "user", + "activityId", + "selection", + "message", + "publicKey", + "signature", + "scheme", + "createdAt" + ] + }, + "v1Wallet": { + "type": "object", + "properties": { + "walletId": { + "type": "string", + "description": "Unique identifier for a given Wallet." + }, + "walletName": { + "type": "string", + "description": "Human-readable name for a Wallet." + }, + "createdAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + }, + "updatedAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + }, + "exported": { + "type": "boolean", + "description": "True when a given Wallet is exported, false otherwise." + }, + "imported": { + "type": "boolean", + "description": "True when a given Wallet is imported, false otherwise." + } + }, + "required": [ + "walletId", + "walletName", + "createdAt", + "updatedAt", + "exported", + "imported" + ] + }, + "v1WalletAccount": { + "type": "object", + "properties": { + "walletAccountId": { + "type": "string", + "description": "Unique identifier for a given Wallet Account." + }, + "organizationId": { + "type": "string", + "description": "The Organization the Account belongs to." + }, + "walletId": { + "type": "string", + "description": "The Wallet the Account was derived from." + }, + "curve": { + "$ref": "#/definitions/v1Curve", + "description": "Cryptographic curve used to generate the Account." + }, + "pathFormat": { + "$ref": "#/definitions/v1PathFormat", + "description": "Path format used to generate the Account." + }, + "path": { + "type": "string", + "description": "Path used to generate the Account." + }, + "addressFormat": { + "$ref": "#/definitions/v1AddressFormat", + "description": "Address format used to generate the Account." + }, + "address": { + "type": "string", + "description": "Address generated using the Wallet seed and Account parameters." + }, + "createdAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + }, + "updatedAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + }, + "publicKey": { + "type": "string", + "description": "The public component of this wallet account's underlying cryptographic key pair." + } + }, + "required": [ + "walletAccountId", + "organizationId", + "walletId", + "curve", + "pathFormat", + "path", + "addressFormat", + "address", + "createdAt", + "updatedAt" + ] + }, + "v1WalletAccountParams": { + "type": "object", + "properties": { + "curve": { + "$ref": "#/definitions/v1Curve", + "description": "Cryptographic curve used to generate a wallet Account." + }, + "pathFormat": { + "$ref": "#/definitions/v1PathFormat", + "description": "Path format used to generate a wallet Account." + }, + "path": { + "type": "string", + "description": "Path used to generate a wallet Account." + }, + "addressFormat": { + "$ref": "#/definitions/v1AddressFormat", + "description": "Address format used to generate a wallet Acccount." + } + }, + "required": ["curve", "pathFormat", "path", "addressFormat"] + }, + "v1WalletParams": { + "type": "object", + "properties": { + "walletName": { + "type": "string", + "description": "Human-readable name for a Wallet." + }, + "accounts": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1WalletAccountParams" + }, + "description": "A list of wallet Accounts. This field, if not needed, should be an empty array in your request body." + }, + "mnemonicLength": { + "type": "integer", + "format": "int32", + "description": "Length of mnemonic to generate the Wallet seed. Defaults to 12. Accepted values: 12, 15, 18, 21, 24." + } + }, + "required": ["walletName", "accounts"] + }, + "v1WalletResult": { + "type": "object", + "properties": { + "walletId": { + "type": "string" + }, + "addresses": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of account addresses." + } + }, + "required": ["walletId", "addresses"] + }, + "v1WebAuthnStamp": { + "type": "object", + "properties": { + "credentialId": { + "type": "string", + "description": "A base64 url encoded Unique identifier for a given credential." + }, + "clientDataJson": { + "type": "string", + "description": "A base64 encoded payload containing metadata about the signing context and the challenge." + }, + "authenticatorData": { + "type": "string", + "description": "A base64 encoded payload containing metadata about the authenticator." + }, + "signature": { + "type": "string", + "description": "The base64 url encoded signature bytes contained within the WebAuthn assertion response." + } + }, + "required": [ + "credentialId", + "clientDataJson", + "authenticatorData", + "signature" + ] + } + }, + "securityDefinitions": { + "ApiKeyAuth": { + "type": "apiKey", + "name": "X-Stamp", + "in": "header" + }, + "AuthenticatorAuth": { + "type": "apiKey", + "name": "X-Stamp-WebAuthn", + "in": "header" + } + }, + "security": [ + { + "ApiKeyAuth": [] + }, + { + "AuthenticatorAuth": [] + } + ], + "x-tagGroups": [ + { + "name": "ORGANIZATIONS", + "tags": ["Organizations", "Invitations", "Policies", "Features"] + }, + { + "name": "WALLETS AND PRIVATE KEYS", + "tags": ["Wallets", "Signing", "Private Keys", "Private Key Tags"] + }, + { + "name": "USERS", + "tags": ["Users", "User Tags", "User Recovery", "User Auth"] + }, + { + "name": "CREDENTIALS", + "tags": ["Authenticators", "API Keys", "Sessions"] + }, + { + "name": "ACTIVITIES", + "tags": ["Activities", "Consensus"] + } + ] +} diff --git a/packages/sdk-types/src/__inputs__/public_api.types.ts b/packages/sdk-types/src/__inputs__/public_api.types.ts new file mode 100644 index 000000000..4ac44fc8f --- /dev/null +++ b/packages/sdk-types/src/__inputs__/public_api.types.ts @@ -0,0 +1,4714 @@ +/** + * This file was auto-generated by openapi-typescript. + * Do not make direct changes to the file. + */ + +export type paths = { + "/public/v1/query/get_activity": { + /** Get details about an Activity */ + post: operations["PublicApiService_GetActivity"]; + }; + "/public/v1/query/get_api_key": { + /** Get details about an API key */ + post: operations["PublicApiService_GetApiKey"]; + }; + "/public/v1/query/get_api_keys": { + /** Get details about API keys for a user */ + post: operations["PublicApiService_GetApiKeys"]; + }; + "/public/v1/query/get_attestation": { + /** Get the attestation document corresponding to an enclave. */ + post: operations["PublicApiService_GetAttestationDocument"]; + }; + "/public/v1/query/get_authenticator": { + /** Get details about an authenticator */ + post: operations["PublicApiService_GetAuthenticator"]; + }; + "/public/v1/query/get_authenticators": { + /** Get details about authenticators for a user */ + post: operations["PublicApiService_GetAuthenticators"]; + }; + "/public/v1/query/get_oauth_providers": { + /** Get details about Oauth providers for a user */ + post: operations["PublicApiService_GetOauthProviders"]; + }; + "/public/v1/query/get_organization": { + /** Get details about an Organization */ + post: operations["PublicApiService_GetOrganization"]; + }; + "/public/v1/query/get_organization_configs": { + /** Get quorum settings and features for an organization */ + post: operations["PublicApiService_GetOrganizationConfigs"]; + }; + "/public/v1/query/get_policy": { + /** Get details about a Policy */ + post: operations["PublicApiService_GetPolicy"]; + }; + "/public/v1/query/get_private_key": { + /** Get details about a Private Key */ + post: operations["PublicApiService_GetPrivateKey"]; + }; + "/public/v1/query/get_user": { + /** Get details about a User */ + post: operations["PublicApiService_GetUser"]; + }; + "/public/v1/query/get_wallet": { + /** Get details about a Wallet */ + post: operations["PublicApiService_GetWallet"]; + }; + "/public/v1/query/get_wallet_account": { + /** Get a single wallet account */ + post: operations["PublicApiService_GetWalletAccount"]; + }; + "/public/v1/query/list_activities": { + /** List all Activities within an Organization */ + post: operations["PublicApiService_GetActivities"]; + }; + "/public/v1/query/list_policies": { + /** List all Policies within an Organization */ + post: operations["PublicApiService_GetPolicies"]; + }; + "/public/v1/query/list_private_key_tags": { + /** List all Private Key Tags within an Organization */ + post: operations["PublicApiService_ListPrivateKeyTags"]; + }; + "/public/v1/query/list_private_keys": { + /** List all Private Keys within an Organization */ + post: operations["PublicApiService_GetPrivateKeys"]; + }; + "/public/v1/query/list_suborgs": { + /** Get all suborg IDs associated given a parent org ID and an optional filter. */ + post: operations["PublicApiService_GetSubOrgIds"]; + }; + "/public/v1/query/list_user_tags": { + /** List all User Tags within an Organization */ + post: operations["PublicApiService_ListUserTags"]; + }; + "/public/v1/query/list_users": { + /** List all Users within an Organization */ + post: operations["PublicApiService_GetUsers"]; + }; + "/public/v1/query/list_verified_suborgs": { + /** Get all email or phone verified suborg IDs associated given a parent org ID. */ + post: operations["PublicApiService_GetVerifiedSubOrgIds"]; + }; + "/public/v1/query/list_wallet_accounts": { + /** List all Accounts within a Wallet */ + post: operations["PublicApiService_GetWalletAccounts"]; + }; + "/public/v1/query/list_wallets": { + /** List all Wallets within an Organization */ + post: operations["PublicApiService_GetWallets"]; + }; + "/public/v1/query/whoami": { + /** Get basic information about your current API or WebAuthN user and their organization. Affords Sub-Organization look ups via Parent Organization for WebAuthN or API key users. */ + post: operations["PublicApiService_GetWhoami"]; + }; + "/public/v1/submit/approve_activity": { + /** Approve an Activity */ + post: operations["PublicApiService_ApproveActivity"]; + }; + "/public/v1/submit/create_api_keys": { + /** Add api keys to an existing User */ + post: operations["PublicApiService_CreateApiKeys"]; + }; + "/public/v1/submit/create_api_only_users": { + /** Create API-only Users in an existing Organization */ + post: operations["PublicApiService_CreateApiOnlyUsers"]; + }; + "/public/v1/submit/create_authenticators": { + /** Create Authenticators to authenticate requests to Turnkey */ + post: operations["PublicApiService_CreateAuthenticators"]; + }; + "/public/v1/submit/create_invitations": { + /** Create Invitations to join an existing Organization */ + post: operations["PublicApiService_CreateInvitations"]; + }; + "/public/v1/submit/create_oauth_providers": { + /** Creates Oauth providers for a specified user - BETA */ + post: operations["PublicApiService_CreateOauthProviders"]; + }; + "/public/v1/submit/create_policies": { + /** Create new Policies */ + post: operations["PublicApiService_CreatePolicies"]; + }; + "/public/v1/submit/create_policy": { + /** Create a new Policy */ + post: operations["PublicApiService_CreatePolicy"]; + }; + "/public/v1/submit/create_private_key_tag": { + /** Create a private key tag and add it to private keys. */ + post: operations["PublicApiService_CreatePrivateKeyTag"]; + }; + "/public/v1/submit/create_private_keys": { + /** Create new Private Keys */ + post: operations["PublicApiService_CreatePrivateKeys"]; + }; + "/public/v1/submit/create_read_only_session": { + /** Create a read only session for a user (valid for 1 hour) */ + post: operations["PublicApiService_CreateReadOnlySession"]; + }; + "/public/v1/submit/create_read_write_session": { + /** Create a read write session for a user */ + post: operations["PublicApiService_CreateReadWriteSession"]; + }; + "/public/v1/submit/create_sub_organization": { + /** Create a new Sub-Organization */ + post: operations["PublicApiService_CreateSubOrganization"]; + }; + "/public/v1/submit/create_user_tag": { + /** Create a user tag and add it to users. */ + post: operations["PublicApiService_CreateUserTag"]; + }; + "/public/v1/submit/create_users": { + /** Create Users in an existing Organization */ + post: operations["PublicApiService_CreateUsers"]; + }; + "/public/v1/submit/create_wallet": { + /** Create a Wallet and derive addresses */ + post: operations["PublicApiService_CreateWallet"]; + }; + "/public/v1/submit/create_wallet_accounts": { + /** Derive additional addresses using an existing wallet */ + post: operations["PublicApiService_CreateWalletAccounts"]; + }; + "/public/v1/submit/delete_api_keys": { + /** Remove api keys from a User */ + post: operations["PublicApiService_DeleteApiKeys"]; + }; + "/public/v1/submit/delete_authenticators": { + /** Remove authenticators from a User */ + post: operations["PublicApiService_DeleteAuthenticators"]; + }; + "/public/v1/submit/delete_invitation": { + /** Delete an existing Invitation */ + post: operations["PublicApiService_DeleteInvitation"]; + }; + "/public/v1/submit/delete_oauth_providers": { + /** Removes Oauth providers for a specified user - BETA */ + post: operations["PublicApiService_DeleteOauthProviders"]; + }; + "/public/v1/submit/delete_policy": { + /** Delete an existing Policy */ + post: operations["PublicApiService_DeletePolicy"]; + }; + "/public/v1/submit/delete_private_key_tags": { + /** Delete Private Key Tags within an Organization */ + post: operations["PublicApiService_DeletePrivateKeyTags"]; + }; + "/public/v1/submit/delete_private_keys": { + /** Deletes private keys for an organization */ + post: operations["PublicApiService_DeletePrivateKeys"]; + }; + "/public/v1/submit/delete_sub_organization": { + /** Deletes a sub organization */ + post: operations["PublicApiService_DeleteSubOrganization"]; + }; + "/public/v1/submit/delete_user_tags": { + /** Delete User Tags within an Organization */ + post: operations["PublicApiService_DeleteUserTags"]; + }; + "/public/v1/submit/delete_users": { + /** Delete Users within an Organization */ + post: operations["PublicApiService_DeleteUsers"]; + }; + "/public/v1/submit/delete_wallets": { + /** Deletes wallets for an organization */ + post: operations["PublicApiService_DeleteWallets"]; + }; + "/public/v1/submit/email_auth": { + /** Authenticate a user via Email */ + post: operations["PublicApiService_EmailAuth"]; + }; + "/public/v1/submit/export_private_key": { + /** Exports a Private Key */ + post: operations["PublicApiService_ExportPrivateKey"]; + }; + "/public/v1/submit/export_wallet": { + /** Exports a Wallet */ + post: operations["PublicApiService_ExportWallet"]; + }; + "/public/v1/submit/export_wallet_account": { + /** Exports a Wallet Account */ + post: operations["PublicApiService_ExportWalletAccount"]; + }; + "/public/v1/submit/import_private_key": { + /** Imports a private key */ + post: operations["PublicApiService_ImportPrivateKey"]; + }; + "/public/v1/submit/import_wallet": { + /** Imports a wallet */ + post: operations["PublicApiService_ImportWallet"]; + }; + "/public/v1/submit/init_import_private_key": { + /** Initializes a new private key import */ + post: operations["PublicApiService_InitImportPrivateKey"]; + }; + "/public/v1/submit/init_import_wallet": { + /** Initializes a new wallet import */ + post: operations["PublicApiService_InitImportWallet"]; + }; + "/public/v1/submit/init_otp": { + /** Initiate a Generic OTP activity */ + post: operations["PublicApiService_InitOtp"]; + }; + "/public/v1/submit/init_otp_auth": { + /** Initiate an OTP auth activity */ + post: operations["PublicApiService_InitOtpAuth"]; + }; + "/public/v1/submit/init_user_email_recovery": { + /** Initializes a new email recovery */ + post: operations["PublicApiService_InitUserEmailRecovery"]; + }; + "/public/v1/submit/oauth": { + /** Authenticate a user with an Oidc token (Oauth) - BETA */ + post: operations["PublicApiService_Oauth"]; + }; + "/public/v1/submit/oauth_login": { + /** Create an Oauth session for a user */ + post: operations["PublicApiService_OauthLogin"]; + }; + "/public/v1/submit/otp_auth": { + /** Authenticate a user with an OTP code sent via email or SMS */ + post: operations["PublicApiService_OtpAuth"]; + }; + "/public/v1/submit/otp_login": { + /** Create an OTP session for a user */ + post: operations["PublicApiService_OtpLogin"]; + }; + "/public/v1/submit/recover_user": { + /** Completes the process of recovering a user by adding an authenticator */ + post: operations["PublicApiService_RecoverUser"]; + }; + "/public/v1/submit/reject_activity": { + /** Reject an Activity */ + post: operations["PublicApiService_RejectActivity"]; + }; + "/public/v1/submit/remove_organization_feature": { + /** Removes an organization feature. This activity must be approved by the current root quorum. */ + post: operations["PublicApiService_RemoveOrganizationFeature"]; + }; + "/public/v1/submit/set_organization_feature": { + /** Sets an organization feature. This activity must be approved by the current root quorum. */ + post: operations["PublicApiService_SetOrganizationFeature"]; + }; + "/public/v1/submit/sign_raw_payload": { + /** Sign a raw payload */ + post: operations["PublicApiService_SignRawPayload"]; + }; + "/public/v1/submit/sign_raw_payloads": { + /** Sign multiple raw payloads with the same signing parameters */ + post: operations["PublicApiService_SignRawPayloads"]; + }; + "/public/v1/submit/sign_transaction": { + /** Sign a transaction */ + post: operations["PublicApiService_SignTransaction"]; + }; + "/public/v1/submit/stamp_login": { + /** Create a session for a user through stamping client side (api key, wallet client, or passkey client) */ + post: operations["PublicApiService_StampLogin"]; + }; + "/public/v1/submit/update_policy": { + /** Update an existing Policy */ + post: operations["PublicApiService_UpdatePolicy"]; + }; + "/public/v1/submit/update_private_key_tag": { + /** Update human-readable name or associated private keys. Note that this activity is atomic: all of the updates will succeed at once, or all of them will fail. */ + post: operations["PublicApiService_UpdatePrivateKeyTag"]; + }; + "/public/v1/submit/update_root_quorum": { + /** Set the threshold and members of the root quorum. This activity must be approved by the current root quorum. */ + post: operations["PublicApiService_UpdateRootQuorum"]; + }; + "/public/v1/submit/update_user": { + /** Update a User in an existing Organization */ + post: operations["PublicApiService_UpdateUser"]; + }; + "/public/v1/submit/update_user_tag": { + /** Update human-readable name or associated users. Note that this activity is atomic: all of the updates will succeed at once, or all of them will fail. */ + post: operations["PublicApiService_UpdateUserTag"]; + }; + "/public/v1/submit/update_wallet": { + /** Update a wallet for an organization */ + post: operations["PublicApiService_UpdateWallet"]; + }; + "/public/v1/submit/verify_otp": { + /** Verify a Generic OTP */ + post: operations["PublicApiService_VerifyOtp"]; + }; + "/tkhq/api/v1/noop-codegen-anchor": { + post: operations["PublicApiService_NOOPCodegenAnchor"]; + }; + "/tkhq/api/v1/test_rate_limits": { + /** Set a rate local rate limit just on the current endpoint, for purposes of testing with Vivosuite */ + post: operations["PublicApiService_TestRateLimits"]; + }; +}; + +export type definitions = { + apiApiKeyParams: { + /** @description Human-readable name for an API Key. */ + apiKeyName: string; + /** @description The public component of a cryptographic key pair used to sign messages and transactions. */ + publicKey: string; + /** @description Optional window (in seconds) indicating how long the API Key should last. */ + expirationSeconds?: string; + }; + billingActivateBillingTierIntent: { + /** @description The product that the customer wants to subscribe to. */ + productId: string; + }; + billingActivateBillingTierResult: { + /** @description The id of the product being subscribed to. */ + productId: string; + }; + billingDeletePaymentMethodIntent: { + /** @description The payment method that the customer wants to remove. */ + paymentMethodId: string; + }; + billingDeletePaymentMethodResult: { + /** @description The payment method that was removed. */ + paymentMethodId: string; + }; + billingSetPaymentMethodIntent: { + /** @description The account number of the customer's credit card. */ + number: string; + /** @description The verification digits of the customer's credit card. */ + cvv: string; + /** @description The month that the credit card expires. */ + expiryMonth: string; + /** @description The year that the credit card expires. */ + expiryYear: string; + /** @description The email that will receive invoices for the credit card. */ + cardHolderEmail: string; + /** @description The name associated with the credit card. */ + cardHolderName: string; + }; + billingSetPaymentMethodIntentV2: { + /** @description The id of the payment method that was created clientside. */ + paymentMethodId: string; + /** @description The email that will receive invoices for the credit card. */ + cardHolderEmail: string; + /** @description The name associated with the credit card. */ + cardHolderName: string; + }; + billingSetPaymentMethodResult: { + /** @description The last four digits of the credit card added. */ + lastFour: string; + /** @description The name associated with the payment method. */ + cardHolderName: string; + /** @description The email address associated with the payment method. */ + cardHolderEmail: string; + }; + datav1Tag: { + /** @description Unique identifier for a given Tag. */ + tagId: string; + /** @description Human-readable name for a Tag. */ + tagName: string; + tagType: definitions["v1TagType"]; + createdAt: definitions["externaldatav1Timestamp"]; + updatedAt: definitions["externaldatav1Timestamp"]; + }; + externaldatav1Address: { + format?: definitions["v1AddressFormat"]; + address?: string; + }; + externaldatav1Credential: { + /** @description The public component of a cryptographic key pair used to sign messages and transactions. */ + publicKey: string; + type: definitions["v1CredentialType"]; + }; + externaldatav1Quorum: { + /** + * Format: int32 + * @description Count of unique approvals required to meet quorum. + */ + threshold: number; + /** @description Unique identifiers of quorum set members. */ + userIds: string[]; + }; + externaldatav1Timestamp: { + seconds: string; + nanos: string; + }; + immutableactivityv1Address: { + format?: definitions["v1AddressFormat"]; + address?: string; + }; + protobufAny: { + "@type"?: string; + } & { [key: string]: unknown }; + rpcStatus: { + /** Format: int32 */ + code?: number; + message?: string; + details?: definitions["protobufAny"][]; + }; + v1AcceptInvitationIntent: { + /** @description Unique identifier for a given Invitation object. */ + invitationId: string; + /** @description Unique identifier for a given User. */ + userId: string; + /** @description WebAuthN hardware devices that can be used to log in to the Turnkey web app. */ + authenticator: definitions["v1AuthenticatorParams"]; + }; + v1AcceptInvitationIntentV2: { + /** @description Unique identifier for a given Invitation object. */ + invitationId: string; + /** @description Unique identifier for a given User. */ + userId: string; + /** @description WebAuthN hardware devices that can be used to log in to the Turnkey web app. */ + authenticator: definitions["v1AuthenticatorParamsV2"]; + }; + v1AcceptInvitationResult: { + /** @description Unique identifier for a given Invitation. */ + invitationId: string; + /** @description Unique identifier for a given User. */ + userId: string; + }; + /** @enum {string} */ + v1AccessType: "ACCESS_TYPE_WEB" | "ACCESS_TYPE_API" | "ACCESS_TYPE_ALL"; + v1Activity: { + /** @description Unique identifier for a given Activity object. */ + id: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + /** @description The current processing status of a specified Activity. */ + status: definitions["v1ActivityStatus"]; + /** @description Type of Activity, such as Add User, or Sign Transaction. */ + type: definitions["v1ActivityType"]; + /** @description Intent object crafted by Turnkey based on the user request, used to assess the permissibility of an action. */ + intent: definitions["v1Intent"]; + /** @description Result of the intended action. */ + result: definitions["v1Result"]; + /** @description A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. */ + votes: definitions["v1Vote"][]; + /** @description An artifact verifying a User's action. */ + fingerprint: string; + canApprove: boolean; + canReject: boolean; + createdAt: definitions["externaldatav1Timestamp"]; + updatedAt: definitions["externaldatav1Timestamp"]; + /** @description Failure reason of the intended action. */ + failure?: definitions["rpcStatus"]; + }; + v1ActivityResponse: { + /** @description An action that can that can be taken within the Turnkey infrastructure. */ + activity: definitions["v1Activity"]; + }; + /** @enum {string} */ + v1ActivityStatus: + | "ACTIVITY_STATUS_CREATED" + | "ACTIVITY_STATUS_PENDING" + | "ACTIVITY_STATUS_COMPLETED" + | "ACTIVITY_STATUS_FAILED" + | "ACTIVITY_STATUS_CONSENSUS_NEEDED" + | "ACTIVITY_STATUS_REJECTED"; + /** @enum {string} */ + v1ActivityType: + | "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"; + /** @enum {string} */ + v1AddressFormat: + | "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"; + v1ApiKey: { + /** @description A User credential that can be used to authenticate to Turnkey. */ + credential: definitions["externaldatav1Credential"]; + /** @description Unique identifier for a given API Key. */ + apiKeyId: string; + /** @description Human-readable name for an API Key. */ + apiKeyName: string; + createdAt: definitions["externaldatav1Timestamp"]; + updatedAt: definitions["externaldatav1Timestamp"]; + /** + * Format: uint64 + * @description Optional window (in seconds) indicating how long the API Key should last. + */ + expirationSeconds?: string; + }; + /** @enum {string} */ + v1ApiKeyCurve: + | "API_KEY_CURVE_P256" + | "API_KEY_CURVE_SECP256K1" + | "API_KEY_CURVE_ED25519"; + v1ApiKeyParamsV2: { + /** @description Human-readable name for an API Key. */ + apiKeyName: string; + /** @description The public component of a cryptographic key pair used to sign messages and transactions. */ + publicKey: string; + /** @description The curve type to be used for processing API key signatures. */ + curveType: definitions["v1ApiKeyCurve"]; + /** @description Optional window (in seconds) indicating how long the API Key should last. */ + expirationSeconds?: string; + }; + v1ApiOnlyUserParams: { + /** @description The name of the new API-only User. */ + userName: string; + /** @description The email address for this API-only User (optional). */ + userEmail?: string; + /** @description A list of tags assigned to the new API-only User. This field, if not needed, should be an empty array in your request body. */ + userTags: string[]; + /** @description A list of API Key parameters. This field, if not needed, should be an empty array in your request body. */ + apiKeys: definitions["apiApiKeyParams"][]; + }; + v1ApproveActivityIntent: { + /** @description An artifact verifying a User's action. */ + fingerprint: string; + }; + v1ApproveActivityRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_APPROVE_ACTIVITY"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1ApproveActivityIntent"]; + }; + v1Attestation: { + /** @description The cbor encoded then base64 url encoded id of the credential. */ + credentialId: string; + /** @description A base64 url encoded payload containing metadata about the signing context and the challenge. */ + clientDataJson: string; + /** @description A base64 url encoded payload containing authenticator data and any attestation the webauthn provider chooses. */ + attestationObject: string; + /** @description The type of authenticator transports. */ + transports: definitions["v1AuthenticatorTransport"][]; + }; + v1Authenticator: { + /** @description Types of transports that may be used by an Authenticator (e.g., USB, NFC, BLE). */ + transports: definitions["v1AuthenticatorTransport"][]; + attestationType: string; + /** @description Identifier indicating the type of the Security Key. */ + aaguid: string; + /** @description Unique identifier for a WebAuthn credential. */ + credentialId: string; + /** @description The type of Authenticator device. */ + model: string; + /** @description A User credential that can be used to authenticate to Turnkey. */ + credential: definitions["externaldatav1Credential"]; + /** @description Unique identifier for a given Authenticator. */ + authenticatorId: string; + /** @description Human-readable name for an Authenticator. */ + authenticatorName: string; + createdAt: definitions["externaldatav1Timestamp"]; + updatedAt: definitions["externaldatav1Timestamp"]; + }; + v1AuthenticatorAttestationResponse: { + clientDataJson: string; + attestationObject: string; + transports?: definitions["v1AuthenticatorTransport"][]; + /** @enum {string} */ + authenticatorAttachment?: "cross-platform" | "platform" | null; + }; + v1AuthenticatorParams: { + /** @description Human-readable name for an Authenticator. */ + authenticatorName: string; + /** @description Unique identifier for a given User. */ + userId: string; + attestation: definitions["v1PublicKeyCredentialWithAttestation"]; + /** @description Challenge presented for authentication purposes. */ + challenge: string; + }; + v1AuthenticatorParamsV2: { + /** @description Human-readable name for an Authenticator. */ + authenticatorName: string; + /** @description Challenge presented for authentication purposes. */ + challenge: string; + /** @description The attestation that proves custody of the authenticator and provides metadata about it. */ + attestation: definitions["v1Attestation"]; + }; + /** @enum {string} */ + v1AuthenticatorTransport: + | "AUTHENTICATOR_TRANSPORT_BLE" + | "AUTHENTICATOR_TRANSPORT_INTERNAL" + | "AUTHENTICATOR_TRANSPORT_NFC" + | "AUTHENTICATOR_TRANSPORT_USB" + | "AUTHENTICATOR_TRANSPORT_HYBRID"; + v1Config: { + features?: definitions["v1Feature"][]; + quorum?: definitions["externaldatav1Quorum"]; + }; + v1CreateApiKeysIntent: { + /** @description A list of API Keys. */ + apiKeys: definitions["apiApiKeyParams"][]; + /** @description Unique identifier for a given User. */ + userId: string; + }; + v1CreateApiKeysIntentV2: { + /** @description A list of API Keys. */ + apiKeys: definitions["v1ApiKeyParamsV2"][]; + /** @description Unique identifier for a given User. */ + userId: string; + }; + v1CreateApiKeysRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_CREATE_API_KEYS_V2"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1CreateApiKeysIntentV2"]; + }; + v1CreateApiKeysResult: { + /** @description A list of API Key IDs. */ + apiKeyIds: string[]; + }; + v1CreateApiOnlyUsersIntent: { + /** @description A list of API-only Users to create. */ + apiOnlyUsers: definitions["v1ApiOnlyUserParams"][]; + }; + v1CreateApiOnlyUsersRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_CREATE_API_ONLY_USERS"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1CreateApiOnlyUsersIntent"]; + }; + v1CreateApiOnlyUsersResult: { + /** @description A list of API-only User IDs. */ + userIds: string[]; + }; + v1CreateAuthenticatorsIntent: { + /** @description A list of Authenticators. */ + authenticators: definitions["v1AuthenticatorParams"][]; + /** @description Unique identifier for a given User. */ + userId: string; + }; + v1CreateAuthenticatorsIntentV2: { + /** @description A list of Authenticators. */ + authenticators: definitions["v1AuthenticatorParamsV2"][]; + /** @description Unique identifier for a given User. */ + userId: string; + }; + v1CreateAuthenticatorsRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_CREATE_AUTHENTICATORS_V2"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1CreateAuthenticatorsIntentV2"]; + }; + v1CreateAuthenticatorsResult: { + /** @description A list of Authenticator IDs. */ + authenticatorIds: string[]; + }; + v1CreateInvitationsIntent: { + /** @description A list of Invitations. */ + invitations: definitions["v1InvitationParams"][]; + }; + v1CreateInvitationsRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_CREATE_INVITATIONS"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1CreateInvitationsIntent"]; + }; + v1CreateInvitationsResult: { + /** @description A list of Invitation IDs */ + invitationIds: string[]; + }; + v1CreateOauthProvidersIntent: { + /** @description The ID of the User to add an Oauth provider to */ + userId: string; + /** @description A list of Oauth providers. */ + oauthProviders: definitions["v1OauthProviderParams"][]; + }; + v1CreateOauthProvidersRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_CREATE_OAUTH_PROVIDERS"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1CreateOauthProvidersIntent"]; + }; + v1CreateOauthProvidersResult: { + /** @description A list of unique identifiers for Oauth Providers */ + providerIds: string[]; + }; + v1CreateOrganizationIntent: { + /** @description Human-readable name for an Organization. */ + organizationName: string; + /** @description The root user's email address. */ + rootEmail: string; + /** @description The root user's Authenticator. */ + rootAuthenticator: definitions["v1AuthenticatorParams"]; + /** @description Unique identifier for the root user object. */ + rootUserId?: string; + }; + v1CreateOrganizationIntentV2: { + /** @description Human-readable name for an Organization. */ + organizationName: string; + /** @description The root user's email address. */ + rootEmail: string; + /** @description The root user's Authenticator. */ + rootAuthenticator: definitions["v1AuthenticatorParamsV2"]; + /** @description Unique identifier for the root user object. */ + rootUserId?: string; + }; + v1CreateOrganizationResult: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + }; + v1CreatePoliciesIntent: { + /** @description An array of policy intents to be created. */ + policies: definitions["v1CreatePolicyIntentV3"][]; + }; + v1CreatePoliciesRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_CREATE_POLICIES"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1CreatePoliciesIntent"]; + }; + v1CreatePoliciesResult: { + /** @description A list of unique identifiers for the created policies. */ + policyIds: string[]; + }; + v1CreatePolicyIntent: { + /** @description Human-readable name for a Policy. */ + policyName: string; + /** @description A list of simple functions each including a subject, target and boolean. See Policy Engine Language section for additional details. */ + selectors: definitions["v1Selector"][]; + /** @description The instruction to DENY or ALLOW a particular activity following policy selector(s). */ + effect: definitions["v1Effect"]; + notes?: string; + }; + v1CreatePolicyIntentV2: { + /** @description Human-readable name for a Policy. */ + policyName: string; + /** @description A list of simple functions each including a subject, target and boolean. See Policy Engine Language section for additional details. */ + selectors: definitions["v1SelectorV2"][]; + /** @description Whether to ALLOW or DENY requests that match the condition and consensus requirements. */ + effect: definitions["v1Effect"]; + notes?: string; + }; + v1CreatePolicyIntentV3: { + /** @description Human-readable name for a Policy. */ + policyName: string; + /** @description The instruction to DENY or ALLOW an activity. */ + effect: definitions["v1Effect"]; + /** @description The condition expression that triggers the Effect */ + condition?: string; + /** @description The consensus expression that triggers the Effect */ + consensus?: string; + notes?: string; + }; + v1CreatePolicyRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_CREATE_POLICY_V3"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1CreatePolicyIntentV3"]; + }; + v1CreatePolicyResult: { + /** @description Unique identifier for a given Policy. */ + policyId: string; + }; + v1CreatePrivateKeyTagIntent: { + /** @description Human-readable name for a Private Key Tag. */ + privateKeyTagName: string; + /** @description A list of Private Key IDs. */ + privateKeyIds: string[]; + }; + v1CreatePrivateKeyTagRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_CREATE_PRIVATE_KEY_TAG"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1CreatePrivateKeyTagIntent"]; + }; + v1CreatePrivateKeyTagResult: { + /** @description Unique identifier for a given Private Key Tag. */ + privateKeyTagId: string; + /** @description A list of Private Key IDs. */ + privateKeyIds: string[]; + }; + v1CreatePrivateKeysIntent: { + /** @description A list of Private Keys. */ + privateKeys: definitions["v1PrivateKeyParams"][]; + }; + v1CreatePrivateKeysIntentV2: { + /** @description A list of Private Keys. */ + privateKeys: definitions["v1PrivateKeyParams"][]; + }; + v1CreatePrivateKeysRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_CREATE_PRIVATE_KEYS_V2"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1CreatePrivateKeysIntentV2"]; + }; + v1CreatePrivateKeysResult: { + /** @description A list of Private Key IDs. */ + privateKeyIds: string[]; + }; + v1CreatePrivateKeysResultV2: { + /** @description A list of Private Key IDs and addresses. */ + privateKeys: definitions["v1PrivateKeyResult"][]; + }; + v1CreateReadOnlySessionIntent: { [key: string]: unknown }; + v1CreateReadOnlySessionRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_CREATE_READ_ONLY_SESSION"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1CreateReadOnlySessionIntent"]; + }; + v1CreateReadOnlySessionResult: { + /** @description Unique identifier for a given Organization. If the request is being made by a user and their Sub-Organization ID is unknown, this can be the Parent Organization ID. However, using the Sub-Organization ID is preferred due to performance reasons. */ + organizationId: string; + /** @description Human-readable name for an Organization. */ + organizationName: string; + /** @description Unique identifier for a given User. */ + userId: string; + /** @description Human-readable name for a User. */ + username: string; + /** @description String representing a read only session */ + session: string; + /** + * Format: uint64 + * @description UTC timestamp in seconds representing the expiry time for the read only session. + */ + sessionExpiry: string; + }; + v1CreateReadWriteSessionIntent: { + /** @description Client-side public key generated by the user, to which the read write session bundle (credentials) will be encrypted. */ + targetPublicKey: string; + /** @description Email of the user to create a read write session for */ + email: string; + /** @description Optional human-readable name for an API Key. If none provided, default to Read Write Session - */ + apiKeyName?: string; + /** @description Expiration window (in seconds) indicating how long the API key is valid for. If not provided, a default of 15 minutes will be used. */ + expirationSeconds?: string; + }; + v1CreateReadWriteSessionIntentV2: { + /** @description Client-side public key generated by the user, to which the read write session bundle (credentials) will be encrypted. */ + targetPublicKey: string; + /** @description Unique identifier for a given User. */ + userId?: string; + /** @description Optional human-readable name for an API Key. If none provided, default to Read Write Session - */ + apiKeyName?: string; + /** @description Expiration window (in seconds) indicating how long the API key is valid for. If not provided, a default of 15 minutes will be used. */ + expirationSeconds?: string; + /** @description Invalidate all other previously generated ReadWriteSession API keys */ + invalidateExisting?: boolean; + }; + v1CreateReadWriteSessionRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_CREATE_READ_WRITE_SESSION_V2"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1CreateReadWriteSessionIntentV2"]; + }; + v1CreateReadWriteSessionResult: { + /** @description Unique identifier for a given Organization. If the request is being made by a user and their Sub-Organization ID is unknown, this can be the Parent Organization ID. However, using the Sub-Organization ID is preferred due to performance reasons. */ + organizationId: string; + /** @description Human-readable name for an Organization. */ + organizationName: string; + /** @description Unique identifier for a given User. */ + userId: string; + /** @description Human-readable name for a User. */ + username: string; + /** @description Unique identifier for the created API key. */ + apiKeyId: string; + /** @description HPKE encrypted credential bundle */ + credentialBundle: string; + }; + v1CreateReadWriteSessionResultV2: { + /** @description Unique identifier for a given Organization. If the request is being made by a user and their Sub-Organization ID is unknown, this can be the Parent Organization ID. However, using the Sub-Organization ID is preferred due to performance reasons. */ + organizationId: string; + /** @description Human-readable name for an Organization. */ + organizationName: string; + /** @description Unique identifier for a given User. */ + userId: string; + /** @description Human-readable name for a User. */ + username: string; + /** @description Unique identifier for the created API key. */ + apiKeyId: string; + /** @description HPKE encrypted credential bundle */ + credentialBundle: string; + }; + v1CreateSubOrganizationIntent: { + /** @description Name for this sub-organization */ + name: string; + /** @description Root User authenticator for this new sub-organization */ + rootAuthenticator: definitions["v1AuthenticatorParamsV2"]; + }; + v1CreateSubOrganizationIntentV2: { + /** @description Name for this sub-organization */ + subOrganizationName: string; + /** @description Root users to create within this sub-organization */ + rootUsers: definitions["v1RootUserParams"][]; + /** + * Format: int32 + * @description The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users + */ + rootQuorumThreshold: number; + }; + v1CreateSubOrganizationIntentV3: { + /** @description Name for this sub-organization */ + subOrganizationName: string; + /** @description Root users to create within this sub-organization */ + rootUsers: definitions["v1RootUserParams"][]; + /** + * Format: int32 + * @description The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users + */ + rootQuorumThreshold: number; + /** @description A list of Private Keys. */ + privateKeys: definitions["v1PrivateKeyParams"][]; + }; + v1CreateSubOrganizationIntentV4: { + /** @description Name for this sub-organization */ + subOrganizationName: string; + /** @description Root users to create within this sub-organization */ + rootUsers: definitions["v1RootUserParams"][]; + /** + * Format: int32 + * @description The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users + */ + rootQuorumThreshold: number; + /** @description The wallet to create for the sub-organization */ + wallet?: definitions["v1WalletParams"]; + /** @description Disable email recovery for the sub-organization */ + disableEmailRecovery?: boolean; + /** @description Disable email auth for the sub-organization */ + disableEmailAuth?: boolean; + }; + v1CreateSubOrganizationIntentV5: { + /** @description Name for this sub-organization */ + subOrganizationName: string; + /** @description Root users to create within this sub-organization */ + rootUsers: definitions["v1RootUserParamsV2"][]; + /** + * Format: int32 + * @description The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users + */ + rootQuorumThreshold: number; + /** @description The wallet to create for the sub-organization */ + wallet?: definitions["v1WalletParams"]; + /** @description Disable email recovery for the sub-organization */ + disableEmailRecovery?: boolean; + /** @description Disable email auth for the sub-organization */ + disableEmailAuth?: boolean; + }; + v1CreateSubOrganizationIntentV6: { + /** @description Name for this sub-organization */ + subOrganizationName: string; + /** @description Root users to create within this sub-organization */ + rootUsers: definitions["v1RootUserParamsV3"][]; + /** + * Format: int32 + * @description The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users + */ + rootQuorumThreshold: number; + /** @description The wallet to create for the sub-organization */ + wallet?: definitions["v1WalletParams"]; + /** @description Disable email recovery for the sub-organization */ + disableEmailRecovery?: boolean; + /** @description Disable email auth for the sub-organization */ + disableEmailAuth?: boolean; + }; + v1CreateSubOrganizationIntentV7: { + /** @description Name for this sub-organization */ + subOrganizationName: string; + /** @description Root users to create within this sub-organization */ + rootUsers: definitions["v1RootUserParamsV4"][]; + /** + * Format: int32 + * @description The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users + */ + rootQuorumThreshold: number; + /** @description The wallet to create for the sub-organization */ + wallet?: definitions["v1WalletParams"]; + /** @description Disable email recovery for the sub-organization */ + disableEmailRecovery?: boolean; + /** @description Disable email auth for the sub-organization */ + disableEmailAuth?: boolean; + /** @description Disable OTP SMS auth for the sub-organization */ + disableSmsAuth?: boolean; + /** @description Disable OTP email auth for the sub-organization */ + disableOtpEmailAuth?: boolean; + }; + v1CreateSubOrganizationRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_CREATE_SUB_ORGANIZATION_V7"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1CreateSubOrganizationIntentV7"]; + }; + v1CreateSubOrganizationResult: { + subOrganizationId: string; + rootUserIds?: string[]; + }; + v1CreateSubOrganizationResultV3: { + subOrganizationId: string; + /** @description A list of Private Key IDs and addresses. */ + privateKeys: definitions["v1PrivateKeyResult"][]; + rootUserIds?: string[]; + }; + v1CreateSubOrganizationResultV4: { + subOrganizationId: string; + wallet?: definitions["v1WalletResult"]; + rootUserIds?: string[]; + }; + v1CreateSubOrganizationResultV5: { + subOrganizationId: string; + wallet?: definitions["v1WalletResult"]; + rootUserIds?: string[]; + }; + v1CreateSubOrganizationResultV6: { + subOrganizationId: string; + wallet?: definitions["v1WalletResult"]; + rootUserIds?: string[]; + }; + v1CreateSubOrganizationResultV7: { + subOrganizationId: string; + wallet?: definitions["v1WalletResult"]; + rootUserIds?: string[]; + }; + v1CreateUserTagIntent: { + /** @description Human-readable name for a User Tag. */ + userTagName: string; + /** @description A list of User IDs. */ + userIds: string[]; + }; + v1CreateUserTagRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_CREATE_USER_TAG"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1CreateUserTagIntent"]; + }; + v1CreateUserTagResult: { + /** @description Unique identifier for a given User Tag. */ + userTagId: string; + /** @description A list of User IDs. */ + userIds: string[]; + }; + v1CreateUsersIntent: { + /** @description A list of Users. */ + users: definitions["v1UserParams"][]; + }; + v1CreateUsersIntentV2: { + /** @description A list of Users. */ + users: definitions["v1UserParamsV2"][]; + }; + v1CreateUsersIntentV3: { + /** @description A list of Users. */ + users: definitions["v1UserParamsV3"][]; + }; + v1CreateUsersRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_CREATE_USERS_V3"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1CreateUsersIntentV3"]; + }; + v1CreateUsersResult: { + /** @description A list of User IDs. */ + userIds: string[]; + }; + v1CreateWalletAccountsIntent: { + /** @description Unique identifier for a given Wallet. */ + walletId: string; + /** @description A list of wallet Accounts. */ + accounts: definitions["v1WalletAccountParams"][]; + }; + v1CreateWalletAccountsRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_CREATE_WALLET_ACCOUNTS"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1CreateWalletAccountsIntent"]; + }; + v1CreateWalletAccountsResult: { + /** @description A list of derived addresses. */ + addresses: string[]; + }; + v1CreateWalletIntent: { + /** @description Human-readable name for a Wallet. */ + walletName: string; + /** @description A list of wallet Accounts. This field, if not needed, should be an empty array in your request body. */ + accounts: definitions["v1WalletAccountParams"][]; + /** + * Format: int32 + * @description Length of mnemonic to generate the Wallet seed. Defaults to 12. Accepted values: 12, 15, 18, 21, 24. + */ + mnemonicLength?: number; + }; + v1CreateWalletRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_CREATE_WALLET"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1CreateWalletIntent"]; + }; + v1CreateWalletResult: { + /** @description Unique identifier for a Wallet. */ + walletId: string; + /** @description A list of account addresses. */ + addresses: string[]; + }; + v1CredPropsAuthenticationExtensionsClientOutputs: { + rk: boolean; + }; + /** @enum {string} */ + v1CredentialType: + | "CREDENTIAL_TYPE_WEBAUTHN_AUTHENTICATOR" + | "CREDENTIAL_TYPE_API_KEY_P256" + | "CREDENTIAL_TYPE_RECOVER_USER_KEY_P256" + | "CREDENTIAL_TYPE_API_KEY_SECP256K1" + | "CREDENTIAL_TYPE_EMAIL_AUTH_KEY_P256" + | "CREDENTIAL_TYPE_API_KEY_ED25519" + | "CREDENTIAL_TYPE_OTP_AUTH_KEY_P256" + | "CREDENTIAL_TYPE_READ_WRITE_SESSION_KEY_P256" + | "CREDENTIAL_TYPE_OAUTH_KEY_P256" + | "CREDENTIAL_TYPE_LOGIN"; + /** @enum {string} */ + v1Curve: "CURVE_SECP256K1" | "CURVE_ED25519"; + v1DeleteApiKeysIntent: { + /** @description Unique identifier for a given User. */ + userId: string; + /** @description A list of API Key IDs. */ + apiKeyIds: string[]; + }; + v1DeleteApiKeysRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_DELETE_API_KEYS"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1DeleteApiKeysIntent"]; + }; + v1DeleteApiKeysResult: { + /** @description A list of API Key IDs. */ + apiKeyIds: string[]; + }; + v1DeleteAuthenticatorsIntent: { + /** @description Unique identifier for a given User. */ + userId: string; + /** @description A list of Authenticator IDs. */ + authenticatorIds: string[]; + }; + v1DeleteAuthenticatorsRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_DELETE_AUTHENTICATORS"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1DeleteAuthenticatorsIntent"]; + }; + v1DeleteAuthenticatorsResult: { + /** @description Unique identifier for a given Authenticator. */ + authenticatorIds: string[]; + }; + v1DeleteInvitationIntent: { + /** @description Unique identifier for a given Invitation object. */ + invitationId: string; + }; + v1DeleteInvitationRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_DELETE_INVITATION"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1DeleteInvitationIntent"]; + }; + v1DeleteInvitationResult: { + /** @description Unique identifier for a given Invitation. */ + invitationId: string; + }; + v1DeleteOauthProvidersIntent: { + /** @description The ID of the User to remove an Oauth provider from */ + userId: string; + /** @description Unique identifier for a given Provider. */ + providerIds: string[]; + }; + v1DeleteOauthProvidersRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_DELETE_OAUTH_PROVIDERS"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1DeleteOauthProvidersIntent"]; + }; + v1DeleteOauthProvidersResult: { + /** @description A list of unique identifiers for Oauth Providers */ + providerIds: string[]; + }; + v1DeleteOrganizationIntent: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + }; + v1DeleteOrganizationResult: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + }; + v1DeletePolicyIntent: { + /** @description Unique identifier for a given Policy. */ + policyId: string; + }; + v1DeletePolicyRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_DELETE_POLICY"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1DeletePolicyIntent"]; + }; + v1DeletePolicyResult: { + /** @description Unique identifier for a given Policy. */ + policyId: string; + }; + v1DeletePrivateKeyTagsIntent: { + /** @description A list of Private Key Tag IDs. */ + privateKeyTagIds: string[]; + }; + v1DeletePrivateKeyTagsRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_DELETE_PRIVATE_KEY_TAGS"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1DeletePrivateKeyTagsIntent"]; + }; + v1DeletePrivateKeyTagsResult: { + /** @description A list of Private Key Tag IDs. */ + privateKeyTagIds: string[]; + /** @description A list of Private Key IDs. */ + privateKeyIds: string[]; + }; + v1DeletePrivateKeysIntent: { + /** @description List of unique identifiers for private keys within an organization */ + privateKeyIds: string[]; + /** @description Optional parameter for deleting the private keys, even if any have not been previously exported. If they have been exported, this field is ignored. */ + deleteWithoutExport?: boolean; + }; + v1DeletePrivateKeysRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_DELETE_PRIVATE_KEYS"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1DeletePrivateKeysIntent"]; + }; + v1DeletePrivateKeysResult: { + /** @description A list of private key unique identifiers that were removed */ + privateKeyIds: string[]; + }; + v1DeleteSubOrganizationIntent: { + /** @description Sub-organization deletion, by default, requires associated wallets and private keys to be exported for security reasons. Set this boolean to true to force sub-organization deletion even if some wallets or private keys within it have not been exported yet. Default: false. */ + deleteWithoutExport?: boolean; + }; + v1DeleteSubOrganizationRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_DELETE_SUB_ORGANIZATION"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1DeleteSubOrganizationIntent"]; + }; + v1DeleteSubOrganizationResult: { + /** @description Unique identifier of the sub organization that was removed */ + subOrganizationUuid: string; + }; + v1DeleteUserTagsIntent: { + /** @description A list of User Tag IDs. */ + userTagIds: string[]; + }; + v1DeleteUserTagsRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_DELETE_USER_TAGS"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1DeleteUserTagsIntent"]; + }; + v1DeleteUserTagsResult: { + /** @description A list of User Tag IDs. */ + userTagIds: string[]; + /** @description A list of User IDs. */ + userIds: string[]; + }; + v1DeleteUsersIntent: { + /** @description A list of User IDs. */ + userIds: string[]; + }; + v1DeleteUsersRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_DELETE_USERS"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1DeleteUsersIntent"]; + }; + v1DeleteUsersResult: { + /** @description A list of User IDs. */ + userIds: string[]; + }; + v1DeleteWalletsIntent: { + /** @description List of unique identifiers for wallets within an organization */ + walletIds: string[]; + /** @description Optional parameter for deleting the wallets, even if any have not been previously exported. If they have been exported, this field is ignored. */ + deleteWithoutExport?: boolean; + }; + v1DeleteWalletsRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_DELETE_WALLETS"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1DeleteWalletsIntent"]; + }; + v1DeleteWalletsResult: { + /** @description A list of wallet unique identifiers that were removed */ + walletIds: string[]; + }; + v1DisablePrivateKeyIntent: { + /** @description Unique identifier for a given Private Key. */ + privateKeyId: string; + }; + v1DisablePrivateKeyResult: { + /** @description Unique identifier for a given Private Key. */ + privateKeyId: string; + }; + /** @enum {string} */ + v1Effect: "EFFECT_ALLOW" | "EFFECT_DENY"; + v1EmailAuthIntent: { + /** @description Email of the authenticating user. */ + email: string; + /** @description Client-side public key generated by the user, to which the email auth bundle (credentials) will be encrypted. */ + targetPublicKey: string; + /** @description Optional human-readable name for an API Key. If none provided, default to Email Auth - */ + apiKeyName?: string; + /** @description Expiration window (in seconds) indicating how long the API key is valid for. If not provided, a default of 15 minutes will be used. */ + expirationSeconds?: string; + /** @description Optional parameters for customizing emails. If not provided, the default email will be used. */ + emailCustomization?: definitions["v1EmailCustomizationParams"]; + /** @description Invalidate all other previously generated Email Auth API keys */ + invalidateExisting?: boolean; + /** @description Optional custom email address from which to send the email */ + sendFromEmailAddress?: string; + /** @description Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications' */ + sendFromEmailSenderName?: string; + /** @description Optional custom email address to use as reply-to */ + replyToEmailAddress?: string; + }; + v1EmailAuthIntentV2: { + /** @description Email of the authenticating user. */ + email: string; + /** @description Client-side public key generated by the user, to which the email auth bundle (credentials) will be encrypted. */ + targetPublicKey: string; + /** @description Optional human-readable name for an API Key. If none provided, default to Email Auth - */ + apiKeyName?: string; + /** @description Expiration window (in seconds) indicating how long the API key is valid for. If not provided, a default of 15 minutes will be used. */ + expirationSeconds?: string; + /** @description Optional parameters for customizing emails. If not provided, the default email will be used. */ + emailCustomization?: definitions["v1EmailCustomizationParams"]; + /** @description Invalidate all other previously generated Email Auth API keys */ + invalidateExisting?: boolean; + /** @description Optional custom email address from which to send the email */ + sendFromEmailAddress?: string; + /** @description Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications' */ + sendFromEmailSenderName?: string; + /** @description Optional custom email address to use as reply-to */ + replyToEmailAddress?: string; + }; + v1EmailAuthRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_EMAIL_AUTH_V2"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1EmailAuthIntentV2"]; + }; + v1EmailAuthResult: { + /** @description Unique identifier for the authenticating User. */ + userId: string; + /** @description Unique identifier for the created API key. */ + apiKeyId: string; + }; + v1EmailCustomizationParams: { + /** @description The name of the application. */ + appName?: string; + /** @description A URL pointing to a logo in PNG format. Note this logo will be resized to fit into 340px x 124px. */ + logoUrl?: string; + /** @description A template for the URL to be used in a magic link button, e.g. `https://dapp.xyz/%s`. The auth bundle will be interpolated into the `%s`. */ + magicLinkTemplate?: string; + /** @description JSON object containing key/value pairs to be used with custom templates. */ + templateVariables?: string; + /** @description Unique identifier for a given Email Template. If not specified, the default is the most recent Email Template. */ + templateId?: string; + }; + v1ExportPrivateKeyIntent: { + /** @description Unique identifier for a given Private Key. */ + privateKeyId: string; + /** @description Client-side public key generated by the user, to which the export bundle will be encrypted. */ + targetPublicKey: string; + }; + v1ExportPrivateKeyRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_EXPORT_PRIVATE_KEY"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1ExportPrivateKeyIntent"]; + }; + v1ExportPrivateKeyResult: { + /** @description Unique identifier for a given Private Key. */ + privateKeyId: string; + /** @description Export bundle containing a private key encrypted to the client's target public key. */ + exportBundle: string; + }; + v1ExportWalletAccountIntent: { + /** @description Address to identify Wallet Account. */ + address: string; + /** @description Client-side public key generated by the user, to which the export bundle will be encrypted. */ + targetPublicKey: string; + }; + v1ExportWalletAccountRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_EXPORT_WALLET_ACCOUNT"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1ExportWalletAccountIntent"]; + }; + v1ExportWalletAccountResult: { + /** @description Address to identify Wallet Account. */ + address: string; + /** @description Export bundle containing a private key encrypted by the client's target public key. */ + exportBundle: string; + }; + v1ExportWalletIntent: { + /** @description Unique identifier for a given Wallet. */ + walletId: string; + /** @description Client-side public key generated by the user, to which the export bundle will be encrypted. */ + targetPublicKey: string; + /** @description The language of the mnemonic to export. Defaults to English. */ + language?: definitions["v1MnemonicLanguage"]; + }; + v1ExportWalletRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_EXPORT_WALLET"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1ExportWalletIntent"]; + }; + v1ExportWalletResult: { + /** @description Unique identifier for a given Wallet. */ + walletId: string; + /** @description Export bundle containing a wallet mnemonic + optional newline passphrase encrypted by the client's target public key. */ + exportBundle: string; + }; + v1Feature: { + name?: definitions["v1FeatureName"]; + value?: string; + }; + /** @enum {string} */ + v1FeatureName: + | "FEATURE_NAME_ROOT_USER_EMAIL_RECOVERY" + | "FEATURE_NAME_WEBAUTHN_ORIGINS" + | "FEATURE_NAME_EMAIL_AUTH" + | "FEATURE_NAME_EMAIL_RECOVERY" + | "FEATURE_NAME_WEBHOOK" + | "FEATURE_NAME_SMS_AUTH" + | "FEATURE_NAME_OTP_EMAIL_AUTH"; + v1GetActivitiesRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + /** @description Array of Activity Statuses filtering which Activities will be listed in the response. */ + filterByStatus?: definitions["v1ActivityStatus"][]; + /** @description Parameters used for cursor-based pagination. */ + paginationOptions?: definitions["v1Pagination"]; + /** @description Array of Activity Types filtering which Activities will be listed in the response. */ + filterByType?: definitions["v1ActivityType"][]; + }; + v1GetActivitiesResponse: { + /** @description A list of Activities. */ + activities: definitions["v1Activity"][]; + }; + v1GetActivityRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + /** @description Unique identifier for a given Activity object. */ + activityId: string; + }; + v1GetApiKeyRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + /** @description Unique identifier for a given API key. */ + apiKeyId: string; + }; + v1GetApiKeyResponse: { + /** @description An API key. */ + apiKey: definitions["v1ApiKey"]; + }; + v1GetApiKeysRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + /** @description Unique identifier for a given User. */ + userId?: string; + }; + v1GetApiKeysResponse: { + /** @description A list of API keys. */ + apiKeys: definitions["v1ApiKey"][]; + }; + v1GetAttestationDocumentRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + /** @description The enclave type, one of: ump, notarizer, signer, evm-parser */ + enclaveType: string; + }; + v1GetAttestationDocumentResponse: { + /** + * Format: byte + * @description Raw (CBOR-encoded) attestation document + */ + attestationDocument: string; + }; + v1GetAuthenticatorRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + /** @description Unique identifier for a given Authenticator. */ + authenticatorId: string; + }; + v1GetAuthenticatorResponse: { + /** @description An authenticator. */ + authenticator: definitions["v1Authenticator"]; + }; + v1GetAuthenticatorsRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + /** @description Unique identifier for a given User. */ + userId: string; + }; + v1GetAuthenticatorsResponse: { + /** @description A list of authenticators. */ + authenticators: definitions["v1Authenticator"][]; + }; + v1GetOauthProvidersRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + /** @description Unique identifier for a given User. */ + userId?: string; + }; + v1GetOauthProvidersResponse: { + /** @description A list of Oauth Providers */ + oauthProviders: definitions["v1OauthProvider"][]; + }; + v1GetOrganizationConfigsRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + }; + v1GetOrganizationConfigsResponse: { + /** @description Organization configs including quorum settings and organization features */ + configs: definitions["v1Config"]; + }; + v1GetOrganizationRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + }; + v1GetOrganizationResponse: { + /** @description Object representing the full current and deleted / disabled collection of Users, Policies, Private Keys, and Invitations attributable to a particular Organization. */ + organizationData: definitions["v1OrganizationData"]; + }; + v1GetPoliciesRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + }; + v1GetPoliciesResponse: { + /** @description A list of Policies. */ + policies: definitions["v1Policy"][]; + }; + v1GetPolicyRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + /** @description Unique identifier for a given Policy. */ + policyId: string; + }; + v1GetPolicyResponse: { + /** @description Object that codifies rules defining the actions that are permissible within an Organization. */ + policy: definitions["v1Policy"]; + }; + v1GetPrivateKeyRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + /** @description Unique identifier for a given Private Key. */ + privateKeyId: string; + }; + v1GetPrivateKeyResponse: { + /** @description Cryptographic public/private key pair that can be used for cryptocurrency needs or more generalized encryption. */ + privateKey: definitions["v1PrivateKey"]; + }; + v1GetPrivateKeysRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + }; + v1GetPrivateKeysResponse: { + /** @description A list of Private Keys. */ + privateKeys: definitions["v1PrivateKey"][]; + }; + v1GetSubOrgIdsRequest: { + /** @description Unique identifier for the parent Organization. This is used to find sub-organizations within it. */ + organizationId: string; + /** @description Specifies the type of filter to apply, i.e 'CREDENTIAL_ID', 'NAME', 'USERNAME', 'EMAIL', 'PHONE_NUMBER', 'OIDC_TOKEN' or 'PUBLIC_KEY' */ + filterType?: string; + /** @description The value of the filter to apply for the specified type. For example, a specific email or name string. */ + filterValue?: string; + /** @description Parameters used for cursor-based pagination. */ + paginationOptions?: definitions["v1Pagination"]; + }; + v1GetSubOrgIdsResponse: { + /** @description List of unique identifiers for the matching sub-organizations. */ + organizationIds: string[]; + }; + v1GetUserRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + /** @description Unique identifier for a given User. */ + userId: string; + }; + v1GetUserResponse: { + /** @description Web and/or API user within your Organization. */ + user: definitions["v1User"]; + }; + v1GetUsersRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + }; + v1GetUsersResponse: { + /** @description A list of Users. */ + users: definitions["v1User"][]; + }; + v1GetVerifiedSubOrgIdsRequest: { + /** @description Unique identifier for the parent Organization. This is used to find sub-organizations within it. */ + organizationId: string; + /** @description Specifies the type of filter to apply, i.e 'EMAIL', 'PHONE_NUMBER' */ + filterType?: string; + /** @description The value of the filter to apply for the specified type. For example, a specific email or phone number string. */ + filterValue?: string; + /** @description Parameters used for cursor-based pagination. */ + paginationOptions?: definitions["v1Pagination"]; + }; + v1GetVerifiedSubOrgIdsResponse: { + /** @description List of unique identifiers for the matching sub-organizations. */ + organizationIds: string[]; + }; + v1GetWalletAccountRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + /** @description Unique identifier for a given Wallet. */ + walletId: string; + /** @description Address corresponding to a Wallet Account. */ + address?: string; + /** @description Path corresponding to a Wallet Account. */ + path?: string; + }; + v1GetWalletAccountResponse: { + /** @description The resulting Wallet Account. */ + account: definitions["v1WalletAccount"]; + }; + v1GetWalletAccountsRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + /** @description Unique identifier for a given Wallet. */ + walletId: string; + /** @description Parameters used for cursor-based pagination. */ + paginationOptions?: definitions["v1Pagination"]; + }; + v1GetWalletAccountsResponse: { + /** @description A list of Accounts generated from a Wallet that share a common seed. */ + accounts: definitions["v1WalletAccount"][]; + }; + v1GetWalletRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + /** @description Unique identifier for a given Wallet. */ + walletId: string; + }; + v1GetWalletResponse: { + /** @description A collection of deterministically generated cryptographic public / private key pairs that share a common seed */ + wallet: definitions["v1Wallet"]; + }; + v1GetWalletsRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + }; + v1GetWalletsResponse: { + /** @description A list of Wallets. */ + wallets: definitions["v1Wallet"][]; + }; + v1GetWhoamiRequest: { + /** @description 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. */ + organizationId: string; + }; + v1GetWhoamiResponse: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + /** @description Human-readable name for an Organization. */ + organizationName: string; + /** @description Unique identifier for a given User. */ + userId: string; + /** @description Human-readable name for a User. */ + username: string; + }; + /** @enum {string} */ + v1HashFunction: + | "HASH_FUNCTION_NO_OP" + | "HASH_FUNCTION_SHA256" + | "HASH_FUNCTION_KECCAK256" + | "HASH_FUNCTION_NOT_APPLICABLE"; + v1ImportPrivateKeyIntent: { + /** @description The ID of the User importing a Private Key. */ + userId: string; + /** @description Human-readable name for a Private Key. */ + privateKeyName: string; + /** @description Bundle containing a raw private key encrypted to the enclave's target public key. */ + encryptedBundle: string; + /** @description Cryptographic Curve used to generate a given Private Key. */ + curve: definitions["v1Curve"]; + /** @description Cryptocurrency-specific formats for a derived address (e.g., Ethereum). */ + addressFormats: definitions["v1AddressFormat"][]; + }; + v1ImportPrivateKeyRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_IMPORT_PRIVATE_KEY"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1ImportPrivateKeyIntent"]; + }; + v1ImportPrivateKeyResult: { + /** @description Unique identifier for a Private Key. */ + privateKeyId: string; + /** @description A list of addresses. */ + addresses: definitions["immutableactivityv1Address"][]; + }; + v1ImportWalletIntent: { + /** @description The ID of the User importing a Wallet. */ + userId: string; + /** @description Human-readable name for a Wallet. */ + walletName: string; + /** @description Bundle containing a wallet mnemonic encrypted to the enclave's target public key. */ + encryptedBundle: string; + /** @description A list of wallet Accounts. */ + accounts: definitions["v1WalletAccountParams"][]; + }; + v1ImportWalletRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_IMPORT_WALLET"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1ImportWalletIntent"]; + }; + v1ImportWalletResult: { + /** @description Unique identifier for a Wallet. */ + walletId: string; + /** @description A list of account addresses. */ + addresses: string[]; + }; + v1InitImportPrivateKeyIntent: { + /** @description The ID of the User importing a Private Key. */ + userId: string; + }; + v1InitImportPrivateKeyRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_INIT_IMPORT_PRIVATE_KEY"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1InitImportPrivateKeyIntent"]; + }; + v1InitImportPrivateKeyResult: { + /** @description Import bundle containing a public key and signature to use for importing client data. */ + importBundle: string; + }; + v1InitImportWalletIntent: { + /** @description The ID of the User importing a Wallet. */ + userId: string; + }; + v1InitImportWalletRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_INIT_IMPORT_WALLET"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1InitImportWalletIntent"]; + }; + v1InitImportWalletResult: { + /** @description Import bundle containing a public key and signature to use for importing client data. */ + importBundle: string; + }; + v1InitOtpAuthIntent: { + /** @description Enum to specifiy whether to send OTP via SMS or email */ + otpType: string; + /** @description Email or phone number to send the OTP code to */ + contact: string; + /** @description Optional parameters for customizing emails. If not provided, the default email will be used. */ + emailCustomization?: definitions["v1EmailCustomizationParams"]; + /** @description Optional parameters for customizing SMS message. If not provided, the default sms message will be used. */ + smsCustomization?: definitions["v1SmsCustomizationParams"]; + /** @description 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. */ + userIdentifier?: string; + /** @description Optional custom email address from which to send the OTP email */ + sendFromEmailAddress?: string; + /** @description Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications' */ + sendFromEmailSenderName?: string; + /** @description Optional custom email address to use as reply-to */ + replyToEmailAddress?: string; + }; + v1InitOtpAuthIntentV2: { + /** @description Enum to specifiy whether to send OTP via SMS or email */ + otpType: string; + /** @description Email or phone number to send the OTP code to */ + contact: string; + /** + * Format: int32 + * @description Optional length of the OTP code. Default = 9 + */ + otpLength?: number; + /** @description Optional parameters for customizing emails. If not provided, the default email will be used. */ + emailCustomization?: definitions["v1EmailCustomizationParams"]; + /** @description Optional parameters for customizing SMS message. If not provided, the default sms message will be used. */ + smsCustomization?: definitions["v1SmsCustomizationParams"]; + /** @description 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. */ + userIdentifier?: string; + /** @description Optional custom email address from which to send the OTP email */ + sendFromEmailAddress?: string; + /** @description Optional flag to specify if the OTP code should be alphanumeric (Crockford’s Base32). Default = true */ + alphanumeric?: boolean; + /** @description Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications' */ + sendFromEmailSenderName?: string; + /** @description Optional custom email address to use as reply-to */ + replyToEmailAddress?: string; + }; + v1InitOtpAuthRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_INIT_OTP_AUTH_V2"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1InitOtpAuthIntentV2"]; + }; + v1InitOtpAuthResult: { + /** @description Unique identifier for an OTP authentication */ + otpId: string; + }; + v1InitOtpAuthResultV2: { + /** @description Unique identifier for an OTP authentication */ + otpId: string; + }; + v1InitOtpIntent: { + /** @description Whether to send OTP via SMS or email. Possible values: OTP_TYPE_SMS, OTP_TYPE_EMAIL */ + otpType: string; + /** @description Email or phone number to send the OTP code to */ + contact: string; + /** + * Format: int32 + * @description Optional length of the OTP code. Default = 9 + */ + otpLength?: number; + /** @description Optional parameters for customizing emails. If not provided, the default email will be used. */ + emailCustomization?: definitions["v1EmailCustomizationParams"]; + /** @description Optional parameters for customizing SMS message. If not provided, the default sms message will be used. */ + smsCustomization?: definitions["v1SmsCustomizationParams"]; + /** @description 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. */ + userIdentifier?: string; + /** @description Optional custom email address from which to send the OTP email */ + sendFromEmailAddress?: string; + /** @description Optional flag to specify if the OTP code should be alphanumeric (Crockford’s Base32). Default = true */ + alphanumeric?: boolean; + /** @description Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications' */ + sendFromEmailSenderName?: string; + /** @description 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) */ + expirationSeconds?: string; + /** @description Optional custom email address to use as reply-to */ + replyToEmailAddress?: string; + }; + v1InitOtpRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_INIT_OTP"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1InitOtpIntent"]; + }; + v1InitOtpResult: { + /** @description Unique identifier for an OTP authentication */ + otpId: string; + }; + v1InitUserEmailRecoveryIntent: { + /** @description Email of the user starting recovery */ + email: string; + /** @description Client-side public key generated by the user, to which the recovery bundle will be encrypted. */ + targetPublicKey: string; + /** @description Expiration window (in seconds) indicating how long the recovery credential is valid for. If not provided, a default of 15 minutes will be used. */ + expirationSeconds?: string; + /** @description Optional parameters for customizing emails. If not provided, the default email will be used. */ + emailCustomization?: definitions["v1EmailCustomizationParams"]; + }; + v1InitUserEmailRecoveryRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_INIT_USER_EMAIL_RECOVERY"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1InitUserEmailRecoveryIntent"]; + }; + v1InitUserEmailRecoveryResult: { + /** @description Unique identifier for the user being recovered. */ + userId: string; + }; + v1Intent: { + createOrganizationIntent?: definitions["v1CreateOrganizationIntent"]; + createAuthenticatorsIntent?: definitions["v1CreateAuthenticatorsIntent"]; + createUsersIntent?: definitions["v1CreateUsersIntent"]; + createPrivateKeysIntent?: definitions["v1CreatePrivateKeysIntent"]; + signRawPayloadIntent?: definitions["v1SignRawPayloadIntent"]; + createInvitationsIntent?: definitions["v1CreateInvitationsIntent"]; + acceptInvitationIntent?: definitions["v1AcceptInvitationIntent"]; + createPolicyIntent?: definitions["v1CreatePolicyIntent"]; + disablePrivateKeyIntent?: definitions["v1DisablePrivateKeyIntent"]; + deleteUsersIntent?: definitions["v1DeleteUsersIntent"]; + deleteAuthenticatorsIntent?: definitions["v1DeleteAuthenticatorsIntent"]; + deleteInvitationIntent?: definitions["v1DeleteInvitationIntent"]; + deleteOrganizationIntent?: definitions["v1DeleteOrganizationIntent"]; + deletePolicyIntent?: definitions["v1DeletePolicyIntent"]; + createUserTagIntent?: definitions["v1CreateUserTagIntent"]; + deleteUserTagsIntent?: definitions["v1DeleteUserTagsIntent"]; + signTransactionIntent?: definitions["v1SignTransactionIntent"]; + createApiKeysIntent?: definitions["v1CreateApiKeysIntent"]; + deleteApiKeysIntent?: definitions["v1DeleteApiKeysIntent"]; + approveActivityIntent?: definitions["v1ApproveActivityIntent"]; + rejectActivityIntent?: definitions["v1RejectActivityIntent"]; + createPrivateKeyTagIntent?: definitions["v1CreatePrivateKeyTagIntent"]; + deletePrivateKeyTagsIntent?: definitions["v1DeletePrivateKeyTagsIntent"]; + createPolicyIntentV2?: definitions["v1CreatePolicyIntentV2"]; + setPaymentMethodIntent?: definitions["billingSetPaymentMethodIntent"]; + activateBillingTierIntent?: definitions["billingActivateBillingTierIntent"]; + deletePaymentMethodIntent?: definitions["billingDeletePaymentMethodIntent"]; + createPolicyIntentV3?: definitions["v1CreatePolicyIntentV3"]; + createApiOnlyUsersIntent?: definitions["v1CreateApiOnlyUsersIntent"]; + updateRootQuorumIntent?: definitions["v1UpdateRootQuorumIntent"]; + updateUserTagIntent?: definitions["v1UpdateUserTagIntent"]; + updatePrivateKeyTagIntent?: definitions["v1UpdatePrivateKeyTagIntent"]; + createAuthenticatorsIntentV2?: definitions["v1CreateAuthenticatorsIntentV2"]; + acceptInvitationIntentV2?: definitions["v1AcceptInvitationIntentV2"]; + createOrganizationIntentV2?: definitions["v1CreateOrganizationIntentV2"]; + createUsersIntentV2?: definitions["v1CreateUsersIntentV2"]; + createSubOrganizationIntent?: definitions["v1CreateSubOrganizationIntent"]; + createSubOrganizationIntentV2?: definitions["v1CreateSubOrganizationIntentV2"]; + updateAllowedOriginsIntent?: definitions["v1UpdateAllowedOriginsIntent"]; + createPrivateKeysIntentV2?: definitions["v1CreatePrivateKeysIntentV2"]; + updateUserIntent?: definitions["v1UpdateUserIntent"]; + updatePolicyIntent?: definitions["v1UpdatePolicyIntent"]; + setPaymentMethodIntentV2?: definitions["billingSetPaymentMethodIntentV2"]; + createSubOrganizationIntentV3?: definitions["v1CreateSubOrganizationIntentV3"]; + createWalletIntent?: definitions["v1CreateWalletIntent"]; + createWalletAccountsIntent?: definitions["v1CreateWalletAccountsIntent"]; + initUserEmailRecoveryIntent?: definitions["v1InitUserEmailRecoveryIntent"]; + recoverUserIntent?: definitions["v1RecoverUserIntent"]; + setOrganizationFeatureIntent?: definitions["v1SetOrganizationFeatureIntent"]; + removeOrganizationFeatureIntent?: definitions["v1RemoveOrganizationFeatureIntent"]; + signRawPayloadIntentV2?: definitions["v1SignRawPayloadIntentV2"]; + signTransactionIntentV2?: definitions["v1SignTransactionIntentV2"]; + exportPrivateKeyIntent?: definitions["v1ExportPrivateKeyIntent"]; + exportWalletIntent?: definitions["v1ExportWalletIntent"]; + createSubOrganizationIntentV4?: definitions["v1CreateSubOrganizationIntentV4"]; + emailAuthIntent?: definitions["v1EmailAuthIntent"]; + exportWalletAccountIntent?: definitions["v1ExportWalletAccountIntent"]; + initImportWalletIntent?: definitions["v1InitImportWalletIntent"]; + importWalletIntent?: definitions["v1ImportWalletIntent"]; + initImportPrivateKeyIntent?: definitions["v1InitImportPrivateKeyIntent"]; + importPrivateKeyIntent?: definitions["v1ImportPrivateKeyIntent"]; + createPoliciesIntent?: definitions["v1CreatePoliciesIntent"]; + signRawPayloadsIntent?: definitions["v1SignRawPayloadsIntent"]; + createReadOnlySessionIntent?: definitions["v1CreateReadOnlySessionIntent"]; + createOauthProvidersIntent?: definitions["v1CreateOauthProvidersIntent"]; + deleteOauthProvidersIntent?: definitions["v1DeleteOauthProvidersIntent"]; + createSubOrganizationIntentV5?: definitions["v1CreateSubOrganizationIntentV5"]; + oauthIntent?: definitions["v1OauthIntent"]; + createApiKeysIntentV2?: definitions["v1CreateApiKeysIntentV2"]; + createReadWriteSessionIntent?: definitions["v1CreateReadWriteSessionIntent"]; + emailAuthIntentV2?: definitions["v1EmailAuthIntentV2"]; + createSubOrganizationIntentV6?: definitions["v1CreateSubOrganizationIntentV6"]; + deletePrivateKeysIntent?: definitions["v1DeletePrivateKeysIntent"]; + deleteWalletsIntent?: definitions["v1DeleteWalletsIntent"]; + createReadWriteSessionIntentV2?: definitions["v1CreateReadWriteSessionIntentV2"]; + deleteSubOrganizationIntent?: definitions["v1DeleteSubOrganizationIntent"]; + initOtpAuthIntent?: definitions["v1InitOtpAuthIntent"]; + otpAuthIntent?: definitions["v1OtpAuthIntent"]; + createSubOrganizationIntentV7?: definitions["v1CreateSubOrganizationIntentV7"]; + updateWalletIntent?: definitions["v1UpdateWalletIntent"]; + updatePolicyIntentV2?: definitions["v1UpdatePolicyIntentV2"]; + createUsersIntentV3?: definitions["v1CreateUsersIntentV3"]; + initOtpAuthIntentV2?: definitions["v1InitOtpAuthIntentV2"]; + initOtpIntent?: definitions["v1InitOtpIntent"]; + verifyOtpIntent?: definitions["v1VerifyOtpIntent"]; + otpLoginIntent?: definitions["v1OtpLoginIntent"]; + stampLoginIntent?: definitions["v1StampLoginIntent"]; + oauthLoginIntent?: definitions["v1OauthLoginIntent"]; + }; + v1Invitation: { + /** @description Unique identifier for a given Invitation object. */ + invitationId: string; + /** @description The name of the intended Invitation recipient. */ + receiverUserName: string; + /** @description The email address of the intended Invitation recipient. */ + receiverEmail: string; + /** @description A list of tags assigned to the Invitation recipient. */ + receiverUserTags: string[]; + /** @description The User's permissible access method(s). */ + accessType: definitions["v1AccessType"]; + /** @description The current processing status of a specified Invitation. */ + status: definitions["v1InvitationStatus"]; + createdAt: definitions["externaldatav1Timestamp"]; + updatedAt: definitions["externaldatav1Timestamp"]; + /** @description Unique identifier for the Sender of an Invitation. */ + senderUserId: string; + }; + v1InvitationParams: { + /** @description The name of the intended Invitation recipient. */ + receiverUserName: string; + /** @description The email address of the intended Invitation recipient. */ + receiverUserEmail: string; + /** @description A list of tags assigned to the Invitation recipient. This field, if not needed, should be an empty array in your request body. */ + receiverUserTags: string[]; + /** @description The User's permissible access method(s). */ + accessType: definitions["v1AccessType"]; + /** @description Unique identifier for the Sender of an Invitation. */ + senderUserId: string; + }; + /** @enum {string} */ + v1InvitationStatus: + | "INVITATION_STATUS_CREATED" + | "INVITATION_STATUS_ACCEPTED" + | "INVITATION_STATUS_REVOKED"; + v1ListPrivateKeyTagsRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + }; + v1ListPrivateKeyTagsResponse: { + /** @description A list of Private Key Tags */ + privateKeyTags: definitions["datav1Tag"][]; + }; + v1ListUserTagsRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + }; + v1ListUserTagsResponse: { + /** @description A list of User Tags */ + userTags: definitions["datav1Tag"][]; + }; + /** @enum {string} */ + v1MnemonicLanguage: + | "MNEMONIC_LANGUAGE_ENGLISH" + | "MNEMONIC_LANGUAGE_SIMPLIFIED_CHINESE" + | "MNEMONIC_LANGUAGE_TRADITIONAL_CHINESE" + | "MNEMONIC_LANGUAGE_CZECH" + | "MNEMONIC_LANGUAGE_FRENCH" + | "MNEMONIC_LANGUAGE_ITALIAN" + | "MNEMONIC_LANGUAGE_JAPANESE" + | "MNEMONIC_LANGUAGE_KOREAN" + | "MNEMONIC_LANGUAGE_SPANISH"; + v1NOOPCodegenAnchorResponse: { + stamp: definitions["v1WebAuthnStamp"]; + }; + v1OauthIntent: { + /** @description Base64 encoded OIDC token */ + oidcToken: string; + /** @description Client-side public key generated by the user, to which the oauth bundle (credentials) will be encrypted. */ + targetPublicKey: string; + /** @description Optional human-readable name for an API Key. If none provided, default to Oauth - */ + apiKeyName?: string; + /** @description Expiration window (in seconds) indicating how long the API key is valid for. If not provided, a default of 15 minutes will be used. */ + expirationSeconds?: string; + /** @description Invalidate all other previously generated Oauth API keys */ + invalidateExisting?: boolean; + }; + v1OauthLoginIntent: { + /** @description Base64 encoded OIDC token */ + oidcToken: string; + /** @description 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 */ + publicKey: string; + /** @description Expiration window (in seconds) indicating how long the Session is valid for. If not provided, a default of 15 minutes will be used. */ + expirationSeconds?: string; + /** @description Invalidate all other previously generated Login API keys */ + invalidateExisting?: boolean; + }; + v1OauthLoginRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_OAUTH_LOGIN"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1OauthLoginIntent"]; + }; + v1OauthLoginResult: { + /** @description Signed JWT containing an expiry, public key, session type, user id, and organization id */ + session: string; + }; + v1OauthProvider: { + /** @description Unique identifier for an OAuth Provider */ + providerId: string; + /** @description Human-readable name to identify a Provider. */ + providerName: string; + /** @description The issuer of the token, typically a URL indicating the authentication server, e.g https://accounts.google.com */ + issuer: string; + /** @description Expected audience ('aud' attribute of the signed token) which represents the app ID */ + audience: string; + /** @description Expected subject ('sub' attribute of the signed token) which represents the user ID */ + subject: string; + createdAt: definitions["externaldatav1Timestamp"]; + updatedAt: definitions["externaldatav1Timestamp"]; + }; + v1OauthProviderParams: { + /** @description Human-readable name to identify a Provider. */ + providerName: string; + /** @description Base64 encoded OIDC token */ + oidcToken: string; + }; + v1OauthRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_OAUTH"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1OauthIntent"]; + }; + v1OauthResult: { + /** @description Unique identifier for the authenticating User. */ + userId: string; + /** @description Unique identifier for the created API key. */ + apiKeyId: string; + /** @description HPKE encrypted credential bundle */ + credentialBundle: string; + }; + /** @enum {string} */ + v1Operator: + | "OPERATOR_EQUAL" + | "OPERATOR_MORE_THAN" + | "OPERATOR_MORE_THAN_OR_EQUAL" + | "OPERATOR_LESS_THAN" + | "OPERATOR_LESS_THAN_OR_EQUAL" + | "OPERATOR_CONTAINS" + | "OPERATOR_NOT_EQUAL" + | "OPERATOR_IN" + | "OPERATOR_NOT_IN" + | "OPERATOR_CONTAINS_ONE" + | "OPERATOR_CONTAINS_ALL"; + v1OrganizationData: { + organizationId?: string; + name?: string; + users?: definitions["v1User"][]; + policies?: definitions["v1Policy"][]; + privateKeys?: definitions["v1PrivateKey"][]; + invitations?: definitions["v1Invitation"][]; + tags?: definitions["datav1Tag"][]; + rootQuorum?: definitions["externaldatav1Quorum"]; + features?: definitions["v1Feature"][]; + wallets?: definitions["v1Wallet"][]; + }; + v1OtpAuthIntent: { + /** @description ID representing the result of an init OTP activity. */ + otpId: string; + /** @description OTP sent out to a user's contact (email or SMS) */ + otpCode: string; + /** @description Client-side public key generated by the user, to which the OTP bundle (credentials) will be encrypted. */ + targetPublicKey: string; + /** @description Optional human-readable name for an API Key. If none provided, default to OTP Auth - */ + apiKeyName?: string; + /** @description Expiration window (in seconds) indicating how long the API key is valid for. If not provided, a default of 15 minutes will be used. */ + expirationSeconds?: string; + /** @description Invalidate all other previously generated OTP Auth API keys */ + invalidateExisting?: boolean; + }; + v1OtpAuthRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_OTP_AUTH"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1OtpAuthIntent"]; + }; + v1OtpAuthResult: { + /** @description Unique identifier for the authenticating User. */ + userId: string; + /** @description Unique identifier for the created API key. */ + apiKeyId?: string; + /** @description HPKE encrypted credential bundle */ + credentialBundle?: string; + }; + v1OtpLoginIntent: { + /** @description Signed JWT containing a unique id, expiry, verification type, contact */ + verificationToken: string; + /** @description Client-side public key generated by the user, which will be conditionally added to org data based on the validity of the verification token */ + publicKey: string; + /** @description Expiration window (in seconds) indicating how long the Session is valid for. If not provided, a default of 15 minutes will be used. */ + expirationSeconds?: string; + /** @description Invalidate all other previously generated Login API keys */ + invalidateExisting?: boolean; + }; + v1OtpLoginRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_OTP_LOGIN"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1OtpLoginIntent"]; + }; + v1OtpLoginResult: { + /** @description Signed JWT containing an expiry, public key, session type, user id, and organization id */ + session: string; + }; + v1Pagination: { + /** @description A limit of the number of object to be returned, between 1 and 100. Defaults to 10. */ + limit?: string; + /** @description A pagination cursor. This is an object ID that enables you to fetch all objects before this ID. */ + before?: string; + /** @description A pagination cursor. This is an object ID that enables you to fetch all objects after this ID. */ + after?: string; + }; + /** @enum {string} */ + v1PathFormat: "PATH_FORMAT_BIP32"; + /** @enum {string} */ + v1PayloadEncoding: + | "PAYLOAD_ENCODING_HEXADECIMAL" + | "PAYLOAD_ENCODING_TEXT_UTF8"; + v1Policy: { + /** @description Unique identifier for a given Policy. */ + policyId: string; + /** @description Human-readable name for a Policy. */ + policyName: string; + /** @description The instruction to DENY or ALLOW a particular activity following policy selector(s). */ + effect: definitions["v1Effect"]; + createdAt: definitions["externaldatav1Timestamp"]; + updatedAt: definitions["externaldatav1Timestamp"]; + /** @description Human-readable notes added by a User to describe a particular policy. */ + notes: string; + /** @description A consensus expression that evalutes to true or false. */ + consensus: string; + /** @description A condition expression that evalutes to true or false. */ + condition: string; + }; + v1PrivateKey: { + /** @description Unique identifier for a given Private Key. */ + privateKeyId: string; + /** @description The public component of a cryptographic key pair used to sign messages and transactions. */ + publicKey: string; + /** @description Human-readable name for a Private Key. */ + privateKeyName: string; + /** @description Cryptographic Curve used to generate a given Private Key. */ + curve: definitions["v1Curve"]; + /** @description Derived cryptocurrency addresses for a given Private Key. */ + addresses: definitions["externaldatav1Address"][]; + /** @description A list of Private Key Tag IDs. */ + privateKeyTags: string[]; + createdAt: definitions["externaldatav1Timestamp"]; + updatedAt: definitions["externaldatav1Timestamp"]; + /** @description True when a given Private Key is exported, false otherwise. */ + exported: boolean; + /** @description True when a given Private Key is imported, false otherwise. */ + imported: boolean; + }; + v1PrivateKeyParams: { + /** @description Human-readable name for a Private Key. */ + privateKeyName: string; + /** @description Cryptographic Curve used to generate a given Private Key. */ + curve: definitions["v1Curve"]; + /** @description A list of Private Key Tag IDs. This field, if not needed, should be an empty array in your request body. */ + privateKeyTags: string[]; + /** @description Cryptocurrency-specific formats for a derived address (e.g., Ethereum). */ + addressFormats: definitions["v1AddressFormat"][]; + }; + v1PrivateKeyResult: { + privateKeyId?: string; + addresses?: definitions["immutableactivityv1Address"][]; + }; + v1PublicKeyCredentialWithAttestation: { + id: string; + /** @enum {string} */ + type: "public-key"; + rawId: string; + /** @enum {string} */ + authenticatorAttachment?: "cross-platform" | "platform" | null; + response: definitions["v1AuthenticatorAttestationResponse"]; + clientExtensionResults: definitions["v1SimpleClientExtensionResults"]; + }; + v1RecoverUserIntent: { + /** @description The new authenticator to register. */ + authenticator: definitions["v1AuthenticatorParamsV2"]; + /** @description Unique identifier for the user performing recovery. */ + userId: string; + }; + v1RecoverUserRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_RECOVER_USER"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1RecoverUserIntent"]; + }; + v1RecoverUserResult: { + /** @description ID of the authenticator created. */ + authenticatorId: string[]; + }; + v1RejectActivityIntent: { + /** @description An artifact verifying a User's action. */ + fingerprint: string; + }; + v1RejectActivityRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_REJECT_ACTIVITY"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1RejectActivityIntent"]; + }; + v1RemoveOrganizationFeatureIntent: { + /** @description Name of the feature to remove */ + name: definitions["v1FeatureName"]; + }; + v1RemoveOrganizationFeatureRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_REMOVE_ORGANIZATION_FEATURE"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1RemoveOrganizationFeatureIntent"]; + }; + v1RemoveOrganizationFeatureResult: { + /** @description Resulting list of organization features. */ + features: definitions["v1Feature"][]; + }; + v1Result: { + createOrganizationResult?: definitions["v1CreateOrganizationResult"]; + createAuthenticatorsResult?: definitions["v1CreateAuthenticatorsResult"]; + createUsersResult?: definitions["v1CreateUsersResult"]; + createPrivateKeysResult?: definitions["v1CreatePrivateKeysResult"]; + createInvitationsResult?: definitions["v1CreateInvitationsResult"]; + acceptInvitationResult?: definitions["v1AcceptInvitationResult"]; + signRawPayloadResult?: definitions["v1SignRawPayloadResult"]; + createPolicyResult?: definitions["v1CreatePolicyResult"]; + disablePrivateKeyResult?: definitions["v1DisablePrivateKeyResult"]; + deleteUsersResult?: definitions["v1DeleteUsersResult"]; + deleteAuthenticatorsResult?: definitions["v1DeleteAuthenticatorsResult"]; + deleteInvitationResult?: definitions["v1DeleteInvitationResult"]; + deleteOrganizationResult?: definitions["v1DeleteOrganizationResult"]; + deletePolicyResult?: definitions["v1DeletePolicyResult"]; + createUserTagResult?: definitions["v1CreateUserTagResult"]; + deleteUserTagsResult?: definitions["v1DeleteUserTagsResult"]; + signTransactionResult?: definitions["v1SignTransactionResult"]; + deleteApiKeysResult?: definitions["v1DeleteApiKeysResult"]; + createApiKeysResult?: definitions["v1CreateApiKeysResult"]; + createPrivateKeyTagResult?: definitions["v1CreatePrivateKeyTagResult"]; + deletePrivateKeyTagsResult?: definitions["v1DeletePrivateKeyTagsResult"]; + setPaymentMethodResult?: definitions["billingSetPaymentMethodResult"]; + activateBillingTierResult?: definitions["billingActivateBillingTierResult"]; + deletePaymentMethodResult?: definitions["billingDeletePaymentMethodResult"]; + createApiOnlyUsersResult?: definitions["v1CreateApiOnlyUsersResult"]; + updateRootQuorumResult?: definitions["v1UpdateRootQuorumResult"]; + updateUserTagResult?: definitions["v1UpdateUserTagResult"]; + updatePrivateKeyTagResult?: definitions["v1UpdatePrivateKeyTagResult"]; + createSubOrganizationResult?: definitions["v1CreateSubOrganizationResult"]; + updateAllowedOriginsResult?: definitions["v1UpdateAllowedOriginsResult"]; + createPrivateKeysResultV2?: definitions["v1CreatePrivateKeysResultV2"]; + updateUserResult?: definitions["v1UpdateUserResult"]; + updatePolicyResult?: definitions["v1UpdatePolicyResult"]; + createSubOrganizationResultV3?: definitions["v1CreateSubOrganizationResultV3"]; + createWalletResult?: definitions["v1CreateWalletResult"]; + createWalletAccountsResult?: definitions["v1CreateWalletAccountsResult"]; + initUserEmailRecoveryResult?: definitions["v1InitUserEmailRecoveryResult"]; + recoverUserResult?: definitions["v1RecoverUserResult"]; + setOrganizationFeatureResult?: definitions["v1SetOrganizationFeatureResult"]; + removeOrganizationFeatureResult?: definitions["v1RemoveOrganizationFeatureResult"]; + exportPrivateKeyResult?: definitions["v1ExportPrivateKeyResult"]; + exportWalletResult?: definitions["v1ExportWalletResult"]; + createSubOrganizationResultV4?: definitions["v1CreateSubOrganizationResultV4"]; + emailAuthResult?: definitions["v1EmailAuthResult"]; + exportWalletAccountResult?: definitions["v1ExportWalletAccountResult"]; + initImportWalletResult?: definitions["v1InitImportWalletResult"]; + importWalletResult?: definitions["v1ImportWalletResult"]; + initImportPrivateKeyResult?: definitions["v1InitImportPrivateKeyResult"]; + importPrivateKeyResult?: definitions["v1ImportPrivateKeyResult"]; + createPoliciesResult?: definitions["v1CreatePoliciesResult"]; + signRawPayloadsResult?: definitions["v1SignRawPayloadsResult"]; + createReadOnlySessionResult?: definitions["v1CreateReadOnlySessionResult"]; + createOauthProvidersResult?: definitions["v1CreateOauthProvidersResult"]; + deleteOauthProvidersResult?: definitions["v1DeleteOauthProvidersResult"]; + createSubOrganizationResultV5?: definitions["v1CreateSubOrganizationResultV5"]; + oauthResult?: definitions["v1OauthResult"]; + createReadWriteSessionResult?: definitions["v1CreateReadWriteSessionResult"]; + createSubOrganizationResultV6?: definitions["v1CreateSubOrganizationResultV6"]; + deletePrivateKeysResult?: definitions["v1DeletePrivateKeysResult"]; + deleteWalletsResult?: definitions["v1DeleteWalletsResult"]; + createReadWriteSessionResultV2?: definitions["v1CreateReadWriteSessionResultV2"]; + deleteSubOrganizationResult?: definitions["v1DeleteSubOrganizationResult"]; + initOtpAuthResult?: definitions["v1InitOtpAuthResult"]; + otpAuthResult?: definitions["v1OtpAuthResult"]; + createSubOrganizationResultV7?: definitions["v1CreateSubOrganizationResultV7"]; + updateWalletResult?: definitions["v1UpdateWalletResult"]; + updatePolicyResultV2?: definitions["v1UpdatePolicyResultV2"]; + initOtpAuthResultV2?: definitions["v1InitOtpAuthResultV2"]; + initOtpResult?: definitions["v1InitOtpResult"]; + verifyOtpResult?: definitions["v1VerifyOtpResult"]; + otpLoginResult?: definitions["v1OtpLoginResult"]; + stampLoginResult?: definitions["v1StampLoginResult"]; + oauthLoginResult?: definitions["v1OauthLoginResult"]; + }; + v1RootUserParams: { + /** @description Human-readable name for a User. */ + userName: string; + /** @description The user's email address. */ + userEmail?: string; + /** @description A list of API Key parameters. This field, if not needed, should be an empty array in your request body. */ + apiKeys: definitions["apiApiKeyParams"][]; + /** @description A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. */ + authenticators: definitions["v1AuthenticatorParamsV2"][]; + }; + v1RootUserParamsV2: { + /** @description Human-readable name for a User. */ + userName: string; + /** @description The user's email address. */ + userEmail?: string; + /** @description A list of API Key parameters. This field, if not needed, should be an empty array in your request body. */ + apiKeys: definitions["apiApiKeyParams"][]; + /** @description A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. */ + authenticators: definitions["v1AuthenticatorParamsV2"][]; + /** @description A list of Oauth providers. This field, if not needed, should be an empty array in your request body. */ + oauthProviders: definitions["v1OauthProviderParams"][]; + }; + v1RootUserParamsV3: { + /** @description Human-readable name for a User. */ + userName: string; + /** @description The user's email address. */ + userEmail?: string; + /** @description A list of API Key parameters. This field, if not needed, should be an empty array in your request body. */ + apiKeys: definitions["v1ApiKeyParamsV2"][]; + /** @description A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. */ + authenticators: definitions["v1AuthenticatorParamsV2"][]; + /** @description A list of Oauth providers. This field, if not needed, should be an empty array in your request body. */ + oauthProviders: definitions["v1OauthProviderParams"][]; + }; + v1RootUserParamsV4: { + /** @description Human-readable name for a User. */ + userName: string; + /** @description The user's email address. */ + userEmail?: string; + /** @description The user's phone number in E.164 format e.g. +13214567890 */ + userPhoneNumber?: string; + /** @description A list of API Key parameters. This field, if not needed, should be an empty array in your request body. */ + apiKeys: definitions["v1ApiKeyParamsV2"][]; + /** @description A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. */ + authenticators: definitions["v1AuthenticatorParamsV2"][]; + /** @description A list of Oauth providers. This field, if not needed, should be an empty array in your request body. */ + oauthProviders: definitions["v1OauthProviderParams"][]; + }; + v1Selector: { + subject?: string; + operator?: definitions["v1Operator"]; + target?: string; + }; + v1SelectorV2: { + subject?: string; + operator?: definitions["v1Operator"]; + targets?: string[]; + }; + v1SetOrganizationFeatureIntent: { + /** @description Name of the feature to set */ + name: definitions["v1FeatureName"]; + /** @description Optional value for the feature. Will override existing values if feature is already set. */ + value: string; + }; + v1SetOrganizationFeatureRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_SET_ORGANIZATION_FEATURE"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1SetOrganizationFeatureIntent"]; + }; + v1SetOrganizationFeatureResult: { + /** @description Resulting list of organization features. */ + features: definitions["v1Feature"][]; + }; + v1SignRawPayloadIntent: { + /** @description Unique identifier for a given Private Key. */ + privateKeyId: string; + /** @description Raw unsigned payload to be signed. */ + payload: string; + /** @description Encoding of the `payload` string. Turnkey uses this information to convert `payload` into bytes with the correct decoder (e.g. hex, utf8). */ + encoding: definitions["v1PayloadEncoding"]; + /** @description Hash function to apply to payload bytes before signing. This field must be set to HASH_FUNCTION_NOT_APPLICABLE for EdDSA/ed25519 signature requests; configurable payload hashing is not supported by RFC 8032. */ + hashFunction: definitions["v1HashFunction"]; + }; + v1SignRawPayloadIntentV2: { + /** @description A Wallet account address, Private Key address, or Private Key identifier. */ + signWith: string; + /** @description Raw unsigned payload to be signed. */ + payload: string; + /** @description Encoding of the `payload` string. Turnkey uses this information to convert `payload` into bytes with the correct decoder (e.g. hex, utf8). */ + encoding: definitions["v1PayloadEncoding"]; + /** @description Hash function to apply to payload bytes before signing. This field must be set to HASH_FUNCTION_NOT_APPLICABLE for EdDSA/ed25519 signature requests; configurable payload hashing is not supported by RFC 8032. */ + hashFunction: definitions["v1HashFunction"]; + }; + v1SignRawPayloadRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_SIGN_RAW_PAYLOAD_V2"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1SignRawPayloadIntentV2"]; + }; + v1SignRawPayloadResult: { + /** @description Component of an ECSDA signature. */ + r: string; + /** @description Component of an ECSDA signature. */ + s: string; + /** @description Component of an ECSDA signature. */ + v: string; + }; + v1SignRawPayloadsIntent: { + /** @description A Wallet account address, Private Key address, or Private Key identifier. */ + signWith: string; + /** @description An array of raw unsigned payloads to be signed. */ + payloads: string[]; + /** @description Encoding of the `payload` string. Turnkey uses this information to convert `payload` into bytes with the correct decoder (e.g. hex, utf8). */ + encoding: definitions["v1PayloadEncoding"]; + /** @description Hash function to apply to payload bytes before signing. This field must be set to HASH_FUNCTION_NOT_APPLICABLE for EdDSA/ed25519 signature requests; configurable payload hashing is not supported by RFC 8032. */ + hashFunction: definitions["v1HashFunction"]; + }; + v1SignRawPayloadsRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_SIGN_RAW_PAYLOADS"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1SignRawPayloadsIntent"]; + }; + v1SignRawPayloadsResult: { + signatures?: definitions["v1SignRawPayloadResult"][]; + }; + v1SignTransactionIntent: { + /** @description Unique identifier for a given Private Key. */ + privateKeyId: string; + /** @description Raw unsigned transaction to be signed by a particular Private Key. */ + unsignedTransaction: string; + type: definitions["v1TransactionType"]; + }; + v1SignTransactionIntentV2: { + /** @description A Wallet account address, Private Key address, or Private Key identifier. */ + signWith: string; + /** @description Raw unsigned transaction to be signed */ + unsignedTransaction: string; + type: definitions["v1TransactionType"]; + }; + v1SignTransactionRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_SIGN_TRANSACTION_V2"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1SignTransactionIntentV2"]; + }; + v1SignTransactionResult: { + signedTransaction: string; + }; + v1SimpleClientExtensionResults: { + appid?: boolean; + appidExclude?: boolean; + credProps?: definitions["v1CredPropsAuthenticationExtensionsClientOutputs"]; + }; + v1SmsCustomizationParams: { + /** @description Template containing references to .OtpCode i.e Your OTP is {{.OtpCode}} */ + template?: string; + }; + v1StampLoginIntent: { + /** @description Client-side public key generated by the user, which will be conditionally added to org data based on the passkey stamp associated with this request */ + publicKey: string; + /** @description Expiration window (in seconds) indicating how long the Session is valid for. If not provided, a default of 15 minutes will be used. */ + expirationSeconds?: string; + /** @description Invalidate all other previously generated Login API keys */ + invalidateExisting?: boolean; + }; + v1StampLoginRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_STAMP_LOGIN"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1StampLoginIntent"]; + }; + v1StampLoginResult: { + /** @description Signed JWT containing an expiry, public key, session type, user id, and organization id */ + session: string; + }; + /** @enum {string} */ + v1TagType: "TAG_TYPE_USER" | "TAG_TYPE_PRIVATE_KEY"; + v1TestRateLimitsRequest: { + /** @description 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. */ + organizationId: string; + /** @description Whether or not to set a limit on this request. */ + isSetLimit: boolean; + /** + * Format: int64 + * @description Rate limit to set for org, if is_set_limit is set to true + */ + limit: number; + }; + v1TestRateLimitsResponse: { [key: string]: unknown }; + /** @enum {string} */ + v1TransactionType: + | "TRANSACTION_TYPE_ETHEREUM" + | "TRANSACTION_TYPE_SOLANA" + | "TRANSACTION_TYPE_TRON"; + v1UpdateAllowedOriginsIntent: { + /** @description Additional origins requests are allowed from besides Turnkey origins */ + allowedOrigins: string[]; + }; + v1UpdateAllowedOriginsResult: { [key: string]: unknown }; + v1UpdatePolicyIntent: { + /** @description Unique identifier for a given Policy. */ + policyId: string; + /** @description Human-readable name for a Policy. */ + policyName?: string; + /** @description The instruction to DENY or ALLOW an activity (optional). */ + policyEffect?: definitions["v1Effect"]; + /** @description The condition expression that triggers the Effect (optional). */ + policyCondition?: string; + /** @description The consensus expression that triggers the Effect (optional). */ + policyConsensus?: string; + /** @description Accompanying notes for a Policy (optional). */ + policyNotes?: string; + }; + v1UpdatePolicyIntentV2: { + /** @description Unique identifier for a given Policy. */ + policyId: string; + /** @description Human-readable name for a Policy. */ + policyName?: string; + /** @description The instruction to DENY or ALLOW an activity (optional). */ + policyEffect?: definitions["v1Effect"]; + /** @description The condition expression that triggers the Effect (optional). */ + policyCondition?: string; + /** @description The consensus expression that triggers the Effect (optional). */ + policyConsensus?: string; + /** @description Accompanying notes for a Policy (optional). */ + policyNotes?: string; + }; + v1UpdatePolicyRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_UPDATE_POLICY_V2"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1UpdatePolicyIntentV2"]; + }; + v1UpdatePolicyResult: { + /** @description Unique identifier for a given Policy. */ + policyId: string; + }; + v1UpdatePolicyResultV2: { + /** @description Unique identifier for a given Policy. */ + policyId: string; + }; + v1UpdatePrivateKeyTagIntent: { + /** @description Unique identifier for a given Private Key Tag. */ + privateKeyTagId: string; + /** @description The new, human-readable name for the tag with the given ID. */ + newPrivateKeyTagName?: string; + /** @description A list of Private Keys IDs to add this tag to. */ + addPrivateKeyIds: string[]; + /** @description A list of Private Key IDs to remove this tag from. */ + removePrivateKeyIds: string[]; + }; + v1UpdatePrivateKeyTagRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_UPDATE_PRIVATE_KEY_TAG"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1UpdatePrivateKeyTagIntent"]; + }; + v1UpdatePrivateKeyTagResult: { + /** @description Unique identifier for a given Private Key Tag. */ + privateKeyTagId: string; + }; + v1UpdateRootQuorumIntent: { + /** + * Format: int32 + * @description The threshold of unique approvals to reach quorum. + */ + threshold: number; + /** @description The unique identifiers of users who comprise the quorum set. */ + userIds: string[]; + }; + v1UpdateRootQuorumRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_UPDATE_ROOT_QUORUM"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1UpdateRootQuorumIntent"]; + }; + v1UpdateRootQuorumResult: { [key: string]: unknown }; + v1UpdateUserIntent: { + /** @description Unique identifier for a given User. */ + userId: string; + /** @description Human-readable name for a User. */ + userName?: string; + /** @description The user's email address. */ + userEmail?: string; + /** @description An updated list of User Tags to apply to this User. This field, if not needed, should be an empty array in your request body. */ + userTagIds?: string[]; + /** @description The user's phone number in E.164 format e.g. +13214567890 */ + userPhoneNumber?: string; + }; + v1UpdateUserRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_UPDATE_USER"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1UpdateUserIntent"]; + }; + v1UpdateUserResult: { + /** @description A User ID. */ + userId: string; + }; + v1UpdateUserTagIntent: { + /** @description Unique identifier for a given User Tag. */ + userTagId: string; + /** @description The new, human-readable name for the tag with the given ID. */ + newUserTagName?: string; + /** @description A list of User IDs to add this tag to. */ + addUserIds: string[]; + /** @description A list of User IDs to remove this tag from. */ + removeUserIds: string[]; + }; + v1UpdateUserTagRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_UPDATE_USER_TAG"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1UpdateUserTagIntent"]; + }; + v1UpdateUserTagResult: { + /** @description Unique identifier for a given User Tag. */ + userTagId: string; + }; + v1UpdateWalletIntent: { + /** @description Unique identifier for a given Wallet. */ + walletId: string; + /** @description Human-readable name for a Wallet. */ + walletName?: string; + }; + v1UpdateWalletRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_UPDATE_WALLET"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1UpdateWalletIntent"]; + }; + v1UpdateWalletResult: { + /** @description A Wallet ID. */ + walletId: string; + }; + v1User: { + /** @description Unique identifier for a given User. */ + userId: string; + /** @description Human-readable name for a User. */ + userName: string; + /** @description The user's email address. */ + userEmail?: string; + /** @description The user's phone number in E.164 format e.g. +13214567890 */ + userPhoneNumber?: string; + /** @description A list of Authenticator parameters. */ + authenticators: definitions["v1Authenticator"][]; + /** @description A list of API Key parameters. This field, if not needed, should be an empty array in your request body. */ + apiKeys: definitions["v1ApiKey"][]; + /** @description A list of User Tag IDs. */ + userTags: string[]; + /** @description A list of Oauth Providers. */ + oauthProviders: definitions["v1OauthProvider"][]; + createdAt: definitions["externaldatav1Timestamp"]; + updatedAt: definitions["externaldatav1Timestamp"]; + }; + v1UserParams: { + /** @description Human-readable name for a User. */ + userName: string; + /** @description The user's email address. */ + userEmail?: string; + /** @description The User's permissible access method(s). */ + accessType: definitions["v1AccessType"]; + /** @description A list of API Key parameters. This field, if not needed, should be an empty array in your request body. */ + apiKeys: definitions["apiApiKeyParams"][]; + /** @description A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. */ + authenticators: definitions["v1AuthenticatorParams"][]; + /** @description A list of User Tag IDs. This field, if not needed, should be an empty array in your request body. */ + userTags: string[]; + }; + v1UserParamsV2: { + /** @description Human-readable name for a User. */ + userName: string; + /** @description The user's email address. */ + userEmail?: string; + /** @description A list of API Key parameters. This field, if not needed, should be an empty array in your request body. */ + apiKeys: definitions["apiApiKeyParams"][]; + /** @description A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. */ + authenticators: definitions["v1AuthenticatorParamsV2"][]; + /** @description A list of User Tag IDs. This field, if not needed, should be an empty array in your request body. */ + userTags: string[]; + }; + v1UserParamsV3: { + /** @description Human-readable name for a User. */ + userName: string; + /** @description The user's email address. */ + userEmail?: string; + /** @description The user's phone number in E.164 format e.g. +13214567890 */ + userPhoneNumber?: string; + /** @description A list of API Key parameters. This field, if not needed, should be an empty array in your request body. */ + apiKeys: definitions["v1ApiKeyParamsV2"][]; + /** @description A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. */ + authenticators: definitions["v1AuthenticatorParamsV2"][]; + /** @description A list of Oauth providers. This field, if not needed, should be an empty array in your request body. */ + oauthProviders: definitions["v1OauthProviderParams"][]; + /** @description A list of User Tag IDs. This field, if not needed, should be an empty array in your request body. */ + userTags: string[]; + }; + v1VerifyOtpIntent: { + /** @description ID representing the result of an init OTP activity. */ + otpId: string; + /** @description OTP sent out to a user's contact (email or SMS) */ + otpCode: string; + /** @description Expiration window (in seconds) indicating how long the verification token is valid for. If not provided, a default of 1 hour will be used. Maximum value is 86400 seconds (24 hours) */ + expirationSeconds?: string; + }; + v1VerifyOtpRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_VERIFY_OTP"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1VerifyOtpIntent"]; + }; + v1VerifyOtpResult: { + /** @description Signed JWT containing a unique id, expiry, verification type, contact. Verification status of a user is updated when the token is consumed (in OTP_LOGIN requests) */ + verificationToken: string; + }; + v1Vote: { + /** @description Unique identifier for a given Vote object. */ + id: string; + /** @description Unique identifier for a given User. */ + userId: string; + /** @description Web and/or API user within your Organization. */ + user: definitions["v1User"]; + /** @description Unique identifier for a given Activity object. */ + activityId: string; + /** @enum {string} */ + selection: "VOTE_SELECTION_APPROVED" | "VOTE_SELECTION_REJECTED"; + /** @description The raw message being signed within a Vote. */ + message: string; + /** @description The public component of a cryptographic key pair used to sign messages and transactions. */ + publicKey: string; + /** @description The signature applied to a particular vote. */ + signature: string; + /** @description Method used to produce a signature. */ + scheme: string; + createdAt: definitions["externaldatav1Timestamp"]; + }; + v1Wallet: { + /** @description Unique identifier for a given Wallet. */ + walletId: string; + /** @description Human-readable name for a Wallet. */ + walletName: string; + createdAt: definitions["externaldatav1Timestamp"]; + updatedAt: definitions["externaldatav1Timestamp"]; + /** @description True when a given Wallet is exported, false otherwise. */ + exported: boolean; + /** @description True when a given Wallet is imported, false otherwise. */ + imported: boolean; + }; + v1WalletAccount: { + /** @description Unique identifier for a given Wallet Account. */ + walletAccountId: string; + /** @description The Organization the Account belongs to. */ + organizationId: string; + /** @description The Wallet the Account was derived from. */ + walletId: string; + /** @description Cryptographic curve used to generate the Account. */ + curve: definitions["v1Curve"]; + /** @description Path format used to generate the Account. */ + pathFormat: definitions["v1PathFormat"]; + /** @description Path used to generate the Account. */ + path: string; + /** @description Address format used to generate the Account. */ + addressFormat: definitions["v1AddressFormat"]; + /** @description Address generated using the Wallet seed and Account parameters. */ + address: string; + createdAt: definitions["externaldatav1Timestamp"]; + updatedAt: definitions["externaldatav1Timestamp"]; + /** @description The public component of this wallet account's underlying cryptographic key pair. */ + publicKey?: string; + }; + v1WalletAccountParams: { + /** @description Cryptographic curve used to generate a wallet Account. */ + curve: definitions["v1Curve"]; + /** @description Path format used to generate a wallet Account. */ + pathFormat: definitions["v1PathFormat"]; + /** @description Path used to generate a wallet Account. */ + path: string; + /** @description Address format used to generate a wallet Acccount. */ + addressFormat: definitions["v1AddressFormat"]; + }; + v1WalletParams: { + /** @description Human-readable name for a Wallet. */ + walletName: string; + /** @description A list of wallet Accounts. This field, if not needed, should be an empty array in your request body. */ + accounts: definitions["v1WalletAccountParams"][]; + /** + * Format: int32 + * @description Length of mnemonic to generate the Wallet seed. Defaults to 12. Accepted values: 12, 15, 18, 21, 24. + */ + mnemonicLength?: number; + }; + v1WalletResult: { + walletId: string; + /** @description A list of account addresses. */ + addresses: string[]; + }; + v1WebAuthnStamp: { + /** @description A base64 url encoded Unique identifier for a given credential. */ + credentialId: string; + /** @description A base64 encoded payload containing metadata about the signing context and the challenge. */ + clientDataJson: string; + /** @description A base64 encoded payload containing metadata about the authenticator. */ + authenticatorData: string; + /** @description The base64 url encoded signature bytes contained within the WebAuthn assertion response. */ + signature: string; + }; +}; + +export type operations = { + /** Get details about an Activity */ + PublicApiService_GetActivity: { + parameters: { + body: { + body: definitions["v1GetActivityRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Get details about an API key */ + PublicApiService_GetApiKey: { + parameters: { + body: { + body: definitions["v1GetApiKeyRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1GetApiKeyResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Get details about API keys for a user */ + PublicApiService_GetApiKeys: { + parameters: { + body: { + body: definitions["v1GetApiKeysRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1GetApiKeysResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Get the attestation document corresponding to an enclave. */ + PublicApiService_GetAttestationDocument: { + parameters: { + body: { + body: definitions["v1GetAttestationDocumentRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1GetAttestationDocumentResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Get details about an authenticator */ + PublicApiService_GetAuthenticator: { + parameters: { + body: { + body: definitions["v1GetAuthenticatorRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1GetAuthenticatorResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Get details about authenticators for a user */ + PublicApiService_GetAuthenticators: { + parameters: { + body: { + body: definitions["v1GetAuthenticatorsRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1GetAuthenticatorsResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Get details about Oauth providers for a user */ + PublicApiService_GetOauthProviders: { + parameters: { + body: { + body: definitions["v1GetOauthProvidersRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1GetOauthProvidersResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Get details about an Organization */ + PublicApiService_GetOrganization: { + parameters: { + body: { + body: definitions["v1GetOrganizationRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1GetOrganizationResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Get quorum settings and features for an organization */ + PublicApiService_GetOrganizationConfigs: { + parameters: { + body: { + body: definitions["v1GetOrganizationConfigsRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1GetOrganizationConfigsResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Get details about a Policy */ + PublicApiService_GetPolicy: { + parameters: { + body: { + body: definitions["v1GetPolicyRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1GetPolicyResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Get details about a Private Key */ + PublicApiService_GetPrivateKey: { + parameters: { + body: { + body: definitions["v1GetPrivateKeyRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1GetPrivateKeyResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Get details about a User */ + PublicApiService_GetUser: { + parameters: { + body: { + body: definitions["v1GetUserRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1GetUserResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Get details about a Wallet */ + PublicApiService_GetWallet: { + parameters: { + body: { + body: definitions["v1GetWalletRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1GetWalletResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Get a single wallet account */ + PublicApiService_GetWalletAccount: { + parameters: { + body: { + body: definitions["v1GetWalletAccountRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1GetWalletAccountResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** List all Activities within an Organization */ + PublicApiService_GetActivities: { + parameters: { + body: { + body: definitions["v1GetActivitiesRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1GetActivitiesResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** List all Policies within an Organization */ + PublicApiService_GetPolicies: { + parameters: { + body: { + body: definitions["v1GetPoliciesRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1GetPoliciesResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** List all Private Key Tags within an Organization */ + PublicApiService_ListPrivateKeyTags: { + parameters: { + body: { + body: definitions["v1ListPrivateKeyTagsRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ListPrivateKeyTagsResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** List all Private Keys within an Organization */ + PublicApiService_GetPrivateKeys: { + parameters: { + body: { + body: definitions["v1GetPrivateKeysRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1GetPrivateKeysResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Get all suborg IDs associated given a parent org ID and an optional filter. */ + PublicApiService_GetSubOrgIds: { + parameters: { + body: { + body: definitions["v1GetSubOrgIdsRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1GetSubOrgIdsResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** List all User Tags within an Organization */ + PublicApiService_ListUserTags: { + parameters: { + body: { + body: definitions["v1ListUserTagsRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ListUserTagsResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** List all Users within an Organization */ + PublicApiService_GetUsers: { + parameters: { + body: { + body: definitions["v1GetUsersRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1GetUsersResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Get all email or phone verified suborg IDs associated given a parent org ID. */ + PublicApiService_GetVerifiedSubOrgIds: { + parameters: { + body: { + body: definitions["v1GetVerifiedSubOrgIdsRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1GetVerifiedSubOrgIdsResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** List all Accounts within a Wallet */ + PublicApiService_GetWalletAccounts: { + parameters: { + body: { + body: definitions["v1GetWalletAccountsRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1GetWalletAccountsResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** List all Wallets within an Organization */ + PublicApiService_GetWallets: { + parameters: { + body: { + body: definitions["v1GetWalletsRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1GetWalletsResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Get basic information about your current API or WebAuthN user and their organization. Affords Sub-Organization look ups via Parent Organization for WebAuthN or API key users. */ + PublicApiService_GetWhoami: { + parameters: { + body: { + body: definitions["v1GetWhoamiRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1GetWhoamiResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Approve an Activity */ + PublicApiService_ApproveActivity: { + parameters: { + body: { + body: definitions["v1ApproveActivityRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Add api keys to an existing User */ + PublicApiService_CreateApiKeys: { + parameters: { + body: { + body: definitions["v1CreateApiKeysRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Create API-only Users in an existing Organization */ + PublicApiService_CreateApiOnlyUsers: { + parameters: { + body: { + body: definitions["v1CreateApiOnlyUsersRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Create Authenticators to authenticate requests to Turnkey */ + PublicApiService_CreateAuthenticators: { + parameters: { + body: { + body: definitions["v1CreateAuthenticatorsRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Create Invitations to join an existing Organization */ + PublicApiService_CreateInvitations: { + parameters: { + body: { + body: definitions["v1CreateInvitationsRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Creates Oauth providers for a specified user - BETA */ + PublicApiService_CreateOauthProviders: { + parameters: { + body: { + body: definitions["v1CreateOauthProvidersRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Create new Policies */ + PublicApiService_CreatePolicies: { + parameters: { + body: { + body: definitions["v1CreatePoliciesRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Create a new Policy */ + PublicApiService_CreatePolicy: { + parameters: { + body: { + body: definitions["v1CreatePolicyRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Create a private key tag and add it to private keys. */ + PublicApiService_CreatePrivateKeyTag: { + parameters: { + body: { + body: definitions["v1CreatePrivateKeyTagRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Create new Private Keys */ + PublicApiService_CreatePrivateKeys: { + parameters: { + body: { + body: definitions["v1CreatePrivateKeysRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Create a read only session for a user (valid for 1 hour) */ + PublicApiService_CreateReadOnlySession: { + parameters: { + body: { + body: definitions["v1CreateReadOnlySessionRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Create a read write session for a user */ + PublicApiService_CreateReadWriteSession: { + parameters: { + body: { + body: definitions["v1CreateReadWriteSessionRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Create a new Sub-Organization */ + PublicApiService_CreateSubOrganization: { + parameters: { + body: { + body: definitions["v1CreateSubOrganizationRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Create a user tag and add it to users. */ + PublicApiService_CreateUserTag: { + parameters: { + body: { + body: definitions["v1CreateUserTagRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Create Users in an existing Organization */ + PublicApiService_CreateUsers: { + parameters: { + body: { + body: definitions["v1CreateUsersRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Create a Wallet and derive addresses */ + PublicApiService_CreateWallet: { + parameters: { + body: { + body: definitions["v1CreateWalletRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Derive additional addresses using an existing wallet */ + PublicApiService_CreateWalletAccounts: { + parameters: { + body: { + body: definitions["v1CreateWalletAccountsRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Remove api keys from a User */ + PublicApiService_DeleteApiKeys: { + parameters: { + body: { + body: definitions["v1DeleteApiKeysRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Remove authenticators from a User */ + PublicApiService_DeleteAuthenticators: { + parameters: { + body: { + body: definitions["v1DeleteAuthenticatorsRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Delete an existing Invitation */ + PublicApiService_DeleteInvitation: { + parameters: { + body: { + body: definitions["v1DeleteInvitationRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Removes Oauth providers for a specified user - BETA */ + PublicApiService_DeleteOauthProviders: { + parameters: { + body: { + body: definitions["v1DeleteOauthProvidersRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Delete an existing Policy */ + PublicApiService_DeletePolicy: { + parameters: { + body: { + body: definitions["v1DeletePolicyRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Delete Private Key Tags within an Organization */ + PublicApiService_DeletePrivateKeyTags: { + parameters: { + body: { + body: definitions["v1DeletePrivateKeyTagsRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Deletes private keys for an organization */ + PublicApiService_DeletePrivateKeys: { + parameters: { + body: { + body: definitions["v1DeletePrivateKeysRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Deletes a sub organization */ + PublicApiService_DeleteSubOrganization: { + parameters: { + body: { + body: definitions["v1DeleteSubOrganizationRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Delete User Tags within an Organization */ + PublicApiService_DeleteUserTags: { + parameters: { + body: { + body: definitions["v1DeleteUserTagsRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Delete Users within an Organization */ + PublicApiService_DeleteUsers: { + parameters: { + body: { + body: definitions["v1DeleteUsersRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Deletes wallets for an organization */ + PublicApiService_DeleteWallets: { + parameters: { + body: { + body: definitions["v1DeleteWalletsRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Authenticate a user via Email */ + PublicApiService_EmailAuth: { + parameters: { + body: { + body: definitions["v1EmailAuthRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Exports a Private Key */ + PublicApiService_ExportPrivateKey: { + parameters: { + body: { + body: definitions["v1ExportPrivateKeyRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Exports a Wallet */ + PublicApiService_ExportWallet: { + parameters: { + body: { + body: definitions["v1ExportWalletRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Exports a Wallet Account */ + PublicApiService_ExportWalletAccount: { + parameters: { + body: { + body: definitions["v1ExportWalletAccountRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Imports a private key */ + PublicApiService_ImportPrivateKey: { + parameters: { + body: { + body: definitions["v1ImportPrivateKeyRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Imports a wallet */ + PublicApiService_ImportWallet: { + parameters: { + body: { + body: definitions["v1ImportWalletRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Initializes a new private key import */ + PublicApiService_InitImportPrivateKey: { + parameters: { + body: { + body: definitions["v1InitImportPrivateKeyRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Initializes a new wallet import */ + PublicApiService_InitImportWallet: { + parameters: { + body: { + body: definitions["v1InitImportWalletRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Initiate a Generic OTP activity */ + PublicApiService_InitOtp: { + parameters: { + body: { + body: definitions["v1InitOtpRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Initiate an OTP auth activity */ + PublicApiService_InitOtpAuth: { + parameters: { + body: { + body: definitions["v1InitOtpAuthRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Initializes a new email recovery */ + PublicApiService_InitUserEmailRecovery: { + parameters: { + body: { + body: definitions["v1InitUserEmailRecoveryRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Authenticate a user with an Oidc token (Oauth) - BETA */ + PublicApiService_Oauth: { + parameters: { + body: { + body: definitions["v1OauthRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Create an Oauth session for a user */ + PublicApiService_OauthLogin: { + parameters: { + body: { + body: definitions["v1OauthLoginRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Authenticate a user with an OTP code sent via email or SMS */ + PublicApiService_OtpAuth: { + parameters: { + body: { + body: definitions["v1OtpAuthRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Create an OTP session for a user */ + PublicApiService_OtpLogin: { + parameters: { + body: { + body: definitions["v1OtpLoginRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Completes the process of recovering a user by adding an authenticator */ + PublicApiService_RecoverUser: { + parameters: { + body: { + body: definitions["v1RecoverUserRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Reject an Activity */ + PublicApiService_RejectActivity: { + parameters: { + body: { + body: definitions["v1RejectActivityRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Removes an organization feature. This activity must be approved by the current root quorum. */ + PublicApiService_RemoveOrganizationFeature: { + parameters: { + body: { + body: definitions["v1RemoveOrganizationFeatureRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Sets an organization feature. This activity must be approved by the current root quorum. */ + PublicApiService_SetOrganizationFeature: { + parameters: { + body: { + body: definitions["v1SetOrganizationFeatureRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Sign a raw payload */ + PublicApiService_SignRawPayload: { + parameters: { + body: { + body: definitions["v1SignRawPayloadRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Sign multiple raw payloads with the same signing parameters */ + PublicApiService_SignRawPayloads: { + parameters: { + body: { + body: definitions["v1SignRawPayloadsRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Sign a transaction */ + PublicApiService_SignTransaction: { + parameters: { + body: { + body: definitions["v1SignTransactionRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Create a session for a user through stamping client side (api key, wallet client, or passkey client) */ + PublicApiService_StampLogin: { + parameters: { + body: { + body: definitions["v1StampLoginRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Update an existing Policy */ + PublicApiService_UpdatePolicy: { + parameters: { + body: { + body: definitions["v1UpdatePolicyRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Update human-readable name or associated private keys. Note that this activity is atomic: all of the updates will succeed at once, or all of them will fail. */ + PublicApiService_UpdatePrivateKeyTag: { + parameters: { + body: { + body: definitions["v1UpdatePrivateKeyTagRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Set the threshold and members of the root quorum. This activity must be approved by the current root quorum. */ + PublicApiService_UpdateRootQuorum: { + parameters: { + body: { + body: definitions["v1UpdateRootQuorumRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Update a User in an existing Organization */ + PublicApiService_UpdateUser: { + parameters: { + body: { + body: definitions["v1UpdateUserRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Update human-readable name or associated users. Note that this activity is atomic: all of the updates will succeed at once, or all of them will fail. */ + PublicApiService_UpdateUserTag: { + parameters: { + body: { + body: definitions["v1UpdateUserTagRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Update a wallet for an organization */ + PublicApiService_UpdateWallet: { + parameters: { + body: { + body: definitions["v1UpdateWalletRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Verify a Generic OTP */ + PublicApiService_VerifyOtp: { + parameters: { + body: { + body: definitions["v1VerifyOtpRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + PublicApiService_NOOPCodegenAnchor: { + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1NOOPCodegenAnchorResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Set a rate local rate limit just on the current endpoint, for purposes of testing with Vivosuite */ + PublicApiService_TestRateLimits: { + parameters: { + body: { + body: definitions["v1TestRateLimitsRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1TestRateLimitsResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; +}; + +export type external = {}; diff --git a/packages/sdk-types/src/index.ts b/packages/sdk-types/src/index.ts index f47e8c149..d4877adbf 100644 --- a/packages/sdk-types/src/index.ts +++ b/packages/sdk-types/src/index.ts @@ -96,3 +96,4 @@ export enum FiatOnRampPaymentMethod { FIAT_WALLET = "FIAT_ON_RAMP_PAYMENT_METHOD_FIAT_WALLET", // Coinbase: FIAT_WALLET ACH_BANK_ACCOUNT = "FIAT_ON_RAMP_PAYMENT_METHOD_ACH_BANK_ACCOUNT", // Coinbase: ACH_BANK_ACCOUNT } +export * from "./__generated__/types"; From 77bc3710e2898591b8c6b8cfdc8a3e6ada098c3d Mon Sep 17 00:00:00 2001 From: Ethan Konkolowicz Date: Mon, 16 Jun 2025 11:14:42 -0400 Subject: [PATCH 009/184] fixed type generation for request base types --- examples/with-sdk-js/src/app/page.tsx | 34 +- packages/sdk-js/package.json | 11 +- packages/sdk-js/src/__clients__/core.ts | 131 +- .../sdk-js/src/__storage__/web/storage.ts | 7 + packages/sdk-js/src/__types__/base.ts | 8 +- packages/sdk-js/src/utils.ts | 60 +- packages/sdk-types/scripts/codegen.js | 222 +- packages/sdk-types/src/__generated__/types.ts | 3559 ++++++++++++----- pnpm-lock.yaml | 39 + 9 files changed, 3138 insertions(+), 933 deletions(-) diff --git a/examples/with-sdk-js/src/app/page.tsx b/examples/with-sdk-js/src/app/page.tsx index dce1b5dc3..1b3448156 100644 --- a/examples/with-sdk-js/src/app/page.tsx +++ b/examples/with-sdk-js/src/app/page.tsx @@ -2,13 +2,18 @@ import Image from "next/image"; import styles from "./index.module.css"; -import { StamperType, TurnkeyClient } from "@turnkey/sdk-js"; +import { StamperType, TurnkeyClient, TWallet } from "@turnkey/sdk-js"; import { server } from "@turnkey/sdk-server"; import { useEffect, useState } from "react"; +import { Session } from "@turnkey/sdk-types"; +import { get } from "http"; +import { set } from "react-hook-form"; export default function AuthPage() { const [client, setClient] = useState(null); + const [session, setSession] = useState(null); + const [wallets, setWallets] = useState([]); useEffect(() => { const initializeClient = async () => { @@ -42,6 +47,20 @@ export default function AuthPage() { console.log("Response from getWhoami:", resp); }; + const getWallets = async () => { + const res = await client?.getWallets({}); + if (res) { + setWallets(res); + console.log("Wallets:", res); + } else { + console.error("Failed to fetch wallets"); + } + } + + useEffect(() => { + + }) + return (
Log in With Passkey + + {client?.storageManager?.getActiveSession() ? () : null} +
); } diff --git a/packages/sdk-js/package.json b/packages/sdk-js/package.json index d6d961b55..a905acfe1 100644 --- a/packages/sdk-js/package.json +++ b/packages/sdk-js/package.json @@ -25,14 +25,15 @@ "@turnkey/crypto": "workspace:*", "@turnkey/encoding": "workspace:*", "@turnkey/http": "workspace:*", - "@turnkey/wallet-stamper": "workspace:*", - "@turnkey/webauthn-stamper": "workspace:*", "@turnkey/indexed-db-stamper": "workspace:*", "@turnkey/sdk-types": "workspace:*", + "@turnkey/wallet-stamper": "workspace:*", + "@turnkey/webauthn-stamper": "workspace:*", "bs58check": "3.0.1", - "jwt-decode": "4.0.0", "buffer": "^6.0.3", "cross-fetch": "^3.1.5", + "ethers": "^6.10.0", + "jwt-decode": "4.0.0", "uuid": "^11.1.0" }, "devDependencies": { @@ -40,9 +41,9 @@ "typescript": "5.4.3" }, "peerDependencies": { - "react-native-keychain": "^8.1.0 || ^9.2.2 || ^10.0.0", "@react-native-async-storage/async-storage": "^2.2.0", - "@turnkey/react-native-passkey-stamper": "workspace:*" + "@turnkey/react-native-passkey-stamper": "workspace:*", + "react-native-keychain": "^8.1.0 || ^9.2.2 || ^10.0.0" }, "peerDependenciesMeta": { "react-native-keychain": { diff --git a/packages/sdk-js/src/__clients__/core.ts b/packages/sdk-js/src/__clients__/core.ts index c2687cc10..4f7201d23 100644 --- a/packages/sdk-js/src/__clients__/core.ts +++ b/packages/sdk-js/src/__clients__/core.ts @@ -1,15 +1,28 @@ import { TurnkeySDKClientBase } from "../__generated__/sdk-client-base"; -import { SessionType } from "@turnkey/sdk-types"; +import { + GetWalletAccountsResponse, + GetWalletsResponse, + SessionType, + SignRawPayloadIntent, + SignRawPayloadIntentV2, + SignRawPayloadRequest, + SignRawPayloadResult, + Wallet, + WalletAccount, +} from "@turnkey/sdk-types"; import { LoginWithPasskeyParams, DEFAULT_SESSION_EXPIRATION_IN_SECONDS, Passkey, StamperType, CreatePasskeyParams, + ActivityResponse, + TWallet, } from "@types"; // AHHHH, SDK-TYPES import { base64UrlEncode, generateRandomBuffer, + getMessageHashAndEncodingType, isReactNative, isWeb, } from "@utils"; @@ -21,6 +34,7 @@ import { } from "../__storage__/base"; import { CrossPlatformApiKeyStamper } from "../__stampers__/api/base"; import { CrossPlatformPasskeyStamper } from "../__stampers__/passkey/base"; +import { get } from "http"; export class TurnkeyClient { config: any; // Type TBD @@ -39,7 +53,7 @@ export class TurnkeyClient { // Users can pass in their own stampers, or we will create them. Should we remove this? apiKeyStamper?: CrossPlatformApiKeyStamper, - passkeyStamper?: CrossPlatformPasskeyStamper, + passkeyStamper?: CrossPlatformPasskeyStamper ) { this.config = config; @@ -60,7 +74,7 @@ export class TurnkeyClient { await this.apiKeyStamper.init(); this.passkeyStamper = new CrossPlatformPasskeyStamper( - this.config.passkeyConfig, + this.config.passkeyConfig ); await this.passkeyStamper.init(); @@ -114,7 +128,7 @@ export class TurnkeyClient { await this.storageManager.storeSession( readOnlySessionResult.session, - sessionKey, + sessionKey ); // Key pair was successfully used, set to null to prevent cleanup generatedKeyPair = null; @@ -123,7 +137,7 @@ export class TurnkeyClient { } else if (sessionType === SessionType.READ_WRITE) { if (!publicKey) { throw new Error( - "You must provide a publicKey to create a passkey read write session.", + "You must provide a publicKey to create a passkey read write session." ); } const sessionResponse = await this.httpClient.stampLogin( @@ -131,7 +145,7 @@ export class TurnkeyClient { publicKey, expirationSeconds, }, - StamperType.Passkey, + StamperType.Passkey ); // TODO (Amir): This should be done in a helper or something. It's very strange that we have to delete the key pair here @@ -143,7 +157,7 @@ export class TurnkeyClient { await this.storageManager.storeSession( sessionResponse.session, - sessionKey, + sessionKey ); // Key pair was successfully used, set to null to prevent cleanup generatedKeyPair = null; @@ -159,10 +173,111 @@ export class TurnkeyClient { await this.apiKeyStamper?.deleteKeyPair(generatedKeyPair); } catch (cleanupError) { throw new Error( - `Failed to clean up generated key pair: ${cleanupError}`, + `Failed to clean up generated key pair: ${cleanupError}` ); } } } }; + + getWallets = async ({ stamperType }: { stamperType?: StamperType }): Promise => { + const session = await this.storageManager.getActiveSession(); + if (!session) { + throw new Error("No active session found. Please log in first."); + } + try { + const res = await this.httpClient.getWallets( + { organizationId: session.organizationId }, + stamperType + ); + + if (!res || !res.wallets) { + throw new Error("No wallets found in the response"); + } + + const wallets: TWallet[] = res.wallets; + let i = 0 + for (const wallet of wallets) { + const walletAccounts = await this.getWalletAccounts({ + walletId: wallet.walletId}) + + if (walletAccounts.accounts.length > 0 ) { + wallets[i]!.accounts = walletAccounts.accounts; + } + + i++; + } + + return wallets; + + } catch (error) { + throw new Error(`Failed to fetch wallets: ${error}`); + } + }; + + getWalletAccounts = async ({ + walletId, + stamperType, + }: { + walletId: string; + stamperType?: StamperType; + }): Promise => { + const session = await this.storageManager.getActiveSession(); + if (!session) { + throw new Error("No active session found. Please log in first."); + } + + if (!walletId) { + throw new Error("Wallet ID must be provided to fetch accounts"); + } + + try { + return await this.httpClient.getWalletAccounts( + { walletId, organizationId: session.organizationId }, + stamperType + ); + } catch (error) { + throw new Error(`Failed to fetch wallet accounts: ${error}`); + } + } + + signMessage = async ({ + message, + wallet, + stampWith, + }: { + message: string; + wallet?: WalletAccount; + stampWith?: StamperType; + }): Promise => { + if (!wallet) { + throw new Error("A wallet account must be provided for signing"); + } + + if (!wallet.address || !wallet.addressFormat) { + throw new Error("Wallet must have an address and addressFormat"); + } + + // Get the proper encoding and hash function for the address format + const { hashFunction, payloadEncoding } = getMessageHashAndEncodingType( + wallet.addressFormat + ); + + const response = await this.httpClient.signRawPayload( + { + signWith: wallet.address, + payload: message, + encoding: payloadEncoding, + hashFunction, + }, + stampWith + ); + + if (!response.activity.failure) { + throw new Error("Failed to sign message, no signed payload returned"); + } + + return response.activity.result + .signRawPayloadResult as SignRawPayloadResult; + }; } diff --git a/packages/sdk-js/src/__storage__/web/storage.ts b/packages/sdk-js/src/__storage__/web/storage.ts index e35c4ee30..8211f0b24 100644 --- a/packages/sdk-js/src/__storage__/web/storage.ts +++ b/packages/sdk-js/src/__storage__/web/storage.ts @@ -2,6 +2,7 @@ import WindowWrapper from "@polyfills/window"; import { StorageBase, SessionKey } from "../base"; import { parseSession } from "@utils"; import { Session } from "@turnkey/sdk-types"; +import { TWallet } from "@types"; const browserStorage = WindowWrapper.localStorage; @@ -86,4 +87,10 @@ export class WebStorageManager implements StorageBase { await this.removeStorageValue(WebStorageManager.ALL_SESSION_KEYS); await this.removeStorageValue(WebStorageManager.ACTIVE_SESSION_KEY); }; + + storeWallets = async (wallets: TWallet[]): Promise => { + for (const wallet of wallets) { + browserStorage.setItem(wallet.walletId, JSON.stringify(wallet)); + } + } } diff --git a/packages/sdk-js/src/__types__/base.ts b/packages/sdk-js/src/__types__/base.ts index 5fac1881b..2606c74e7 100644 --- a/packages/sdk-js/src/__types__/base.ts +++ b/packages/sdk-js/src/__types__/base.ts @@ -2,7 +2,7 @@ import type { TActivityId, TActivityStatus } from "@turnkey/http"; import type { WalletStamper } from "@turnkey/wallet-stamper"; import type { WebauthnStamper } from "@turnkey/webauthn-stamper"; import type { IndexedDbStamper } from "@turnkey/indexed-db-stamper"; -import type { SessionType } from "@turnkey/sdk-types"; +import type { SessionType, Wallet, WalletAccount } from "@turnkey/sdk-types"; import { StorageBase } from "../__storage__/base"; // TODO (Amir): Get all this outta here and move to sdk-types. Or not, we could just have everything in this package @@ -174,6 +174,10 @@ export interface LoginWithWalletParams { publicKey?: string; } +export type TWallet = Wallet & { + accounts?: WalletAccount[] | undefined; +} + // export interface TurnkeyWalletClientConfig extends SDKClientConfigWithStamper { // wallet: WalletInterface; // } @@ -190,4 +194,4 @@ export enum AuthClient { export enum StamperType { apiKey = "api-key", Passkey = "passkey", -} +} \ No newline at end of file diff --git a/packages/sdk-js/src/utils.ts b/packages/sdk-js/src/utils.ts index de56b958b..7b528c57e 100644 --- a/packages/sdk-js/src/utils.ts +++ b/packages/sdk-js/src/utils.ts @@ -1,6 +1,50 @@ import { Buffer } from "buffer"; -import type { Session } from "@turnkey/sdk-types"; +type AddressFormatConfig = { + encoding: "PAYLOAD_ENCODING_HEXADECIMAL" | "PAYLOAD_ENCODING_TEXT_UTF8"; + hashFunction: "HASH_FUNCTION_NOT_APPLICABLE" | "HASH_FUNCTION_NO_OP" | "HASH_FUNCTION_SHA256" | "HASH_FUNCTION_KECCAK256"; +}; + +const addressFormatConfig: Record = { + ADDRESS_FORMAT_UNCOMPRESSED: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, + ADDRESS_FORMAT_COMPRESSED: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, + ADDRESS_FORMAT_ETHEREUM: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_KECCAK256" }, + ADDRESS_FORMAT_SOLANA: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_NOT_APPLICABLE" }, + ADDRESS_FORMAT_COSMOS: { encoding: "PAYLOAD_ENCODING_TEXT_UTF8", hashFunction: "HASH_FUNCTION_SHA256" }, + ADDRESS_FORMAT_TRON: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, + ADDRESS_FORMAT_SUI: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, + ADDRESS_FORMAT_APTOS: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_NOT_APPLICABLE" }, + ADDRESS_FORMAT_BITCOIN_MAINNET_P2PKH: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, + ADDRESS_FORMAT_BITCOIN_MAINNET_P2SH: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, + ADDRESS_FORMAT_BITCOIN_MAINNET_P2WPKH: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, + ADDRESS_FORMAT_BITCOIN_MAINNET_P2WSH: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, + ADDRESS_FORMAT_BITCOIN_MAINNET_P2TR: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, + ADDRESS_FORMAT_BITCOIN_TESTNET_P2PKH: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, + ADDRESS_FORMAT_BITCOIN_TESTNET_P2SH: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, + ADDRESS_FORMAT_BITCOIN_TESTNET_P2WPKH: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, + ADDRESS_FORMAT_BITCOIN_TESTNET_P2WSH: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, + ADDRESS_FORMAT_BITCOIN_TESTNET_P2TR: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, + ADDRESS_FORMAT_BITCOIN_SIGNET_P2PKH: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, + ADDRESS_FORMAT_BITCOIN_SIGNET_P2SH: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, + ADDRESS_FORMAT_BITCOIN_SIGNET_P2WPKH: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, + ADDRESS_FORMAT_BITCOIN_SIGNET_P2WSH: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, + ADDRESS_FORMAT_BITCOIN_SIGNET_P2TR: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, + ADDRESS_FORMAT_BITCOIN_REGTEST_P2PKH: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, + ADDRESS_FORMAT_BITCOIN_REGTEST_P2SH: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, + ADDRESS_FORMAT_BITCOIN_REGTEST_P2WPKH: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, + ADDRESS_FORMAT_BITCOIN_REGTEST_P2WSH: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, + ADDRESS_FORMAT_BITCOIN_REGTEST_P2TR: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, + ADDRESS_FORMAT_SEI: { encoding: "PAYLOAD_ENCODING_TEXT_UTF8", hashFunction: "HASH_FUNCTION_SHA256" }, + ADDRESS_FORMAT_XLM: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, + ADDRESS_FORMAT_DOGE_MAINNET: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, + ADDRESS_FORMAT_DOGE_TESTNET: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, + ADDRESS_FORMAT_TON_V3R2: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, + ADDRESS_FORMAT_TON_V4R2: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, + ADDRESS_FORMAT_TON_V5R1: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, + ADDRESS_FORMAT_XRP: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, +}; + +import type { AddressFormat, HashFunction, PayloadEncoding, Session } from "@turnkey/sdk-types"; export const isReactNative = (): boolean => { return ( @@ -69,3 +113,17 @@ export function parseSession(token: string | Session): Session { token: publicKey, // TODO (Amir): Should token be the JWT then add another field for publicKey? }; } + +export function getMessageHashAndEncodingType (addressFormat: AddressFormat): { + hashFunction: HashFunction; + payloadEncoding: PayloadEncoding; +} { + const config = addressFormatConfig[addressFormat]; + if (!config) { + throw new Error(`Unsupported address format: ${addressFormat}`); + } + return { + hashFunction: config.hashFunction, + payloadEncoding: config.encoding, + }; +} diff --git a/packages/sdk-types/scripts/codegen.js b/packages/sdk-types/scripts/codegen.js index d96f9c968..060adcb55 100644 --- a/packages/sdk-types/scripts/codegen.js +++ b/packages/sdk-types/scripts/codegen.js @@ -4,14 +4,33 @@ const path = require("path"); // Paths const swaggerPath = path.resolve( __dirname, - "../src/__inputs__/public_api.swagger.json", + "../src/__inputs__/public_api.swagger.json" ); const typesPath = path.resolve( __dirname, - "../src/__inputs__/public_api.types.ts", + "../src/__inputs__/public_api.types.ts" ); const outputPath = path.resolve(__dirname, "../src/__generated__/types.ts"); +const COMMENT_HEADER = "/* @generated by codegen. DO NOT EDIT BY HAND */"; + +const VERSIONED_ACTIVITY_TYPES = { + ACTIVITY_TYPE_CREATE_AUTHENTICATORS: "ACTIVITY_TYPE_CREATE_AUTHENTICATORS_V2", + ACTIVITY_TYPE_CREATE_API_KEYS: "ACTIVITY_TYPE_CREATE_API_KEYS_V2", + ACTIVITY_TYPE_CREATE_POLICY: "ACTIVITY_TYPE_CREATE_POLICY_V3", + ACTIVITY_TYPE_CREATE_PRIVATE_KEYS: "ACTIVITY_TYPE_CREATE_PRIVATE_KEYS_V2", + ACTIVITY_TYPE_CREATE_SUB_ORGANIZATION: + "ACTIVITY_TYPE_CREATE_SUB_ORGANIZATION_V7", + ACTIVITY_TYPE_CREATE_USERS: "ACTIVITY_TYPE_CREATE_USERS_V3", + ACTIVITY_TYPE_SIGN_RAW_PAYLOAD: "ACTIVITY_TYPE_SIGN_RAW_PAYLOAD_V2", + ACTIVITY_TYPE_SIGN_TRANSACTION: "ACTIVITY_TYPE_SIGN_TRANSACTION_V2", + ACTIVITY_TYPE_EMAIL_AUTH: "ACTIVITY_TYPE_EMAIL_AUTH_V2", + ACTIVITY_TYPE_CREATE_READ_WRITE_SESSION: + "ACTIVITY_TYPE_CREATE_READ_WRITE_SESSION_V2", + ACTIVITY_TYPE_UPDATE_POLICY: "ACTIVITY_TYPE_UPDATE_POLICY_V2", + ACTIVITY_TYPE_INIT_OTP_AUTH: "ACTIVITY_TYPE_INIT_OTP_AUTH_V2", +}; + // Helper: Convert Swagger type to TS type /** * @param {string} type @@ -52,8 +71,109 @@ function stripVersionPrefix(name) { * @returns {string} */ function refToTs(ref) { - // "#/definitions/v1GetAuthenticatorRequest" -> "GetAuthenticatorRequest" - return stripVersionPrefix(ref.replace(/^#\/definitions\//, "")); + return ref.replace(/^#\/definitions\//, ""); +} + +// /** +// * @param {string} ref +// * @returns {string} +// */ +// function refToTsWithVersionPrefixAndSuffixStrip(ref) { +// return stripVersionPrefixAndSuffix(ref.replace(/^#\/definitions\//, "")); +// } + +/** + * @param {string} methodName + * @returns {string} + */ +function methodTypeFromMethodName(methodName) { + if (["approveActivity", "rejectActivity"].includes(methodName)) { + return "activityDecision"; + } + if (methodName.startsWith("nOOP")) { + return "noop"; + } + // TODO: filter out unnecessary client methods, whether here or from the source + if ( + methodName.startsWith("get") || + methodName.startsWith("list") || + methodName.startsWith("test") + ) { + return "query"; + } + // Rename to submit? + return "command"; +} + +/** + * Maps activity types to their most recent versions in VERSIONED_ACTIVITY_TYPES. + * If a type has multiple versions, it will return the latest one based on the versioning scheme. + * @param {object} definitions - Swagger definitions object + * @returns {object} - Map of base type to most recent versioned type + */ +function buildLatestVersionMap(definitions) { + const versionMap = {}; + + // Group definitions by their base name (without version) + const groupedDefs = {}; + for (const defName of Object.keys(definitions)) { + if (!defName.match(/^v\d+/)) { + continue; + } + + const baseName = stripVersionPrefixAndSuffix(defName); + + if (!groupedDefs[baseName]) { + groupedDefs[baseName] = []; + } + groupedDefs[baseName].push(defName); + } + + // For each group, find the latest versioned type + for (const [baseName, defNames] of Object.entries(groupedDefs)) { + // Remove REQUEST/RESPONSE/RESULT/INTENT suffix for activityTypeKey + const activityBase = baseName.replace( + /(Request|Response|Result|Intent)$/, + "" + ); + const activityTypeKey = `ACTIVITY_TYPE_${activityBase.replace(/([a-z])([A-Z])/g, "$1_$2").toUpperCase()}`; + const mappedVersion = VERSIONED_ACTIVITY_TYPES[activityTypeKey]; + if (mappedVersion) { + const versionSuffixMatch = mappedVersion.match(/(V\d+)$/); + const versionSuffix = versionSuffixMatch ? versionSuffixMatch[1] : ""; + // Try to find a defName that ends with the version suffix (e.g., V2) + const matchedDef = defNames.find((name) => name.endsWith(versionSuffix)); + if (matchedDef) { + versionMap[baseName] = matchedDef; + continue; + } + } + let latest = defNames[0]; + let latestVersion = 1; + for (const name of defNames) { + const match = name.match(/V(\d+)$/); + const version = match ? parseInt(match[1], 10) : 1; + if (version > latestVersion) { + latest = name; + latestVersion = version; + } + } + versionMap[baseName] = latest; + } + + return versionMap; +} + +/** + * Strip both prefix and suffix version numbers + * @param {string} name - Type name with version info + * @returns {string} - Clean base name + */ +function stripVersionPrefixAndSuffix(name) { + let baseName = stripVersionPrefix(name); + baseName = baseName.replace(/V\d+$/, ""); + + return baseName; } /** @@ -70,12 +190,11 @@ function isValidIdentifier(name) { * @returns {string} */ function generateTsType(name, def) { - const cleanName = stripVersionPrefix(name); if ( def.type === "object" && (def.properties || def.additionalProperties !== undefined) ) { - let out = `export type ${cleanName} = {\n`; + let out = `export type ${name} = {\n`; if (def.properties) { for (const [prop, schema] of Object.entries(def.properties)) { const required = def.required && def.required.includes(prop) ? "" : "?"; @@ -100,20 +219,16 @@ function generateTsType(name, def) { out += "};\n"; return out; } - // enums if (def.type === "string" && def.enum) { - return `export type ${cleanName} =\n ${def.enum.map((e) => `"${e}"`).join(" |\n ")};\n`; + return `export type ${name} =\n ${def.enum.map((e) => `"${e}"`).join(" |\n ")};\n`; } - // fallback - return `export type ${cleanName} = any;\n`; + return `export type ${name} = any;\n`; } function main() { - // 1. Load files const swagger = JSON.parse(fs.readFileSync(swaggerPath, "utf8")); const typesSrc = fs.readFileSync(typesPath, "utf8"); - // 2. Extract type definitions from types file (very basic, just for demo) const typeDefRegex = /export type (\w+) = ([^;]+);/g; const interfaceDefRegex = /export type (\w+) = {([^}]+)}/g; @@ -126,11 +241,12 @@ function main() { typeDefs[match[1]] = `{${match[2]}}`; } - // 3. Generate base types from swagger definitions - let output = `// AUTO-GENERATED FILE. DO NOT EDIT.\n// Generated by codegen.js\n\n`; + let output = COMMENT_HEADER + "\n\n"; // --- Base Types --- output += `// --- Base Types from Swagger Definitions ---\n`; + + // First generate all versioned types for (const [defName, def] of Object.entries(swagger.definitions)) { // Only parse object and enum types if ( @@ -139,7 +255,83 @@ function main() { ) { output += generateTsType(defName, def) + "\n"; } else { - output += `export type ${stripVersionPrefix(defName)} = any;\n`; + output += `export type ${defName} = any;\n`; + } + } + + // Build a map of base types to their latest versioned counterparts + const latestVersionMap = buildLatestVersionMap(swagger.definitions); + + // Check all Request types for organizationId, if present modify their respective Intent types and add optional organizationId + for (const [baseName, latestVersionName] of Object.entries( + latestVersionMap + )) { + const def = swagger.definitions[latestVersionName]; + if (def && def.type === "object" && def.properties) { + // If the baseName ends with "Request", check for organizationId + + console.log(`Checking ${baseName} for organizationId...`); + if (baseName.endsWith("Request") && def.properties.organizationId) { + // Modify the corresponding Intent type to make organizationId optional + const intentTypeName = latestVersionName.replace(/Request$/, "Intent"); + console.log( + `Modifying Intent type ${intentTypeName} to make organizationId optional` + ); + if (swagger.definitions[intentTypeName] && swagger.definitions[intentTypeName].properties) { + if (swagger.definitions[intentTypeName]?.organizationId) { + swagger.definitions[intentTypeName].organizationId = { + ...swagger.definitions[intentTypeName]?.properties.organizationId, + required: false, + }; + } + // Add organizationId if it doesn't exist + if (!swagger.definitions[intentTypeName]?.organizationId) { + swagger.definitions[intentTypeName].properties.organizationId = { + type: "string", + description: "Unique identifier for a given Organization.", + }; + } + // Always make it optional + swagger.definitions[intentTypeName].required = ( + swagger.definitions[intentTypeName].required || [] + ).filter((r) => r !== "organizationId"); + console.log(swagger.definitions[intentTypeName]); + } + } + } + } + + // Then generate the abstracted types that reference the correct versioned types + output += "\n// --- Latest Version Type Aliases ---\n"; + for (const [baseName, latestVersionName] of Object.entries( + latestVersionMap + )) { + const def = swagger.definitions[latestVersionName]; + + if (/(.+)Request$/.test(baseName)) { + continue; + } + + // If baseName ends with "Intent" and has characters before "Intent", also emit a corresponding Request type + if ( + /(.+)Intent$/.test(baseName) && + def && + def.type === "object" && + def.properties + ) { + const requestTypeName = baseName.replace(/Intent$/, "Request"); + output += generateTsType(requestTypeName, def) + "\n"; + } + + if (/(.+)Intent$/.test(baseName)) { + continue; + } + + if (def && def.type === "object" && def.properties) { + // Redefine the type with all properties, making organizationId optional if present + output += generateTsType(baseName, def) + "\n"; + } else { + output += `export type ${baseName} = ${latestVersionName};\n`; } } diff --git a/packages/sdk-types/src/__generated__/types.ts b/packages/sdk-types/src/__generated__/types.ts index c20359b01..0cd5294ac 100644 --- a/packages/sdk-types/src/__generated__/types.ts +++ b/packages/sdk-types/src/__generated__/types.ts @@ -1,5 +1,4 @@ -// AUTO-GENERATED FILE. DO NOT EDIT. -// Generated by codegen.js +/* @generated by codegen. DO NOT EDIT BY HAND */ // --- Base Types from Swagger Definitions --- export type apiApiKeyParams = { @@ -69,20 +68,20 @@ export type datav1Tag = { tagId: string; /** Human-readable name for a Tag. */ tagName: string; - tagType: TagType; + tagType: v1TagType; createdAt: externaldatav1Timestamp; updatedAt: externaldatav1Timestamp; }; export type externaldatav1Address = { - format?: AddressFormat; + format?: v1AddressFormat; address?: string; }; export type externaldatav1Credential = { /** The public component of a cryptographic key pair used to sign messages and transactions. */ publicKey: string; - type: CredentialType; + type: v1CredentialType; }; export type externaldatav1Quorum = { @@ -98,7 +97,7 @@ export type externaldatav1Timestamp = { }; export type immutableactivityv1Address = { - format?: AddressFormat; + format?: v1AddressFormat; address?: string; }; @@ -113,51 +112,51 @@ export type rpcStatus = { details?: protobufAny[]; }; -export type AcceptInvitationIntent = { +export type v1AcceptInvitationIntent = { /** Unique identifier for a given Invitation object. */ invitationId: string; /** Unique identifier for a given User. */ userId: string; /** WebAuthN hardware devices that can be used to log in to the Turnkey web app. */ - authenticator: AuthenticatorParams; + authenticator: v1AuthenticatorParams; }; -export type AcceptInvitationIntentV2 = { +export type v1AcceptInvitationIntentV2 = { /** Unique identifier for a given Invitation object. */ invitationId: string; /** Unique identifier for a given User. */ userId: string; /** WebAuthN hardware devices that can be used to log in to the Turnkey web app. */ - authenticator: AuthenticatorParamsV2; + authenticator: v1AuthenticatorParamsV2; }; -export type AcceptInvitationResult = { +export type v1AcceptInvitationResult = { /** Unique identifier for a given Invitation. */ invitationId: string; /** Unique identifier for a given User. */ userId: string; }; -export type AccessType = - | "ACCESS_TYPE_WEB" - | "ACCESS_TYPE_API" - | "ACCESS_TYPE_ALL"; +export type v1AccessType = + "ACCESS_TYPE_WEB" | + "ACCESS_TYPE_API" | + "ACCESS_TYPE_ALL"; -export type Activity = { +export type v1Activity = { /** Unique identifier for a given Activity object. */ id: string; /** Unique identifier for a given Organization. */ organizationId: string; /** The current processing status of a specified Activity. */ - status: ActivityStatus; + status: v1ActivityStatus; /** Type of Activity, such as Add User, or Sign Transaction. */ - type: ActivityType; + type: v1ActivityType; /** Intent object crafted by Turnkey based on the user request, used to assess the permissibility of an action. */ - intent: Intent; + intent: v1Intent; /** Result of the intended action. */ - result: Result; + result: v1Result; /** A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. */ - votes: Vote[]; + votes: v1Vote[]; /** An artifact verifying a User's action. */ fingerprint: string; canApprove: boolean; @@ -168,148 +167,148 @@ export type Activity = { failure?: rpcStatus; }; -export type ActivityResponse = { +export type v1ActivityResponse = { /** An action that can that can be taken within the Turnkey infrastructure. */ - activity: Activity; -}; - -export type ActivityStatus = - | "ACTIVITY_STATUS_CREATED" - | "ACTIVITY_STATUS_PENDING" - | "ACTIVITY_STATUS_COMPLETED" - | "ACTIVITY_STATUS_FAILED" - | "ACTIVITY_STATUS_CONSENSUS_NEEDED" - | "ACTIVITY_STATUS_REJECTED"; - -export type ActivityType = - | "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"; - -export type AddressFormat = - | "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"; - -export type ApiKey = { + activity: v1Activity; +}; + +export type v1ActivityStatus = + "ACTIVITY_STATUS_CREATED" | + "ACTIVITY_STATUS_PENDING" | + "ACTIVITY_STATUS_COMPLETED" | + "ACTIVITY_STATUS_FAILED" | + "ACTIVITY_STATUS_CONSENSUS_NEEDED" | + "ACTIVITY_STATUS_REJECTED"; + +export type v1ActivityType = + "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"; + +export type v1AddressFormat = + "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"; + +export type v1ApiKey = { /** A User credential that can be used to authenticate to Turnkey. */ credential: externaldatav1Credential; /** Unique identifier for a given API Key. */ @@ -322,23 +321,23 @@ export type ApiKey = { expirationSeconds?: string; }; -export type ApiKeyCurve = - | "API_KEY_CURVE_P256" - | "API_KEY_CURVE_SECP256K1" - | "API_KEY_CURVE_ED25519"; +export type v1ApiKeyCurve = + "API_KEY_CURVE_P256" | + "API_KEY_CURVE_SECP256K1" | + "API_KEY_CURVE_ED25519"; -export type ApiKeyParamsV2 = { +export type v1ApiKeyParamsV2 = { /** Human-readable name for an API Key. */ apiKeyName: string; /** The public component of a cryptographic key pair used to sign messages and transactions. */ publicKey: string; /** The curve type to be used for processing API key signatures. */ - curveType: ApiKeyCurve; + curveType: v1ApiKeyCurve; /** Optional window (in seconds) indicating how long the API Key should last. */ expirationSeconds?: string; }; -export type ApiOnlyUserParams = { +export type v1ApiOnlyUserParams = { /** The name of the new API-only User. */ userName: string; /** The email address for this API-only User (optional). */ @@ -349,21 +348,21 @@ export type ApiOnlyUserParams = { apiKeys: apiApiKeyParams[]; }; -export type ApproveActivityIntent = { +export type v1ApproveActivityIntent = { /** An artifact verifying a User's action. */ fingerprint: string; }; -export type ApproveActivityRequest = { +export type v1ApproveActivityRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: ApproveActivityIntent; + parameters: v1ApproveActivityIntent; }; -export type Attestation = { +export type v1Attestation = { /** The cbor encoded then base64 url encoded id of the credential. */ credentialId: string; /** A base64 url encoded payload containing metadata about the signing context and the challenge. */ @@ -371,12 +370,12 @@ export type Attestation = { /** A base64 url encoded payload containing authenticator data and any attestation the webauthn provider chooses. */ attestationObject: string; /** The type of authenticator transports. */ - transports: AuthenticatorTransport[]; + transports: v1AuthenticatorTransport[]; }; -export type Authenticator = { +export type v1Authenticator = { /** Types of transports that may be used by an Authenticator (e.g., USB, NFC, BLE). */ - transports: AuthenticatorTransport[]; + transports: v1AuthenticatorTransport[]; attestationType: string; /** Identifier indicating the type of the Security Key. */ aaguid: string; @@ -394,230 +393,230 @@ export type Authenticator = { updatedAt: externaldatav1Timestamp; }; -export type AuthenticatorAttestationResponse = { +export type v1AuthenticatorAttestationResponse = { clientDataJson: string; attestationObject: string; - transports?: AuthenticatorTransport[]; + transports?: v1AuthenticatorTransport[]; authenticatorAttachment?: string; }; -export type AuthenticatorParams = { +export type v1AuthenticatorParams = { /** Human-readable name for an Authenticator. */ authenticatorName: string; /** Unique identifier for a given User. */ userId: string; - attestation: PublicKeyCredentialWithAttestation; + attestation: v1PublicKeyCredentialWithAttestation; /** Challenge presented for authentication purposes. */ challenge: string; }; -export type AuthenticatorParamsV2 = { +export type v1AuthenticatorParamsV2 = { /** Human-readable name for an Authenticator. */ authenticatorName: string; /** Challenge presented for authentication purposes. */ challenge: string; /** The attestation that proves custody of the authenticator and provides metadata about it. */ - attestation: Attestation; + attestation: v1Attestation; }; -export type AuthenticatorTransport = - | "AUTHENTICATOR_TRANSPORT_BLE" - | "AUTHENTICATOR_TRANSPORT_INTERNAL" - | "AUTHENTICATOR_TRANSPORT_NFC" - | "AUTHENTICATOR_TRANSPORT_USB" - | "AUTHENTICATOR_TRANSPORT_HYBRID"; +export type v1AuthenticatorTransport = + "AUTHENTICATOR_TRANSPORT_BLE" | + "AUTHENTICATOR_TRANSPORT_INTERNAL" | + "AUTHENTICATOR_TRANSPORT_NFC" | + "AUTHENTICATOR_TRANSPORT_USB" | + "AUTHENTICATOR_TRANSPORT_HYBRID"; -export type Config = { - features?: Feature[]; +export type v1Config = { + features?: v1Feature[]; quorum?: externaldatav1Quorum; }; -export type CreateApiKeysIntent = { +export type v1CreateApiKeysIntent = { /** A list of API Keys. */ apiKeys: apiApiKeyParams[]; /** Unique identifier for a given User. */ userId: string; }; -export type CreateApiKeysIntentV2 = { +export type v1CreateApiKeysIntentV2 = { /** A list of API Keys. */ - apiKeys: ApiKeyParamsV2[]; + apiKeys: v1ApiKeyParamsV2[]; /** Unique identifier for a given User. */ userId: string; }; -export type CreateApiKeysRequest = { +export type v1CreateApiKeysRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: CreateApiKeysIntentV2; + parameters: v1CreateApiKeysIntentV2; }; -export type CreateApiKeysResult = { +export type v1CreateApiKeysResult = { /** A list of API Key IDs. */ apiKeyIds: string[]; }; -export type CreateApiOnlyUsersIntent = { +export type v1CreateApiOnlyUsersIntent = { /** A list of API-only Users to create. */ - apiOnlyUsers: ApiOnlyUserParams[]; + apiOnlyUsers: v1ApiOnlyUserParams[]; }; -export type CreateApiOnlyUsersRequest = { +export type v1CreateApiOnlyUsersRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: CreateApiOnlyUsersIntent; + parameters: v1CreateApiOnlyUsersIntent; }; -export type CreateApiOnlyUsersResult = { +export type v1CreateApiOnlyUsersResult = { /** A list of API-only User IDs. */ userIds: string[]; }; -export type CreateAuthenticatorsIntent = { +export type v1CreateAuthenticatorsIntent = { /** A list of Authenticators. */ - authenticators: AuthenticatorParams[]; + authenticators: v1AuthenticatorParams[]; /** Unique identifier for a given User. */ userId: string; }; -export type CreateAuthenticatorsIntentV2 = { +export type v1CreateAuthenticatorsIntentV2 = { /** A list of Authenticators. */ - authenticators: AuthenticatorParamsV2[]; + authenticators: v1AuthenticatorParamsV2[]; /** Unique identifier for a given User. */ userId: string; }; -export type CreateAuthenticatorsRequest = { +export type v1CreateAuthenticatorsRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: CreateAuthenticatorsIntentV2; + parameters: v1CreateAuthenticatorsIntentV2; }; -export type CreateAuthenticatorsResult = { +export type v1CreateAuthenticatorsResult = { /** A list of Authenticator IDs. */ authenticatorIds: string[]; }; -export type CreateInvitationsIntent = { +export type v1CreateInvitationsIntent = { /** A list of Invitations. */ - invitations: InvitationParams[]; + invitations: v1InvitationParams[]; }; -export type CreateInvitationsRequest = { +export type v1CreateInvitationsRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: CreateInvitationsIntent; + parameters: v1CreateInvitationsIntent; }; -export type CreateInvitationsResult = { +export type v1CreateInvitationsResult = { /** A list of Invitation IDs */ invitationIds: string[]; }; -export type CreateOauthProvidersIntent = { +export type v1CreateOauthProvidersIntent = { /** The ID of the User to add an Oauth provider to */ userId: string; /** A list of Oauth providers. */ - oauthProviders: OauthProviderParams[]; + oauthProviders: v1OauthProviderParams[]; }; -export type CreateOauthProvidersRequest = { +export type v1CreateOauthProvidersRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: CreateOauthProvidersIntent; + parameters: v1CreateOauthProvidersIntent; }; -export type CreateOauthProvidersResult = { +export type v1CreateOauthProvidersResult = { /** A list of unique identifiers for Oauth Providers */ providerIds: string[]; }; -export type CreateOrganizationIntent = { +export type v1CreateOrganizationIntent = { /** Human-readable name for an Organization. */ organizationName: string; /** The root user's email address. */ rootEmail: string; /** The root user's Authenticator. */ - rootAuthenticator: AuthenticatorParams; + rootAuthenticator: v1AuthenticatorParams; /** Unique identifier for the root user object. */ rootUserId?: string; }; -export type CreateOrganizationIntentV2 = { +export type v1CreateOrganizationIntentV2 = { /** Human-readable name for an Organization. */ organizationName: string; /** The root user's email address. */ rootEmail: string; /** The root user's Authenticator. */ - rootAuthenticator: AuthenticatorParamsV2; + rootAuthenticator: v1AuthenticatorParamsV2; /** Unique identifier for the root user object. */ rootUserId?: string; }; -export type CreateOrganizationResult = { +export type v1CreateOrganizationResult = { /** Unique identifier for a given Organization. */ organizationId: string; }; -export type CreatePoliciesIntent = { +export type v1CreatePoliciesIntent = { /** An array of policy intents to be created. */ - policies: CreatePolicyIntentV3[]; + policies: v1CreatePolicyIntentV3[]; }; -export type CreatePoliciesRequest = { +export type v1CreatePoliciesRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: CreatePoliciesIntent; + parameters: v1CreatePoliciesIntent; }; -export type CreatePoliciesResult = { +export type v1CreatePoliciesResult = { /** A list of unique identifiers for the created policies. */ policyIds: string[]; }; -export type CreatePolicyIntent = { +export type v1CreatePolicyIntent = { /** Human-readable name for a Policy. */ policyName: string; /** A list of simple functions each including a subject, target and boolean. See Policy Engine Language section for additional details. */ - selectors: Selector[]; + selectors: v1Selector[]; /** The instruction to DENY or ALLOW a particular activity following policy selector(s). */ - effect: Effect; + effect: v1Effect; notes?: string; }; -export type CreatePolicyIntentV2 = { +export type v1CreatePolicyIntentV2 = { /** Human-readable name for a Policy. */ policyName: string; /** A list of simple functions each including a subject, target and boolean. See Policy Engine Language section for additional details. */ - selectors: SelectorV2[]; + selectors: v1SelectorV2[]; /** Whether to ALLOW or DENY requests that match the condition and consensus requirements. */ - effect: Effect; + effect: v1Effect; notes?: string; }; -export type CreatePolicyIntentV3 = { +export type v1CreatePolicyIntentV3 = { /** Human-readable name for a Policy. */ policyName: string; /** The instruction to DENY or ALLOW an activity. */ - effect: Effect; + effect: v1Effect; /** The condition expression that triggers the Effect */ condition?: string; /** The consensus expression that triggers the Effect */ @@ -625,83 +624,83 @@ export type CreatePolicyIntentV3 = { notes?: string; }; -export type CreatePolicyRequest = { +export type v1CreatePolicyRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: CreatePolicyIntentV3; + parameters: v1CreatePolicyIntentV3; }; -export type CreatePolicyResult = { +export type v1CreatePolicyResult = { /** Unique identifier for a given Policy. */ policyId: string; }; -export type CreatePrivateKeyTagIntent = { +export type v1CreatePrivateKeyTagIntent = { /** Human-readable name for a Private Key Tag. */ privateKeyTagName: string; /** A list of Private Key IDs. */ privateKeyIds: string[]; }; -export type CreatePrivateKeyTagRequest = { +export type v1CreatePrivateKeyTagRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: CreatePrivateKeyTagIntent; + parameters: v1CreatePrivateKeyTagIntent; }; -export type CreatePrivateKeyTagResult = { +export type v1CreatePrivateKeyTagResult = { /** Unique identifier for a given Private Key Tag. */ privateKeyTagId: string; /** A list of Private Key IDs. */ privateKeyIds: string[]; }; -export type CreatePrivateKeysIntent = { +export type v1CreatePrivateKeysIntent = { /** A list of Private Keys. */ - privateKeys: PrivateKeyParams[]; + privateKeys: v1PrivateKeyParams[]; }; -export type CreatePrivateKeysIntentV2 = { +export type v1CreatePrivateKeysIntentV2 = { /** A list of Private Keys. */ - privateKeys: PrivateKeyParams[]; + privateKeys: v1PrivateKeyParams[]; }; -export type CreatePrivateKeysRequest = { +export type v1CreatePrivateKeysRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: CreatePrivateKeysIntentV2; + parameters: v1CreatePrivateKeysIntentV2; }; -export type CreatePrivateKeysResult = { +export type v1CreatePrivateKeysResult = { /** A list of Private Key IDs. */ privateKeyIds: string[]; }; -export type CreatePrivateKeysResultV2 = { +export type v1CreatePrivateKeysResultV2 = { /** A list of Private Key IDs and addresses. */ - privateKeys: PrivateKeyResult[]; + privateKeys: v1PrivateKeyResult[]; }; -export type CreateReadOnlySessionIntent = any; -export type CreateReadOnlySessionRequest = { +export type v1CreateReadOnlySessionIntent = any; +export type v1CreateReadOnlySessionRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: CreateReadOnlySessionIntent; + parameters: v1CreateReadOnlySessionIntent; }; -export type CreateReadOnlySessionResult = { +export type v1CreateReadOnlySessionResult = { /** Unique identifier for a given Organization. If the request is being made by a user and their Sub-Organization ID is unknown, this can be the Parent Organization ID. However, using the Sub-Organization ID is preferred due to performance reasons. */ organizationId: string; /** Human-readable name for an Organization. */ @@ -716,7 +715,7 @@ export type CreateReadOnlySessionResult = { sessionExpiry: string; }; -export type CreateReadWriteSessionIntent = { +export type v1CreateReadWriteSessionIntent = { /** Client-side public key generated by the user, to which the read write session bundle (credentials) will be encrypted. */ targetPublicKey: string; /** Email of the user to create a read write session for */ @@ -727,7 +726,7 @@ export type CreateReadWriteSessionIntent = { expirationSeconds?: string; }; -export type CreateReadWriteSessionIntentV2 = { +export type v1CreateReadWriteSessionIntentV2 = { /** Client-side public key generated by the user, to which the read write session bundle (credentials) will be encrypted. */ targetPublicKey: string; /** Unique identifier for a given User. */ @@ -740,16 +739,16 @@ export type CreateReadWriteSessionIntentV2 = { invalidateExisting?: boolean; }; -export type CreateReadWriteSessionRequest = { +export type v1CreateReadWriteSessionRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: CreateReadWriteSessionIntentV2; + parameters: v1CreateReadWriteSessionIntentV2; }; -export type CreateReadWriteSessionResult = { +export type v1CreateReadWriteSessionResult = { /** Unique identifier for a given Organization. If the request is being made by a user and their Sub-Organization ID is unknown, this can be the Parent Organization ID. However, using the Sub-Organization ID is preferred due to performance reasons. */ organizationId: string; /** Human-readable name for an Organization. */ @@ -764,7 +763,7 @@ export type CreateReadWriteSessionResult = { credentialBundle: string; }; -export type CreateReadWriteSessionResultV2 = { +export type v1CreateReadWriteSessionResultV2 = { /** Unique identifier for a given Organization. If the request is being made by a user and their Sub-Organization ID is unknown, this can be the Parent Organization ID. However, using the Sub-Organization ID is preferred due to performance reasons. */ organizationId: string; /** Human-readable name for an Organization. */ @@ -779,87 +778,87 @@ export type CreateReadWriteSessionResultV2 = { credentialBundle: string; }; -export type CreateSubOrganizationIntent = { +export type v1CreateSubOrganizationIntent = { /** Name for this sub-organization */ name: string; /** Root User authenticator for this new sub-organization */ - rootAuthenticator: AuthenticatorParamsV2; + rootAuthenticator: v1AuthenticatorParamsV2; }; -export type CreateSubOrganizationIntentV2 = { +export type v1CreateSubOrganizationIntentV2 = { /** Name for this sub-organization */ subOrganizationName: string; /** Root users to create within this sub-organization */ - rootUsers: RootUserParams[]; + rootUsers: v1RootUserParams[]; /** The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users */ rootQuorumThreshold: number; }; -export type CreateSubOrganizationIntentV3 = { +export type v1CreateSubOrganizationIntentV3 = { /** Name for this sub-organization */ subOrganizationName: string; /** Root users to create within this sub-organization */ - rootUsers: RootUserParams[]; + rootUsers: v1RootUserParams[]; /** The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users */ rootQuorumThreshold: number; /** A list of Private Keys. */ - privateKeys: PrivateKeyParams[]; + privateKeys: v1PrivateKeyParams[]; }; -export type CreateSubOrganizationIntentV4 = { +export type v1CreateSubOrganizationIntentV4 = { /** Name for this sub-organization */ subOrganizationName: string; /** Root users to create within this sub-organization */ - rootUsers: RootUserParams[]; + rootUsers: v1RootUserParams[]; /** The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users */ rootQuorumThreshold: number; /** The wallet to create for the sub-organization */ - wallet?: WalletParams; + wallet?: v1WalletParams; /** Disable email recovery for the sub-organization */ disableEmailRecovery?: boolean; /** Disable email auth for the sub-organization */ disableEmailAuth?: boolean; }; -export type CreateSubOrganizationIntentV5 = { +export type v1CreateSubOrganizationIntentV5 = { /** Name for this sub-organization */ subOrganizationName: string; /** Root users to create within this sub-organization */ - rootUsers: RootUserParamsV2[]; + rootUsers: v1RootUserParamsV2[]; /** The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users */ rootQuorumThreshold: number; /** The wallet to create for the sub-organization */ - wallet?: WalletParams; + wallet?: v1WalletParams; /** Disable email recovery for the sub-organization */ disableEmailRecovery?: boolean; /** Disable email auth for the sub-organization */ disableEmailAuth?: boolean; }; -export type CreateSubOrganizationIntentV6 = { +export type v1CreateSubOrganizationIntentV6 = { /** Name for this sub-organization */ subOrganizationName: string; /** Root users to create within this sub-organization */ - rootUsers: RootUserParamsV3[]; + rootUsers: v1RootUserParamsV3[]; /** The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users */ rootQuorumThreshold: number; /** The wallet to create for the sub-organization */ - wallet?: WalletParams; + wallet?: v1WalletParams; /** Disable email recovery for the sub-organization */ disableEmailRecovery?: boolean; /** Disable email auth for the sub-organization */ disableEmailAuth?: boolean; }; -export type CreateSubOrganizationIntentV7 = { +export type v1CreateSubOrganizationIntentV7 = { /** Name for this sub-organization */ subOrganizationName: string; /** Root users to create within this sub-organization */ - rootUsers: RootUserParamsV4[]; + rootUsers: v1RootUserParamsV4[]; /** The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users */ rootQuorumThreshold: number; /** The wallet to create for the sub-organization */ - wallet?: WalletParams; + wallet?: v1WalletParams; /** Disable email recovery for the sub-organization */ disableEmailRecovery?: boolean; /** Disable email auth for the sub-organization */ @@ -870,413 +869,417 @@ export type CreateSubOrganizationIntentV7 = { disableOtpEmailAuth?: boolean; }; -export type CreateSubOrganizationRequest = { +export type v1CreateSubOrganizationRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: CreateSubOrganizationIntentV7; + parameters: v1CreateSubOrganizationIntentV7; }; -export type CreateSubOrganizationResult = { +export type v1CreateSubOrganizationResult = { subOrganizationId: string; rootUserIds?: string[]; }; -export type CreateSubOrganizationResultV3 = { +export type v1CreateSubOrganizationResultV3 = { subOrganizationId: string; /** A list of Private Key IDs and addresses. */ - privateKeys: PrivateKeyResult[]; + privateKeys: v1PrivateKeyResult[]; rootUserIds?: string[]; }; -export type CreateSubOrganizationResultV4 = { +export type v1CreateSubOrganizationResultV4 = { subOrganizationId: string; - wallet?: WalletResult; + wallet?: v1WalletResult; rootUserIds?: string[]; }; -export type CreateSubOrganizationResultV5 = { +export type v1CreateSubOrganizationResultV5 = { subOrganizationId: string; - wallet?: WalletResult; + wallet?: v1WalletResult; rootUserIds?: string[]; }; -export type CreateSubOrganizationResultV6 = { +export type v1CreateSubOrganizationResultV6 = { subOrganizationId: string; - wallet?: WalletResult; + wallet?: v1WalletResult; rootUserIds?: string[]; }; -export type CreateSubOrganizationResultV7 = { +export type v1CreateSubOrganizationResultV7 = { subOrganizationId: string; - wallet?: WalletResult; + wallet?: v1WalletResult; rootUserIds?: string[]; }; -export type CreateUserTagIntent = { +export type v1CreateUserTagIntent = { /** Human-readable name for a User Tag. */ userTagName: string; /** A list of User IDs. */ userIds: string[]; }; -export type CreateUserTagRequest = { +export type v1CreateUserTagRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: CreateUserTagIntent; + parameters: v1CreateUserTagIntent; }; -export type CreateUserTagResult = { +export type v1CreateUserTagResult = { /** Unique identifier for a given User Tag. */ userTagId: string; /** A list of User IDs. */ userIds: string[]; }; -export type CreateUsersIntent = { +export type v1CreateUsersIntent = { /** A list of Users. */ - users: UserParams[]; + users: v1UserParams[]; }; -export type CreateUsersIntentV2 = { +export type v1CreateUsersIntentV2 = { /** A list of Users. */ - users: UserParamsV2[]; + users: v1UserParamsV2[]; }; -export type CreateUsersIntentV3 = { +export type v1CreateUsersIntentV3 = { /** A list of Users. */ - users: UserParamsV3[]; + users: v1UserParamsV3[]; }; -export type CreateUsersRequest = { +export type v1CreateUsersRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: CreateUsersIntentV3; + parameters: v1CreateUsersIntentV3; }; -export type CreateUsersResult = { +export type v1CreateUsersResult = { /** A list of User IDs. */ userIds: string[]; }; -export type CreateWalletAccountsIntent = { +export type v1CreateWalletAccountsIntent = { /** Unique identifier for a given Wallet. */ walletId: string; /** A list of wallet Accounts. */ - accounts: WalletAccountParams[]; + accounts: v1WalletAccountParams[]; }; -export type CreateWalletAccountsRequest = { +export type v1CreateWalletAccountsRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: CreateWalletAccountsIntent; + parameters: v1CreateWalletAccountsIntent; }; -export type CreateWalletAccountsResult = { +export type v1CreateWalletAccountsResult = { /** A list of derived addresses. */ addresses: string[]; }; -export type CreateWalletIntent = { +export type v1CreateWalletIntent = { /** Human-readable name for a Wallet. */ walletName: string; /** A list of wallet Accounts. This field, if not needed, should be an empty array in your request body. */ - accounts: WalletAccountParams[]; + accounts: v1WalletAccountParams[]; /** Length of mnemonic to generate the Wallet seed. Defaults to 12. Accepted values: 12, 15, 18, 21, 24. */ mnemonicLength?: number; }; -export type CreateWalletRequest = { +export type v1CreateWalletRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: CreateWalletIntent; + parameters: v1CreateWalletIntent; }; -export type CreateWalletResult = { +export type v1CreateWalletResult = { /** Unique identifier for a Wallet. */ walletId: string; /** A list of account addresses. */ addresses: string[]; }; -export type CredPropsAuthenticationExtensionsClientOutputs = { +export type v1CredPropsAuthenticationExtensionsClientOutputs = { rk: boolean; }; -export type CredentialType = - | "CREDENTIAL_TYPE_WEBAUTHN_AUTHENTICATOR" - | "CREDENTIAL_TYPE_API_KEY_P256" - | "CREDENTIAL_TYPE_RECOVER_USER_KEY_P256" - | "CREDENTIAL_TYPE_API_KEY_SECP256K1" - | "CREDENTIAL_TYPE_EMAIL_AUTH_KEY_P256" - | "CREDENTIAL_TYPE_API_KEY_ED25519" - | "CREDENTIAL_TYPE_OTP_AUTH_KEY_P256" - | "CREDENTIAL_TYPE_READ_WRITE_SESSION_KEY_P256" - | "CREDENTIAL_TYPE_OAUTH_KEY_P256" - | "CREDENTIAL_TYPE_LOGIN"; +export type v1CredentialType = + "CREDENTIAL_TYPE_WEBAUTHN_AUTHENTICATOR" | + "CREDENTIAL_TYPE_API_KEY_P256" | + "CREDENTIAL_TYPE_RECOVER_USER_KEY_P256" | + "CREDENTIAL_TYPE_API_KEY_SECP256K1" | + "CREDENTIAL_TYPE_EMAIL_AUTH_KEY_P256" | + "CREDENTIAL_TYPE_API_KEY_ED25519" | + "CREDENTIAL_TYPE_OTP_AUTH_KEY_P256" | + "CREDENTIAL_TYPE_READ_WRITE_SESSION_KEY_P256" | + "CREDENTIAL_TYPE_OAUTH_KEY_P256" | + "CREDENTIAL_TYPE_LOGIN"; -export type Curve = "CURVE_SECP256K1" | "CURVE_ED25519"; +export type v1Curve = + "CURVE_SECP256K1" | + "CURVE_ED25519"; -export type DeleteApiKeysIntent = { +export type v1DeleteApiKeysIntent = { /** Unique identifier for a given User. */ userId: string; /** A list of API Key IDs. */ apiKeyIds: string[]; }; -export type DeleteApiKeysRequest = { +export type v1DeleteApiKeysRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: DeleteApiKeysIntent; + parameters: v1DeleteApiKeysIntent; }; -export type DeleteApiKeysResult = { +export type v1DeleteApiKeysResult = { /** A list of API Key IDs. */ apiKeyIds: string[]; }; -export type DeleteAuthenticatorsIntent = { +export type v1DeleteAuthenticatorsIntent = { /** Unique identifier for a given User. */ userId: string; /** A list of Authenticator IDs. */ authenticatorIds: string[]; }; -export type DeleteAuthenticatorsRequest = { +export type v1DeleteAuthenticatorsRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: DeleteAuthenticatorsIntent; + parameters: v1DeleteAuthenticatorsIntent; }; -export type DeleteAuthenticatorsResult = { +export type v1DeleteAuthenticatorsResult = { /** Unique identifier for a given Authenticator. */ authenticatorIds: string[]; }; -export type DeleteInvitationIntent = { +export type v1DeleteInvitationIntent = { /** Unique identifier for a given Invitation object. */ invitationId: string; }; -export type DeleteInvitationRequest = { +export type v1DeleteInvitationRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: DeleteInvitationIntent; + parameters: v1DeleteInvitationIntent; }; -export type DeleteInvitationResult = { +export type v1DeleteInvitationResult = { /** Unique identifier for a given Invitation. */ invitationId: string; }; -export type DeleteOauthProvidersIntent = { +export type v1DeleteOauthProvidersIntent = { /** The ID of the User to remove an Oauth provider from */ userId: string; /** Unique identifier for a given Provider. */ providerIds: string[]; }; -export type DeleteOauthProvidersRequest = { +export type v1DeleteOauthProvidersRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: DeleteOauthProvidersIntent; + parameters: v1DeleteOauthProvidersIntent; }; -export type DeleteOauthProvidersResult = { +export type v1DeleteOauthProvidersResult = { /** A list of unique identifiers for Oauth Providers */ providerIds: string[]; }; -export type DeleteOrganizationIntent = { +export type v1DeleteOrganizationIntent = { /** Unique identifier for a given Organization. */ organizationId: string; }; -export type DeleteOrganizationResult = { +export type v1DeleteOrganizationResult = { /** Unique identifier for a given Organization. */ organizationId: string; }; -export type DeletePolicyIntent = { +export type v1DeletePolicyIntent = { /** Unique identifier for a given Policy. */ policyId: string; }; -export type DeletePolicyRequest = { +export type v1DeletePolicyRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: DeletePolicyIntent; + parameters: v1DeletePolicyIntent; }; -export type DeletePolicyResult = { +export type v1DeletePolicyResult = { /** Unique identifier for a given Policy. */ policyId: string; }; -export type DeletePrivateKeyTagsIntent = { +export type v1DeletePrivateKeyTagsIntent = { /** A list of Private Key Tag IDs. */ privateKeyTagIds: string[]; }; -export type DeletePrivateKeyTagsRequest = { +export type v1DeletePrivateKeyTagsRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: DeletePrivateKeyTagsIntent; + parameters: v1DeletePrivateKeyTagsIntent; }; -export type DeletePrivateKeyTagsResult = { +export type v1DeletePrivateKeyTagsResult = { /** A list of Private Key Tag IDs. */ privateKeyTagIds: string[]; /** A list of Private Key IDs. */ privateKeyIds: string[]; }; -export type DeletePrivateKeysIntent = { +export type v1DeletePrivateKeysIntent = { /** List of unique identifiers for private keys within an organization */ privateKeyIds: string[]; /** Optional parameter for deleting the private keys, even if any have not been previously exported. If they have been exported, this field is ignored. */ deleteWithoutExport?: boolean; }; -export type DeletePrivateKeysRequest = { +export type v1DeletePrivateKeysRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: DeletePrivateKeysIntent; + parameters: v1DeletePrivateKeysIntent; }; -export type DeletePrivateKeysResult = { +export type v1DeletePrivateKeysResult = { /** A list of private key unique identifiers that were removed */ privateKeyIds: string[]; }; -export type DeleteSubOrganizationIntent = { +export type v1DeleteSubOrganizationIntent = { /** Sub-organization deletion, by default, requires associated wallets and private keys to be exported for security reasons. Set this boolean to true to force sub-organization deletion even if some wallets or private keys within it have not been exported yet. Default: false. */ deleteWithoutExport?: boolean; }; -export type DeleteSubOrganizationRequest = { +export type v1DeleteSubOrganizationRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: DeleteSubOrganizationIntent; + parameters: v1DeleteSubOrganizationIntent; }; -export type DeleteSubOrganizationResult = { +export type v1DeleteSubOrganizationResult = { /** Unique identifier of the sub organization that was removed */ subOrganizationUuid: string; }; -export type DeleteUserTagsIntent = { +export type v1DeleteUserTagsIntent = { /** A list of User Tag IDs. */ userTagIds: string[]; }; -export type DeleteUserTagsRequest = { +export type v1DeleteUserTagsRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: DeleteUserTagsIntent; + parameters: v1DeleteUserTagsIntent; }; -export type DeleteUserTagsResult = { +export type v1DeleteUserTagsResult = { /** A list of User Tag IDs. */ userTagIds: string[]; /** A list of User IDs. */ userIds: string[]; }; -export type DeleteUsersIntent = { +export type v1DeleteUsersIntent = { /** A list of User IDs. */ userIds: string[]; }; -export type DeleteUsersRequest = { +export type v1DeleteUsersRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: DeleteUsersIntent; + parameters: v1DeleteUsersIntent; }; -export type DeleteUsersResult = { +export type v1DeleteUsersResult = { /** A list of User IDs. */ userIds: string[]; }; -export type DeleteWalletsIntent = { +export type v1DeleteWalletsIntent = { /** List of unique identifiers for wallets within an organization */ walletIds: string[]; /** Optional parameter for deleting the wallets, even if any have not been previously exported. If they have been exported, this field is ignored. */ deleteWithoutExport?: boolean; }; -export type DeleteWalletsRequest = { +export type v1DeleteWalletsRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: DeleteWalletsIntent; + parameters: v1DeleteWalletsIntent; }; -export type DeleteWalletsResult = { +export type v1DeleteWalletsResult = { /** A list of wallet unique identifiers that were removed */ walletIds: string[]; }; -export type DisablePrivateKeyIntent = { +export type v1DisablePrivateKeyIntent = { /** Unique identifier for a given Private Key. */ privateKeyId: string; }; -export type DisablePrivateKeyResult = { +export type v1DisablePrivateKeyResult = { /** Unique identifier for a given Private Key. */ privateKeyId: string; }; -export type Effect = "EFFECT_ALLOW" | "EFFECT_DENY"; +export type v1Effect = + "EFFECT_ALLOW" | + "EFFECT_DENY"; -export type EmailAuthIntent = { +export type v1EmailAuthIntent = { /** Email of the authenticating user. */ email: string; /** Client-side public key generated by the user, to which the email auth bundle (credentials) will be encrypted. */ @@ -1286,7 +1289,7 @@ export type EmailAuthIntent = { /** Expiration window (in seconds) indicating how long the API key is valid for. If not provided, a default of 15 minutes will be used. */ expirationSeconds?: string; /** Optional parameters for customizing emails. If not provided, the default email will be used. */ - emailCustomization?: EmailCustomizationParams; + emailCustomization?: v1EmailCustomizationParams; /** Invalidate all other previously generated Email Auth API keys */ invalidateExisting?: boolean; /** Optional custom email address from which to send the email */ @@ -1297,7 +1300,7 @@ export type EmailAuthIntent = { replyToEmailAddress?: string; }; -export type EmailAuthIntentV2 = { +export type v1EmailAuthIntentV2 = { /** Email of the authenticating user. */ email: string; /** Client-side public key generated by the user, to which the email auth bundle (credentials) will be encrypted. */ @@ -1307,7 +1310,7 @@ export type EmailAuthIntentV2 = { /** Expiration window (in seconds) indicating how long the API key is valid for. If not provided, a default of 15 minutes will be used. */ expirationSeconds?: string; /** Optional parameters for customizing emails. If not provided, the default email will be used. */ - emailCustomization?: EmailCustomizationParams; + emailCustomization?: v1EmailCustomizationParams; /** Invalidate all other previously generated Email Auth API keys */ invalidateExisting?: boolean; /** Optional custom email address from which to send the email */ @@ -1318,23 +1321,23 @@ export type EmailAuthIntentV2 = { replyToEmailAddress?: string; }; -export type EmailAuthRequest = { +export type v1EmailAuthRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: EmailAuthIntentV2; + parameters: v1EmailAuthIntentV2; }; -export type EmailAuthResult = { +export type v1EmailAuthResult = { /** Unique identifier for the authenticating User. */ userId: string; /** Unique identifier for the created API key. */ apiKeyId: string; }; -export type EmailCustomizationParams = { +export type v1EmailCustomizationParams = { /** The name of the application. */ appName?: string; /** A URL pointing to a logo in PNG format. Note this logo will be resized to fit into 340px x 124px. */ @@ -1347,251 +1350,251 @@ export type EmailCustomizationParams = { templateId?: string; }; -export type ExportPrivateKeyIntent = { +export type v1ExportPrivateKeyIntent = { /** Unique identifier for a given Private Key. */ privateKeyId: string; /** Client-side public key generated by the user, to which the export bundle will be encrypted. */ targetPublicKey: string; }; -export type ExportPrivateKeyRequest = { +export type v1ExportPrivateKeyRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: ExportPrivateKeyIntent; + parameters: v1ExportPrivateKeyIntent; }; -export type ExportPrivateKeyResult = { +export type v1ExportPrivateKeyResult = { /** Unique identifier for a given Private Key. */ privateKeyId: string; /** Export bundle containing a private key encrypted to the client's target public key. */ exportBundle: string; }; -export type ExportWalletAccountIntent = { +export type v1ExportWalletAccountIntent = { /** Address to identify Wallet Account. */ address: string; /** Client-side public key generated by the user, to which the export bundle will be encrypted. */ targetPublicKey: string; }; -export type ExportWalletAccountRequest = { +export type v1ExportWalletAccountRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: ExportWalletAccountIntent; + parameters: v1ExportWalletAccountIntent; }; -export type ExportWalletAccountResult = { +export type v1ExportWalletAccountResult = { /** Address to identify Wallet Account. */ address: string; /** Export bundle containing a private key encrypted by the client's target public key. */ exportBundle: string; }; -export type ExportWalletIntent = { +export type v1ExportWalletIntent = { /** Unique identifier for a given Wallet. */ walletId: string; /** Client-side public key generated by the user, to which the export bundle will be encrypted. */ targetPublicKey: string; /** The language of the mnemonic to export. Defaults to English. */ - language?: MnemonicLanguage; + language?: v1MnemonicLanguage; }; -export type ExportWalletRequest = { +export type v1ExportWalletRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: ExportWalletIntent; + parameters: v1ExportWalletIntent; }; -export type ExportWalletResult = { +export type v1ExportWalletResult = { /** Unique identifier for a given Wallet. */ walletId: string; /** Export bundle containing a wallet mnemonic + optional newline passphrase encrypted by the client's target public key. */ exportBundle: string; }; -export type Feature = { - name?: FeatureName; +export type v1Feature = { + name?: v1FeatureName; value?: string; }; -export type FeatureName = - | "FEATURE_NAME_ROOT_USER_EMAIL_RECOVERY" - | "FEATURE_NAME_WEBAUTHN_ORIGINS" - | "FEATURE_NAME_EMAIL_AUTH" - | "FEATURE_NAME_EMAIL_RECOVERY" - | "FEATURE_NAME_WEBHOOK" - | "FEATURE_NAME_SMS_AUTH" - | "FEATURE_NAME_OTP_EMAIL_AUTH"; +export type v1FeatureName = + "FEATURE_NAME_ROOT_USER_EMAIL_RECOVERY" | + "FEATURE_NAME_WEBAUTHN_ORIGINS" | + "FEATURE_NAME_EMAIL_AUTH" | + "FEATURE_NAME_EMAIL_RECOVERY" | + "FEATURE_NAME_WEBHOOK" | + "FEATURE_NAME_SMS_AUTH" | + "FEATURE_NAME_OTP_EMAIL_AUTH"; -export type GetActivitiesRequest = { +export type v1GetActivitiesRequest = { /** Unique identifier for a given Organization. */ organizationId: string; /** Array of Activity Statuses filtering which Activities will be listed in the response. */ - filterByStatus?: ActivityStatus[]; + filterByStatus?: v1ActivityStatus[]; /** Parameters used for cursor-based pagination. */ - paginationOptions?: Pagination; + paginationOptions?: v1Pagination; /** Array of Activity Types filtering which Activities will be listed in the response. */ - filterByType?: ActivityType[]; + filterByType?: v1ActivityType[]; }; -export type GetActivitiesResponse = { +export type v1GetActivitiesResponse = { /** A list of Activities. */ - activities: Activity[]; + activities: v1Activity[]; }; -export type GetActivityRequest = { +export type v1GetActivityRequest = { /** Unique identifier for a given Organization. */ organizationId: string; /** Unique identifier for a given Activity object. */ activityId: string; }; -export type GetApiKeyRequest = { +export type v1GetApiKeyRequest = { /** Unique identifier for a given Organization. */ organizationId: string; /** Unique identifier for a given API key. */ apiKeyId: string; }; -export type GetApiKeyResponse = { +export type v1GetApiKeyResponse = { /** An API key. */ - apiKey: ApiKey; + apiKey: v1ApiKey; }; -export type GetApiKeysRequest = { +export type v1GetApiKeysRequest = { /** Unique identifier for a given Organization. */ organizationId: string; /** Unique identifier for a given User. */ userId?: string; }; -export type GetApiKeysResponse = { +export type v1GetApiKeysResponse = { /** A list of API keys. */ - apiKeys: ApiKey[]; + apiKeys: v1ApiKey[]; }; -export type GetAttestationDocumentRequest = { +export type v1GetAttestationDocumentRequest = { /** Unique identifier for a given Organization. */ organizationId: string; /** The enclave type, one of: ump, notarizer, signer, evm-parser */ enclaveType: string; }; -export type GetAttestationDocumentResponse = { +export type v1GetAttestationDocumentResponse = { /** Raw (CBOR-encoded) attestation document */ attestationDocument: string; }; -export type GetAuthenticatorRequest = { +export type v1GetAuthenticatorRequest = { /** Unique identifier for a given Organization. */ organizationId: string; /** Unique identifier for a given Authenticator. */ authenticatorId: string; }; -export type GetAuthenticatorResponse = { +export type v1GetAuthenticatorResponse = { /** An authenticator. */ - authenticator: Authenticator; + authenticator: v1Authenticator; }; -export type GetAuthenticatorsRequest = { +export type v1GetAuthenticatorsRequest = { /** Unique identifier for a given Organization. */ organizationId: string; /** Unique identifier for a given User. */ userId: string; }; -export type GetAuthenticatorsResponse = { +export type v1GetAuthenticatorsResponse = { /** A list of authenticators. */ - authenticators: Authenticator[]; + authenticators: v1Authenticator[]; }; -export type GetOauthProvidersRequest = { +export type v1GetOauthProvidersRequest = { /** Unique identifier for a given Organization. */ organizationId: string; /** Unique identifier for a given User. */ userId?: string; }; -export type GetOauthProvidersResponse = { +export type v1GetOauthProvidersResponse = { /** A list of Oauth Providers */ - oauthProviders: OauthProvider[]; + oauthProviders: v1OauthProvider[]; }; -export type GetOrganizationConfigsRequest = { +export type v1GetOrganizationConfigsRequest = { /** Unique identifier for a given Organization. */ organizationId: string; }; -export type GetOrganizationConfigsResponse = { +export type v1GetOrganizationConfigsResponse = { /** Organization configs including quorum settings and organization features */ - configs: Config; + configs: v1Config; }; -export type GetOrganizationRequest = { +export type v1GetOrganizationRequest = { /** Unique identifier for a given Organization. */ organizationId: string; }; -export type GetOrganizationResponse = { +export type v1GetOrganizationResponse = { /** Object representing the full current and deleted / disabled collection of Users, Policies, Private Keys, and Invitations attributable to a particular Organization. */ - organizationData: OrganizationData; + organizationData: v1OrganizationData; }; -export type GetPoliciesRequest = { +export type v1GetPoliciesRequest = { /** Unique identifier for a given Organization. */ organizationId: string; }; -export type GetPoliciesResponse = { +export type v1GetPoliciesResponse = { /** A list of Policies. */ - policies: Policy[]; + policies: v1Policy[]; }; -export type GetPolicyRequest = { +export type v1GetPolicyRequest = { /** Unique identifier for a given Organization. */ organizationId: string; /** Unique identifier for a given Policy. */ policyId: string; }; -export type GetPolicyResponse = { +export type v1GetPolicyResponse = { /** Object that codifies rules defining the actions that are permissible within an Organization. */ - policy: Policy; + policy: v1Policy; }; -export type GetPrivateKeyRequest = { +export type v1GetPrivateKeyRequest = { /** Unique identifier for a given Organization. */ organizationId: string; /** Unique identifier for a given Private Key. */ privateKeyId: string; }; -export type GetPrivateKeyResponse = { +export type v1GetPrivateKeyResponse = { /** Cryptographic public/private key pair that can be used for cryptocurrency needs or more generalized encryption. */ - privateKey: PrivateKey; + privateKey: v1PrivateKey; }; -export type GetPrivateKeysRequest = { +export type v1GetPrivateKeysRequest = { /** Unique identifier for a given Organization. */ organizationId: string; }; -export type GetPrivateKeysResponse = { +export type v1GetPrivateKeysResponse = { /** A list of Private Keys. */ - privateKeys: PrivateKey[]; + privateKeys: v1PrivateKey[]; }; -export type GetSubOrgIdsRequest = { +export type v1GetSubOrgIdsRequest = { /** Unique identifier for the parent Organization. This is used to find sub-organizations within it. */ organizationId: string; /** Specifies the type of filter to apply, i.e 'CREDENTIAL_ID', 'NAME', 'USERNAME', 'EMAIL', 'PHONE_NUMBER', 'OIDC_TOKEN' or 'PUBLIC_KEY' */ @@ -1599,37 +1602,37 @@ export type GetSubOrgIdsRequest = { /** The value of the filter to apply for the specified type. For example, a specific email or name string. */ filterValue?: string; /** Parameters used for cursor-based pagination. */ - paginationOptions?: Pagination; + paginationOptions?: v1Pagination; }; -export type GetSubOrgIdsResponse = { +export type v1GetSubOrgIdsResponse = { /** List of unique identifiers for the matching sub-organizations. */ organizationIds: string[]; }; -export type GetUserRequest = { +export type v1GetUserRequest = { /** Unique identifier for a given Organization. */ organizationId: string; /** Unique identifier for a given User. */ userId: string; }; -export type GetUserResponse = { +export type v1GetUserResponse = { /** Web and/or API user within your Organization. */ - user: User; + user: v1User; }; -export type GetUsersRequest = { +export type v1GetUsersRequest = { /** Unique identifier for a given Organization. */ organizationId: string; }; -export type GetUsersResponse = { +export type v1GetUsersResponse = { /** A list of Users. */ - users: User[]; + users: v1User[]; }; -export type GetVerifiedSubOrgIdsRequest = { +export type v1GetVerifiedSubOrgIdsRequest = { /** Unique identifier for the parent Organization. This is used to find sub-organizations within it. */ organizationId: string; /** Specifies the type of filter to apply, i.e 'EMAIL', 'PHONE_NUMBER' */ @@ -1637,15 +1640,15 @@ export type GetVerifiedSubOrgIdsRequest = { /** The value of the filter to apply for the specified type. For example, a specific email or phone number string. */ filterValue?: string; /** Parameters used for cursor-based pagination. */ - paginationOptions?: Pagination; + paginationOptions?: v1Pagination; }; -export type GetVerifiedSubOrgIdsResponse = { +export type v1GetVerifiedSubOrgIdsResponse = { /** List of unique identifiers for the matching sub-organizations. */ organizationIds: string[]; }; -export type GetWalletAccountRequest = { +export type v1GetWalletAccountRequest = { /** Unique identifier for a given Organization. */ organizationId: string; /** Unique identifier for a given Wallet. */ @@ -1656,53 +1659,53 @@ export type GetWalletAccountRequest = { path?: string; }; -export type GetWalletAccountResponse = { +export type v1GetWalletAccountResponse = { /** The resulting Wallet Account. */ - account: WalletAccount; + account: v1WalletAccount; }; -export type GetWalletAccountsRequest = { +export type v1GetWalletAccountsRequest = { /** Unique identifier for a given Organization. */ organizationId: string; /** Unique identifier for a given Wallet. */ walletId: string; /** Parameters used for cursor-based pagination. */ - paginationOptions?: Pagination; + paginationOptions?: v1Pagination; }; -export type GetWalletAccountsResponse = { +export type v1GetWalletAccountsResponse = { /** A list of Accounts generated from a Wallet that share a common seed. */ - accounts: WalletAccount[]; + accounts: v1WalletAccount[]; }; -export type GetWalletRequest = { +export type v1GetWalletRequest = { /** Unique identifier for a given Organization. */ organizationId: string; /** Unique identifier for a given Wallet. */ walletId: string; }; -export type GetWalletResponse = { +export type v1GetWalletResponse = { /** A collection of deterministically generated cryptographic public / private key pairs that share a common seed */ - wallet: Wallet; + wallet: v1Wallet; }; -export type GetWalletsRequest = { +export type v1GetWalletsRequest = { /** Unique identifier for a given Organization. */ organizationId: string; }; -export type GetWalletsResponse = { +export type v1GetWalletsResponse = { /** A list of Wallets. */ - wallets: Wallet[]; + wallets: v1Wallet[]; }; -export type GetWhoamiRequest = { +export type v1GetWhoamiRequest = { /** 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. */ organizationId: string; }; -export type GetWhoamiResponse = { +export type v1GetWhoamiResponse = { /** Unique identifier for a given Organization. */ organizationId: string; /** Human-readable name for an Organization. */ @@ -1713,13 +1716,13 @@ export type GetWhoamiResponse = { username: string; }; -export type HashFunction = - | "HASH_FUNCTION_NO_OP" - | "HASH_FUNCTION_SHA256" - | "HASH_FUNCTION_KECCAK256" - | "HASH_FUNCTION_NOT_APPLICABLE"; +export type v1HashFunction = + "HASH_FUNCTION_NO_OP" | + "HASH_FUNCTION_SHA256" | + "HASH_FUNCTION_KECCAK256" | + "HASH_FUNCTION_NOT_APPLICABLE"; -export type ImportPrivateKeyIntent = { +export type v1ImportPrivateKeyIntent = { /** The ID of the User importing a Private Key. */ userId: string; /** Human-readable name for a Private Key. */ @@ -1727,28 +1730,28 @@ export type ImportPrivateKeyIntent = { /** Bundle containing a raw private key encrypted to the enclave's target public key. */ encryptedBundle: string; /** Cryptographic Curve used to generate a given Private Key. */ - curve: Curve; + curve: v1Curve; /** Cryptocurrency-specific formats for a derived address (e.g., Ethereum). */ - addressFormats: AddressFormat[]; + addressFormats: v1AddressFormat[]; }; -export type ImportPrivateKeyRequest = { +export type v1ImportPrivateKeyRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: ImportPrivateKeyIntent; + parameters: v1ImportPrivateKeyIntent; }; -export type ImportPrivateKeyResult = { +export type v1ImportPrivateKeyResult = { /** Unique identifier for a Private Key. */ privateKeyId: string; /** A list of addresses. */ addresses: immutableactivityv1Address[]; }; -export type ImportWalletIntent = { +export type v1ImportWalletIntent = { /** The ID of the User importing a Wallet. */ userId: string; /** Human-readable name for a Wallet. */ @@ -1756,72 +1759,72 @@ export type ImportWalletIntent = { /** Bundle containing a wallet mnemonic encrypted to the enclave's target public key. */ encryptedBundle: string; /** A list of wallet Accounts. */ - accounts: WalletAccountParams[]; + accounts: v1WalletAccountParams[]; }; -export type ImportWalletRequest = { +export type v1ImportWalletRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: ImportWalletIntent; + parameters: v1ImportWalletIntent; }; -export type ImportWalletResult = { +export type v1ImportWalletResult = { /** Unique identifier for a Wallet. */ walletId: string; /** A list of account addresses. */ addresses: string[]; }; -export type InitImportPrivateKeyIntent = { +export type v1InitImportPrivateKeyIntent = { /** The ID of the User importing a Private Key. */ userId: string; }; -export type InitImportPrivateKeyRequest = { +export type v1InitImportPrivateKeyRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: InitImportPrivateKeyIntent; + parameters: v1InitImportPrivateKeyIntent; }; -export type InitImportPrivateKeyResult = { +export type v1InitImportPrivateKeyResult = { /** Import bundle containing a public key and signature to use for importing client data. */ importBundle: string; }; -export type InitImportWalletIntent = { +export type v1InitImportWalletIntent = { /** The ID of the User importing a Wallet. */ userId: string; }; -export type InitImportWalletRequest = { +export type v1InitImportWalletRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: InitImportWalletIntent; + parameters: v1InitImportWalletIntent; }; -export type InitImportWalletResult = { +export type v1InitImportWalletResult = { /** Import bundle containing a public key and signature to use for importing client data. */ importBundle: string; }; -export type InitOtpAuthIntent = { +export type v1InitOtpAuthIntent = { /** Enum to specifiy whether to send OTP via SMS or email */ otpType: string; /** Email or phone number to send the OTP code to */ contact: string; /** Optional parameters for customizing emails. If not provided, the default email will be used. */ - emailCustomization?: EmailCustomizationParams; + emailCustomization?: v1EmailCustomizationParams; /** Optional parameters for customizing SMS message. If not provided, the default sms message will be used. */ - smsCustomization?: SmsCustomizationParams; + smsCustomization?: v1SmsCustomizationParams; /** 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. */ userIdentifier?: string; /** Optional custom email address from which to send the OTP email */ @@ -1832,7 +1835,7 @@ export type InitOtpAuthIntent = { replyToEmailAddress?: string; }; -export type InitOtpAuthIntentV2 = { +export type v1InitOtpAuthIntentV2 = { /** Enum to specifiy whether to send OTP via SMS or email */ otpType: string; /** Email or phone number to send the OTP code to */ @@ -1840,9 +1843,9 @@ export type InitOtpAuthIntentV2 = { /** Optional length of the OTP code. Default = 9 */ otpLength?: number; /** Optional parameters for customizing emails. If not provided, the default email will be used. */ - emailCustomization?: EmailCustomizationParams; + emailCustomization?: v1EmailCustomizationParams; /** Optional parameters for customizing SMS message. If not provided, the default sms message will be used. */ - smsCustomization?: SmsCustomizationParams; + smsCustomization?: v1SmsCustomizationParams; /** 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. */ userIdentifier?: string; /** Optional custom email address from which to send the OTP email */ @@ -1855,26 +1858,26 @@ export type InitOtpAuthIntentV2 = { replyToEmailAddress?: string; }; -export type InitOtpAuthRequest = { +export type v1InitOtpAuthRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: InitOtpAuthIntentV2; + parameters: v1InitOtpAuthIntentV2; }; -export type InitOtpAuthResult = { +export type v1InitOtpAuthResult = { /** Unique identifier for an OTP authentication */ otpId: string; }; -export type InitOtpAuthResultV2 = { +export type v1InitOtpAuthResultV2 = { /** Unique identifier for an OTP authentication */ otpId: string; }; -export type InitOtpIntent = { +export type v1InitOtpIntent = { /** Whether to send OTP via SMS or email. Possible values: OTP_TYPE_SMS, OTP_TYPE_EMAIL */ otpType: string; /** Email or phone number to send the OTP code to */ @@ -1882,9 +1885,9 @@ export type InitOtpIntent = { /** Optional length of the OTP code. Default = 9 */ otpLength?: number; /** Optional parameters for customizing emails. If not provided, the default email will be used. */ - emailCustomization?: EmailCustomizationParams; + emailCustomization?: v1EmailCustomizationParams; /** Optional parameters for customizing SMS message. If not provided, the default sms message will be used. */ - smsCustomization?: SmsCustomizationParams; + smsCustomization?: v1SmsCustomizationParams; /** 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. */ userIdentifier?: string; /** Optional custom email address from which to send the OTP email */ @@ -1899,21 +1902,21 @@ export type InitOtpIntent = { replyToEmailAddress?: string; }; -export type InitOtpRequest = { +export type v1InitOtpRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: InitOtpIntent; + parameters: v1InitOtpIntent; }; -export type InitOtpResult = { +export type v1InitOtpResult = { /** Unique identifier for an OTP authentication */ otpId: string; }; -export type InitUserEmailRecoveryIntent = { +export type v1InitUserEmailRecoveryIntent = { /** Email of the user starting recovery */ email: string; /** Client-side public key generated by the user, to which the recovery bundle will be encrypted. */ @@ -1921,115 +1924,115 @@ export type InitUserEmailRecoveryIntent = { /** Expiration window (in seconds) indicating how long the recovery credential is valid for. If not provided, a default of 15 minutes will be used. */ expirationSeconds?: string; /** Optional parameters for customizing emails. If not provided, the default email will be used. */ - emailCustomization?: EmailCustomizationParams; + emailCustomization?: v1EmailCustomizationParams; }; -export type InitUserEmailRecoveryRequest = { +export type v1InitUserEmailRecoveryRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: InitUserEmailRecoveryIntent; + parameters: v1InitUserEmailRecoveryIntent; }; -export type InitUserEmailRecoveryResult = { +export type v1InitUserEmailRecoveryResult = { /** Unique identifier for the user being recovered. */ userId: string; }; -export type Intent = { - createOrganizationIntent?: CreateOrganizationIntent; - createAuthenticatorsIntent?: CreateAuthenticatorsIntent; - createUsersIntent?: CreateUsersIntent; - createPrivateKeysIntent?: CreatePrivateKeysIntent; - signRawPayloadIntent?: SignRawPayloadIntent; - createInvitationsIntent?: CreateInvitationsIntent; - acceptInvitationIntent?: AcceptInvitationIntent; - createPolicyIntent?: CreatePolicyIntent; - disablePrivateKeyIntent?: DisablePrivateKeyIntent; - deleteUsersIntent?: DeleteUsersIntent; - deleteAuthenticatorsIntent?: DeleteAuthenticatorsIntent; - deleteInvitationIntent?: DeleteInvitationIntent; - deleteOrganizationIntent?: DeleteOrganizationIntent; - deletePolicyIntent?: DeletePolicyIntent; - createUserTagIntent?: CreateUserTagIntent; - deleteUserTagsIntent?: DeleteUserTagsIntent; - signTransactionIntent?: SignTransactionIntent; - createApiKeysIntent?: CreateApiKeysIntent; - deleteApiKeysIntent?: DeleteApiKeysIntent; - approveActivityIntent?: ApproveActivityIntent; - rejectActivityIntent?: RejectActivityIntent; - createPrivateKeyTagIntent?: CreatePrivateKeyTagIntent; - deletePrivateKeyTagsIntent?: DeletePrivateKeyTagsIntent; - createPolicyIntentV2?: CreatePolicyIntentV2; +export type v1Intent = { + createOrganizationIntent?: v1CreateOrganizationIntent; + createAuthenticatorsIntent?: v1CreateAuthenticatorsIntent; + createUsersIntent?: v1CreateUsersIntent; + createPrivateKeysIntent?: v1CreatePrivateKeysIntent; + signRawPayloadIntent?: v1SignRawPayloadIntent; + createInvitationsIntent?: v1CreateInvitationsIntent; + acceptInvitationIntent?: v1AcceptInvitationIntent; + createPolicyIntent?: v1CreatePolicyIntent; + disablePrivateKeyIntent?: v1DisablePrivateKeyIntent; + deleteUsersIntent?: v1DeleteUsersIntent; + deleteAuthenticatorsIntent?: v1DeleteAuthenticatorsIntent; + deleteInvitationIntent?: v1DeleteInvitationIntent; + deleteOrganizationIntent?: v1DeleteOrganizationIntent; + deletePolicyIntent?: v1DeletePolicyIntent; + createUserTagIntent?: v1CreateUserTagIntent; + deleteUserTagsIntent?: v1DeleteUserTagsIntent; + signTransactionIntent?: v1SignTransactionIntent; + createApiKeysIntent?: v1CreateApiKeysIntent; + deleteApiKeysIntent?: v1DeleteApiKeysIntent; + approveActivityIntent?: v1ApproveActivityIntent; + rejectActivityIntent?: v1RejectActivityIntent; + createPrivateKeyTagIntent?: v1CreatePrivateKeyTagIntent; + deletePrivateKeyTagsIntent?: v1DeletePrivateKeyTagsIntent; + createPolicyIntentV2?: v1CreatePolicyIntentV2; setPaymentMethodIntent?: billingSetPaymentMethodIntent; activateBillingTierIntent?: billingActivateBillingTierIntent; deletePaymentMethodIntent?: billingDeletePaymentMethodIntent; - createPolicyIntentV3?: CreatePolicyIntentV3; - createApiOnlyUsersIntent?: CreateApiOnlyUsersIntent; - updateRootQuorumIntent?: UpdateRootQuorumIntent; - updateUserTagIntent?: UpdateUserTagIntent; - updatePrivateKeyTagIntent?: UpdatePrivateKeyTagIntent; - createAuthenticatorsIntentV2?: CreateAuthenticatorsIntentV2; - acceptInvitationIntentV2?: AcceptInvitationIntentV2; - createOrganizationIntentV2?: CreateOrganizationIntentV2; - createUsersIntentV2?: CreateUsersIntentV2; - createSubOrganizationIntent?: CreateSubOrganizationIntent; - createSubOrganizationIntentV2?: CreateSubOrganizationIntentV2; - updateAllowedOriginsIntent?: UpdateAllowedOriginsIntent; - createPrivateKeysIntentV2?: CreatePrivateKeysIntentV2; - updateUserIntent?: UpdateUserIntent; - updatePolicyIntent?: UpdatePolicyIntent; + createPolicyIntentV3?: v1CreatePolicyIntentV3; + createApiOnlyUsersIntent?: v1CreateApiOnlyUsersIntent; + updateRootQuorumIntent?: v1UpdateRootQuorumIntent; + updateUserTagIntent?: v1UpdateUserTagIntent; + updatePrivateKeyTagIntent?: v1UpdatePrivateKeyTagIntent; + createAuthenticatorsIntentV2?: v1CreateAuthenticatorsIntentV2; + acceptInvitationIntentV2?: v1AcceptInvitationIntentV2; + createOrganizationIntentV2?: v1CreateOrganizationIntentV2; + createUsersIntentV2?: v1CreateUsersIntentV2; + createSubOrganizationIntent?: v1CreateSubOrganizationIntent; + createSubOrganizationIntentV2?: v1CreateSubOrganizationIntentV2; + updateAllowedOriginsIntent?: v1UpdateAllowedOriginsIntent; + createPrivateKeysIntentV2?: v1CreatePrivateKeysIntentV2; + updateUserIntent?: v1UpdateUserIntent; + updatePolicyIntent?: v1UpdatePolicyIntent; setPaymentMethodIntentV2?: billingSetPaymentMethodIntentV2; - createSubOrganizationIntentV3?: CreateSubOrganizationIntentV3; - createWalletIntent?: CreateWalletIntent; - createWalletAccountsIntent?: CreateWalletAccountsIntent; - initUserEmailRecoveryIntent?: InitUserEmailRecoveryIntent; - recoverUserIntent?: RecoverUserIntent; - setOrganizationFeatureIntent?: SetOrganizationFeatureIntent; - removeOrganizationFeatureIntent?: RemoveOrganizationFeatureIntent; - signRawPayloadIntentV2?: SignRawPayloadIntentV2; - signTransactionIntentV2?: SignTransactionIntentV2; - exportPrivateKeyIntent?: ExportPrivateKeyIntent; - exportWalletIntent?: ExportWalletIntent; - createSubOrganizationIntentV4?: CreateSubOrganizationIntentV4; - emailAuthIntent?: EmailAuthIntent; - exportWalletAccountIntent?: ExportWalletAccountIntent; - initImportWalletIntent?: InitImportWalletIntent; - importWalletIntent?: ImportWalletIntent; - initImportPrivateKeyIntent?: InitImportPrivateKeyIntent; - importPrivateKeyIntent?: ImportPrivateKeyIntent; - createPoliciesIntent?: CreatePoliciesIntent; - signRawPayloadsIntent?: SignRawPayloadsIntent; - createReadOnlySessionIntent?: CreateReadOnlySessionIntent; - createOauthProvidersIntent?: CreateOauthProvidersIntent; - deleteOauthProvidersIntent?: DeleteOauthProvidersIntent; - createSubOrganizationIntentV5?: CreateSubOrganizationIntentV5; - oauthIntent?: OauthIntent; - createApiKeysIntentV2?: CreateApiKeysIntentV2; - createReadWriteSessionIntent?: CreateReadWriteSessionIntent; - emailAuthIntentV2?: EmailAuthIntentV2; - createSubOrganizationIntentV6?: CreateSubOrganizationIntentV6; - deletePrivateKeysIntent?: DeletePrivateKeysIntent; - deleteWalletsIntent?: DeleteWalletsIntent; - createReadWriteSessionIntentV2?: CreateReadWriteSessionIntentV2; - deleteSubOrganizationIntent?: DeleteSubOrganizationIntent; - initOtpAuthIntent?: InitOtpAuthIntent; - otpAuthIntent?: OtpAuthIntent; - createSubOrganizationIntentV7?: CreateSubOrganizationIntentV7; - updateWalletIntent?: UpdateWalletIntent; - updatePolicyIntentV2?: UpdatePolicyIntentV2; - createUsersIntentV3?: CreateUsersIntentV3; - initOtpAuthIntentV2?: InitOtpAuthIntentV2; - initOtpIntent?: InitOtpIntent; - verifyOtpIntent?: VerifyOtpIntent; - otpLoginIntent?: OtpLoginIntent; - stampLoginIntent?: StampLoginIntent; - oauthLoginIntent?: OauthLoginIntent; -}; - -export type Invitation = { + createSubOrganizationIntentV3?: v1CreateSubOrganizationIntentV3; + createWalletIntent?: v1CreateWalletIntent; + createWalletAccountsIntent?: v1CreateWalletAccountsIntent; + initUserEmailRecoveryIntent?: v1InitUserEmailRecoveryIntent; + recoverUserIntent?: v1RecoverUserIntent; + setOrganizationFeatureIntent?: v1SetOrganizationFeatureIntent; + removeOrganizationFeatureIntent?: v1RemoveOrganizationFeatureIntent; + signRawPayloadIntentV2?: v1SignRawPayloadIntentV2; + signTransactionIntentV2?: v1SignTransactionIntentV2; + exportPrivateKeyIntent?: v1ExportPrivateKeyIntent; + exportWalletIntent?: v1ExportWalletIntent; + createSubOrganizationIntentV4?: v1CreateSubOrganizationIntentV4; + emailAuthIntent?: v1EmailAuthIntent; + exportWalletAccountIntent?: v1ExportWalletAccountIntent; + initImportWalletIntent?: v1InitImportWalletIntent; + importWalletIntent?: v1ImportWalletIntent; + initImportPrivateKeyIntent?: v1InitImportPrivateKeyIntent; + importPrivateKeyIntent?: v1ImportPrivateKeyIntent; + createPoliciesIntent?: v1CreatePoliciesIntent; + signRawPayloadsIntent?: v1SignRawPayloadsIntent; + createReadOnlySessionIntent?: v1CreateReadOnlySessionIntent; + createOauthProvidersIntent?: v1CreateOauthProvidersIntent; + deleteOauthProvidersIntent?: v1DeleteOauthProvidersIntent; + createSubOrganizationIntentV5?: v1CreateSubOrganizationIntentV5; + oauthIntent?: v1OauthIntent; + createApiKeysIntentV2?: v1CreateApiKeysIntentV2; + createReadWriteSessionIntent?: v1CreateReadWriteSessionIntent; + emailAuthIntentV2?: v1EmailAuthIntentV2; + createSubOrganizationIntentV6?: v1CreateSubOrganizationIntentV6; + deletePrivateKeysIntent?: v1DeletePrivateKeysIntent; + deleteWalletsIntent?: v1DeleteWalletsIntent; + createReadWriteSessionIntentV2?: v1CreateReadWriteSessionIntentV2; + deleteSubOrganizationIntent?: v1DeleteSubOrganizationIntent; + initOtpAuthIntent?: v1InitOtpAuthIntent; + otpAuthIntent?: v1OtpAuthIntent; + createSubOrganizationIntentV7?: v1CreateSubOrganizationIntentV7; + updateWalletIntent?: v1UpdateWalletIntent; + updatePolicyIntentV2?: v1UpdatePolicyIntentV2; + createUsersIntentV3?: v1CreateUsersIntentV3; + initOtpAuthIntentV2?: v1InitOtpAuthIntentV2; + initOtpIntent?: v1InitOtpIntent; + verifyOtpIntent?: v1VerifyOtpIntent; + otpLoginIntent?: v1OtpLoginIntent; + stampLoginIntent?: v1StampLoginIntent; + oauthLoginIntent?: v1OauthLoginIntent; +}; + +export type v1Invitation = { /** Unique identifier for a given Invitation object. */ invitationId: string; /** The name of the intended Invitation recipient. */ @@ -2039,16 +2042,16 @@ export type Invitation = { /** A list of tags assigned to the Invitation recipient. */ receiverUserTags: string[]; /** The User's permissible access method(s). */ - accessType: AccessType; + accessType: v1AccessType; /** The current processing status of a specified Invitation. */ - status: InvitationStatus; + status: v1InvitationStatus; createdAt: externaldatav1Timestamp; updatedAt: externaldatav1Timestamp; /** Unique identifier for the Sender of an Invitation. */ senderUserId: string; }; -export type InvitationParams = { +export type v1InvitationParams = { /** The name of the intended Invitation recipient. */ receiverUserName: string; /** The email address of the intended Invitation recipient. */ @@ -2056,52 +2059,52 @@ export type InvitationParams = { /** A list of tags assigned to the Invitation recipient. This field, if not needed, should be an empty array in your request body. */ receiverUserTags: string[]; /** The User's permissible access method(s). */ - accessType: AccessType; + accessType: v1AccessType; /** Unique identifier for the Sender of an Invitation. */ senderUserId: string; }; -export type InvitationStatus = - | "INVITATION_STATUS_CREATED" - | "INVITATION_STATUS_ACCEPTED" - | "INVITATION_STATUS_REVOKED"; +export type v1InvitationStatus = + "INVITATION_STATUS_CREATED" | + "INVITATION_STATUS_ACCEPTED" | + "INVITATION_STATUS_REVOKED"; -export type ListPrivateKeyTagsRequest = { +export type v1ListPrivateKeyTagsRequest = { /** Unique identifier for a given Organization. */ organizationId: string; }; -export type ListPrivateKeyTagsResponse = { +export type v1ListPrivateKeyTagsResponse = { /** A list of Private Key Tags */ privateKeyTags: datav1Tag[]; }; -export type ListUserTagsRequest = { +export type v1ListUserTagsRequest = { /** Unique identifier for a given Organization. */ organizationId: string; }; -export type ListUserTagsResponse = { +export type v1ListUserTagsResponse = { /** A list of User Tags */ userTags: datav1Tag[]; }; -export type MnemonicLanguage = - | "MNEMONIC_LANGUAGE_ENGLISH" - | "MNEMONIC_LANGUAGE_SIMPLIFIED_CHINESE" - | "MNEMONIC_LANGUAGE_TRADITIONAL_CHINESE" - | "MNEMONIC_LANGUAGE_CZECH" - | "MNEMONIC_LANGUAGE_FRENCH" - | "MNEMONIC_LANGUAGE_ITALIAN" - | "MNEMONIC_LANGUAGE_JAPANESE" - | "MNEMONIC_LANGUAGE_KOREAN" - | "MNEMONIC_LANGUAGE_SPANISH"; +export type v1MnemonicLanguage = + "MNEMONIC_LANGUAGE_ENGLISH" | + "MNEMONIC_LANGUAGE_SIMPLIFIED_CHINESE" | + "MNEMONIC_LANGUAGE_TRADITIONAL_CHINESE" | + "MNEMONIC_LANGUAGE_CZECH" | + "MNEMONIC_LANGUAGE_FRENCH" | + "MNEMONIC_LANGUAGE_ITALIAN" | + "MNEMONIC_LANGUAGE_JAPANESE" | + "MNEMONIC_LANGUAGE_KOREAN" | + "MNEMONIC_LANGUAGE_SPANISH"; -export type NOOPCodegenAnchorResponse = { - stamp: WebAuthnStamp; +export type v1NOOPCodegenAnchorResponse = { + stamp: v1WebAuthnStamp; }; -export type OauthIntent = { +export type v1OauthIntent = { /** Base64 encoded OIDC token */ oidcToken: string; /** Client-side public key generated by the user, to which the oauth bundle (credentials) will be encrypted. */ @@ -2114,7 +2117,7 @@ export type OauthIntent = { invalidateExisting?: boolean; }; -export type OauthLoginIntent = { +export type v1OauthLoginIntent = { /** Base64 encoded OIDC token */ oidcToken: string; /** 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 */ @@ -2125,21 +2128,21 @@ export type OauthLoginIntent = { invalidateExisting?: boolean; }; -export type OauthLoginRequest = { +export type v1OauthLoginRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: OauthLoginIntent; + parameters: v1OauthLoginIntent; }; -export type OauthLoginResult = { +export type v1OauthLoginResult = { /** Signed JWT containing an expiry, public key, session type, user id, and organization id */ session: string; }; -export type OauthProvider = { +export type v1OauthProvider = { /** Unique identifier for an OAuth Provider */ providerId: string; /** Human-readable name to identify a Provider. */ @@ -2154,23 +2157,23 @@ export type OauthProvider = { updatedAt: externaldatav1Timestamp; }; -export type OauthProviderParams = { +export type v1OauthProviderParams = { /** Human-readable name to identify a Provider. */ providerName: string; /** Base64 encoded OIDC token */ oidcToken: string; }; -export type OauthRequest = { +export type v1OauthRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: OauthIntent; + parameters: v1OauthIntent; }; -export type OauthResult = { +export type v1OauthResult = { /** Unique identifier for the authenticating User. */ userId: string; /** Unique identifier for the created API key. */ @@ -2179,33 +2182,33 @@ export type OauthResult = { credentialBundle: string; }; -export type Operator = - | "OPERATOR_EQUAL" - | "OPERATOR_MORE_THAN" - | "OPERATOR_MORE_THAN_OR_EQUAL" - | "OPERATOR_LESS_THAN" - | "OPERATOR_LESS_THAN_OR_EQUAL" - | "OPERATOR_CONTAINS" - | "OPERATOR_NOT_EQUAL" - | "OPERATOR_IN" - | "OPERATOR_NOT_IN" - | "OPERATOR_CONTAINS_ONE" - | "OPERATOR_CONTAINS_ALL"; - -export type OrganizationData = { +export type v1Operator = + "OPERATOR_EQUAL" | + "OPERATOR_MORE_THAN" | + "OPERATOR_MORE_THAN_OR_EQUAL" | + "OPERATOR_LESS_THAN" | + "OPERATOR_LESS_THAN_OR_EQUAL" | + "OPERATOR_CONTAINS" | + "OPERATOR_NOT_EQUAL" | + "OPERATOR_IN" | + "OPERATOR_NOT_IN" | + "OPERATOR_CONTAINS_ONE" | + "OPERATOR_CONTAINS_ALL"; + +export type v1OrganizationData = { organizationId?: string; name?: string; - users?: User[]; - policies?: Policy[]; - privateKeys?: PrivateKey[]; - invitations?: Invitation[]; + users?: v1User[]; + policies?: v1Policy[]; + privateKeys?: v1PrivateKey[]; + invitations?: v1Invitation[]; tags?: datav1Tag[]; rootQuorum?: externaldatav1Quorum; - features?: Feature[]; - wallets?: Wallet[]; + features?: v1Feature[]; + wallets?: v1Wallet[]; }; -export type OtpAuthIntent = { +export type v1OtpAuthIntent = { /** ID representing the result of an init OTP activity. */ otpId: string; /** OTP sent out to a user's contact (email or SMS) */ @@ -2220,16 +2223,16 @@ export type OtpAuthIntent = { invalidateExisting?: boolean; }; -export type OtpAuthRequest = { +export type v1OtpAuthRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: OtpAuthIntent; + parameters: v1OtpAuthIntent; }; -export type OtpAuthResult = { +export type v1OtpAuthResult = { /** Unique identifier for the authenticating User. */ userId: string; /** Unique identifier for the created API key. */ @@ -2238,7 +2241,7 @@ export type OtpAuthResult = { credentialBundle?: string; }; -export type OtpLoginIntent = { +export type v1OtpLoginIntent = { /** Signed JWT containing a unique id, expiry, verification type, contact */ verificationToken: string; /** Client-side public key generated by the user, which will be conditionally added to org data based on the validity of the verification token */ @@ -2249,21 +2252,21 @@ export type OtpLoginIntent = { invalidateExisting?: boolean; }; -export type OtpLoginRequest = { +export type v1OtpLoginRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: OtpLoginIntent; + parameters: v1OtpLoginIntent; }; -export type OtpLoginResult = { +export type v1OtpLoginResult = { /** Signed JWT containing an expiry, public key, session type, user id, and organization id */ session: string; }; -export type Pagination = { +export type v1Pagination = { /** A limit of the number of object to be returned, between 1 and 100. Defaults to 10. */ limit?: string; /** A pagination cursor. This is an object ID that enables you to fetch all objects before this ID. */ @@ -2272,19 +2275,20 @@ export type Pagination = { after?: string; }; -export type PathFormat = "PATH_FORMAT_BIP32"; +export type v1PathFormat = + "PATH_FORMAT_BIP32"; -export type PayloadEncoding = - | "PAYLOAD_ENCODING_HEXADECIMAL" - | "PAYLOAD_ENCODING_TEXT_UTF8"; +export type v1PayloadEncoding = + "PAYLOAD_ENCODING_HEXADECIMAL" | + "PAYLOAD_ENCODING_TEXT_UTF8"; -export type Policy = { +export type v1Policy = { /** Unique identifier for a given Policy. */ policyId: string; /** Human-readable name for a Policy. */ policyName: string; /** The instruction to DENY or ALLOW a particular activity following policy selector(s). */ - effect: Effect; + effect: v1Effect; createdAt: externaldatav1Timestamp; updatedAt: externaldatav1Timestamp; /** Human-readable notes added by a User to describe a particular policy. */ @@ -2295,7 +2299,7 @@ export type Policy = { condition: string; }; -export type PrivateKey = { +export type v1PrivateKey = { /** Unique identifier for a given Private Key. */ privateKeyId: string; /** The public component of a cryptographic key pair used to sign messages and transactions. */ @@ -2303,7 +2307,7 @@ export type PrivateKey = { /** Human-readable name for a Private Key. */ privateKeyName: string; /** Cryptographic Curve used to generate a given Private Key. */ - curve: Curve; + curve: v1Curve; /** Derived cryptocurrency addresses for a given Private Key. */ addresses: externaldatav1Address[]; /** A list of Private Key Tag IDs. */ @@ -2316,162 +2320,162 @@ export type PrivateKey = { imported: boolean; }; -export type PrivateKeyParams = { +export type v1PrivateKeyParams = { /** Human-readable name for a Private Key. */ privateKeyName: string; /** Cryptographic Curve used to generate a given Private Key. */ - curve: Curve; + curve: v1Curve; /** A list of Private Key Tag IDs. This field, if not needed, should be an empty array in your request body. */ privateKeyTags: string[]; /** Cryptocurrency-specific formats for a derived address (e.g., Ethereum). */ - addressFormats: AddressFormat[]; + addressFormats: v1AddressFormat[]; }; -export type PrivateKeyResult = { +export type v1PrivateKeyResult = { privateKeyId?: string; addresses?: immutableactivityv1Address[]; }; -export type PublicKeyCredentialWithAttestation = { +export type v1PublicKeyCredentialWithAttestation = { id: string; type: string; rawId: string; authenticatorAttachment?: string; - response: AuthenticatorAttestationResponse; - clientExtensionResults: SimpleClientExtensionResults; + response: v1AuthenticatorAttestationResponse; + clientExtensionResults: v1SimpleClientExtensionResults; }; -export type RecoverUserIntent = { +export type v1RecoverUserIntent = { /** The new authenticator to register. */ - authenticator: AuthenticatorParamsV2; + authenticator: v1AuthenticatorParamsV2; /** Unique identifier for the user performing recovery. */ userId: string; }; -export type RecoverUserRequest = { +export type v1RecoverUserRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: RecoverUserIntent; + parameters: v1RecoverUserIntent; }; -export type RecoverUserResult = { +export type v1RecoverUserResult = { /** ID of the authenticator created. */ authenticatorId: string[]; }; -export type RejectActivityIntent = { +export type v1RejectActivityIntent = { /** An artifact verifying a User's action. */ fingerprint: string; }; -export type RejectActivityRequest = { +export type v1RejectActivityRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: RejectActivityIntent; + parameters: v1RejectActivityIntent; }; -export type RemoveOrganizationFeatureIntent = { +export type v1RemoveOrganizationFeatureIntent = { /** Name of the feature to remove */ - name: FeatureName; + name: v1FeatureName; }; -export type RemoveOrganizationFeatureRequest = { +export type v1RemoveOrganizationFeatureRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: RemoveOrganizationFeatureIntent; + parameters: v1RemoveOrganizationFeatureIntent; }; -export type RemoveOrganizationFeatureResult = { +export type v1RemoveOrganizationFeatureResult = { /** Resulting list of organization features. */ - features: Feature[]; -}; - -export type Result = { - createOrganizationResult?: CreateOrganizationResult; - createAuthenticatorsResult?: CreateAuthenticatorsResult; - createUsersResult?: CreateUsersResult; - createPrivateKeysResult?: CreatePrivateKeysResult; - createInvitationsResult?: CreateInvitationsResult; - acceptInvitationResult?: AcceptInvitationResult; - signRawPayloadResult?: SignRawPayloadResult; - createPolicyResult?: CreatePolicyResult; - disablePrivateKeyResult?: DisablePrivateKeyResult; - deleteUsersResult?: DeleteUsersResult; - deleteAuthenticatorsResult?: DeleteAuthenticatorsResult; - deleteInvitationResult?: DeleteInvitationResult; - deleteOrganizationResult?: DeleteOrganizationResult; - deletePolicyResult?: DeletePolicyResult; - createUserTagResult?: CreateUserTagResult; - deleteUserTagsResult?: DeleteUserTagsResult; - signTransactionResult?: SignTransactionResult; - deleteApiKeysResult?: DeleteApiKeysResult; - createApiKeysResult?: CreateApiKeysResult; - createPrivateKeyTagResult?: CreatePrivateKeyTagResult; - deletePrivateKeyTagsResult?: DeletePrivateKeyTagsResult; + features: v1Feature[]; +}; + +export type v1Result = { + createOrganizationResult?: v1CreateOrganizationResult; + createAuthenticatorsResult?: v1CreateAuthenticatorsResult; + createUsersResult?: v1CreateUsersResult; + createPrivateKeysResult?: v1CreatePrivateKeysResult; + createInvitationsResult?: v1CreateInvitationsResult; + acceptInvitationResult?: v1AcceptInvitationResult; + signRawPayloadResult?: v1SignRawPayloadResult; + createPolicyResult?: v1CreatePolicyResult; + disablePrivateKeyResult?: v1DisablePrivateKeyResult; + deleteUsersResult?: v1DeleteUsersResult; + deleteAuthenticatorsResult?: v1DeleteAuthenticatorsResult; + deleteInvitationResult?: v1DeleteInvitationResult; + deleteOrganizationResult?: v1DeleteOrganizationResult; + deletePolicyResult?: v1DeletePolicyResult; + createUserTagResult?: v1CreateUserTagResult; + deleteUserTagsResult?: v1DeleteUserTagsResult; + signTransactionResult?: v1SignTransactionResult; + deleteApiKeysResult?: v1DeleteApiKeysResult; + createApiKeysResult?: v1CreateApiKeysResult; + createPrivateKeyTagResult?: v1CreatePrivateKeyTagResult; + deletePrivateKeyTagsResult?: v1DeletePrivateKeyTagsResult; setPaymentMethodResult?: billingSetPaymentMethodResult; activateBillingTierResult?: billingActivateBillingTierResult; deletePaymentMethodResult?: billingDeletePaymentMethodResult; - createApiOnlyUsersResult?: CreateApiOnlyUsersResult; - updateRootQuorumResult?: UpdateRootQuorumResult; - updateUserTagResult?: UpdateUserTagResult; - updatePrivateKeyTagResult?: UpdatePrivateKeyTagResult; - createSubOrganizationResult?: CreateSubOrganizationResult; - updateAllowedOriginsResult?: UpdateAllowedOriginsResult; - createPrivateKeysResultV2?: CreatePrivateKeysResultV2; - updateUserResult?: UpdateUserResult; - updatePolicyResult?: UpdatePolicyResult; - createSubOrganizationResultV3?: CreateSubOrganizationResultV3; - createWalletResult?: CreateWalletResult; - createWalletAccountsResult?: CreateWalletAccountsResult; - initUserEmailRecoveryResult?: InitUserEmailRecoveryResult; - recoverUserResult?: RecoverUserResult; - setOrganizationFeatureResult?: SetOrganizationFeatureResult; - removeOrganizationFeatureResult?: RemoveOrganizationFeatureResult; - exportPrivateKeyResult?: ExportPrivateKeyResult; - exportWalletResult?: ExportWalletResult; - createSubOrganizationResultV4?: CreateSubOrganizationResultV4; - emailAuthResult?: EmailAuthResult; - exportWalletAccountResult?: ExportWalletAccountResult; - initImportWalletResult?: InitImportWalletResult; - importWalletResult?: ImportWalletResult; - initImportPrivateKeyResult?: InitImportPrivateKeyResult; - importPrivateKeyResult?: ImportPrivateKeyResult; - createPoliciesResult?: CreatePoliciesResult; - signRawPayloadsResult?: SignRawPayloadsResult; - createReadOnlySessionResult?: CreateReadOnlySessionResult; - createOauthProvidersResult?: CreateOauthProvidersResult; - deleteOauthProvidersResult?: DeleteOauthProvidersResult; - createSubOrganizationResultV5?: CreateSubOrganizationResultV5; - oauthResult?: OauthResult; - createReadWriteSessionResult?: CreateReadWriteSessionResult; - createSubOrganizationResultV6?: CreateSubOrganizationResultV6; - deletePrivateKeysResult?: DeletePrivateKeysResult; - deleteWalletsResult?: DeleteWalletsResult; - createReadWriteSessionResultV2?: CreateReadWriteSessionResultV2; - deleteSubOrganizationResult?: DeleteSubOrganizationResult; - initOtpAuthResult?: InitOtpAuthResult; - otpAuthResult?: OtpAuthResult; - createSubOrganizationResultV7?: CreateSubOrganizationResultV7; - updateWalletResult?: UpdateWalletResult; - updatePolicyResultV2?: UpdatePolicyResultV2; - initOtpAuthResultV2?: InitOtpAuthResultV2; - initOtpResult?: InitOtpResult; - verifyOtpResult?: VerifyOtpResult; - otpLoginResult?: OtpLoginResult; - stampLoginResult?: StampLoginResult; - oauthLoginResult?: OauthLoginResult; -}; - -export type RootUserParams = { + createApiOnlyUsersResult?: v1CreateApiOnlyUsersResult; + updateRootQuorumResult?: v1UpdateRootQuorumResult; + updateUserTagResult?: v1UpdateUserTagResult; + updatePrivateKeyTagResult?: v1UpdatePrivateKeyTagResult; + createSubOrganizationResult?: v1CreateSubOrganizationResult; + updateAllowedOriginsResult?: v1UpdateAllowedOriginsResult; + createPrivateKeysResultV2?: v1CreatePrivateKeysResultV2; + updateUserResult?: v1UpdateUserResult; + updatePolicyResult?: v1UpdatePolicyResult; + createSubOrganizationResultV3?: v1CreateSubOrganizationResultV3; + createWalletResult?: v1CreateWalletResult; + createWalletAccountsResult?: v1CreateWalletAccountsResult; + initUserEmailRecoveryResult?: v1InitUserEmailRecoveryResult; + recoverUserResult?: v1RecoverUserResult; + setOrganizationFeatureResult?: v1SetOrganizationFeatureResult; + removeOrganizationFeatureResult?: v1RemoveOrganizationFeatureResult; + exportPrivateKeyResult?: v1ExportPrivateKeyResult; + exportWalletResult?: v1ExportWalletResult; + createSubOrganizationResultV4?: v1CreateSubOrganizationResultV4; + emailAuthResult?: v1EmailAuthResult; + exportWalletAccountResult?: v1ExportWalletAccountResult; + initImportWalletResult?: v1InitImportWalletResult; + importWalletResult?: v1ImportWalletResult; + initImportPrivateKeyResult?: v1InitImportPrivateKeyResult; + importPrivateKeyResult?: v1ImportPrivateKeyResult; + createPoliciesResult?: v1CreatePoliciesResult; + signRawPayloadsResult?: v1SignRawPayloadsResult; + createReadOnlySessionResult?: v1CreateReadOnlySessionResult; + createOauthProvidersResult?: v1CreateOauthProvidersResult; + deleteOauthProvidersResult?: v1DeleteOauthProvidersResult; + createSubOrganizationResultV5?: v1CreateSubOrganizationResultV5; + oauthResult?: v1OauthResult; + createReadWriteSessionResult?: v1CreateReadWriteSessionResult; + createSubOrganizationResultV6?: v1CreateSubOrganizationResultV6; + deletePrivateKeysResult?: v1DeletePrivateKeysResult; + deleteWalletsResult?: v1DeleteWalletsResult; + createReadWriteSessionResultV2?: v1CreateReadWriteSessionResultV2; + deleteSubOrganizationResult?: v1DeleteSubOrganizationResult; + initOtpAuthResult?: v1InitOtpAuthResult; + otpAuthResult?: v1OtpAuthResult; + createSubOrganizationResultV7?: v1CreateSubOrganizationResultV7; + updateWalletResult?: v1UpdateWalletResult; + updatePolicyResultV2?: v1UpdatePolicyResultV2; + initOtpAuthResultV2?: v1InitOtpAuthResultV2; + initOtpResult?: v1InitOtpResult; + verifyOtpResult?: v1VerifyOtpResult; + otpLoginResult?: v1OtpLoginResult; + stampLoginResult?: v1StampLoginResult; + oauthLoginResult?: v1OauthLoginResult; +}; + +export type v1RootUserParams = { /** Human-readable name for a User. */ userName: string; /** The user's email address. */ @@ -2479,10 +2483,10 @@ export type RootUserParams = { /** A list of API Key parameters. This field, if not needed, should be an empty array in your request body. */ apiKeys: apiApiKeyParams[]; /** A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. */ - authenticators: AuthenticatorParamsV2[]; + authenticators: v1AuthenticatorParamsV2[]; }; -export type RootUserParamsV2 = { +export type v1RootUserParamsV2 = { /** Human-readable name for a User. */ userName: string; /** The user's email address. */ @@ -2490,25 +2494,25 @@ export type RootUserParamsV2 = { /** A list of API Key parameters. This field, if not needed, should be an empty array in your request body. */ apiKeys: apiApiKeyParams[]; /** A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. */ - authenticators: AuthenticatorParamsV2[]; + authenticators: v1AuthenticatorParamsV2[]; /** A list of Oauth providers. This field, if not needed, should be an empty array in your request body. */ - oauthProviders: OauthProviderParams[]; + oauthProviders: v1OauthProviderParams[]; }; -export type RootUserParamsV3 = { +export type v1RootUserParamsV3 = { /** Human-readable name for a User. */ userName: string; /** The user's email address. */ userEmail?: string; /** A list of API Key parameters. This field, if not needed, should be an empty array in your request body. */ - apiKeys: ApiKeyParamsV2[]; + apiKeys: v1ApiKeyParamsV2[]; /** A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. */ - authenticators: AuthenticatorParamsV2[]; + authenticators: v1AuthenticatorParamsV2[]; /** A list of Oauth providers. This field, if not needed, should be an empty array in your request body. */ - oauthProviders: OauthProviderParams[]; + oauthProviders: v1OauthProviderParams[]; }; -export type RootUserParamsV4 = { +export type v1RootUserParamsV4 = { /** Human-readable name for a User. */ userName: string; /** The user's email address. */ @@ -2516,78 +2520,78 @@ export type RootUserParamsV4 = { /** The user's phone number in E.164 format e.g. +13214567890 */ userPhoneNumber?: string; /** A list of API Key parameters. This field, if not needed, should be an empty array in your request body. */ - apiKeys: ApiKeyParamsV2[]; + apiKeys: v1ApiKeyParamsV2[]; /** A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. */ - authenticators: AuthenticatorParamsV2[]; + authenticators: v1AuthenticatorParamsV2[]; /** A list of Oauth providers. This field, if not needed, should be an empty array in your request body. */ - oauthProviders: OauthProviderParams[]; + oauthProviders: v1OauthProviderParams[]; }; -export type Selector = { +export type v1Selector = { subject?: string; - operator?: Operator; + operator?: v1Operator; target?: string; }; -export type SelectorV2 = { +export type v1SelectorV2 = { subject?: string; - operator?: Operator; + operator?: v1Operator; targets?: string[]; }; -export type SetOrganizationFeatureIntent = { +export type v1SetOrganizationFeatureIntent = { /** Name of the feature to set */ - name: FeatureName; + name: v1FeatureName; /** Optional value for the feature. Will override existing values if feature is already set. */ value: string; }; -export type SetOrganizationFeatureRequest = { +export type v1SetOrganizationFeatureRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: SetOrganizationFeatureIntent; + parameters: v1SetOrganizationFeatureIntent; }; -export type SetOrganizationFeatureResult = { +export type v1SetOrganizationFeatureResult = { /** Resulting list of organization features. */ - features: Feature[]; + features: v1Feature[]; }; -export type SignRawPayloadIntent = { +export type v1SignRawPayloadIntent = { /** Unique identifier for a given Private Key. */ privateKeyId: string; /** Raw unsigned payload to be signed. */ payload: string; /** Encoding of the `payload` string. Turnkey uses this information to convert `payload` into bytes with the correct decoder (e.g. hex, utf8). */ - encoding: PayloadEncoding; + encoding: v1PayloadEncoding; /** Hash function to apply to payload bytes before signing. This field must be set to HASH_FUNCTION_NOT_APPLICABLE for EdDSA/ed25519 signature requests; configurable payload hashing is not supported by RFC 8032. */ - hashFunction: HashFunction; + hashFunction: v1HashFunction; }; -export type SignRawPayloadIntentV2 = { +export type v1SignRawPayloadIntentV2 = { /** A Wallet account address, Private Key address, or Private Key identifier. */ signWith: string; /** Raw unsigned payload to be signed. */ payload: string; /** Encoding of the `payload` string. Turnkey uses this information to convert `payload` into bytes with the correct decoder (e.g. hex, utf8). */ - encoding: PayloadEncoding; + encoding: v1PayloadEncoding; /** Hash function to apply to payload bytes before signing. This field must be set to HASH_FUNCTION_NOT_APPLICABLE for EdDSA/ed25519 signature requests; configurable payload hashing is not supported by RFC 8032. */ - hashFunction: HashFunction; + hashFunction: v1HashFunction; }; -export type SignRawPayloadRequest = { +export type v1SignRawPayloadRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: SignRawPayloadIntentV2; + parameters: v1SignRawPayloadIntentV2; }; -export type SignRawPayloadResult = { +export type v1SignRawPayloadResult = { /** Component of an ECSDA signature. */ r: string; /** Component of an ECSDA signature. */ @@ -2596,71 +2600,71 @@ export type SignRawPayloadResult = { v: string; }; -export type SignRawPayloadsIntent = { +export type v1SignRawPayloadsIntent = { /** A Wallet account address, Private Key address, or Private Key identifier. */ signWith: string; /** An array of raw unsigned payloads to be signed. */ payloads: string[]; /** Encoding of the `payload` string. Turnkey uses this information to convert `payload` into bytes with the correct decoder (e.g. hex, utf8). */ - encoding: PayloadEncoding; + encoding: v1PayloadEncoding; /** Hash function to apply to payload bytes before signing. This field must be set to HASH_FUNCTION_NOT_APPLICABLE for EdDSA/ed25519 signature requests; configurable payload hashing is not supported by RFC 8032. */ - hashFunction: HashFunction; + hashFunction: v1HashFunction; }; -export type SignRawPayloadsRequest = { +export type v1SignRawPayloadsRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: SignRawPayloadsIntent; + parameters: v1SignRawPayloadsIntent; }; -export type SignRawPayloadsResult = { - signatures?: SignRawPayloadResult[]; +export type v1SignRawPayloadsResult = { + signatures?: v1SignRawPayloadResult[]; }; -export type SignTransactionIntent = { +export type v1SignTransactionIntent = { /** Unique identifier for a given Private Key. */ privateKeyId: string; /** Raw unsigned transaction to be signed by a particular Private Key. */ unsignedTransaction: string; - type: TransactionType; + type: v1TransactionType; }; -export type SignTransactionIntentV2 = { +export type v1SignTransactionIntentV2 = { /** A Wallet account address, Private Key address, or Private Key identifier. */ signWith: string; /** Raw unsigned transaction to be signed */ unsignedTransaction: string; - type: TransactionType; + type: v1TransactionType; }; -export type SignTransactionRequest = { +export type v1SignTransactionRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: SignTransactionIntentV2; + parameters: v1SignTransactionIntentV2; }; -export type SignTransactionResult = { +export type v1SignTransactionResult = { signedTransaction: string; }; -export type SimpleClientExtensionResults = { +export type v1SimpleClientExtensionResults = { appid?: boolean; appidExclude?: boolean; - credProps?: CredPropsAuthenticationExtensionsClientOutputs; + credProps?: v1CredPropsAuthenticationExtensionsClientOutputs; }; -export type SmsCustomizationParams = { +export type v1SmsCustomizationParams = { /** Template containing references to .OtpCode i.e Your OTP is {{.OtpCode}} */ template?: string; }; -export type StampLoginIntent = { +export type v1StampLoginIntent = { /** Client-side public key generated by the user, which will be conditionally added to org data based on the passkey stamp associated with this request */ publicKey: string; /** Expiration window (in seconds) indicating how long the Session is valid for. If not provided, a default of 15 minutes will be used. */ @@ -2669,23 +2673,25 @@ export type StampLoginIntent = { invalidateExisting?: boolean; }; -export type StampLoginRequest = { +export type v1StampLoginRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: StampLoginIntent; + parameters: v1StampLoginIntent; }; -export type StampLoginResult = { +export type v1StampLoginResult = { /** Signed JWT containing an expiry, public key, session type, user id, and organization id */ session: string; }; -export type TagType = "TAG_TYPE_USER" | "TAG_TYPE_PRIVATE_KEY"; +export type v1TagType = + "TAG_TYPE_USER" | + "TAG_TYPE_PRIVATE_KEY"; -export type TestRateLimitsRequest = { +export type v1TestRateLimitsRequest = { /** 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. */ organizationId: string; /** Whether or not to set a limit on this request. */ @@ -2694,25 +2700,25 @@ export type TestRateLimitsRequest = { limit: number; }; -export type TestRateLimitsResponse = any; -export type TransactionType = - | "TRANSACTION_TYPE_ETHEREUM" - | "TRANSACTION_TYPE_SOLANA" - | "TRANSACTION_TYPE_TRON"; +export type v1TestRateLimitsResponse = any; +export type v1TransactionType = + "TRANSACTION_TYPE_ETHEREUM" | + "TRANSACTION_TYPE_SOLANA" | + "TRANSACTION_TYPE_TRON"; -export type UpdateAllowedOriginsIntent = { +export type v1UpdateAllowedOriginsIntent = { /** Additional origins requests are allowed from besides Turnkey origins */ allowedOrigins: string[]; }; -export type UpdateAllowedOriginsResult = any; -export type UpdatePolicyIntent = { +export type v1UpdateAllowedOriginsResult = any; +export type v1UpdatePolicyIntent = { /** Unique identifier for a given Policy. */ policyId: string; /** Human-readable name for a Policy. */ policyName?: string; /** The instruction to DENY or ALLOW an activity (optional). */ - policyEffect?: Effect; + policyEffect?: v1Effect; /** The condition expression that triggers the Effect (optional). */ policyCondition?: string; /** The consensus expression that triggers the Effect (optional). */ @@ -2721,13 +2727,13 @@ export type UpdatePolicyIntent = { policyNotes?: string; }; -export type UpdatePolicyIntentV2 = { +export type v1UpdatePolicyIntentV2 = { /** Unique identifier for a given Policy. */ policyId: string; /** Human-readable name for a Policy. */ policyName?: string; /** The instruction to DENY or ALLOW an activity (optional). */ - policyEffect?: Effect; + policyEffect?: v1Effect; /** The condition expression that triggers the Effect (optional). */ policyCondition?: string; /** The consensus expression that triggers the Effect (optional). */ @@ -2736,26 +2742,26 @@ export type UpdatePolicyIntentV2 = { policyNotes?: string; }; -export type UpdatePolicyRequest = { +export type v1UpdatePolicyRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: UpdatePolicyIntentV2; + parameters: v1UpdatePolicyIntentV2; }; -export type UpdatePolicyResult = { +export type v1UpdatePolicyResult = { /** Unique identifier for a given Policy. */ policyId: string; }; -export type UpdatePolicyResultV2 = { +export type v1UpdatePolicyResultV2 = { /** Unique identifier for a given Policy. */ policyId: string; }; -export type UpdatePrivateKeyTagIntent = { +export type v1UpdatePrivateKeyTagIntent = { /** Unique identifier for a given Private Key Tag. */ privateKeyTagId: string; /** The new, human-readable name for the tag with the given ID. */ @@ -2766,38 +2772,38 @@ export type UpdatePrivateKeyTagIntent = { removePrivateKeyIds: string[]; }; -export type UpdatePrivateKeyTagRequest = { +export type v1UpdatePrivateKeyTagRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: UpdatePrivateKeyTagIntent; + parameters: v1UpdatePrivateKeyTagIntent; }; -export type UpdatePrivateKeyTagResult = { +export type v1UpdatePrivateKeyTagResult = { /** Unique identifier for a given Private Key Tag. */ privateKeyTagId: string; }; -export type UpdateRootQuorumIntent = { +export type v1UpdateRootQuorumIntent = { /** The threshold of unique approvals to reach quorum. */ threshold: number; /** The unique identifiers of users who comprise the quorum set. */ userIds: string[]; }; -export type UpdateRootQuorumRequest = { +export type v1UpdateRootQuorumRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: UpdateRootQuorumIntent; + parameters: v1UpdateRootQuorumIntent; }; -export type UpdateRootQuorumResult = any; -export type UpdateUserIntent = { +export type v1UpdateRootQuorumResult = any; +export type v1UpdateUserIntent = { /** Unique identifier for a given User. */ userId: string; /** Human-readable name for a User. */ @@ -2810,21 +2816,21 @@ export type UpdateUserIntent = { userPhoneNumber?: string; }; -export type UpdateUserRequest = { +export type v1UpdateUserRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: UpdateUserIntent; + parameters: v1UpdateUserIntent; }; -export type UpdateUserResult = { +export type v1UpdateUserResult = { /** A User ID. */ userId: string; }; -export type UpdateUserTagIntent = { +export type v1UpdateUserTagIntent = { /** Unique identifier for a given User Tag. */ userTagId: string; /** The new, human-readable name for the tag with the given ID. */ @@ -2835,42 +2841,42 @@ export type UpdateUserTagIntent = { removeUserIds: string[]; }; -export type UpdateUserTagRequest = { +export type v1UpdateUserTagRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: UpdateUserTagIntent; + parameters: v1UpdateUserTagIntent; }; -export type UpdateUserTagResult = { +export type v1UpdateUserTagResult = { /** Unique identifier for a given User Tag. */ userTagId: string; }; -export type UpdateWalletIntent = { +export type v1UpdateWalletIntent = { /** Unique identifier for a given Wallet. */ walletId: string; /** Human-readable name for a Wallet. */ walletName?: string; }; -export type UpdateWalletRequest = { +export type v1UpdateWalletRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: UpdateWalletIntent; + parameters: v1UpdateWalletIntent; }; -export type UpdateWalletResult = { +export type v1UpdateWalletResult = { /** A Wallet ID. */ walletId: string; }; -export type User = { +export type v1User = { /** Unique identifier for a given User. */ userId: string; /** Human-readable name for a User. */ @@ -2880,33 +2886,33 @@ export type User = { /** The user's phone number in E.164 format e.g. +13214567890 */ userPhoneNumber?: string; /** A list of Authenticator parameters. */ - authenticators: Authenticator[]; + authenticators: v1Authenticator[]; /** A list of API Key parameters. This field, if not needed, should be an empty array in your request body. */ - apiKeys: ApiKey[]; + apiKeys: v1ApiKey[]; /** A list of User Tag IDs. */ userTags: string[]; /** A list of Oauth Providers. */ - oauthProviders: OauthProvider[]; + oauthProviders: v1OauthProvider[]; createdAt: externaldatav1Timestamp; updatedAt: externaldatav1Timestamp; }; -export type UserParams = { +export type v1UserParams = { /** Human-readable name for a User. */ userName: string; /** The user's email address. */ userEmail?: string; /** The User's permissible access method(s). */ - accessType: AccessType; + accessType: v1AccessType; /** A list of API Key parameters. This field, if not needed, should be an empty array in your request body. */ apiKeys: apiApiKeyParams[]; /** A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. */ - authenticators: AuthenticatorParams[]; + authenticators: v1AuthenticatorParams[]; /** A list of User Tag IDs. This field, if not needed, should be an empty array in your request body. */ userTags: string[]; }; -export type UserParamsV2 = { +export type v1UserParamsV2 = { /** Human-readable name for a User. */ userName: string; /** The user's email address. */ @@ -2914,12 +2920,12 @@ export type UserParamsV2 = { /** A list of API Key parameters. This field, if not needed, should be an empty array in your request body. */ apiKeys: apiApiKeyParams[]; /** A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. */ - authenticators: AuthenticatorParamsV2[]; + authenticators: v1AuthenticatorParamsV2[]; /** A list of User Tag IDs. This field, if not needed, should be an empty array in your request body. */ userTags: string[]; }; -export type UserParamsV3 = { +export type v1UserParamsV3 = { /** Human-readable name for a User. */ userName: string; /** The user's email address. */ @@ -2927,16 +2933,16 @@ export type UserParamsV3 = { /** The user's phone number in E.164 format e.g. +13214567890 */ userPhoneNumber?: string; /** A list of API Key parameters. This field, if not needed, should be an empty array in your request body. */ - apiKeys: ApiKeyParamsV2[]; + apiKeys: v1ApiKeyParamsV2[]; /** A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. */ - authenticators: AuthenticatorParamsV2[]; + authenticators: v1AuthenticatorParamsV2[]; /** A list of Oauth providers. This field, if not needed, should be an empty array in your request body. */ - oauthProviders: OauthProviderParams[]; + oauthProviders: v1OauthProviderParams[]; /** A list of User Tag IDs. This field, if not needed, should be an empty array in your request body. */ userTags: string[]; }; -export type VerifyOtpIntent = { +export type v1VerifyOtpIntent = { /** ID representing the result of an init OTP activity. */ otpId: string; /** OTP sent out to a user's contact (email or SMS) */ @@ -2945,27 +2951,27 @@ export type VerifyOtpIntent = { expirationSeconds?: string; }; -export type VerifyOtpRequest = { +export type v1VerifyOtpRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ timestampMs: string; /** Unique identifier for a given Organization. */ organizationId: string; - parameters: VerifyOtpIntent; + parameters: v1VerifyOtpIntent; }; -export type VerifyOtpResult = { +export type v1VerifyOtpResult = { /** Signed JWT containing a unique id, expiry, verification type, contact. Verification status of a user is updated when the token is consumed (in OTP_LOGIN requests) */ verificationToken: string; }; -export type Vote = { +export type v1Vote = { /** Unique identifier for a given Vote object. */ id: string; /** Unique identifier for a given User. */ userId: string; /** Web and/or API user within your Organization. */ - user: User; + user: v1User; /** Unique identifier for a given Activity object. */ activityId: string; selection: string; @@ -2980,7 +2986,7 @@ export type Vote = { createdAt: externaldatav1Timestamp; }; -export type Wallet = { +export type v1Wallet = { /** Unique identifier for a given Wallet. */ walletId: string; /** Human-readable name for a Wallet. */ @@ -2993,7 +2999,7 @@ export type Wallet = { imported: boolean; }; -export type WalletAccount = { +export type v1WalletAccount = { /** Unique identifier for a given Wallet Account. */ walletAccountId: string; /** The Organization the Account belongs to. */ @@ -3001,13 +3007,13 @@ export type WalletAccount = { /** The Wallet the Account was derived from. */ walletId: string; /** Cryptographic curve used to generate the Account. */ - curve: Curve; + curve: v1Curve; /** Path format used to generate the Account. */ - pathFormat: PathFormat; + pathFormat: v1PathFormat; /** Path used to generate the Account. */ path: string; /** Address format used to generate the Account. */ - addressFormat: AddressFormat; + addressFormat: v1AddressFormat; /** Address generated using the Wallet seed and Account parameters. */ address: string; createdAt: externaldatav1Timestamp; @@ -3016,33 +3022,33 @@ export type WalletAccount = { publicKey?: string; }; -export type WalletAccountParams = { +export type v1WalletAccountParams = { /** Cryptographic curve used to generate a wallet Account. */ - curve: Curve; + curve: v1Curve; /** Path format used to generate a wallet Account. */ - pathFormat: PathFormat; + pathFormat: v1PathFormat; /** Path used to generate a wallet Account. */ path: string; /** Address format used to generate a wallet Acccount. */ - addressFormat: AddressFormat; + addressFormat: v1AddressFormat; }; -export type WalletParams = { +export type v1WalletParams = { /** Human-readable name for a Wallet. */ walletName: string; /** A list of wallet Accounts. This field, if not needed, should be an empty array in your request body. */ - accounts: WalletAccountParams[]; + accounts: v1WalletAccountParams[]; /** Length of mnemonic to generate the Wallet seed. Defaults to 12. Accepted values: 12, 15, 18, 21, 24. */ mnemonicLength?: number; }; -export type WalletResult = { +export type v1WalletResult = { walletId: string; /** A list of account addresses. */ addresses: string[]; }; -export type WebAuthnStamp = { +export type v1WebAuthnStamp = { /** A base64 url encoded Unique identifier for a given credential. */ credentialId: string; /** A base64 encoded payload containing metadata about the signing context and the challenge. */ @@ -3052,3 +3058,1754 @@ export type WebAuthnStamp = { /** The base64 url encoded signature bytes contained within the WebAuthn assertion response. */ signature: string; }; + + +// --- Latest Version Type Aliases --- +export type AcceptInvitationRequest = { + /** Unique identifier for a given Invitation object. */ + invitationId: string; + /** Unique identifier for a given User. */ + userId: string; + /** WebAuthN hardware devices that can be used to log in to the Turnkey web app. */ + authenticator: v1AuthenticatorParamsV2; +}; + +export type AcceptInvitationResult = { + /** Unique identifier for a given Invitation. */ + invitationId: string; + /** Unique identifier for a given User. */ + userId: string; +}; + +export type AccessType = v1AccessType; +export type Activity = { + /** Unique identifier for a given Activity object. */ + id: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + /** The current processing status of a specified Activity. */ + status: v1ActivityStatus; + /** Type of Activity, such as Add User, or Sign Transaction. */ + type: v1ActivityType; + /** Intent object crafted by Turnkey based on the user request, used to assess the permissibility of an action. */ + intent: v1Intent; + /** Result of the intended action. */ + result: v1Result; + /** A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. */ + votes: v1Vote[]; + /** An artifact verifying a User's action. */ + fingerprint: string; + canApprove: boolean; + canReject: boolean; + createdAt: externaldatav1Timestamp; + updatedAt: externaldatav1Timestamp; + /** Failure reason of the intended action. */ + failure?: rpcStatus; +}; + +export type ActivityResponse = { + /** An action that can that can be taken within the Turnkey infrastructure. */ + activity: v1Activity; +}; + +export type ActivityStatus = v1ActivityStatus; +export type ActivityType = v1ActivityType; +export type AddressFormat = v1AddressFormat; +export type ApiKey = { + /** A User credential that can be used to authenticate to Turnkey. */ + credential: externaldatav1Credential; + /** Unique identifier for a given API Key. */ + apiKeyId: string; + /** Human-readable name for an API Key. */ + apiKeyName: string; + createdAt: externaldatav1Timestamp; + updatedAt: externaldatav1Timestamp; + /** Optional window (in seconds) indicating how long the API Key should last. */ + expirationSeconds?: string; +}; + +export type ApiKeyCurve = v1ApiKeyCurve; +export type ApiKeyParams = { + /** Human-readable name for an API Key. */ + apiKeyName: string; + /** The public component of a cryptographic key pair used to sign messages and transactions. */ + publicKey: string; + /** The curve type to be used for processing API key signatures. */ + curveType: v1ApiKeyCurve; + /** Optional window (in seconds) indicating how long the API Key should last. */ + expirationSeconds?: string; +}; + +export type ApiOnlyUserParams = { + /** The name of the new API-only User. */ + userName: string; + /** The email address for this API-only User (optional). */ + userEmail?: string; + /** A list of tags assigned to the new API-only User. This field, if not needed, should be an empty array in your request body. */ + userTags: string[]; + /** A list of API Key parameters. This field, if not needed, should be an empty array in your request body. */ + apiKeys: apiApiKeyParams[]; +}; + +export type ApproveActivityRequest = { + /** An artifact verifying a User's action. */ + fingerprint: string; + /** Unique identifier for a given Organization. */ + organizationId?: string; +}; + +export type Attestation = { + /** The cbor encoded then base64 url encoded id of the credential. */ + credentialId: string; + /** A base64 url encoded payload containing metadata about the signing context and the challenge. */ + clientDataJson: string; + /** A base64 url encoded payload containing authenticator data and any attestation the webauthn provider chooses. */ + attestationObject: string; + /** The type of authenticator transports. */ + transports: v1AuthenticatorTransport[]; +}; + +export type Authenticator = { + /** Types of transports that may be used by an Authenticator (e.g., USB, NFC, BLE). */ + transports: v1AuthenticatorTransport[]; + attestationType: string; + /** Identifier indicating the type of the Security Key. */ + aaguid: string; + /** Unique identifier for a WebAuthn credential. */ + credentialId: string; + /** The type of Authenticator device. */ + model: string; + /** A User credential that can be used to authenticate to Turnkey. */ + credential: externaldatav1Credential; + /** Unique identifier for a given Authenticator. */ + authenticatorId: string; + /** Human-readable name for an Authenticator. */ + authenticatorName: string; + createdAt: externaldatav1Timestamp; + updatedAt: externaldatav1Timestamp; +}; + +export type AuthenticatorAttestationResponse = { + clientDataJson: string; + attestationObject: string; + transports?: v1AuthenticatorTransport[]; + authenticatorAttachment?: string; +}; + +export type AuthenticatorParams = { + /** Human-readable name for an Authenticator. */ + authenticatorName: string; + /** Challenge presented for authentication purposes. */ + challenge: string; + /** The attestation that proves custody of the authenticator and provides metadata about it. */ + attestation: v1Attestation; +}; + +export type AuthenticatorTransport = v1AuthenticatorTransport; +export type Config = { + features?: v1Feature[]; + quorum?: externaldatav1Quorum; +}; + +export type CreateApiKeysRequest = { + /** A list of API Keys. */ + apiKeys: v1ApiKeyParamsV2[]; + /** Unique identifier for a given User. */ + userId: string; +}; + +export type CreateApiKeysResult = { + /** A list of API Key IDs. */ + apiKeyIds: string[]; +}; + +export type CreateApiOnlyUsersRequest = { + /** A list of API-only Users to create. */ + apiOnlyUsers: v1ApiOnlyUserParams[]; + /** Unique identifier for a given Organization. */ + organizationId?: string; +}; + +export type CreateApiOnlyUsersResult = { + /** A list of API-only User IDs. */ + userIds: string[]; +}; + +export type CreateAuthenticatorsRequest = { + /** A list of Authenticators. */ + authenticators: v1AuthenticatorParamsV2[]; + /** Unique identifier for a given User. */ + userId: string; +}; + +export type CreateAuthenticatorsResult = { + /** A list of Authenticator IDs. */ + authenticatorIds: string[]; +}; + +export type CreateInvitationsRequest = { + /** A list of Invitations. */ + invitations: v1InvitationParams[]; + /** Unique identifier for a given Organization. */ + organizationId?: string; +}; + +export type CreateInvitationsResult = { + /** A list of Invitation IDs */ + invitationIds: string[]; +}; + +export type CreateOauthProvidersRequest = { + /** The ID of the User to add an Oauth provider to */ + userId: string; + /** A list of Oauth providers. */ + oauthProviders: v1OauthProviderParams[]; + /** Unique identifier for a given Organization. */ + organizationId?: string; +}; + +export type CreateOauthProvidersResult = { + /** A list of unique identifiers for Oauth Providers */ + providerIds: string[]; +}; + +export type CreateOrganizationRequest = { + /** Human-readable name for an Organization. */ + organizationName: string; + /** The root user's email address. */ + rootEmail: string; + /** The root user's Authenticator. */ + rootAuthenticator: v1AuthenticatorParamsV2; + /** Unique identifier for the root user object. */ + rootUserId?: string; +}; + +export type CreateOrganizationResult = { + /** Unique identifier for a given Organization. */ + organizationId: string; +}; + +export type CreatePoliciesRequest = { + /** An array of policy intents to be created. */ + policies: v1CreatePolicyIntentV3[]; + /** Unique identifier for a given Organization. */ + organizationId?: string; +}; + +export type CreatePoliciesResult = { + /** A list of unique identifiers for the created policies. */ + policyIds: string[]; +}; + +export type CreatePolicyRequest = { + /** Human-readable name for a Policy. */ + policyName: string; + /** The instruction to DENY or ALLOW an activity. */ + effect: v1Effect; + /** The condition expression that triggers the Effect */ + condition?: string; + /** The consensus expression that triggers the Effect */ + consensus?: string; + notes?: string; +}; + +export type CreatePolicyResult = { + /** Unique identifier for a given Policy. */ + policyId: string; +}; + +export type CreatePrivateKeyTagRequest = { + /** Human-readable name for a Private Key Tag. */ + privateKeyTagName: string; + /** A list of Private Key IDs. */ + privateKeyIds: string[]; + /** Unique identifier for a given Organization. */ + organizationId?: string; +}; + +export type CreatePrivateKeyTagResult = { + /** Unique identifier for a given Private Key Tag. */ + privateKeyTagId: string; + /** A list of Private Key IDs. */ + privateKeyIds: string[]; +}; + +export type CreatePrivateKeysRequest = { + /** A list of Private Keys. */ + privateKeys: v1PrivateKeyParams[]; +}; + +export type CreatePrivateKeysResult = { + /** A list of Private Key IDs and addresses. */ + privateKeys: v1PrivateKeyResult[]; +}; + +export type CreateReadOnlySessionResult = { + /** Unique identifier for a given Organization. If the request is being made by a user and their Sub-Organization ID is unknown, this can be the Parent Organization ID. However, using the Sub-Organization ID is preferred due to performance reasons. */ + organizationId: string; + /** Human-readable name for an Organization. */ + organizationName: string; + /** Unique identifier for a given User. */ + userId: string; + /** Human-readable name for a User. */ + username: string; + /** String representing a read only session */ + session: string; + /** UTC timestamp in seconds representing the expiry time for the read only session. */ + sessionExpiry: string; +}; + +export type CreateReadWriteSessionRequest = { + /** Client-side public key generated by the user, to which the read write session bundle (credentials) will be encrypted. */ + targetPublicKey: string; + /** Unique identifier for a given User. */ + userId?: string; + /** Optional human-readable name for an API Key. If none provided, default to Read Write Session - */ + apiKeyName?: string; + /** Expiration window (in seconds) indicating how long the API key is valid for. If not provided, a default of 15 minutes will be used. */ + expirationSeconds?: string; + /** Invalidate all other previously generated ReadWriteSession API keys */ + invalidateExisting?: boolean; +}; + +export type CreateReadWriteSessionResult = { + /** Unique identifier for a given Organization. If the request is being made by a user and their Sub-Organization ID is unknown, this can be the Parent Organization ID. However, using the Sub-Organization ID is preferred due to performance reasons. */ + organizationId: string; + /** Human-readable name for an Organization. */ + organizationName: string; + /** Unique identifier for a given User. */ + userId: string; + /** Human-readable name for a User. */ + username: string; + /** Unique identifier for the created API key. */ + apiKeyId: string; + /** HPKE encrypted credential bundle */ + credentialBundle: string; +}; + +export type CreateSubOrganizationRequest = { + /** Name for this sub-organization */ + subOrganizationName: string; + /** Root users to create within this sub-organization */ + rootUsers: v1RootUserParamsV4[]; + /** The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users */ + rootQuorumThreshold: number; + /** The wallet to create for the sub-organization */ + wallet?: v1WalletParams; + /** Disable email recovery for the sub-organization */ + disableEmailRecovery?: boolean; + /** Disable email auth for the sub-organization */ + disableEmailAuth?: boolean; + /** Disable OTP SMS auth for the sub-organization */ + disableSmsAuth?: boolean; + /** Disable OTP email auth for the sub-organization */ + disableOtpEmailAuth?: boolean; +}; + +export type CreateSubOrganizationResult = { + subOrganizationId: string; + wallet?: v1WalletResult; + rootUserIds?: string[]; +}; + +export type CreateUserTagRequest = { + /** Human-readable name for a User Tag. */ + userTagName: string; + /** A list of User IDs. */ + userIds: string[]; + /** Unique identifier for a given Organization. */ + organizationId?: string; +}; + +export type CreateUserTagResult = { + /** Unique identifier for a given User Tag. */ + userTagId: string; + /** A list of User IDs. */ + userIds: string[]; +}; + +export type CreateUsersRequest = { + /** A list of Users. */ + users: v1UserParamsV3[]; +}; + +export type CreateUsersResult = { + /** A list of User IDs. */ + userIds: string[]; +}; + +export type CreateWalletAccountsRequest = { + /** Unique identifier for a given Wallet. */ + walletId: string; + /** A list of wallet Accounts. */ + accounts: v1WalletAccountParams[]; + /** Unique identifier for a given Organization. */ + organizationId?: string; +}; + +export type CreateWalletAccountsResult = { + /** A list of derived addresses. */ + addresses: string[]; +}; + +export type CreateWalletRequest = { + /** Human-readable name for a Wallet. */ + walletName: string; + /** A list of wallet Accounts. This field, if not needed, should be an empty array in your request body. */ + accounts: v1WalletAccountParams[]; + /** Length of mnemonic to generate the Wallet seed. Defaults to 12. Accepted values: 12, 15, 18, 21, 24. */ + mnemonicLength?: number; + /** Unique identifier for a given Organization. */ + organizationId?: string; +}; + +export type CreateWalletResult = { + /** Unique identifier for a Wallet. */ + walletId: string; + /** A list of account addresses. */ + addresses: string[]; +}; + +export type CredPropsAuthenticationExtensionsClientOutputs = { + rk: boolean; +}; + +export type CredentialType = v1CredentialType; +export type Curve = v1Curve; +export type DeleteApiKeysRequest = { + /** Unique identifier for a given User. */ + userId: string; + /** A list of API Key IDs. */ + apiKeyIds: string[]; + /** Unique identifier for a given Organization. */ + organizationId?: string; +}; + +export type DeleteApiKeysResult = { + /** A list of API Key IDs. */ + apiKeyIds: string[]; +}; + +export type DeleteAuthenticatorsRequest = { + /** Unique identifier for a given User. */ + userId: string; + /** A list of Authenticator IDs. */ + authenticatorIds: string[]; + /** Unique identifier for a given Organization. */ + organizationId?: string; +}; + +export type DeleteAuthenticatorsResult = { + /** Unique identifier for a given Authenticator. */ + authenticatorIds: string[]; +}; + +export type DeleteInvitationRequest = { + /** Unique identifier for a given Invitation object. */ + invitationId: string; + /** Unique identifier for a given Organization. */ + organizationId?: string; +}; + +export type DeleteInvitationResult = { + /** Unique identifier for a given Invitation. */ + invitationId: string; +}; + +export type DeleteOauthProvidersRequest = { + /** The ID of the User to remove an Oauth provider from */ + userId: string; + /** Unique identifier for a given Provider. */ + providerIds: string[]; + /** Unique identifier for a given Organization. */ + organizationId?: string; +}; + +export type DeleteOauthProvidersResult = { + /** A list of unique identifiers for Oauth Providers */ + providerIds: string[]; +}; + +export type DeleteOrganizationRequest = { + /** Unique identifier for a given Organization. */ + organizationId: string; +}; + +export type DeleteOrganizationResult = { + /** Unique identifier for a given Organization. */ + organizationId: string; +}; + +export type DeletePolicyRequest = { + /** Unique identifier for a given Policy. */ + policyId: string; + /** Unique identifier for a given Organization. */ + organizationId?: string; +}; + +export type DeletePolicyResult = { + /** Unique identifier for a given Policy. */ + policyId: string; +}; + +export type DeletePrivateKeyTagsRequest = { + /** A list of Private Key Tag IDs. */ + privateKeyTagIds: string[]; + /** Unique identifier for a given Organization. */ + organizationId?: string; +}; + +export type DeletePrivateKeyTagsResult = { + /** A list of Private Key Tag IDs. */ + privateKeyTagIds: string[]; + /** A list of Private Key IDs. */ + privateKeyIds: string[]; +}; + +export type DeletePrivateKeysRequest = { + /** List of unique identifiers for private keys within an organization */ + privateKeyIds: string[]; + /** Optional parameter for deleting the private keys, even if any have not been previously exported. If they have been exported, this field is ignored. */ + deleteWithoutExport?: boolean; + /** Unique identifier for a given Organization. */ + organizationId?: string; +}; + +export type DeletePrivateKeysResult = { + /** A list of private key unique identifiers that were removed */ + privateKeyIds: string[]; +}; + +export type DeleteSubOrganizationRequest = { + /** Sub-organization deletion, by default, requires associated wallets and private keys to be exported for security reasons. Set this boolean to true to force sub-organization deletion even if some wallets or private keys within it have not been exported yet. Default: false. */ + deleteWithoutExport?: boolean; + /** Unique identifier for a given Organization. */ + organizationId?: string; +}; + +export type DeleteSubOrganizationResult = { + /** Unique identifier of the sub organization that was removed */ + subOrganizationUuid: string; +}; + +export type DeleteUserTagsRequest = { + /** A list of User Tag IDs. */ + userTagIds: string[]; + /** Unique identifier for a given Organization. */ + organizationId?: string; +}; + +export type DeleteUserTagsResult = { + /** A list of User Tag IDs. */ + userTagIds: string[]; + /** A list of User IDs. */ + userIds: string[]; +}; + +export type DeleteUsersRequest = { + /** A list of User IDs. */ + userIds: string[]; + /** Unique identifier for a given Organization. */ + organizationId?: string; +}; + +export type DeleteUsersResult = { + /** A list of User IDs. */ + userIds: string[]; +}; + +export type DeleteWalletsRequest = { + /** List of unique identifiers for wallets within an organization */ + walletIds: string[]; + /** Optional parameter for deleting the wallets, even if any have not been previously exported. If they have been exported, this field is ignored. */ + deleteWithoutExport?: boolean; + /** Unique identifier for a given Organization. */ + organizationId?: string; +}; + +export type DeleteWalletsResult = { + /** A list of wallet unique identifiers that were removed */ + walletIds: string[]; +}; + +export type DisablePrivateKeyRequest = { + /** Unique identifier for a given Private Key. */ + privateKeyId: string; +}; + +export type DisablePrivateKeyResult = { + /** Unique identifier for a given Private Key. */ + privateKeyId: string; +}; + +export type Effect = v1Effect; +export type EmailAuthRequest = { + /** Email of the authenticating user. */ + email: string; + /** Client-side public key generated by the user, to which the email auth bundle (credentials) will be encrypted. */ + targetPublicKey: string; + /** Optional human-readable name for an API Key. If none provided, default to Email Auth - */ + apiKeyName?: string; + /** Expiration window (in seconds) indicating how long the API key is valid for. If not provided, a default of 15 minutes will be used. */ + expirationSeconds?: string; + /** Optional parameters for customizing emails. If not provided, the default email will be used. */ + emailCustomization?: v1EmailCustomizationParams; + /** Invalidate all other previously generated Email Auth API keys */ + invalidateExisting?: boolean; + /** Optional custom email address from which to send the email */ + sendFromEmailAddress?: string; + /** Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications' */ + sendFromEmailSenderName?: string; + /** Optional custom email address to use as reply-to */ + replyToEmailAddress?: string; +}; + +export type EmailAuthResult = { + /** Unique identifier for the authenticating User. */ + userId: string; + /** Unique identifier for the created API key. */ + apiKeyId: string; +}; + +export type EmailCustomizationParams = { + /** The name of the application. */ + appName?: string; + /** A URL pointing to a logo in PNG format. Note this logo will be resized to fit into 340px x 124px. */ + logoUrl?: string; + /** A template for the URL to be used in a magic link button, e.g. `https://dapp.xyz/%s`. The auth bundle will be interpolated into the `%s`. */ + magicLinkTemplate?: string; + /** JSON object containing key/value pairs to be used with custom templates. */ + templateVariables?: string; + /** Unique identifier for a given Email Template. If not specified, the default is the most recent Email Template. */ + templateId?: string; +}; + +export type ExportPrivateKeyRequest = { + /** Unique identifier for a given Private Key. */ + privateKeyId: string; + /** Client-side public key generated by the user, to which the export bundle will be encrypted. */ + targetPublicKey: string; + /** Unique identifier for a given Organization. */ + organizationId?: string; +}; + +export type ExportPrivateKeyResult = { + /** Unique identifier for a given Private Key. */ + privateKeyId: string; + /** Export bundle containing a private key encrypted to the client's target public key. */ + exportBundle: string; +}; + +export type ExportWalletAccountRequest = { + /** Address to identify Wallet Account. */ + address: string; + /** Client-side public key generated by the user, to which the export bundle will be encrypted. */ + targetPublicKey: string; + /** Unique identifier for a given Organization. */ + organizationId?: string; +}; + +export type ExportWalletAccountResult = { + /** Address to identify Wallet Account. */ + address: string; + /** Export bundle containing a private key encrypted by the client's target public key. */ + exportBundle: string; +}; + +export type ExportWalletRequest = { + /** Unique identifier for a given Wallet. */ + walletId: string; + /** Client-side public key generated by the user, to which the export bundle will be encrypted. */ + targetPublicKey: string; + /** The language of the mnemonic to export. Defaults to English. */ + language?: v1MnemonicLanguage; + /** Unique identifier for a given Organization. */ + organizationId?: string; +}; + +export type ExportWalletResult = { + /** Unique identifier for a given Wallet. */ + walletId: string; + /** Export bundle containing a wallet mnemonic + optional newline passphrase encrypted by the client's target public key. */ + exportBundle: string; +}; + +export type Feature = { + name?: v1FeatureName; + value?: string; +}; + +export type FeatureName = v1FeatureName; +export type GetActivitiesResponse = { + /** A list of Activities. */ + activities: v1Activity[]; +}; + +export type GetApiKeyResponse = { + /** An API key. */ + apiKey: v1ApiKey; +}; + +export type GetApiKeysResponse = { + /** A list of API keys. */ + apiKeys: v1ApiKey[]; +}; + +export type GetAttestationDocumentResponse = { + /** Raw (CBOR-encoded) attestation document */ + attestationDocument: string; +}; + +export type GetAuthenticatorResponse = { + /** An authenticator. */ + authenticator: v1Authenticator; +}; + +export type GetAuthenticatorsResponse = { + /** A list of authenticators. */ + authenticators: v1Authenticator[]; +}; + +export type GetOauthProvidersResponse = { + /** A list of Oauth Providers */ + oauthProviders: v1OauthProvider[]; +}; + +export type GetOrganizationConfigsResponse = { + /** Organization configs including quorum settings and organization features */ + configs: v1Config; +}; + +export type GetOrganizationResponse = { + /** Object representing the full current and deleted / disabled collection of Users, Policies, Private Keys, and Invitations attributable to a particular Organization. */ + organizationData: v1OrganizationData; +}; + +export type GetPoliciesResponse = { + /** A list of Policies. */ + policies: v1Policy[]; +}; + +export type GetPolicyResponse = { + /** Object that codifies rules defining the actions that are permissible within an Organization. */ + policy: v1Policy; +}; + +export type GetPrivateKeyResponse = { + /** Cryptographic public/private key pair that can be used for cryptocurrency needs or more generalized encryption. */ + privateKey: v1PrivateKey; +}; + +export type GetPrivateKeysResponse = { + /** A list of Private Keys. */ + privateKeys: v1PrivateKey[]; +}; + +export type GetSubOrgIdsResponse = { + /** List of unique identifiers for the matching sub-organizations. */ + organizationIds: string[]; +}; + +export type GetUserResponse = { + /** Web and/or API user within your Organization. */ + user: v1User; +}; + +export type GetUsersResponse = { + /** A list of Users. */ + users: v1User[]; +}; + +export type GetVerifiedSubOrgIdsResponse = { + /** List of unique identifiers for the matching sub-organizations. */ + organizationIds: string[]; +}; + +export type GetWalletAccountResponse = { + /** The resulting Wallet Account. */ + account: v1WalletAccount; +}; + +export type GetWalletAccountsResponse = { + /** A list of Accounts generated from a Wallet that share a common seed. */ + accounts: v1WalletAccount[]; +}; + +export type GetWalletResponse = { + /** A collection of deterministically generated cryptographic public / private key pairs that share a common seed */ + wallet: v1Wallet; +}; + +export type GetWalletsResponse = { + /** A list of Wallets. */ + wallets: v1Wallet[]; +}; + +export type GetWhoamiResponse = { + /** Unique identifier for a given Organization. */ + organizationId: string; + /** Human-readable name for an Organization. */ + organizationName: string; + /** Unique identifier for a given User. */ + userId: string; + /** Human-readable name for a User. */ + username: string; +}; + +export type HashFunction = v1HashFunction; +export type ImportPrivateKeyRequest = { + /** The ID of the User importing a Private Key. */ + userId: string; + /** Human-readable name for a Private Key. */ + privateKeyName: string; + /** Bundle containing a raw private key encrypted to the enclave's target public key. */ + encryptedBundle: string; + /** Cryptographic Curve used to generate a given Private Key. */ + curve: v1Curve; + /** Cryptocurrency-specific formats for a derived address (e.g., Ethereum). */ + addressFormats: v1AddressFormat[]; + /** Unique identifier for a given Organization. */ + organizationId?: string; +}; + +export type ImportPrivateKeyResult = { + /** Unique identifier for a Private Key. */ + privateKeyId: string; + /** A list of addresses. */ + addresses: immutableactivityv1Address[]; +}; + +export type ImportWalletRequest = { + /** The ID of the User importing a Wallet. */ + userId: string; + /** Human-readable name for a Wallet. */ + walletName: string; + /** Bundle containing a wallet mnemonic encrypted to the enclave's target public key. */ + encryptedBundle: string; + /** A list of wallet Accounts. */ + accounts: v1WalletAccountParams[]; + /** Unique identifier for a given Organization. */ + organizationId?: string; +}; + +export type ImportWalletResult = { + /** Unique identifier for a Wallet. */ + walletId: string; + /** A list of account addresses. */ + addresses: string[]; +}; + +export type InitImportPrivateKeyRequest = { + /** The ID of the User importing a Private Key. */ + userId: string; + /** Unique identifier for a given Organization. */ + organizationId?: string; +}; + +export type InitImportPrivateKeyResult = { + /** Import bundle containing a public key and signature to use for importing client data. */ + importBundle: string; +}; + +export type InitImportWalletRequest = { + /** The ID of the User importing a Wallet. */ + userId: string; + /** Unique identifier for a given Organization. */ + organizationId?: string; +}; + +export type InitImportWalletResult = { + /** Import bundle containing a public key and signature to use for importing client data. */ + importBundle: string; +}; + +export type InitOtpAuthRequest = { + /** Enum to specifiy whether to send OTP via SMS or email */ + otpType: string; + /** Email or phone number to send the OTP code to */ + contact: string; + /** Optional length of the OTP code. Default = 9 */ + otpLength?: number; + /** Optional parameters for customizing emails. If not provided, the default email will be used. */ + emailCustomization?: v1EmailCustomizationParams; + /** Optional parameters for customizing SMS message. If not provided, the default sms message will be used. */ + smsCustomization?: v1SmsCustomizationParams; + /** 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. */ + userIdentifier?: string; + /** Optional custom email address from which to send the OTP email */ + sendFromEmailAddress?: string; + /** Optional flag to specify if the OTP code should be alphanumeric (Crockford’s Base32). Default = true */ + alphanumeric?: boolean; + /** Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications' */ + sendFromEmailSenderName?: string; + /** Optional custom email address to use as reply-to */ + replyToEmailAddress?: string; +}; + +export type InitOtpAuthResult = { + /** Unique identifier for an OTP authentication */ + otpId: string; +}; + +export type InitOtpRequest = { + /** Whether to send OTP via SMS or email. Possible values: OTP_TYPE_SMS, OTP_TYPE_EMAIL */ + otpType: string; + /** Email or phone number to send the OTP code to */ + contact: string; + /** Optional length of the OTP code. Default = 9 */ + otpLength?: number; + /** Optional parameters for customizing emails. If not provided, the default email will be used. */ + emailCustomization?: v1EmailCustomizationParams; + /** Optional parameters for customizing SMS message. If not provided, the default sms message will be used. */ + smsCustomization?: v1SmsCustomizationParams; + /** 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. */ + userIdentifier?: string; + /** Optional custom email address from which to send the OTP email */ + sendFromEmailAddress?: string; + /** Optional flag to specify if the OTP code should be alphanumeric (Crockford’s Base32). Default = true */ + alphanumeric?: boolean; + /** Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications' */ + sendFromEmailSenderName?: string; + /** 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) */ + expirationSeconds?: string; + /** Optional custom email address to use as reply-to */ + replyToEmailAddress?: string; + /** Unique identifier for a given Organization. */ + organizationId?: string; +}; + +export type InitOtpResult = { + /** Unique identifier for an OTP authentication */ + otpId: string; +}; + +export type InitUserEmailRecoveryRequest = { + /** Email of the user starting recovery */ + email: string; + /** Client-side public key generated by the user, to which the recovery bundle will be encrypted. */ + targetPublicKey: string; + /** Expiration window (in seconds) indicating how long the recovery credential is valid for. If not provided, a default of 15 minutes will be used. */ + expirationSeconds?: string; + /** Optional parameters for customizing emails. If not provided, the default email will be used. */ + emailCustomization?: v1EmailCustomizationParams; + /** Unique identifier for a given Organization. */ + organizationId?: string; +}; + +export type InitUserEmailRecoveryResult = { + /** Unique identifier for the user being recovered. */ + userId: string; +}; + +export type Intent = { + createOrganizationIntent?: v1CreateOrganizationIntent; + createAuthenticatorsIntent?: v1CreateAuthenticatorsIntent; + createUsersIntent?: v1CreateUsersIntent; + createPrivateKeysIntent?: v1CreatePrivateKeysIntent; + signRawPayloadIntent?: v1SignRawPayloadIntent; + createInvitationsIntent?: v1CreateInvitationsIntent; + acceptInvitationIntent?: v1AcceptInvitationIntent; + createPolicyIntent?: v1CreatePolicyIntent; + disablePrivateKeyIntent?: v1DisablePrivateKeyIntent; + deleteUsersIntent?: v1DeleteUsersIntent; + deleteAuthenticatorsIntent?: v1DeleteAuthenticatorsIntent; + deleteInvitationIntent?: v1DeleteInvitationIntent; + deleteOrganizationIntent?: v1DeleteOrganizationIntent; + deletePolicyIntent?: v1DeletePolicyIntent; + createUserTagIntent?: v1CreateUserTagIntent; + deleteUserTagsIntent?: v1DeleteUserTagsIntent; + signTransactionIntent?: v1SignTransactionIntent; + createApiKeysIntent?: v1CreateApiKeysIntent; + deleteApiKeysIntent?: v1DeleteApiKeysIntent; + approveActivityIntent?: v1ApproveActivityIntent; + rejectActivityIntent?: v1RejectActivityIntent; + createPrivateKeyTagIntent?: v1CreatePrivateKeyTagIntent; + deletePrivateKeyTagsIntent?: v1DeletePrivateKeyTagsIntent; + createPolicyIntentV2?: v1CreatePolicyIntentV2; + setPaymentMethodIntent?: billingSetPaymentMethodIntent; + activateBillingTierIntent?: billingActivateBillingTierIntent; + deletePaymentMethodIntent?: billingDeletePaymentMethodIntent; + createPolicyIntentV3?: v1CreatePolicyIntentV3; + createApiOnlyUsersIntent?: v1CreateApiOnlyUsersIntent; + updateRootQuorumIntent?: v1UpdateRootQuorumIntent; + updateUserTagIntent?: v1UpdateUserTagIntent; + updatePrivateKeyTagIntent?: v1UpdatePrivateKeyTagIntent; + createAuthenticatorsIntentV2?: v1CreateAuthenticatorsIntentV2; + acceptInvitationIntentV2?: v1AcceptInvitationIntentV2; + createOrganizationIntentV2?: v1CreateOrganizationIntentV2; + createUsersIntentV2?: v1CreateUsersIntentV2; + createSubOrganizationIntent?: v1CreateSubOrganizationIntent; + createSubOrganizationIntentV2?: v1CreateSubOrganizationIntentV2; + updateAllowedOriginsIntent?: v1UpdateAllowedOriginsIntent; + createPrivateKeysIntentV2?: v1CreatePrivateKeysIntentV2; + updateUserIntent?: v1UpdateUserIntent; + updatePolicyIntent?: v1UpdatePolicyIntent; + setPaymentMethodIntentV2?: billingSetPaymentMethodIntentV2; + createSubOrganizationIntentV3?: v1CreateSubOrganizationIntentV3; + createWalletIntent?: v1CreateWalletIntent; + createWalletAccountsIntent?: v1CreateWalletAccountsIntent; + initUserEmailRecoveryIntent?: v1InitUserEmailRecoveryIntent; + recoverUserIntent?: v1RecoverUserIntent; + setOrganizationFeatureIntent?: v1SetOrganizationFeatureIntent; + removeOrganizationFeatureIntent?: v1RemoveOrganizationFeatureIntent; + signRawPayloadIntentV2?: v1SignRawPayloadIntentV2; + signTransactionIntentV2?: v1SignTransactionIntentV2; + exportPrivateKeyIntent?: v1ExportPrivateKeyIntent; + exportWalletIntent?: v1ExportWalletIntent; + createSubOrganizationIntentV4?: v1CreateSubOrganizationIntentV4; + emailAuthIntent?: v1EmailAuthIntent; + exportWalletAccountIntent?: v1ExportWalletAccountIntent; + initImportWalletIntent?: v1InitImportWalletIntent; + importWalletIntent?: v1ImportWalletIntent; + initImportPrivateKeyIntent?: v1InitImportPrivateKeyIntent; + importPrivateKeyIntent?: v1ImportPrivateKeyIntent; + createPoliciesIntent?: v1CreatePoliciesIntent; + signRawPayloadsIntent?: v1SignRawPayloadsIntent; + createReadOnlySessionIntent?: v1CreateReadOnlySessionIntent; + createOauthProvidersIntent?: v1CreateOauthProvidersIntent; + deleteOauthProvidersIntent?: v1DeleteOauthProvidersIntent; + createSubOrganizationIntentV5?: v1CreateSubOrganizationIntentV5; + oauthIntent?: v1OauthIntent; + createApiKeysIntentV2?: v1CreateApiKeysIntentV2; + createReadWriteSessionIntent?: v1CreateReadWriteSessionIntent; + emailAuthIntentV2?: v1EmailAuthIntentV2; + createSubOrganizationIntentV6?: v1CreateSubOrganizationIntentV6; + deletePrivateKeysIntent?: v1DeletePrivateKeysIntent; + deleteWalletsIntent?: v1DeleteWalletsIntent; + createReadWriteSessionIntentV2?: v1CreateReadWriteSessionIntentV2; + deleteSubOrganizationIntent?: v1DeleteSubOrganizationIntent; + initOtpAuthIntent?: v1InitOtpAuthIntent; + otpAuthIntent?: v1OtpAuthIntent; + createSubOrganizationIntentV7?: v1CreateSubOrganizationIntentV7; + updateWalletIntent?: v1UpdateWalletIntent; + updatePolicyIntentV2?: v1UpdatePolicyIntentV2; + createUsersIntentV3?: v1CreateUsersIntentV3; + initOtpAuthIntentV2?: v1InitOtpAuthIntentV2; + initOtpIntent?: v1InitOtpIntent; + verifyOtpIntent?: v1VerifyOtpIntent; + otpLoginIntent?: v1OtpLoginIntent; + stampLoginIntent?: v1StampLoginIntent; + oauthLoginIntent?: v1OauthLoginIntent; +}; + +export type Invitation = { + /** Unique identifier for a given Invitation object. */ + invitationId: string; + /** The name of the intended Invitation recipient. */ + receiverUserName: string; + /** The email address of the intended Invitation recipient. */ + receiverEmail: string; + /** A list of tags assigned to the Invitation recipient. */ + receiverUserTags: string[]; + /** The User's permissible access method(s). */ + accessType: v1AccessType; + /** The current processing status of a specified Invitation. */ + status: v1InvitationStatus; + createdAt: externaldatav1Timestamp; + updatedAt: externaldatav1Timestamp; + /** Unique identifier for the Sender of an Invitation. */ + senderUserId: string; +}; + +export type InvitationParams = { + /** The name of the intended Invitation recipient. */ + receiverUserName: string; + /** The email address of the intended Invitation recipient. */ + receiverUserEmail: string; + /** A list of tags assigned to the Invitation recipient. This field, if not needed, should be an empty array in your request body. */ + receiverUserTags: string[]; + /** The User's permissible access method(s). */ + accessType: v1AccessType; + /** Unique identifier for the Sender of an Invitation. */ + senderUserId: string; +}; + +export type InvitationStatus = v1InvitationStatus; +export type ListPrivateKeyTagsResponse = { + /** A list of Private Key Tags */ + privateKeyTags: datav1Tag[]; +}; + +export type ListUserTagsResponse = { + /** A list of User Tags */ + userTags: datav1Tag[]; +}; + +export type MnemonicLanguage = v1MnemonicLanguage; +export type NOOPCodegenAnchorResponse = { + stamp: v1WebAuthnStamp; +}; + +export type OauthRequest = { + /** Base64 encoded OIDC token */ + oidcToken: string; + /** Client-side public key generated by the user, to which the oauth bundle (credentials) will be encrypted. */ + targetPublicKey: string; + /** Optional human-readable name for an API Key. If none provided, default to Oauth - */ + apiKeyName?: string; + /** Expiration window (in seconds) indicating how long the API key is valid for. If not provided, a default of 15 minutes will be used. */ + expirationSeconds?: string; + /** Invalidate all other previously generated Oauth API keys */ + invalidateExisting?: boolean; + /** Unique identifier for a given Organization. */ + organizationId?: string; +}; + +export type OauthLoginRequest = { + /** Base64 encoded OIDC token */ + oidcToken: string; + /** 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 */ + publicKey: string; + /** Expiration window (in seconds) indicating how long the Session is valid for. If not provided, a default of 15 minutes will be used. */ + expirationSeconds?: string; + /** Invalidate all other previously generated Login API keys */ + invalidateExisting?: boolean; + /** Unique identifier for a given Organization. */ + organizationId?: string; +}; + +export type OauthLoginResult = { + /** Signed JWT containing an expiry, public key, session type, user id, and organization id */ + session: string; +}; + +export type OauthProvider = { + /** Unique identifier for an OAuth Provider */ + providerId: string; + /** Human-readable name to identify a Provider. */ + providerName: string; + /** The issuer of the token, typically a URL indicating the authentication server, e.g https://accounts.google.com */ + issuer: string; + /** Expected audience ('aud' attribute of the signed token) which represents the app ID */ + audience: string; + /** Expected subject ('sub' attribute of the signed token) which represents the user ID */ + subject: string; + createdAt: externaldatav1Timestamp; + updatedAt: externaldatav1Timestamp; +}; + +export type OauthProviderParams = { + /** Human-readable name to identify a Provider. */ + providerName: string; + /** Base64 encoded OIDC token */ + oidcToken: string; +}; + +export type OauthResult = { + /** Unique identifier for the authenticating User. */ + userId: string; + /** Unique identifier for the created API key. */ + apiKeyId: string; + /** HPKE encrypted credential bundle */ + credentialBundle: string; +}; + +export type Operator = v1Operator; +export type OrganizationData = { + organizationId?: string; + name?: string; + users?: v1User[]; + policies?: v1Policy[]; + privateKeys?: v1PrivateKey[]; + invitations?: v1Invitation[]; + tags?: datav1Tag[]; + rootQuorum?: externaldatav1Quorum; + features?: v1Feature[]; + wallets?: v1Wallet[]; +}; + +export type OtpAuthRequest = { + /** ID representing the result of an init OTP activity. */ + otpId: string; + /** OTP sent out to a user's contact (email or SMS) */ + otpCode: string; + /** Client-side public key generated by the user, to which the OTP bundle (credentials) will be encrypted. */ + targetPublicKey: string; + /** Optional human-readable name for an API Key. If none provided, default to OTP Auth - */ + apiKeyName?: string; + /** Expiration window (in seconds) indicating how long the API key is valid for. If not provided, a default of 15 minutes will be used. */ + expirationSeconds?: string; + /** Invalidate all other previously generated OTP Auth API keys */ + invalidateExisting?: boolean; + /** Unique identifier for a given Organization. */ + organizationId?: string; +}; + +export type OtpAuthResult = { + /** Unique identifier for the authenticating User. */ + userId: string; + /** Unique identifier for the created API key. */ + apiKeyId?: string; + /** HPKE encrypted credential bundle */ + credentialBundle?: string; +}; + +export type OtpLoginRequest = { + /** Signed JWT containing a unique id, expiry, verification type, contact */ + verificationToken: string; + /** Client-side public key generated by the user, which will be conditionally added to org data based on the validity of the verification token */ + publicKey: string; + /** Expiration window (in seconds) indicating how long the Session is valid for. If not provided, a default of 15 minutes will be used. */ + expirationSeconds?: string; + /** Invalidate all other previously generated Login API keys */ + invalidateExisting?: boolean; + /** Unique identifier for a given Organization. */ + organizationId?: string; +}; + +export type OtpLoginResult = { + /** Signed JWT containing an expiry, public key, session type, user id, and organization id */ + session: string; +}; + +export type Pagination = { + /** A limit of the number of object to be returned, between 1 and 100. Defaults to 10. */ + limit?: string; + /** A pagination cursor. This is an object ID that enables you to fetch all objects before this ID. */ + before?: string; + /** A pagination cursor. This is an object ID that enables you to fetch all objects after this ID. */ + after?: string; +}; + +export type PathFormat = v1PathFormat; +export type PayloadEncoding = v1PayloadEncoding; +export type Policy = { + /** Unique identifier for a given Policy. */ + policyId: string; + /** Human-readable name for a Policy. */ + policyName: string; + /** The instruction to DENY or ALLOW a particular activity following policy selector(s). */ + effect: v1Effect; + createdAt: externaldatav1Timestamp; + updatedAt: externaldatav1Timestamp; + /** Human-readable notes added by a User to describe a particular policy. */ + notes: string; + /** A consensus expression that evalutes to true or false. */ + consensus: string; + /** A condition expression that evalutes to true or false. */ + condition: string; +}; + +export type PrivateKey = { + /** Unique identifier for a given Private Key. */ + privateKeyId: string; + /** The public component of a cryptographic key pair used to sign messages and transactions. */ + publicKey: string; + /** Human-readable name for a Private Key. */ + privateKeyName: string; + /** Cryptographic Curve used to generate a given Private Key. */ + curve: v1Curve; + /** Derived cryptocurrency addresses for a given Private Key. */ + addresses: externaldatav1Address[]; + /** A list of Private Key Tag IDs. */ + privateKeyTags: string[]; + createdAt: externaldatav1Timestamp; + updatedAt: externaldatav1Timestamp; + /** True when a given Private Key is exported, false otherwise. */ + exported: boolean; + /** True when a given Private Key is imported, false otherwise. */ + imported: boolean; +}; + +export type PrivateKeyParams = { + /** Human-readable name for a Private Key. */ + privateKeyName: string; + /** Cryptographic Curve used to generate a given Private Key. */ + curve: v1Curve; + /** A list of Private Key Tag IDs. This field, if not needed, should be an empty array in your request body. */ + privateKeyTags: string[]; + /** Cryptocurrency-specific formats for a derived address (e.g., Ethereum). */ + addressFormats: v1AddressFormat[]; +}; + +export type PrivateKeyResult = { + privateKeyId?: string; + addresses?: immutableactivityv1Address[]; +}; + +export type PublicKeyCredentialWithAttestation = { + id: string; + type: string; + rawId: string; + authenticatorAttachment?: string; + response: v1AuthenticatorAttestationResponse; + clientExtensionResults: v1SimpleClientExtensionResults; +}; + +export type RecoverUserRequest = { + /** The new authenticator to register. */ + authenticator: v1AuthenticatorParamsV2; + /** Unique identifier for the user performing recovery. */ + userId: string; + /** Unique identifier for a given Organization. */ + organizationId?: string; +}; + +export type RecoverUserResult = { + /** ID of the authenticator created. */ + authenticatorId: string[]; +}; + +export type RejectActivityRequest = { + /** An artifact verifying a User's action. */ + fingerprint: string; + /** Unique identifier for a given Organization. */ + organizationId?: string; +}; + +export type RemoveOrganizationFeatureRequest = { + /** Name of the feature to remove */ + name: v1FeatureName; + /** Unique identifier for a given Organization. */ + organizationId?: string; +}; + +export type RemoveOrganizationFeatureResult = { + /** Resulting list of organization features. */ + features: v1Feature[]; +}; + +export type Result = { + createOrganizationResult?: v1CreateOrganizationResult; + createAuthenticatorsResult?: v1CreateAuthenticatorsResult; + createUsersResult?: v1CreateUsersResult; + createPrivateKeysResult?: v1CreatePrivateKeysResult; + createInvitationsResult?: v1CreateInvitationsResult; + acceptInvitationResult?: v1AcceptInvitationResult; + signRawPayloadResult?: v1SignRawPayloadResult; + createPolicyResult?: v1CreatePolicyResult; + disablePrivateKeyResult?: v1DisablePrivateKeyResult; + deleteUsersResult?: v1DeleteUsersResult; + deleteAuthenticatorsResult?: v1DeleteAuthenticatorsResult; + deleteInvitationResult?: v1DeleteInvitationResult; + deleteOrganizationResult?: v1DeleteOrganizationResult; + deletePolicyResult?: v1DeletePolicyResult; + createUserTagResult?: v1CreateUserTagResult; + deleteUserTagsResult?: v1DeleteUserTagsResult; + signTransactionResult?: v1SignTransactionResult; + deleteApiKeysResult?: v1DeleteApiKeysResult; + createApiKeysResult?: v1CreateApiKeysResult; + createPrivateKeyTagResult?: v1CreatePrivateKeyTagResult; + deletePrivateKeyTagsResult?: v1DeletePrivateKeyTagsResult; + setPaymentMethodResult?: billingSetPaymentMethodResult; + activateBillingTierResult?: billingActivateBillingTierResult; + deletePaymentMethodResult?: billingDeletePaymentMethodResult; + createApiOnlyUsersResult?: v1CreateApiOnlyUsersResult; + updateRootQuorumResult?: v1UpdateRootQuorumResult; + updateUserTagResult?: v1UpdateUserTagResult; + updatePrivateKeyTagResult?: v1UpdatePrivateKeyTagResult; + createSubOrganizationResult?: v1CreateSubOrganizationResult; + updateAllowedOriginsResult?: v1UpdateAllowedOriginsResult; + createPrivateKeysResultV2?: v1CreatePrivateKeysResultV2; + updateUserResult?: v1UpdateUserResult; + updatePolicyResult?: v1UpdatePolicyResult; + createSubOrganizationResultV3?: v1CreateSubOrganizationResultV3; + createWalletResult?: v1CreateWalletResult; + createWalletAccountsResult?: v1CreateWalletAccountsResult; + initUserEmailRecoveryResult?: v1InitUserEmailRecoveryResult; + recoverUserResult?: v1RecoverUserResult; + setOrganizationFeatureResult?: v1SetOrganizationFeatureResult; + removeOrganizationFeatureResult?: v1RemoveOrganizationFeatureResult; + exportPrivateKeyResult?: v1ExportPrivateKeyResult; + exportWalletResult?: v1ExportWalletResult; + createSubOrganizationResultV4?: v1CreateSubOrganizationResultV4; + emailAuthResult?: v1EmailAuthResult; + exportWalletAccountResult?: v1ExportWalletAccountResult; + initImportWalletResult?: v1InitImportWalletResult; + importWalletResult?: v1ImportWalletResult; + initImportPrivateKeyResult?: v1InitImportPrivateKeyResult; + importPrivateKeyResult?: v1ImportPrivateKeyResult; + createPoliciesResult?: v1CreatePoliciesResult; + signRawPayloadsResult?: v1SignRawPayloadsResult; + createReadOnlySessionResult?: v1CreateReadOnlySessionResult; + createOauthProvidersResult?: v1CreateOauthProvidersResult; + deleteOauthProvidersResult?: v1DeleteOauthProvidersResult; + createSubOrganizationResultV5?: v1CreateSubOrganizationResultV5; + oauthResult?: v1OauthResult; + createReadWriteSessionResult?: v1CreateReadWriteSessionResult; + createSubOrganizationResultV6?: v1CreateSubOrganizationResultV6; + deletePrivateKeysResult?: v1DeletePrivateKeysResult; + deleteWalletsResult?: v1DeleteWalletsResult; + createReadWriteSessionResultV2?: v1CreateReadWriteSessionResultV2; + deleteSubOrganizationResult?: v1DeleteSubOrganizationResult; + initOtpAuthResult?: v1InitOtpAuthResult; + otpAuthResult?: v1OtpAuthResult; + createSubOrganizationResultV7?: v1CreateSubOrganizationResultV7; + updateWalletResult?: v1UpdateWalletResult; + updatePolicyResultV2?: v1UpdatePolicyResultV2; + initOtpAuthResultV2?: v1InitOtpAuthResultV2; + initOtpResult?: v1InitOtpResult; + verifyOtpResult?: v1VerifyOtpResult; + otpLoginResult?: v1OtpLoginResult; + stampLoginResult?: v1StampLoginResult; + oauthLoginResult?: v1OauthLoginResult; +}; + +export type RootUserParams = { + /** Human-readable name for a User. */ + userName: string; + /** The user's email address. */ + userEmail?: string; + /** The user's phone number in E.164 format e.g. +13214567890 */ + userPhoneNumber?: string; + /** A list of API Key parameters. This field, if not needed, should be an empty array in your request body. */ + apiKeys: v1ApiKeyParamsV2[]; + /** A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. */ + authenticators: v1AuthenticatorParamsV2[]; + /** A list of Oauth providers. This field, if not needed, should be an empty array in your request body. */ + oauthProviders: v1OauthProviderParams[]; +}; + +export type Selector = { + subject?: string; + operator?: v1Operator; + targets?: string[]; +}; + +export type SetOrganizationFeatureRequest = { + /** Name of the feature to set */ + name: v1FeatureName; + /** Optional value for the feature. Will override existing values if feature is already set. */ + value: string; + /** Unique identifier for a given Organization. */ + organizationId?: string; +}; + +export type SetOrganizationFeatureResult = { + /** Resulting list of organization features. */ + features: v1Feature[]; +}; + +export type SignRawPayloadRequest = { + /** A Wallet account address, Private Key address, or Private Key identifier. */ + signWith: string; + /** Raw unsigned payload to be signed. */ + payload: string; + /** Encoding of the `payload` string. Turnkey uses this information to convert `payload` into bytes with the correct decoder (e.g. hex, utf8). */ + encoding: v1PayloadEncoding; + /** Hash function to apply to payload bytes before signing. This field must be set to HASH_FUNCTION_NOT_APPLICABLE for EdDSA/ed25519 signature requests; configurable payload hashing is not supported by RFC 8032. */ + hashFunction: v1HashFunction; +}; + +export type SignRawPayloadResult = { + /** Component of an ECSDA signature. */ + r: string; + /** Component of an ECSDA signature. */ + s: string; + /** Component of an ECSDA signature. */ + v: string; +}; + +export type SignRawPayloadsRequest = { + /** A Wallet account address, Private Key address, or Private Key identifier. */ + signWith: string; + /** An array of raw unsigned payloads to be signed. */ + payloads: string[]; + /** Encoding of the `payload` string. Turnkey uses this information to convert `payload` into bytes with the correct decoder (e.g. hex, utf8). */ + encoding: v1PayloadEncoding; + /** Hash function to apply to payload bytes before signing. This field must be set to HASH_FUNCTION_NOT_APPLICABLE for EdDSA/ed25519 signature requests; configurable payload hashing is not supported by RFC 8032. */ + hashFunction: v1HashFunction; + /** Unique identifier for a given Organization. */ + organizationId?: string; +}; + +export type SignRawPayloadsResult = { + signatures?: v1SignRawPayloadResult[]; +}; + +export type SignTransactionRequest = { + /** A Wallet account address, Private Key address, or Private Key identifier. */ + signWith: string; + /** Raw unsigned transaction to be signed */ + unsignedTransaction: string; + type: v1TransactionType; +}; + +export type SignTransactionResult = { + signedTransaction: string; +}; + +export type SimpleClientExtensionResults = { + appid?: boolean; + appidExclude?: boolean; + credProps?: v1CredPropsAuthenticationExtensionsClientOutputs; +}; + +export type SmsCustomizationParams = { + /** Template containing references to .OtpCode i.e Your OTP is {{.OtpCode}} */ + template?: string; +}; + +export type StampLoginRequest = { + /** Client-side public key generated by the user, which will be conditionally added to org data based on the passkey stamp associated with this request */ + publicKey: string; + /** Expiration window (in seconds) indicating how long the Session is valid for. If not provided, a default of 15 minutes will be used. */ + expirationSeconds?: string; + /** Invalidate all other previously generated Login API keys */ + invalidateExisting?: boolean; + /** Unique identifier for a given Organization. */ + organizationId?: string; +}; + +export type StampLoginResult = { + /** Signed JWT containing an expiry, public key, session type, user id, and organization id */ + session: string; +}; + +export type TagType = v1TagType; +export type TestRateLimitsResponse = v1TestRateLimitsResponse; +export type TransactionType = v1TransactionType; +export type UpdateAllowedOriginsRequest = { + /** Additional origins requests are allowed from besides Turnkey origins */ + allowedOrigins: string[]; +}; + +export type UpdateAllowedOriginsResult = v1UpdateAllowedOriginsResult; +export type UpdatePolicyRequest = { + /** Unique identifier for a given Policy. */ + policyId: string; + /** Human-readable name for a Policy. */ + policyName?: string; + /** The instruction to DENY or ALLOW an activity (optional). */ + policyEffect?: v1Effect; + /** The condition expression that triggers the Effect (optional). */ + policyCondition?: string; + /** The consensus expression that triggers the Effect (optional). */ + policyConsensus?: string; + /** Accompanying notes for a Policy (optional). */ + policyNotes?: string; +}; + +export type UpdatePolicyResult = { + /** Unique identifier for a given Policy. */ + policyId: string; +}; + +export type UpdatePrivateKeyTagRequest = { + /** Unique identifier for a given Private Key Tag. */ + privateKeyTagId: string; + /** The new, human-readable name for the tag with the given ID. */ + newPrivateKeyTagName?: string; + /** A list of Private Keys IDs to add this tag to. */ + addPrivateKeyIds: string[]; + /** A list of Private Key IDs to remove this tag from. */ + removePrivateKeyIds: string[]; + /** Unique identifier for a given Organization. */ + organizationId?: string; +}; + +export type UpdatePrivateKeyTagResult = { + /** Unique identifier for a given Private Key Tag. */ + privateKeyTagId: string; +}; + +export type UpdateRootQuorumRequest = { + /** The threshold of unique approvals to reach quorum. */ + threshold: number; + /** The unique identifiers of users who comprise the quorum set. */ + userIds: string[]; + /** Unique identifier for a given Organization. */ + organizationId?: string; +}; + +export type UpdateRootQuorumResult = v1UpdateRootQuorumResult; +export type UpdateUserRequest = { + /** Unique identifier for a given User. */ + userId: string; + /** Human-readable name for a User. */ + userName?: string; + /** The user's email address. */ + userEmail?: string; + /** An updated list of User Tags to apply to this User. This field, if not needed, should be an empty array in your request body. */ + userTagIds?: string[]; + /** The user's phone number in E.164 format e.g. +13214567890 */ + userPhoneNumber?: string; + /** Unique identifier for a given Organization. */ + organizationId?: string; +}; + +export type UpdateUserResult = { + /** A User ID. */ + userId: string; +}; + +export type UpdateUserTagRequest = { + /** Unique identifier for a given User Tag. */ + userTagId: string; + /** The new, human-readable name for the tag with the given ID. */ + newUserTagName?: string; + /** A list of User IDs to add this tag to. */ + addUserIds: string[]; + /** A list of User IDs to remove this tag from. */ + removeUserIds: string[]; + /** Unique identifier for a given Organization. */ + organizationId?: string; +}; + +export type UpdateUserTagResult = { + /** Unique identifier for a given User Tag. */ + userTagId: string; +}; + +export type UpdateWalletRequest = { + /** Unique identifier for a given Wallet. */ + walletId: string; + /** Human-readable name for a Wallet. */ + walletName?: string; + /** Unique identifier for a given Organization. */ + organizationId?: string; +}; + +export type UpdateWalletResult = { + /** A Wallet ID. */ + walletId: string; +}; + +export type User = { + /** Unique identifier for a given User. */ + userId: string; + /** Human-readable name for a User. */ + userName: string; + /** The user's email address. */ + userEmail?: string; + /** The user's phone number in E.164 format e.g. +13214567890 */ + userPhoneNumber?: string; + /** A list of Authenticator parameters. */ + authenticators: v1Authenticator[]; + /** A list of API Key parameters. This field, if not needed, should be an empty array in your request body. */ + apiKeys: v1ApiKey[]; + /** A list of User Tag IDs. */ + userTags: string[]; + /** A list of Oauth Providers. */ + oauthProviders: v1OauthProvider[]; + createdAt: externaldatav1Timestamp; + updatedAt: externaldatav1Timestamp; +}; + +export type UserParams = { + /** Human-readable name for a User. */ + userName: string; + /** The user's email address. */ + userEmail?: string; + /** The user's phone number in E.164 format e.g. +13214567890 */ + userPhoneNumber?: string; + /** A list of API Key parameters. This field, if not needed, should be an empty array in your request body. */ + apiKeys: v1ApiKeyParamsV2[]; + /** A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. */ + authenticators: v1AuthenticatorParamsV2[]; + /** A list of Oauth providers. This field, if not needed, should be an empty array in your request body. */ + oauthProviders: v1OauthProviderParams[]; + /** A list of User Tag IDs. This field, if not needed, should be an empty array in your request body. */ + userTags: string[]; +}; + +export type VerifyOtpRequest = { + /** ID representing the result of an init OTP activity. */ + otpId: string; + /** OTP sent out to a user's contact (email or SMS) */ + otpCode: string; + /** Expiration window (in seconds) indicating how long the verification token is valid for. If not provided, a default of 1 hour will be used. Maximum value is 86400 seconds (24 hours) */ + expirationSeconds?: string; + /** Unique identifier for a given Organization. */ + organizationId?: string; +}; + +export type VerifyOtpResult = { + /** Signed JWT containing a unique id, expiry, verification type, contact. Verification status of a user is updated when the token is consumed (in OTP_LOGIN requests) */ + verificationToken: string; +}; + +export type Vote = { + /** Unique identifier for a given Vote object. */ + id: string; + /** Unique identifier for a given User. */ + userId: string; + /** Web and/or API user within your Organization. */ + user: v1User; + /** Unique identifier for a given Activity object. */ + activityId: string; + selection: string; + /** The raw message being signed within a Vote. */ + message: string; + /** The public component of a cryptographic key pair used to sign messages and transactions. */ + publicKey: string; + /** The signature applied to a particular vote. */ + signature: string; + /** Method used to produce a signature. */ + scheme: string; + createdAt: externaldatav1Timestamp; +}; + +export type Wallet = { + /** Unique identifier for a given Wallet. */ + walletId: string; + /** Human-readable name for a Wallet. */ + walletName: string; + createdAt: externaldatav1Timestamp; + updatedAt: externaldatav1Timestamp; + /** True when a given Wallet is exported, false otherwise. */ + exported: boolean; + /** True when a given Wallet is imported, false otherwise. */ + imported: boolean; +}; + +export type WalletAccount = { + /** Unique identifier for a given Wallet Account. */ + walletAccountId: string; + /** The Organization the Account belongs to. */ + organizationId: string; + /** The Wallet the Account was derived from. */ + walletId: string; + /** Cryptographic curve used to generate the Account. */ + curve: v1Curve; + /** Path format used to generate the Account. */ + pathFormat: v1PathFormat; + /** Path used to generate the Account. */ + path: string; + /** Address format used to generate the Account. */ + addressFormat: v1AddressFormat; + /** Address generated using the Wallet seed and Account parameters. */ + address: string; + createdAt: externaldatav1Timestamp; + updatedAt: externaldatav1Timestamp; + /** The public component of this wallet account's underlying cryptographic key pair. */ + publicKey?: string; +}; + +export type WalletAccountParams = { + /** Cryptographic curve used to generate a wallet Account. */ + curve: v1Curve; + /** Path format used to generate a wallet Account. */ + pathFormat: v1PathFormat; + /** Path used to generate a wallet Account. */ + path: string; + /** Address format used to generate a wallet Acccount. */ + addressFormat: v1AddressFormat; +}; + +export type WalletParams = { + /** Human-readable name for a Wallet. */ + walletName: string; + /** A list of wallet Accounts. This field, if not needed, should be an empty array in your request body. */ + accounts: v1WalletAccountParams[]; + /** Length of mnemonic to generate the Wallet seed. Defaults to 12. Accepted values: 12, 15, 18, 21, 24. */ + mnemonicLength?: number; +}; + +export type WalletResult = { + walletId: string; + /** A list of account addresses. */ + addresses: string[]; +}; + +export type WebAuthnStamp = { + /** A base64 url encoded Unique identifier for a given credential. */ + credentialId: string; + /** A base64 encoded payload containing metadata about the signing context and the challenge. */ + clientDataJson: string; + /** A base64 encoded payload containing metadata about the authenticator. */ + authenticatorData: string; + /** The base64 url encoded signature bytes contained within the WebAuthn assertion response. */ + signature: string; +}; + diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5d583910f..1e3667e4c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2192,6 +2192,9 @@ importers: cross-fetch: specifier: ^3.1.5 version: 3.1.5 + ethers: + specifier: ^6.10.0 + version: 6.13.5 jwt-decode: specifier: 4.0.0 version: 4.0.0 @@ -5478,14 +5481,50 @@ packages: '@rtsao/scc@1.1.0': resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} +<<<<<<< HEAD '@rushstack/eslint-patch@1.11.0': resolution: {integrity: sha512-zxnHvoMQVqewTJr/W4pKjF0bMGiKJv1WX7bSrkl46Hg0QjESbzBROWK0Wg4RphzSOS5Jiy7eFimmM3UgMrMZbQ==} +======= + /@safe-global/protocol-kit@3.0.1(typescript@5.4.3): + resolution: {integrity: sha512-7S2QCvIDw3NsErF0f8tIfiTBz32btCAkw7IYuQFPc+G7clLrvDNhDaZYSoDsa8F0EoEhn+605VA7XP//iL6AIg==} + dependencies: + '@noble/hashes': 1.4.0 + '@safe-global/safe-deployments': 1.34.0 + ethereumjs-util: 7.1.5 + ethers: 6.13.5 + semver: 7.5.4 + web3: 4.7.0(typescript@5.4.3) + web3-core: 4.3.2 + web3-utils: 4.2.1 + transitivePeerDependencies: + - bufferutil + - encoding + - typescript + - utf-8-validate + - zod + dev: false +>>>>>>> 5bfb018e (fixed type generation for request base types) '@safe-global/protocol-kit@3.1.1': resolution: {integrity: sha512-ai/N1DI6U53CsC46Do8eOyb6IkgVhjoQFhbFIh5rFSAKiuw3B0hTF7nrVRb0jw4NFlNHCcWDAER/uNH0Qy2Pkg==} +<<<<<<< HEAD '@safe-global/safe-apps-provider@0.18.6': resolution: {integrity: sha512-4LhMmjPWlIO8TTDC2AwLk44XKXaK6hfBTWyljDm0HQ6TWlOEijVWNrt2s3OCVMSxlXAcEzYfqyu1daHZooTC2Q==} +======= + /@safe-global/safe-core-sdk-types@4.0.1: + resolution: {integrity: sha512-cXW6petRWqUw1n04ZhVPgjzIL65FkAMqbPwkFAAlQ1lBxTt6xdxktLoAhgEDlqLNGibvncsNvKhxa1ib4T9MGg==} + dependencies: + '@safe-global/safe-deployments': 1.34.0 + ethers: 6.13.5 + web3-core: 4.3.2 + web3-utils: 4.2.1 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + dev: false +>>>>>>> 5bfb018e (fixed type generation for request base types) '@safe-global/safe-apps-sdk@9.1.0': resolution: {integrity: sha512-N5p/ulfnnA2Pi2M3YeWjULeWbjo7ei22JwU/IXnhoHzKq3pYCN6ynL9mJBOlvDVv892EgLPCWCOwQk/uBT2v0Q==} From 768938aba0872ba80a64a0d8e731353149bf92d4 Mon Sep 17 00:00:00 2001 From: Amir Cheikh Date: Mon, 16 Jun 2025 11:16:52 -0400 Subject: [PATCH 010/184] Small fixes for mismatched orgid --- examples/with-sdk-js/src/app/layout.tsx | 4 +-- examples/with-sdk-js/src/app/page.tsx | 24 +++++++++++--- packages/sdk-js/scripts/codegen.js | 6 ++-- packages/sdk-js/src/__clients__/core.ts | 32 ++++++++++++------- .../src/__generated__/sdk-client-base.ts | 6 ++-- .../sdk-js/src/__stampers__/passkey/base.ts | 2 +- packages/sdk-js/src/__types__/base.ts | 21 ++++++------ 7 files changed, 58 insertions(+), 37 deletions(-) diff --git a/examples/with-sdk-js/src/app/layout.tsx b/examples/with-sdk-js/src/app/layout.tsx index c77d1584d..3a32c39eb 100644 --- a/examples/with-sdk-js/src/app/layout.tsx +++ b/examples/with-sdk-js/src/app/layout.tsx @@ -19,9 +19,7 @@ function RootLayout({ children }: RootLayoutProps) { A monumental leap - - {children} - + {children} ); } diff --git a/examples/with-sdk-js/src/app/page.tsx b/examples/with-sdk-js/src/app/page.tsx index 1b3448156..d8091176d 100644 --- a/examples/with-sdk-js/src/app/page.tsx +++ b/examples/with-sdk-js/src/app/page.tsx @@ -39,9 +39,14 @@ export default function AuthPage() { await client?.createPasskey({}); }; - const logInWithPasskey = async () => { - await client?.loginWithPasskey({}); + const logInWithPasskey1 = async () => { + await client?.loginWithPasskey({ sessionKey: "session-1" }); }; + + const logInWithPasskey2 = async () => { + await client?.loginWithPasskey({ sessionKey: "session-2" }); + }; + const indexedDB = async () => { const resp = await client?.httpClient.getWhoami({}); console.log("Response from getWhoami:", resp); @@ -102,7 +107,7 @@ export default function AuthPage() { Create Passkey + {client?.storageManager?.getActiveSession() ? ( - - {client?.storageManager?.getActiveSession() ? () : null} - + + {client?.storageManager?.getActiveSession() ? ( + + ) : null} ); } diff --git a/packages/sdk-js/src/__clients__/core.ts b/packages/sdk-js/src/__clients__/core.ts index 64df50d34..ea2c935f4 100644 --- a/packages/sdk-js/src/__clients__/core.ts +++ b/packages/sdk-js/src/__clients__/core.ts @@ -1,33 +1,19 @@ import { TurnkeySDKClientBase } from "../__generated__/sdk-client-base"; import { GetWalletAccountsResponse, - GetWalletsResponse, SessionType, - SignRawPayloadIntent, - SignRawPayloadIntentV2, - SignRawPayloadRequest, SignRawPayloadResult, - Wallet, + User, WalletAccount, } from "@turnkey/sdk-types"; import { - LoginWithPasskeyParams, DEFAULT_SESSION_EXPIRATION_IN_SECONDS, - Passkey, StamperType, - CreatePasskeyParams, - ActivityResponse, + TUser, TWallet, TurnkeySDKClientConfig, } from "@types"; // AHHHH, SDK-TYPES -import { - base64UrlEncode, - generateRandomBuffer, - getMessageHashAndEncodingType, - isReactNative, - isWeb, -} from "@utils"; -import { getWebAuthnAttestation } from "@turnkey/http"; +import { getMessageHashAndEncodingType, isReactNative, isWeb } from "@utils"; import { createStorageManager, StorageBase, @@ -35,15 +21,14 @@ import { } from "../__storage__/base"; import { CrossPlatformApiKeyStamper } from "../__stampers__/api/base"; import { CrossPlatformPasskeyStamper } from "../__stampers__/passkey/base"; -import { get } from "http"; export class TurnkeyClient { config: TurnkeySDKClientConfig; // Type TBD httpClient!: TurnkeySDKClientBase; // public session?: Session | undefined; // TODO (Amir): Define session type. Or not maybe??? - // public user?: any; // TODO (Amir): Define user type - // public wallets?: any; // TODO (Amir): Define wallets type + public user?: TUser; // TO IMPLEMENT: fetchUser + public wallets?: TWallet[]; apiKeyStamper?: CrossPlatformApiKeyStamper | undefined; // TODO (Amir): TEMPORARILY PUBLIC, MAKE PRIVATE LATER private passkeyStamper?: CrossPlatformPasskeyStamper | undefined; @@ -54,7 +39,7 @@ export class TurnkeyClient { // Users can pass in their own stampers, or we will create them. Should we remove this? apiKeyStamper?: CrossPlatformApiKeyStamper, - passkeyStamper?: CrossPlatformPasskeyStamper + passkeyStamper?: CrossPlatformPasskeyStamper, ) { this.config = config; @@ -76,7 +61,7 @@ export class TurnkeyClient { if (this.config.passkeyConfig) { this.passkeyStamper = new CrossPlatformPasskeyStamper( - this.config.passkeyConfig + this.config.passkeyConfig, ); await this.passkeyStamper.init(); } @@ -90,7 +75,10 @@ export class TurnkeyClient { }); } - createPasskey = async (params: CreatePasskeyParams): Promise => { + createPasskey = async (params: { + name?: string; + displayName?: string; + }): Promise => { try { const { name = "A Passkey", displayName = "A Passkey" } = params; if (isWeb()) { @@ -113,7 +101,12 @@ export class TurnkeyClient { } }; - loginWithPasskey = async (params: LoginWithPasskeyParams): Promise => { + loginWithPasskey = async (params: { + sessionType?: SessionType; + expirationSeconds?: string | undefined; + publicKey?: string; + sessionKey?: string | undefined; + }): Promise => { let generatedKeyPair = null; try { generatedKeyPair = await this.apiKeyStamper?.createKeyPair(); @@ -131,7 +124,7 @@ export class TurnkeyClient { await this.storageManager.storeSession( readOnlySessionResult.session, - sessionKey + sessionKey, ); // Key pair was successfully used, set to null to prevent cleanup generatedKeyPair = null; @@ -140,7 +133,7 @@ export class TurnkeyClient { } else if (sessionType === SessionType.READ_WRITE) { if (!publicKey) { throw new Error( - "You must provide a publicKey to create a passkey read write session." + "You must provide a publicKey to create a passkey read write session.", ); } const sessionResponse = await this.httpClient.stampLogin( @@ -149,7 +142,7 @@ export class TurnkeyClient { expirationSeconds, organizationId: this.config.organizationId, }, - StamperType.Passkey + StamperType.Passkey, ); // TODO (Amir): This should be done in a helper or something. It's very strange that we have to delete the key pair here @@ -161,7 +154,7 @@ export class TurnkeyClient { await this.storageManager.storeSession( sessionResponse.session, - sessionKey + sessionKey, ); // Key pair was successfully used, set to null to prevent cleanup generatedKeyPair = null; @@ -177,18 +170,18 @@ export class TurnkeyClient { await this.apiKeyStamper?.deleteKeyPair(generatedKeyPair); } catch (cleanupError) { throw new Error( - `Failed to clean up generated key pair: ${cleanupError}` + `Failed to clean up generated key pair: ${cleanupError}`, ); } } } }; - getWallets = async ({ - stamperType, - }: { + fetchWallets = async (params: { stamperType?: StamperType; + saveInClient?: boolean; }): Promise => { + const { stamperType, saveInClient = true } = params; const session = await this.storageManager.getActiveSession(); if (!session) { throw new Error("No active session found. Please log in first."); @@ -196,7 +189,7 @@ export class TurnkeyClient { try { const res = await this.httpClient.getWallets( { organizationId: session.organizationId }, - stamperType + stamperType, ); if (!res || !res.wallets) { @@ -206,7 +199,7 @@ export class TurnkeyClient { const wallets: TWallet[] = res.wallets; let i = 0; for (const wallet of wallets) { - const walletAccounts = await this.getWalletAccounts({ + const walletAccounts = await this.fetchWalletAccounts({ walletId: wallet.walletId, }); @@ -217,19 +210,20 @@ export class TurnkeyClient { i++; } + if (saveInClient) { + this.wallets = wallets; + } return wallets; } catch (error) { throw new Error(`Failed to fetch wallets: ${error}`); } }; - getWalletAccounts = async ({ - walletId, - stamperType, - }: { + fetchWalletAccounts = async (params: { walletId: string; stamperType?: StamperType; }): Promise => { + const { walletId, stamperType } = params; const session = await this.storageManager.getActiveSession(); if (!session) { throw new Error("No active session found. Please log in first."); @@ -242,22 +236,19 @@ export class TurnkeyClient { try { return await this.httpClient.getWalletAccounts( { walletId, organizationId: session.organizationId }, - stamperType + stamperType, ); } catch (error) { throw new Error(`Failed to fetch wallet accounts: ${error}`); } }; - signMessage = async ({ - message, - wallet, - stampWith, - }: { + signMessage = async (params: { message: string; wallet?: WalletAccount; stampWith?: StamperType; }): Promise => { + const { message, wallet, stampWith } = params; if (!wallet) { throw new Error("A wallet account must be provided for signing"); } @@ -268,7 +259,7 @@ export class TurnkeyClient { // Get the proper encoding and hash function for the address format const { hashFunction, payloadEncoding } = getMessageHashAndEncodingType( - wallet.addressFormat + wallet.addressFormat, ); const response = await this.httpClient.signRawPayload( @@ -278,7 +269,7 @@ export class TurnkeyClient { encoding: payloadEncoding, hashFunction, }, - stampWith + stampWith, ); if (!response.activity.failure) { @@ -289,3 +280,5 @@ export class TurnkeyClient { .signRawPayloadResult as SignRawPayloadResult; }; } + +// TO IMPLEMENT: fetchUser diff --git a/packages/sdk-js/src/__generated__/sdk-client-base.ts b/packages/sdk-js/src/__generated__/sdk-client-base.ts index 24dc09b24..baae80407 100644 --- a/packages/sdk-js/src/__generated__/sdk-client-base.ts +++ b/packages/sdk-js/src/__generated__/sdk-client-base.ts @@ -54,7 +54,7 @@ export class TurnkeySDKClientBase { if (!stampWith) return this.apiKeyStamper || this.passkeyStamper; switch (stampWith) { - case StamperType.apiKey: + case StamperType.ApiKey: return this.apiKeyStamper; case StamperType.Passkey: return this.passkeyStamper; diff --git a/packages/sdk-js/src/__storage__/web/storage.ts b/packages/sdk-js/src/__storage__/web/storage.ts index 8211f0b24..026f8fcf6 100644 --- a/packages/sdk-js/src/__storage__/web/storage.ts +++ b/packages/sdk-js/src/__storage__/web/storage.ts @@ -92,5 +92,5 @@ export class WebStorageManager implements StorageBase { for (const wallet of wallets) { browserStorage.setItem(wallet.walletId, JSON.stringify(wallet)); } - } + }; } diff --git a/packages/sdk-js/src/__types__/base.ts b/packages/sdk-js/src/__types__/base.ts index eb81e9555..ec706b353 100644 --- a/packages/sdk-js/src/__types__/base.ts +++ b/packages/sdk-js/src/__types__/base.ts @@ -2,7 +2,12 @@ import type { TActivityId, TActivityStatus } from "@turnkey/http"; import type { WalletStamper } from "@turnkey/wallet-stamper"; import type { WebauthnStamper } from "@turnkey/webauthn-stamper"; import type { IndexedDbStamper } from "@turnkey/indexed-db-stamper"; -import type { SessionType, Wallet, WalletAccount } from "@turnkey/sdk-types"; +import type { + SessionType, + User, + Wallet, + WalletAccount, +} from "@turnkey/sdk-types"; import { StorageBase } from "../__storage__/base"; import { TPasskeyStamperConfig } from "../__stampers__/passkey/base"; @@ -143,12 +148,6 @@ export interface PasskeyClientParams { userVerification?: UserVerificationRequirement; allowCredentials?: PublicKeyCredentialDescriptor[]; } - -export interface CreatePasskeyParams { - name?: string; - displayName?: string; -} - export interface RefreshSessionParams { sessionType: SessionType; expirationSeconds?: string | undefined; @@ -160,26 +159,17 @@ export interface LoginWithBundleParams { expirationSeconds?: string; } -export interface LoginWithPasskeyParams { - sessionType?: SessionType; - expirationSeconds?: string | undefined; - publicKey?: string; - sessionKey?: string | undefined; -} - export interface LoginWithWalletParams { sessionType: SessionType; expirationSeconds?: string | undefined; publicKey?: string; } +export type TUser = User; // TODO (Amir): I dunno if we need this. We may want to add more stuff to the user type in the future, so let's keep it for now since + export type TWallet = Wallet & { accounts?: WalletAccount[] | undefined; -} - -// export interface TurnkeyWalletClientConfig extends SDKClientConfigWithStamper { -// wallet: WalletInterface; -// } +}; /** * The Client used to authenticate the user. @@ -191,6 +181,6 @@ export enum AuthClient { } export enum StamperType { - apiKey = "api-key", + ApiKey = "api-key", Passkey = "passkey", -} \ No newline at end of file +} diff --git a/packages/sdk-js/src/utils.ts b/packages/sdk-js/src/utils.ts index 7b528c57e..45742cea8 100644 --- a/packages/sdk-js/src/utils.ts +++ b/packages/sdk-js/src/utils.ts @@ -1,51 +1,168 @@ import { Buffer } from "buffer"; +import type { + AddressFormat, + HashFunction, + PayloadEncoding, + Session, +} from "@turnkey/sdk-types"; + type AddressFormatConfig = { encoding: "PAYLOAD_ENCODING_HEXADECIMAL" | "PAYLOAD_ENCODING_TEXT_UTF8"; - hashFunction: "HASH_FUNCTION_NOT_APPLICABLE" | "HASH_FUNCTION_NO_OP" | "HASH_FUNCTION_SHA256" | "HASH_FUNCTION_KECCAK256"; + hashFunction: + | "HASH_FUNCTION_NOT_APPLICABLE" + | "HASH_FUNCTION_NO_OP" + | "HASH_FUNCTION_SHA256" + | "HASH_FUNCTION_KECCAK256"; }; const addressFormatConfig: Record = { - ADDRESS_FORMAT_UNCOMPRESSED: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, - ADDRESS_FORMAT_COMPRESSED: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, - ADDRESS_FORMAT_ETHEREUM: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_KECCAK256" }, - ADDRESS_FORMAT_SOLANA: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_NOT_APPLICABLE" }, - ADDRESS_FORMAT_COSMOS: { encoding: "PAYLOAD_ENCODING_TEXT_UTF8", hashFunction: "HASH_FUNCTION_SHA256" }, - ADDRESS_FORMAT_TRON: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, - ADDRESS_FORMAT_SUI: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, - ADDRESS_FORMAT_APTOS: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_NOT_APPLICABLE" }, - ADDRESS_FORMAT_BITCOIN_MAINNET_P2PKH: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, - ADDRESS_FORMAT_BITCOIN_MAINNET_P2SH: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, - ADDRESS_FORMAT_BITCOIN_MAINNET_P2WPKH: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, - ADDRESS_FORMAT_BITCOIN_MAINNET_P2WSH: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, - ADDRESS_FORMAT_BITCOIN_MAINNET_P2TR: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, - ADDRESS_FORMAT_BITCOIN_TESTNET_P2PKH: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, - ADDRESS_FORMAT_BITCOIN_TESTNET_P2SH: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, - ADDRESS_FORMAT_BITCOIN_TESTNET_P2WPKH: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, - ADDRESS_FORMAT_BITCOIN_TESTNET_P2WSH: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, - ADDRESS_FORMAT_BITCOIN_TESTNET_P2TR: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, - ADDRESS_FORMAT_BITCOIN_SIGNET_P2PKH: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, - ADDRESS_FORMAT_BITCOIN_SIGNET_P2SH: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, - ADDRESS_FORMAT_BITCOIN_SIGNET_P2WPKH: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, - ADDRESS_FORMAT_BITCOIN_SIGNET_P2WSH: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, - ADDRESS_FORMAT_BITCOIN_SIGNET_P2TR: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, - ADDRESS_FORMAT_BITCOIN_REGTEST_P2PKH: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, - ADDRESS_FORMAT_BITCOIN_REGTEST_P2SH: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, - ADDRESS_FORMAT_BITCOIN_REGTEST_P2WPKH: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, - ADDRESS_FORMAT_BITCOIN_REGTEST_P2WSH: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, - ADDRESS_FORMAT_BITCOIN_REGTEST_P2TR: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, - ADDRESS_FORMAT_SEI: { encoding: "PAYLOAD_ENCODING_TEXT_UTF8", hashFunction: "HASH_FUNCTION_SHA256" }, - ADDRESS_FORMAT_XLM: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, - ADDRESS_FORMAT_DOGE_MAINNET: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, - ADDRESS_FORMAT_DOGE_TESTNET: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, - ADDRESS_FORMAT_TON_V3R2: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, - ADDRESS_FORMAT_TON_V4R2: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, - ADDRESS_FORMAT_TON_V5R1: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, - ADDRESS_FORMAT_XRP: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256" }, + ADDRESS_FORMAT_UNCOMPRESSED: { + encoding: "PAYLOAD_ENCODING_HEXADECIMAL", + hashFunction: "HASH_FUNCTION_SHA256", + }, + ADDRESS_FORMAT_COMPRESSED: { + encoding: "PAYLOAD_ENCODING_HEXADECIMAL", + hashFunction: "HASH_FUNCTION_SHA256", + }, + ADDRESS_FORMAT_ETHEREUM: { + encoding: "PAYLOAD_ENCODING_HEXADECIMAL", + hashFunction: "HASH_FUNCTION_KECCAK256", + }, + ADDRESS_FORMAT_SOLANA: { + encoding: "PAYLOAD_ENCODING_HEXADECIMAL", + hashFunction: "HASH_FUNCTION_NOT_APPLICABLE", + }, + ADDRESS_FORMAT_COSMOS: { + encoding: "PAYLOAD_ENCODING_TEXT_UTF8", + hashFunction: "HASH_FUNCTION_SHA256", + }, + ADDRESS_FORMAT_TRON: { + encoding: "PAYLOAD_ENCODING_HEXADECIMAL", + hashFunction: "HASH_FUNCTION_SHA256", + }, + ADDRESS_FORMAT_SUI: { + encoding: "PAYLOAD_ENCODING_HEXADECIMAL", + hashFunction: "HASH_FUNCTION_SHA256", + }, + ADDRESS_FORMAT_APTOS: { + encoding: "PAYLOAD_ENCODING_HEXADECIMAL", + hashFunction: "HASH_FUNCTION_NOT_APPLICABLE", + }, + ADDRESS_FORMAT_BITCOIN_MAINNET_P2PKH: { + encoding: "PAYLOAD_ENCODING_HEXADECIMAL", + hashFunction: "HASH_FUNCTION_SHA256", + }, + ADDRESS_FORMAT_BITCOIN_MAINNET_P2SH: { + encoding: "PAYLOAD_ENCODING_HEXADECIMAL", + hashFunction: "HASH_FUNCTION_SHA256", + }, + ADDRESS_FORMAT_BITCOIN_MAINNET_P2WPKH: { + encoding: "PAYLOAD_ENCODING_HEXADECIMAL", + hashFunction: "HASH_FUNCTION_SHA256", + }, + ADDRESS_FORMAT_BITCOIN_MAINNET_P2WSH: { + encoding: "PAYLOAD_ENCODING_HEXADECIMAL", + hashFunction: "HASH_FUNCTION_SHA256", + }, + ADDRESS_FORMAT_BITCOIN_MAINNET_P2TR: { + encoding: "PAYLOAD_ENCODING_HEXADECIMAL", + hashFunction: "HASH_FUNCTION_SHA256", + }, + ADDRESS_FORMAT_BITCOIN_TESTNET_P2PKH: { + encoding: "PAYLOAD_ENCODING_HEXADECIMAL", + hashFunction: "HASH_FUNCTION_SHA256", + }, + ADDRESS_FORMAT_BITCOIN_TESTNET_P2SH: { + encoding: "PAYLOAD_ENCODING_HEXADECIMAL", + hashFunction: "HASH_FUNCTION_SHA256", + }, + ADDRESS_FORMAT_BITCOIN_TESTNET_P2WPKH: { + encoding: "PAYLOAD_ENCODING_HEXADECIMAL", + hashFunction: "HASH_FUNCTION_SHA256", + }, + ADDRESS_FORMAT_BITCOIN_TESTNET_P2WSH: { + encoding: "PAYLOAD_ENCODING_HEXADECIMAL", + hashFunction: "HASH_FUNCTION_SHA256", + }, + ADDRESS_FORMAT_BITCOIN_TESTNET_P2TR: { + encoding: "PAYLOAD_ENCODING_HEXADECIMAL", + hashFunction: "HASH_FUNCTION_SHA256", + }, + ADDRESS_FORMAT_BITCOIN_SIGNET_P2PKH: { + encoding: "PAYLOAD_ENCODING_HEXADECIMAL", + hashFunction: "HASH_FUNCTION_SHA256", + }, + ADDRESS_FORMAT_BITCOIN_SIGNET_P2SH: { + encoding: "PAYLOAD_ENCODING_HEXADECIMAL", + hashFunction: "HASH_FUNCTION_SHA256", + }, + ADDRESS_FORMAT_BITCOIN_SIGNET_P2WPKH: { + encoding: "PAYLOAD_ENCODING_HEXADECIMAL", + hashFunction: "HASH_FUNCTION_SHA256", + }, + ADDRESS_FORMAT_BITCOIN_SIGNET_P2WSH: { + encoding: "PAYLOAD_ENCODING_HEXADECIMAL", + hashFunction: "HASH_FUNCTION_SHA256", + }, + ADDRESS_FORMAT_BITCOIN_SIGNET_P2TR: { + encoding: "PAYLOAD_ENCODING_HEXADECIMAL", + hashFunction: "HASH_FUNCTION_SHA256", + }, + ADDRESS_FORMAT_BITCOIN_REGTEST_P2PKH: { + encoding: "PAYLOAD_ENCODING_HEXADECIMAL", + hashFunction: "HASH_FUNCTION_SHA256", + }, + ADDRESS_FORMAT_BITCOIN_REGTEST_P2SH: { + encoding: "PAYLOAD_ENCODING_HEXADECIMAL", + hashFunction: "HASH_FUNCTION_SHA256", + }, + ADDRESS_FORMAT_BITCOIN_REGTEST_P2WPKH: { + encoding: "PAYLOAD_ENCODING_HEXADECIMAL", + hashFunction: "HASH_FUNCTION_SHA256", + }, + ADDRESS_FORMAT_BITCOIN_REGTEST_P2WSH: { + encoding: "PAYLOAD_ENCODING_HEXADECIMAL", + hashFunction: "HASH_FUNCTION_SHA256", + }, + ADDRESS_FORMAT_BITCOIN_REGTEST_P2TR: { + encoding: "PAYLOAD_ENCODING_HEXADECIMAL", + hashFunction: "HASH_FUNCTION_SHA256", + }, + ADDRESS_FORMAT_SEI: { + encoding: "PAYLOAD_ENCODING_TEXT_UTF8", + hashFunction: "HASH_FUNCTION_SHA256", + }, + ADDRESS_FORMAT_XLM: { + encoding: "PAYLOAD_ENCODING_HEXADECIMAL", + hashFunction: "HASH_FUNCTION_SHA256", + }, + ADDRESS_FORMAT_DOGE_MAINNET: { + encoding: "PAYLOAD_ENCODING_HEXADECIMAL", + hashFunction: "HASH_FUNCTION_SHA256", + }, + ADDRESS_FORMAT_DOGE_TESTNET: { + encoding: "PAYLOAD_ENCODING_HEXADECIMAL", + hashFunction: "HASH_FUNCTION_SHA256", + }, + ADDRESS_FORMAT_TON_V3R2: { + encoding: "PAYLOAD_ENCODING_HEXADECIMAL", + hashFunction: "HASH_FUNCTION_SHA256", + }, + ADDRESS_FORMAT_TON_V4R2: { + encoding: "PAYLOAD_ENCODING_HEXADECIMAL", + hashFunction: "HASH_FUNCTION_SHA256", + }, + ADDRESS_FORMAT_TON_V5R1: { + encoding: "PAYLOAD_ENCODING_HEXADECIMAL", + hashFunction: "HASH_FUNCTION_SHA256", + }, + ADDRESS_FORMAT_XRP: { + encoding: "PAYLOAD_ENCODING_HEXADECIMAL", + hashFunction: "HASH_FUNCTION_SHA256", + }, }; -import type { AddressFormat, HashFunction, PayloadEncoding, Session } from "@turnkey/sdk-types"; - export const isReactNative = (): boolean => { return ( typeof navigator !== "undefined" && navigator.product === "ReactNative" @@ -114,7 +231,7 @@ export function parseSession(token: string | Session): Session { }; } -export function getMessageHashAndEncodingType (addressFormat: AddressFormat): { +export function getMessageHashAndEncodingType(addressFormat: AddressFormat): { hashFunction: HashFunction; payloadEncoding: PayloadEncoding; } { diff --git a/packages/sdk-types/scripts/codegen.js b/packages/sdk-types/scripts/codegen.js index 060adcb55..11f8a01c5 100644 --- a/packages/sdk-types/scripts/codegen.js +++ b/packages/sdk-types/scripts/codegen.js @@ -4,11 +4,11 @@ const path = require("path"); // Paths const swaggerPath = path.resolve( __dirname, - "../src/__inputs__/public_api.swagger.json" + "../src/__inputs__/public_api.swagger.json", ); const typesPath = path.resolve( __dirname, - "../src/__inputs__/public_api.types.ts" + "../src/__inputs__/public_api.types.ts", ); const outputPath = path.resolve(__dirname, "../src/__generated__/types.ts"); @@ -134,7 +134,7 @@ function buildLatestVersionMap(definitions) { // Remove REQUEST/RESPONSE/RESULT/INTENT suffix for activityTypeKey const activityBase = baseName.replace( /(Request|Response|Result|Intent)$/, - "" + "", ); const activityTypeKey = `ACTIVITY_TYPE_${activityBase.replace(/([a-z])([A-Z])/g, "$1_$2").toUpperCase()}`; const mappedVersion = VERSIONED_ACTIVITY_TYPES[activityTypeKey]; @@ -264,20 +264,23 @@ function main() { // Check all Request types for organizationId, if present modify their respective Intent types and add optional organizationId for (const [baseName, latestVersionName] of Object.entries( - latestVersionMap + latestVersionMap, )) { const def = swagger.definitions[latestVersionName]; if (def && def.type === "object" && def.properties) { // If the baseName ends with "Request", check for organizationId - console.log(`Checking ${baseName} for organizationId...`); + console.log(`Checking ${baseName} for organizationId...`); if (baseName.endsWith("Request") && def.properties.organizationId) { // Modify the corresponding Intent type to make organizationId optional const intentTypeName = latestVersionName.replace(/Request$/, "Intent"); console.log( - `Modifying Intent type ${intentTypeName} to make organizationId optional` + `Modifying Intent type ${intentTypeName} to make organizationId optional`, ); - if (swagger.definitions[intentTypeName] && swagger.definitions[intentTypeName].properties) { + if ( + swagger.definitions[intentTypeName] && + swagger.definitions[intentTypeName].properties + ) { if (swagger.definitions[intentTypeName]?.organizationId) { swagger.definitions[intentTypeName].organizationId = { ...swagger.definitions[intentTypeName]?.properties.organizationId, @@ -304,12 +307,12 @@ function main() { // Then generate the abstracted types that reference the correct versioned types output += "\n// --- Latest Version Type Aliases ---\n"; for (const [baseName, latestVersionName] of Object.entries( - latestVersionMap + latestVersionMap, )) { const def = swagger.definitions[latestVersionName]; if (/(.+)Request$/.test(baseName)) { - continue; + continue; } // If baseName ends with "Intent" and has characters before "Intent", also emit a corresponding Request type diff --git a/packages/sdk-types/src/__generated__/types.ts b/packages/sdk-types/src/__generated__/types.ts index 0cd5294ac..4aac801fc 100644 --- a/packages/sdk-types/src/__generated__/types.ts +++ b/packages/sdk-types/src/__generated__/types.ts @@ -138,9 +138,9 @@ export type v1AcceptInvitationResult = { }; export type v1AccessType = - "ACCESS_TYPE_WEB" | - "ACCESS_TYPE_API" | - "ACCESS_TYPE_ALL"; + | "ACCESS_TYPE_WEB" + | "ACCESS_TYPE_API" + | "ACCESS_TYPE_ALL"; export type v1Activity = { /** Unique identifier for a given Activity object. */ @@ -173,140 +173,140 @@ export type v1ActivityResponse = { }; export type v1ActivityStatus = - "ACTIVITY_STATUS_CREATED" | - "ACTIVITY_STATUS_PENDING" | - "ACTIVITY_STATUS_COMPLETED" | - "ACTIVITY_STATUS_FAILED" | - "ACTIVITY_STATUS_CONSENSUS_NEEDED" | - "ACTIVITY_STATUS_REJECTED"; + | "ACTIVITY_STATUS_CREATED" + | "ACTIVITY_STATUS_PENDING" + | "ACTIVITY_STATUS_COMPLETED" + | "ACTIVITY_STATUS_FAILED" + | "ACTIVITY_STATUS_CONSENSUS_NEEDED" + | "ACTIVITY_STATUS_REJECTED"; export type v1ActivityType = - "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_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"; export type v1AddressFormat = - "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_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"; export type v1ApiKey = { /** A User credential that can be used to authenticate to Turnkey. */ @@ -322,9 +322,9 @@ export type v1ApiKey = { }; export type v1ApiKeyCurve = - "API_KEY_CURVE_P256" | - "API_KEY_CURVE_SECP256K1" | - "API_KEY_CURVE_ED25519"; + | "API_KEY_CURVE_P256" + | "API_KEY_CURVE_SECP256K1" + | "API_KEY_CURVE_ED25519"; export type v1ApiKeyParamsV2 = { /** Human-readable name for an API Key. */ @@ -420,11 +420,11 @@ export type v1AuthenticatorParamsV2 = { }; export type v1AuthenticatorTransport = - "AUTHENTICATOR_TRANSPORT_BLE" | - "AUTHENTICATOR_TRANSPORT_INTERNAL" | - "AUTHENTICATOR_TRANSPORT_NFC" | - "AUTHENTICATOR_TRANSPORT_USB" | - "AUTHENTICATOR_TRANSPORT_HYBRID"; + | "AUTHENTICATOR_TRANSPORT_BLE" + | "AUTHENTICATOR_TRANSPORT_INTERNAL" + | "AUTHENTICATOR_TRANSPORT_NFC" + | "AUTHENTICATOR_TRANSPORT_USB" + | "AUTHENTICATOR_TRANSPORT_HYBRID"; export type v1Config = { features?: v1Feature[]; @@ -1017,20 +1017,18 @@ export type v1CredPropsAuthenticationExtensionsClientOutputs = { }; export type v1CredentialType = - "CREDENTIAL_TYPE_WEBAUTHN_AUTHENTICATOR" | - "CREDENTIAL_TYPE_API_KEY_P256" | - "CREDENTIAL_TYPE_RECOVER_USER_KEY_P256" | - "CREDENTIAL_TYPE_API_KEY_SECP256K1" | - "CREDENTIAL_TYPE_EMAIL_AUTH_KEY_P256" | - "CREDENTIAL_TYPE_API_KEY_ED25519" | - "CREDENTIAL_TYPE_OTP_AUTH_KEY_P256" | - "CREDENTIAL_TYPE_READ_WRITE_SESSION_KEY_P256" | - "CREDENTIAL_TYPE_OAUTH_KEY_P256" | - "CREDENTIAL_TYPE_LOGIN"; - -export type v1Curve = - "CURVE_SECP256K1" | - "CURVE_ED25519"; + | "CREDENTIAL_TYPE_WEBAUTHN_AUTHENTICATOR" + | "CREDENTIAL_TYPE_API_KEY_P256" + | "CREDENTIAL_TYPE_RECOVER_USER_KEY_P256" + | "CREDENTIAL_TYPE_API_KEY_SECP256K1" + | "CREDENTIAL_TYPE_EMAIL_AUTH_KEY_P256" + | "CREDENTIAL_TYPE_API_KEY_ED25519" + | "CREDENTIAL_TYPE_OTP_AUTH_KEY_P256" + | "CREDENTIAL_TYPE_READ_WRITE_SESSION_KEY_P256" + | "CREDENTIAL_TYPE_OAUTH_KEY_P256" + | "CREDENTIAL_TYPE_LOGIN"; + +export type v1Curve = "CURVE_SECP256K1" | "CURVE_ED25519"; export type v1DeleteApiKeysIntent = { /** Unique identifier for a given User. */ @@ -1275,9 +1273,7 @@ export type v1DisablePrivateKeyResult = { privateKeyId: string; }; -export type v1Effect = - "EFFECT_ALLOW" | - "EFFECT_DENY"; +export type v1Effect = "EFFECT_ALLOW" | "EFFECT_DENY"; export type v1EmailAuthIntent = { /** Email of the authenticating user. */ @@ -1427,13 +1423,13 @@ export type v1Feature = { }; export type v1FeatureName = - "FEATURE_NAME_ROOT_USER_EMAIL_RECOVERY" | - "FEATURE_NAME_WEBAUTHN_ORIGINS" | - "FEATURE_NAME_EMAIL_AUTH" | - "FEATURE_NAME_EMAIL_RECOVERY" | - "FEATURE_NAME_WEBHOOK" | - "FEATURE_NAME_SMS_AUTH" | - "FEATURE_NAME_OTP_EMAIL_AUTH"; + | "FEATURE_NAME_ROOT_USER_EMAIL_RECOVERY" + | "FEATURE_NAME_WEBAUTHN_ORIGINS" + | "FEATURE_NAME_EMAIL_AUTH" + | "FEATURE_NAME_EMAIL_RECOVERY" + | "FEATURE_NAME_WEBHOOK" + | "FEATURE_NAME_SMS_AUTH" + | "FEATURE_NAME_OTP_EMAIL_AUTH"; export type v1GetActivitiesRequest = { /** Unique identifier for a given Organization. */ @@ -1717,10 +1713,10 @@ export type v1GetWhoamiResponse = { }; export type v1HashFunction = - "HASH_FUNCTION_NO_OP" | - "HASH_FUNCTION_SHA256" | - "HASH_FUNCTION_KECCAK256" | - "HASH_FUNCTION_NOT_APPLICABLE"; + | "HASH_FUNCTION_NO_OP" + | "HASH_FUNCTION_SHA256" + | "HASH_FUNCTION_KECCAK256" + | "HASH_FUNCTION_NOT_APPLICABLE"; export type v1ImportPrivateKeyIntent = { /** The ID of the User importing a Private Key. */ @@ -2065,9 +2061,9 @@ export type v1InvitationParams = { }; export type v1InvitationStatus = - "INVITATION_STATUS_CREATED" | - "INVITATION_STATUS_ACCEPTED" | - "INVITATION_STATUS_REVOKED"; + | "INVITATION_STATUS_CREATED" + | "INVITATION_STATUS_ACCEPTED" + | "INVITATION_STATUS_REVOKED"; export type v1ListPrivateKeyTagsRequest = { /** Unique identifier for a given Organization. */ @@ -2090,15 +2086,15 @@ export type v1ListUserTagsResponse = { }; export type v1MnemonicLanguage = - "MNEMONIC_LANGUAGE_ENGLISH" | - "MNEMONIC_LANGUAGE_SIMPLIFIED_CHINESE" | - "MNEMONIC_LANGUAGE_TRADITIONAL_CHINESE" | - "MNEMONIC_LANGUAGE_CZECH" | - "MNEMONIC_LANGUAGE_FRENCH" | - "MNEMONIC_LANGUAGE_ITALIAN" | - "MNEMONIC_LANGUAGE_JAPANESE" | - "MNEMONIC_LANGUAGE_KOREAN" | - "MNEMONIC_LANGUAGE_SPANISH"; + | "MNEMONIC_LANGUAGE_ENGLISH" + | "MNEMONIC_LANGUAGE_SIMPLIFIED_CHINESE" + | "MNEMONIC_LANGUAGE_TRADITIONAL_CHINESE" + | "MNEMONIC_LANGUAGE_CZECH" + | "MNEMONIC_LANGUAGE_FRENCH" + | "MNEMONIC_LANGUAGE_ITALIAN" + | "MNEMONIC_LANGUAGE_JAPANESE" + | "MNEMONIC_LANGUAGE_KOREAN" + | "MNEMONIC_LANGUAGE_SPANISH"; export type v1NOOPCodegenAnchorResponse = { stamp: v1WebAuthnStamp; @@ -2183,17 +2179,17 @@ export type v1OauthResult = { }; export type v1Operator = - "OPERATOR_EQUAL" | - "OPERATOR_MORE_THAN" | - "OPERATOR_MORE_THAN_OR_EQUAL" | - "OPERATOR_LESS_THAN" | - "OPERATOR_LESS_THAN_OR_EQUAL" | - "OPERATOR_CONTAINS" | - "OPERATOR_NOT_EQUAL" | - "OPERATOR_IN" | - "OPERATOR_NOT_IN" | - "OPERATOR_CONTAINS_ONE" | - "OPERATOR_CONTAINS_ALL"; + | "OPERATOR_EQUAL" + | "OPERATOR_MORE_THAN" + | "OPERATOR_MORE_THAN_OR_EQUAL" + | "OPERATOR_LESS_THAN" + | "OPERATOR_LESS_THAN_OR_EQUAL" + | "OPERATOR_CONTAINS" + | "OPERATOR_NOT_EQUAL" + | "OPERATOR_IN" + | "OPERATOR_NOT_IN" + | "OPERATOR_CONTAINS_ONE" + | "OPERATOR_CONTAINS_ALL"; export type v1OrganizationData = { organizationId?: string; @@ -2275,12 +2271,11 @@ export type v1Pagination = { after?: string; }; -export type v1PathFormat = - "PATH_FORMAT_BIP32"; +export type v1PathFormat = "PATH_FORMAT_BIP32"; export type v1PayloadEncoding = - "PAYLOAD_ENCODING_HEXADECIMAL" | - "PAYLOAD_ENCODING_TEXT_UTF8"; + | "PAYLOAD_ENCODING_HEXADECIMAL" + | "PAYLOAD_ENCODING_TEXT_UTF8"; export type v1Policy = { /** Unique identifier for a given Policy. */ @@ -2687,9 +2682,7 @@ export type v1StampLoginResult = { session: string; }; -export type v1TagType = - "TAG_TYPE_USER" | - "TAG_TYPE_PRIVATE_KEY"; +export type v1TagType = "TAG_TYPE_USER" | "TAG_TYPE_PRIVATE_KEY"; export type v1TestRateLimitsRequest = { /** 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. */ @@ -2702,9 +2695,9 @@ export type v1TestRateLimitsRequest = { export type v1TestRateLimitsResponse = any; export type v1TransactionType = - "TRANSACTION_TYPE_ETHEREUM" | - "TRANSACTION_TYPE_SOLANA" | - "TRANSACTION_TYPE_TRON"; + | "TRANSACTION_TYPE_ETHEREUM" + | "TRANSACTION_TYPE_SOLANA" + | "TRANSACTION_TYPE_TRON"; export type v1UpdateAllowedOriginsIntent = { /** Additional origins requests are allowed from besides Turnkey origins */ @@ -3059,7 +3052,6 @@ export type v1WebAuthnStamp = { signature: string; }; - // --- Latest Version Type Aliases --- export type AcceptInvitationRequest = { /** Unique identifier for a given Invitation object. */ @@ -4808,4 +4800,3 @@ export type WebAuthnStamp = { /** The base64 url encoded signature bytes contained within the WebAuthn assertion response. */ signature: string; }; - From c0ab2c287b3d62851b5b5f67258b5eda21b3f202 Mon Sep 17 00:00:00 2001 From: Ethan Konkolowicz Date: Mon, 16 Jun 2025 12:13:48 -0400 Subject: [PATCH 012/184] added custom activity responses --- packages/sdk-types/scripts/codegen.js | 44 +- packages/sdk-types/src/__generated__/types.ts | 448 ++++++++++++++++++ 2 files changed, 482 insertions(+), 10 deletions(-) diff --git a/packages/sdk-types/scripts/codegen.js b/packages/sdk-types/scripts/codegen.js index 11f8a01c5..3c21002c1 100644 --- a/packages/sdk-types/scripts/codegen.js +++ b/packages/sdk-types/scripts/codegen.js @@ -263,6 +263,7 @@ function main() { const latestVersionMap = buildLatestVersionMap(swagger.definitions); // Check all Request types for organizationId, if present modify their respective Intent types and add optional organizationId + // Also check Result types and add Response type for them for (const [baseName, latestVersionName] of Object.entries( latestVersionMap, )) { @@ -270,13 +271,9 @@ function main() { if (def && def.type === "object" && def.properties) { // If the baseName ends with "Request", check for organizationId - console.log(`Checking ${baseName} for organizationId...`); if (baseName.endsWith("Request") && def.properties.organizationId) { // Modify the corresponding Intent type to make organizationId optional const intentTypeName = latestVersionName.replace(/Request$/, "Intent"); - console.log( - `Modifying Intent type ${intentTypeName} to make organizationId optional`, - ); if ( swagger.definitions[intentTypeName] && swagger.definitions[intentTypeName].properties @@ -298,7 +295,38 @@ function main() { swagger.definitions[intentTypeName].required = ( swagger.definitions[intentTypeName].required || [] ).filter((r) => r !== "organizationId"); - console.log(swagger.definitions[intentTypeName]); + } + } else if ( + baseName.endsWith("Result") && + !/^v\d+Result$/.test(latestVersionName) + ) { + // If baseName ends with "Result" and not just vXResult, create a corresponding Response type + if (swagger.definitions[latestVersionName]) { + const responseTypeName = stripVersionPrefixAndSuffix( + latestVersionName.replace(/(.+)Result$/, (m, p1) => `${p1}Response`) + ); + + swagger.definitions[responseTypeName] = { + type: "object", + properties: { + activity: { + $ref: `#/definitions/v1Activity`, + description: "The activity that was processed.", + }, + ...swagger.definitions[latestVersionName].properties, + }, + required: [ + "activity", + ...(Array.isArray(swagger.definitions[latestVersionName].required) + ? swagger.definitions[latestVersionName].required + : []) + ], + }; + + console.log(swagger.definitions[responseTypeName]); + + // Add the new Response type to latestVersionMap + latestVersionMap[responseTypeName] = responseTypeName; } } } @@ -311,10 +339,6 @@ function main() { )) { const def = swagger.definitions[latestVersionName]; - if (/(.+)Request$/.test(baseName)) { - continue; - } - // If baseName ends with "Intent" and has characters before "Intent", also emit a corresponding Request type if ( /(.+)Intent$/.test(baseName) && @@ -326,7 +350,7 @@ function main() { output += generateTsType(requestTypeName, def) + "\n"; } - if (/(.+)Intent$/.test(baseName)) { + if (/(.+)Intent$/.test(baseName) || /(.+)Request$/.test(baseName)) { continue; } diff --git a/packages/sdk-types/src/__generated__/types.ts b/packages/sdk-types/src/__generated__/types.ts index 4aac801fc..3b2a5109c 100644 --- a/packages/sdk-types/src/__generated__/types.ts +++ b/packages/sdk-types/src/__generated__/types.ts @@ -3328,6 +3328,8 @@ export type CreatePrivateKeysRequest = { }; export type CreatePrivateKeysResult = { + /** The activity that was processed. */ + activity: v1Activity; /** A list of Private Key IDs and addresses. */ privateKeys: v1PrivateKeyResult[]; }; @@ -3361,6 +3363,8 @@ export type CreateReadWriteSessionRequest = { }; export type CreateReadWriteSessionResult = { + /** The activity that was processed. */ + activity: v1Activity; /** Unique identifier for a given Organization. If the request is being made by a user and their Sub-Organization ID is unknown, this can be the Parent Organization ID. However, using the Sub-Organization ID is preferred due to performance reasons. */ organizationId: string; /** Human-readable name for an Organization. */ @@ -3395,6 +3399,8 @@ export type CreateSubOrganizationRequest = { }; export type CreateSubOrganizationResult = { + /** The activity that was processed. */ + activity: v1Activity; subOrganizationId: string; wallet?: v1WalletResult; rootUserIds?: string[]; @@ -3935,6 +3941,8 @@ export type InitOtpAuthRequest = { }; export type InitOtpAuthResult = { + /** The activity that was processed. */ + activity: v1Activity; /** Unique identifier for an OTP authentication */ otpId: string; }; @@ -4569,6 +4577,8 @@ export type UpdatePolicyRequest = { }; export type UpdatePolicyResult = { + /** The activity that was processed. */ + activity: v1Activity; /** Unique identifier for a given Policy. */ policyId: string; }; @@ -4800,3 +4810,441 @@ export type WebAuthnStamp = { /** The base64 url encoded signature bytes contained within the WebAuthn assertion response. */ signature: string; }; + +export type AcceptInvitationResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** Unique identifier for a given Invitation. */ + invitationId: string; + /** Unique identifier for a given User. */ + userId: string; +}; + +export type CreateApiKeysResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** A list of API Key IDs. */ + apiKeyIds: string[]; +}; + +export type CreateApiOnlyUsersResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** A list of API-only User IDs. */ + userIds: string[]; +}; + +export type CreateAuthenticatorsResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** A list of Authenticator IDs. */ + authenticatorIds: string[]; +}; + +export type CreateInvitationsResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** A list of Invitation IDs */ + invitationIds: string[]; +}; + +export type CreateOauthProvidersResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** A list of unique identifiers for Oauth Providers */ + providerIds: string[]; +}; + +export type CreateOrganizationResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** Unique identifier for a given Organization. */ + organizationId: string; +}; + +export type CreatePoliciesResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** A list of unique identifiers for the created policies. */ + policyIds: string[]; +}; + +export type CreatePolicyResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** Unique identifier for a given Policy. */ + policyId: string; +}; + +export type CreatePrivateKeyTagResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** Unique identifier for a given Private Key Tag. */ + privateKeyTagId: string; + /** A list of Private Key IDs. */ + privateKeyIds: string[]; +}; + +export type CreateReadOnlySessionResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** Unique identifier for a given Organization. If the request is being made by a user and their Sub-Organization ID is unknown, this can be the Parent Organization ID. However, using the Sub-Organization ID is preferred due to performance reasons. */ + organizationId: string; + /** Human-readable name for an Organization. */ + organizationName: string; + /** Unique identifier for a given User. */ + userId: string; + /** Human-readable name for a User. */ + username: string; + /** String representing a read only session */ + session: string; + /** UTC timestamp in seconds representing the expiry time for the read only session. */ + sessionExpiry: string; +}; + +export type CreateUserTagResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** Unique identifier for a given User Tag. */ + userTagId: string; + /** A list of User IDs. */ + userIds: string[]; +}; + +export type CreateUsersResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** A list of User IDs. */ + userIds: string[]; +}; + +export type CreateWalletAccountsResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** A list of derived addresses. */ + addresses: string[]; +}; + +export type CreateWalletResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** Unique identifier for a Wallet. */ + walletId: string; + /** A list of account addresses. */ + addresses: string[]; +}; + +export type DeleteApiKeysResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** A list of API Key IDs. */ + apiKeyIds: string[]; +}; + +export type DeleteAuthenticatorsResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** Unique identifier for a given Authenticator. */ + authenticatorIds: string[]; +}; + +export type DeleteInvitationResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** Unique identifier for a given Invitation. */ + invitationId: string; +}; + +export type DeleteOauthProvidersResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** A list of unique identifiers for Oauth Providers */ + providerIds: string[]; +}; + +export type DeleteOrganizationResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** Unique identifier for a given Organization. */ + organizationId: string; +}; + +export type DeletePolicyResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** Unique identifier for a given Policy. */ + policyId: string; +}; + +export type DeletePrivateKeyTagsResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** A list of Private Key Tag IDs. */ + privateKeyTagIds: string[]; + /** A list of Private Key IDs. */ + privateKeyIds: string[]; +}; + +export type DeletePrivateKeysResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** A list of private key unique identifiers that were removed */ + privateKeyIds: string[]; +}; + +export type DeleteSubOrganizationResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** Unique identifier of the sub organization that was removed */ + subOrganizationUuid: string; +}; + +export type DeleteUserTagsResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** A list of User Tag IDs. */ + userTagIds: string[]; + /** A list of User IDs. */ + userIds: string[]; +}; + +export type DeleteUsersResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** A list of User IDs. */ + userIds: string[]; +}; + +export type DeleteWalletsResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** A list of wallet unique identifiers that were removed */ + walletIds: string[]; +}; + +export type DisablePrivateKeyResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** Unique identifier for a given Private Key. */ + privateKeyId: string; +}; + +export type EmailAuthResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** Unique identifier for the authenticating User. */ + userId: string; + /** Unique identifier for the created API key. */ + apiKeyId: string; +}; + +export type ExportPrivateKeyResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** Unique identifier for a given Private Key. */ + privateKeyId: string; + /** Export bundle containing a private key encrypted to the client's target public key. */ + exportBundle: string; +}; + +export type ExportWalletAccountResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** Address to identify Wallet Account. */ + address: string; + /** Export bundle containing a private key encrypted by the client's target public key. */ + exportBundle: string; +}; + +export type ExportWalletResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** Unique identifier for a given Wallet. */ + walletId: string; + /** Export bundle containing a wallet mnemonic + optional newline passphrase encrypted by the client's target public key. */ + exportBundle: string; +}; + +export type ImportPrivateKeyResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** Unique identifier for a Private Key. */ + privateKeyId: string; + /** A list of addresses. */ + addresses: immutableactivityv1Address[]; +}; + +export type ImportWalletResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** Unique identifier for a Wallet. */ + walletId: string; + /** A list of account addresses. */ + addresses: string[]; +}; + +export type InitImportPrivateKeyResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** Import bundle containing a public key and signature to use for importing client data. */ + importBundle: string; +}; + +export type InitImportWalletResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** Import bundle containing a public key and signature to use for importing client data. */ + importBundle: string; +}; + +export type InitOtpResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** Unique identifier for an OTP authentication */ + otpId: string; +}; + +export type InitUserEmailRecoveryResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** Unique identifier for the user being recovered. */ + userId: string; +}; + +export type OauthLoginResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** Signed JWT containing an expiry, public key, session type, user id, and organization id */ + session: string; +}; + +export type OauthResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** Unique identifier for the authenticating User. */ + userId: string; + /** Unique identifier for the created API key. */ + apiKeyId: string; + /** HPKE encrypted credential bundle */ + credentialBundle: string; +}; + +export type OtpAuthResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** Unique identifier for the authenticating User. */ + userId: string; + /** Unique identifier for the created API key. */ + apiKeyId?: string; + /** HPKE encrypted credential bundle */ + credentialBundle?: string; +}; + +export type OtpLoginResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** Signed JWT containing an expiry, public key, session type, user id, and organization id */ + session: string; +}; + +export type PrivateKeyResponse = { + /** The activity that was processed. */ + activity: v1Activity; + privateKeyId?: string; + addresses?: immutableactivityv1Address[]; +}; + +export type RecoverUserResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** ID of the authenticator created. */ + authenticatorId: string[]; +}; + +export type RemoveOrganizationFeatureResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** Resulting list of organization features. */ + features: v1Feature[]; +}; + +export type SetOrganizationFeatureResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** Resulting list of organization features. */ + features: v1Feature[]; +}; + +export type SignRawPayloadResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** Component of an ECSDA signature. */ + r: string; + /** Component of an ECSDA signature. */ + s: string; + /** Component of an ECSDA signature. */ + v: string; +}; + +export type SignRawPayloadsResponse = { + /** The activity that was processed. */ + activity: v1Activity; + signatures?: v1SignRawPayloadResult[]; +}; + +export type SignTransactionResponse = { + /** The activity that was processed. */ + activity: v1Activity; + signedTransaction: string; +}; + +export type StampLoginResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** Signed JWT containing an expiry, public key, session type, user id, and organization id */ + session: string; +}; + +export type UpdatePrivateKeyTagResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** Unique identifier for a given Private Key Tag. */ + privateKeyTagId: string; +}; + +export type UpdateUserResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** A User ID. */ + userId: string; +}; + +export type UpdateUserTagResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** Unique identifier for a given User Tag. */ + userTagId: string; +}; + +export type UpdateWalletResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** A Wallet ID. */ + walletId: string; +}; + +export type VerifyOtpResponse = { + /** The activity that was processed. */ + activity: v1Activity; + /** Signed JWT containing a unique id, expiry, verification type, contact. Verification status of a user is updated when the token is consumed (in OTP_LOGIN requests) */ + verificationToken: string; +}; + +export type WalletResponse = { + /** The activity that was processed. */ + activity: v1Activity; + walletId: string; + /** A list of account addresses. */ + addresses: string[]; +}; + From 4fdc327040b81ebddf71d7505fb81d7086a035b8 Mon Sep 17 00:00:00 2001 From: Ethan Konkolowicz Date: Mon, 16 Jun 2025 12:22:36 -0400 Subject: [PATCH 013/184] rebased --- packages/sdk-types/scripts/codegen.js | 59 ++++--------------- packages/sdk-types/src/__generated__/types.ts | 1 - 2 files changed, 13 insertions(+), 47 deletions(-) diff --git a/packages/sdk-types/scripts/codegen.js b/packages/sdk-types/scripts/codegen.js index 3c21002c1..b4ee5d79b 100644 --- a/packages/sdk-types/scripts/codegen.js +++ b/packages/sdk-types/scripts/codegen.js @@ -74,37 +74,6 @@ function refToTs(ref) { return ref.replace(/^#\/definitions\//, ""); } -// /** -// * @param {string} ref -// * @returns {string} -// */ -// function refToTsWithVersionPrefixAndSuffixStrip(ref) { -// return stripVersionPrefixAndSuffix(ref.replace(/^#\/definitions\//, "")); -// } - -/** - * @param {string} methodName - * @returns {string} - */ -function methodTypeFromMethodName(methodName) { - if (["approveActivity", "rejectActivity"].includes(methodName)) { - return "activityDecision"; - } - if (methodName.startsWith("nOOP")) { - return "noop"; - } - // TODO: filter out unnecessary client methods, whether here or from the source - if ( - methodName.startsWith("get") || - methodName.startsWith("list") || - methodName.startsWith("test") - ) { - return "query"; - } - // Rename to submit? - return "command"; -} - /** * Maps activity types to their most recent versions in VERSIONED_ACTIVITY_TYPES. * If a type has multiple versions, it will return the latest one based on the versioning scheme. @@ -263,7 +232,7 @@ function main() { const latestVersionMap = buildLatestVersionMap(swagger.definitions); // Check all Request types for organizationId, if present modify their respective Intent types and add optional organizationId - // Also check Result types and add Response type for them + // Also check Result types and add Response type for them for (const [baseName, latestVersionName] of Object.entries( latestVersionMap, )) { @@ -303,29 +272,32 @@ function main() { // If baseName ends with "Result" and not just vXResult, create a corresponding Response type if (swagger.definitions[latestVersionName]) { const responseTypeName = stripVersionPrefixAndSuffix( - latestVersionName.replace(/(.+)Result$/, (m, p1) => `${p1}Response`) + latestVersionName.replace( + /(.+)Result$/, + (m, p1) => `${p1}Response`, + ), ); - + swagger.definitions[responseTypeName] = { type: "object", properties: { - activity: { - $ref: `#/definitions/v1Activity`, - description: "The activity that was processed.", - }, - ...swagger.definitions[latestVersionName].properties, + activity: { + $ref: `#/definitions/v1Activity`, + description: "The activity that was processed.", + }, + ...swagger.definitions[latestVersionName].properties, }, required: [ "activity", ...(Array.isArray(swagger.definitions[latestVersionName].required) ? swagger.definitions[latestVersionName].required - : []) + : []), ], }; console.log(swagger.definitions[responseTypeName]); - // Add the new Response type to latestVersionMap + // Add the new Response type to latestVersionMap latestVersionMap[responseTypeName] = responseTypeName; } } @@ -339,7 +311,6 @@ function main() { )) { const def = swagger.definitions[latestVersionName]; - // If baseName ends with "Intent" and has characters before "Intent", also emit a corresponding Request type if ( /(.+)Intent$/.test(baseName) && def && @@ -355,17 +326,13 @@ function main() { } if (def && def.type === "object" && def.properties) { - // Redefine the type with all properties, making organizationId optional if present output += generateTsType(baseName, def) + "\n"; } else { output += `export type ${baseName} = ${latestVersionName};\n`; } } - // 5. Write output fs.writeFileSync(outputPath, output); - - console.log(`Nice types generated at ${outputPath}`); } main(); diff --git a/packages/sdk-types/src/__generated__/types.ts b/packages/sdk-types/src/__generated__/types.ts index 3b2a5109c..ce3665f7f 100644 --- a/packages/sdk-types/src/__generated__/types.ts +++ b/packages/sdk-types/src/__generated__/types.ts @@ -5247,4 +5247,3 @@ export type WalletResponse = { /** A list of account addresses. */ addresses: string[]; }; - From 3a13c4164e517224f2f31445d8089bba368c27f7 Mon Sep 17 00:00:00 2001 From: Ethan Konkolowicz Date: Mon, 16 Jun 2025 17:36:08 -0400 Subject: [PATCH 014/184] fixed sdk-types api Response and Request type generation --- examples/with-sdk-js/src/app/page.tsx | 2 +- packages/sdk-js/scripts/codegen.js | 18 +- packages/sdk-js/src/__clients__/core.ts | 11 +- .../src/__generated__/sdk-client-base.ts | 506 +-- packages/sdk-js/src/__types__/base.ts | 12 +- packages/sdk-types/scripts/codegen.js | 468 ++- packages/sdk-types/src/__generated__/types.ts | 2886 +++++++---------- .../src/__inputs__/public_api.swagger.json | 465 ++- .../src/__inputs__/public_api.types.ts | 265 +- 9 files changed, 2439 insertions(+), 2194 deletions(-) diff --git a/examples/with-sdk-js/src/app/page.tsx b/examples/with-sdk-js/src/app/page.tsx index f3de12818..65d9eb706 100644 --- a/examples/with-sdk-js/src/app/page.tsx +++ b/examples/with-sdk-js/src/app/page.tsx @@ -53,7 +53,7 @@ export default function AuthPage() { }; const getWallets = async () => { - const res = await client?.getWallets({}); + const res = await client?.fetchWallets({}); if (res) { setWallets(res); console.log("Wallets:", res); diff --git a/packages/sdk-js/scripts/codegen.js b/packages/sdk-js/scripts/codegen.js index 3ea7bbd1d..1b3d8e5d3 100644 --- a/packages/sdk-js/scripts/codegen.js +++ b/packages/sdk-js/scripts/codegen.js @@ -266,6 +266,8 @@ const generateSDKClientFromSwagger = async (swaggerSpec, targetPath) => { imports.push('import type * as SdkApiTypes from "./sdk_api_types";'); + imports.push('import type * as SdkTypes from "@turnkey/sdk-types";'); + imports.push('import { StorageBase } from "../__storage__/base";'); imports.push('import { parseSession } from "../utils";'); @@ -300,7 +302,7 @@ const generateSDKClientFromSwagger = async (swaggerSpec, targetPath) => { if (!stampWith) return this.apiKeyStamper || this.passkeyStamper; switch (stampWith) { - case StamperType.apiKey: + case StamperType.ApiKey: return this.apiKeyStamper; case StamperType.Passkey: return this.passkeyStamper; @@ -444,17 +446,17 @@ const generateSDKClientFromSwagger = async (swaggerSpec, targetPath) => { }`; const methodType = methodTypeFromMethodName(methodName); - const inputType = `T${operationNameWithoutNamespace}Body`; - const responseType = `T${operationNameWithoutNamespace}Response`; + const inputType = `${operationNameWithoutNamespace}Request`; + const responseType = `${operationNameWithoutNamespace}Response`; // For query methods if (methodType === "query") { codeBuffer.push( - `\n\t${methodName} = async (input: SdkApiTypes.${inputType}${ + `\n\t${methodName} = async (input: SdkTypes.${inputType}${ METHODS_WITH_ONLY_OPTIONAL_PARAMETERS.includes(methodName) ? " = {}" : "" - }, stampWith?: StamperType): Promise => { + }, stampWith?: StamperType): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request("${endpointPath}", { @@ -475,7 +477,7 @@ const generateSDKClientFromSwagger = async (swaggerSpec, targetPath) => { const versionedMethodName = latestVersions[resultKey].formattedKeyName; codeBuffer.push( - `\n\t${methodName} = async (input: SdkApiTypes.${inputType}, stampWith?: StamperType): Promise => { + `\n\t${methodName} = async (input: SdkTypes.${inputType}, stampWith?: StamperType): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -491,7 +493,7 @@ const generateSDKClientFromSwagger = async (swaggerSpec, targetPath) => { } else if (methodType === "activityDecision") { // For activityDecision methods codeBuffer.push( - `\n\t${methodName} = async (input: SdkApiTypes.${inputType}, stampWith?: StamperType): Promise => { + `\n\t${methodName} = async (input: SdkTypes.${inputType}, stampWith?: StamperType): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -509,7 +511,7 @@ const generateSDKClientFromSwagger = async (swaggerSpec, targetPath) => { } // generate a stamping method for each method codeBuffer.push( - `\n\tstamp${operationNameWithoutNamespace} = async (input: SdkApiTypes.${inputType}, stampWith?: StamperType): Promise => { + `\n\tstamp${operationNameWithoutNamespace} = async (input: SdkTypes.${inputType}, stampWith?: StamperType): Promise => { const activeStamper = this.getStamper(stampWith); if (!activeStamper) { return undefined; diff --git a/packages/sdk-js/src/__clients__/core.ts b/packages/sdk-js/src/__clients__/core.ts index ea2c935f4..f7b8a5ace 100644 --- a/packages/sdk-js/src/__clients__/core.ts +++ b/packages/sdk-js/src/__clients__/core.ts @@ -2,9 +2,8 @@ import { TurnkeySDKClientBase } from "../__generated__/sdk-client-base"; import { GetWalletAccountsResponse, SessionType, - SignRawPayloadResult, - User, - WalletAccount, + v1SignRawPayloadResult, + v1WalletAccount, } from "@turnkey/sdk-types"; import { DEFAULT_SESSION_EXPIRATION_IN_SECONDS, @@ -245,9 +244,9 @@ export class TurnkeyClient { signMessage = async (params: { message: string; - wallet?: WalletAccount; + wallet?: v1WalletAccount; stampWith?: StamperType; - }): Promise => { + }): Promise => { const { message, wallet, stampWith } = params; if (!wallet) { throw new Error("A wallet account must be provided for signing"); @@ -277,7 +276,7 @@ export class TurnkeyClient { } return response.activity.result - .signRawPayloadResult as SignRawPayloadResult; + .signRawPayloadResult as v1SignRawPayloadResult; }; } diff --git a/packages/sdk-js/src/__generated__/sdk-client-base.ts b/packages/sdk-js/src/__generated__/sdk-client-base.ts index baae80407..f8bf275c7 100644 --- a/packages/sdk-js/src/__generated__/sdk-client-base.ts +++ b/packages/sdk-js/src/__generated__/sdk-client-base.ts @@ -20,6 +20,8 @@ import { VERSION } from "../__generated__/version"; import type * as SdkApiTypes from "./sdk_api_types"; +import type * as SdkTypes from "@turnkey/sdk-types"; + import { StorageBase } from "../__storage__/base"; import { parseSession } from "../utils"; @@ -198,9 +200,9 @@ export class TurnkeySDKClientBase { } getActivity = async ( - input: SdkApiTypes.TGetActivityBody, + input: SdkTypes.GetActivityRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -217,7 +219,7 @@ export class TurnkeySDKClientBase { }; stampGetActivity = async ( - input: SdkApiTypes.TGetActivityBody, + input: SdkTypes.GetActivityRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -236,9 +238,9 @@ export class TurnkeySDKClientBase { }; getApiKey = async ( - input: SdkApiTypes.TGetApiKeyBody, + input: SdkTypes.GetApiKeyRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -255,7 +257,7 @@ export class TurnkeySDKClientBase { }; stampGetApiKey = async ( - input: SdkApiTypes.TGetApiKeyBody, + input: SdkTypes.GetApiKeyRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -274,9 +276,9 @@ export class TurnkeySDKClientBase { }; getApiKeys = async ( - input: SdkApiTypes.TGetApiKeysBody = {}, + input: SdkTypes.GetApiKeysRequest = {}, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -293,7 +295,7 @@ export class TurnkeySDKClientBase { }; stampGetApiKeys = async ( - input: SdkApiTypes.TGetApiKeysBody, + input: SdkTypes.GetApiKeysRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -312,9 +314,9 @@ export class TurnkeySDKClientBase { }; getAttestationDocument = async ( - input: SdkApiTypes.TGetAttestationDocumentBody, + input: SdkTypes.GetAttestationDocumentRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -331,7 +333,7 @@ export class TurnkeySDKClientBase { }; stampGetAttestationDocument = async ( - input: SdkApiTypes.TGetAttestationDocumentBody, + input: SdkTypes.GetAttestationDocumentRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -350,9 +352,9 @@ export class TurnkeySDKClientBase { }; getAuthenticator = async ( - input: SdkApiTypes.TGetAuthenticatorBody, + input: SdkTypes.GetAuthenticatorRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -369,7 +371,7 @@ export class TurnkeySDKClientBase { }; stampGetAuthenticator = async ( - input: SdkApiTypes.TGetAuthenticatorBody, + input: SdkTypes.GetAuthenticatorRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -389,9 +391,9 @@ export class TurnkeySDKClientBase { }; getAuthenticators = async ( - input: SdkApiTypes.TGetAuthenticatorsBody, + input: SdkTypes.GetAuthenticatorsRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -408,7 +410,7 @@ export class TurnkeySDKClientBase { }; stampGetAuthenticators = async ( - input: SdkApiTypes.TGetAuthenticatorsBody, + input: SdkTypes.GetAuthenticatorsRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -428,9 +430,9 @@ export class TurnkeySDKClientBase { }; getOauthProviders = async ( - input: SdkApiTypes.TGetOauthProvidersBody, + input: SdkTypes.GetOauthProvidersRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -447,7 +449,7 @@ export class TurnkeySDKClientBase { }; stampGetOauthProviders = async ( - input: SdkApiTypes.TGetOauthProvidersBody, + input: SdkTypes.GetOauthProvidersRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -467,9 +469,9 @@ export class TurnkeySDKClientBase { }; getOrganization = async ( - input: SdkApiTypes.TGetOrganizationBody = {}, + input: SdkTypes.GetOrganizationRequest = {}, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -486,7 +488,7 @@ export class TurnkeySDKClientBase { }; stampGetOrganization = async ( - input: SdkApiTypes.TGetOrganizationBody, + input: SdkTypes.GetOrganizationRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -506,9 +508,9 @@ export class TurnkeySDKClientBase { }; getOrganizationConfigs = async ( - input: SdkApiTypes.TGetOrganizationConfigsBody, + input: SdkTypes.GetOrganizationConfigsRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -525,7 +527,7 @@ export class TurnkeySDKClientBase { }; stampGetOrganizationConfigs = async ( - input: SdkApiTypes.TGetOrganizationConfigsBody, + input: SdkTypes.GetOrganizationConfigsRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -545,9 +547,9 @@ export class TurnkeySDKClientBase { }; getPolicy = async ( - input: SdkApiTypes.TGetPolicyBody, + input: SdkTypes.GetPolicyRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -564,7 +566,7 @@ export class TurnkeySDKClientBase { }; stampGetPolicy = async ( - input: SdkApiTypes.TGetPolicyBody, + input: SdkTypes.GetPolicyRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -583,9 +585,9 @@ export class TurnkeySDKClientBase { }; getPrivateKey = async ( - input: SdkApiTypes.TGetPrivateKeyBody, + input: SdkTypes.GetPrivateKeyRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -602,7 +604,7 @@ export class TurnkeySDKClientBase { }; stampGetPrivateKey = async ( - input: SdkApiTypes.TGetPrivateKeyBody, + input: SdkTypes.GetPrivateKeyRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -621,9 +623,9 @@ export class TurnkeySDKClientBase { }; getUser = async ( - input: SdkApiTypes.TGetUserBody, + input: SdkTypes.GetUserRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -640,7 +642,7 @@ export class TurnkeySDKClientBase { }; stampGetUser = async ( - input: SdkApiTypes.TGetUserBody, + input: SdkTypes.GetUserRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -659,9 +661,9 @@ export class TurnkeySDKClientBase { }; getWallet = async ( - input: SdkApiTypes.TGetWalletBody, + input: SdkTypes.GetWalletRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -678,7 +680,7 @@ export class TurnkeySDKClientBase { }; stampGetWallet = async ( - input: SdkApiTypes.TGetWalletBody, + input: SdkTypes.GetWalletRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -697,9 +699,9 @@ export class TurnkeySDKClientBase { }; getWalletAccount = async ( - input: SdkApiTypes.TGetWalletAccountBody, + input: SdkTypes.GetWalletAccountRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -716,7 +718,7 @@ export class TurnkeySDKClientBase { }; stampGetWalletAccount = async ( - input: SdkApiTypes.TGetWalletAccountBody, + input: SdkTypes.GetWalletAccountRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -736,9 +738,9 @@ export class TurnkeySDKClientBase { }; getActivities = async ( - input: SdkApiTypes.TGetActivitiesBody = {}, + input: SdkTypes.GetActivitiesRequest = {}, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -755,7 +757,7 @@ export class TurnkeySDKClientBase { }; stampGetActivities = async ( - input: SdkApiTypes.TGetActivitiesBody, + input: SdkTypes.GetActivitiesRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -774,9 +776,9 @@ export class TurnkeySDKClientBase { }; getPolicies = async ( - input: SdkApiTypes.TGetPoliciesBody = {}, + input: SdkTypes.GetPoliciesRequest = {}, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -793,7 +795,7 @@ export class TurnkeySDKClientBase { }; stampGetPolicies = async ( - input: SdkApiTypes.TGetPoliciesBody, + input: SdkTypes.GetPoliciesRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -812,9 +814,9 @@ export class TurnkeySDKClientBase { }; listPrivateKeyTags = async ( - input: SdkApiTypes.TListPrivateKeyTagsBody, + input: SdkTypes.ListPrivateKeyTagsRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -831,7 +833,7 @@ export class TurnkeySDKClientBase { }; stampListPrivateKeyTags = async ( - input: SdkApiTypes.TListPrivateKeyTagsBody, + input: SdkTypes.ListPrivateKeyTagsRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -851,9 +853,9 @@ export class TurnkeySDKClientBase { }; getPrivateKeys = async ( - input: SdkApiTypes.TGetPrivateKeysBody = {}, + input: SdkTypes.GetPrivateKeysRequest = {}, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -870,7 +872,7 @@ export class TurnkeySDKClientBase { }; stampGetPrivateKeys = async ( - input: SdkApiTypes.TGetPrivateKeysBody, + input: SdkTypes.GetPrivateKeysRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -890,9 +892,9 @@ export class TurnkeySDKClientBase { }; getSubOrgIds = async ( - input: SdkApiTypes.TGetSubOrgIdsBody = {}, + input: SdkTypes.GetSubOrgIdsRequest = {}, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -909,7 +911,7 @@ export class TurnkeySDKClientBase { }; stampGetSubOrgIds = async ( - input: SdkApiTypes.TGetSubOrgIdsBody, + input: SdkTypes.GetSubOrgIdsRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -928,9 +930,9 @@ export class TurnkeySDKClientBase { }; listUserTags = async ( - input: SdkApiTypes.TListUserTagsBody = {}, + input: SdkTypes.ListUserTagsRequest = {}, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -947,7 +949,7 @@ export class TurnkeySDKClientBase { }; stampListUserTags = async ( - input: SdkApiTypes.TListUserTagsBody, + input: SdkTypes.ListUserTagsRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -966,9 +968,9 @@ export class TurnkeySDKClientBase { }; getUsers = async ( - input: SdkApiTypes.TGetUsersBody = {}, + input: SdkTypes.GetUsersRequest = {}, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -985,7 +987,7 @@ export class TurnkeySDKClientBase { }; stampGetUsers = async ( - input: SdkApiTypes.TGetUsersBody, + input: SdkTypes.GetUsersRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -1004,9 +1006,9 @@ export class TurnkeySDKClientBase { }; getVerifiedSubOrgIds = async ( - input: SdkApiTypes.TGetVerifiedSubOrgIdsBody, + input: SdkTypes.GetVerifiedSubOrgIdsRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -1023,7 +1025,7 @@ export class TurnkeySDKClientBase { }; stampGetVerifiedSubOrgIds = async ( - input: SdkApiTypes.TGetVerifiedSubOrgIdsBody, + input: SdkTypes.GetVerifiedSubOrgIdsRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -1043,9 +1045,9 @@ export class TurnkeySDKClientBase { }; getWalletAccounts = async ( - input: SdkApiTypes.TGetWalletAccountsBody, + input: SdkTypes.GetWalletAccountsRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -1062,7 +1064,7 @@ export class TurnkeySDKClientBase { }; stampGetWalletAccounts = async ( - input: SdkApiTypes.TGetWalletAccountsBody, + input: SdkTypes.GetWalletAccountsRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -1082,9 +1084,9 @@ export class TurnkeySDKClientBase { }; getWallets = async ( - input: SdkApiTypes.TGetWalletsBody = {}, + input: SdkTypes.GetWalletsRequest = {}, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -1101,7 +1103,7 @@ export class TurnkeySDKClientBase { }; stampGetWallets = async ( - input: SdkApiTypes.TGetWalletsBody, + input: SdkTypes.GetWalletsRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -1120,9 +1122,9 @@ export class TurnkeySDKClientBase { }; getWhoami = async ( - input: SdkApiTypes.TGetWhoamiBody = {}, + input: SdkTypes.GetWhoamiRequest = {}, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -1139,7 +1141,7 @@ export class TurnkeySDKClientBase { }; stampGetWhoami = async ( - input: SdkApiTypes.TGetWhoamiBody, + input: SdkTypes.GetWhoamiRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -1158,9 +1160,9 @@ export class TurnkeySDKClientBase { }; approveActivity = async ( - input: SdkApiTypes.TApproveActivityBody, + input: SdkTypes.ApproveActivityRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -1180,7 +1182,7 @@ export class TurnkeySDKClientBase { }; stampApproveActivity = async ( - input: SdkApiTypes.TApproveActivityBody, + input: SdkTypes.ApproveActivityRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -1200,9 +1202,9 @@ export class TurnkeySDKClientBase { }; createApiKeys = async ( - input: SdkApiTypes.TCreateApiKeysBody, + input: SdkTypes.CreateApiKeysRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -1224,7 +1226,7 @@ export class TurnkeySDKClientBase { }; stampCreateApiKeys = async ( - input: SdkApiTypes.TCreateApiKeysBody, + input: SdkTypes.CreateApiKeysRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -1244,9 +1246,9 @@ export class TurnkeySDKClientBase { }; createApiOnlyUsers = async ( - input: SdkApiTypes.TCreateApiOnlyUsersBody, + input: SdkTypes.CreateApiOnlyUsersRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -1268,7 +1270,7 @@ export class TurnkeySDKClientBase { }; stampCreateApiOnlyUsers = async ( - input: SdkApiTypes.TCreateApiOnlyUsersBody, + input: SdkTypes.CreateApiOnlyUsersRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -1288,9 +1290,9 @@ export class TurnkeySDKClientBase { }; createAuthenticators = async ( - input: SdkApiTypes.TCreateAuthenticatorsBody, + input: SdkTypes.CreateAuthenticatorsRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -1312,7 +1314,7 @@ export class TurnkeySDKClientBase { }; stampCreateAuthenticators = async ( - input: SdkApiTypes.TCreateAuthenticatorsBody, + input: SdkTypes.CreateAuthenticatorsRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -1332,9 +1334,9 @@ export class TurnkeySDKClientBase { }; createInvitations = async ( - input: SdkApiTypes.TCreateInvitationsBody, + input: SdkTypes.CreateInvitationsRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -1356,7 +1358,7 @@ export class TurnkeySDKClientBase { }; stampCreateInvitations = async ( - input: SdkApiTypes.TCreateInvitationsBody, + input: SdkTypes.CreateInvitationsRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -1376,9 +1378,9 @@ export class TurnkeySDKClientBase { }; createOauthProviders = async ( - input: SdkApiTypes.TCreateOauthProvidersBody, + input: SdkTypes.CreateOauthProvidersRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -1400,7 +1402,7 @@ export class TurnkeySDKClientBase { }; stampCreateOauthProviders = async ( - input: SdkApiTypes.TCreateOauthProvidersBody, + input: SdkTypes.CreateOauthProvidersRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -1420,9 +1422,9 @@ export class TurnkeySDKClientBase { }; createPolicies = async ( - input: SdkApiTypes.TCreatePoliciesBody, + input: SdkTypes.CreatePoliciesRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -1444,7 +1446,7 @@ export class TurnkeySDKClientBase { }; stampCreatePolicies = async ( - input: SdkApiTypes.TCreatePoliciesBody, + input: SdkTypes.CreatePoliciesRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -1464,9 +1466,9 @@ export class TurnkeySDKClientBase { }; createPolicy = async ( - input: SdkApiTypes.TCreatePolicyBody, + input: SdkTypes.CreatePolicyRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -1488,7 +1490,7 @@ export class TurnkeySDKClientBase { }; stampCreatePolicy = async ( - input: SdkApiTypes.TCreatePolicyBody, + input: SdkTypes.CreatePolicyRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -1507,9 +1509,9 @@ export class TurnkeySDKClientBase { }; createPrivateKeyTag = async ( - input: SdkApiTypes.TCreatePrivateKeyTagBody, + input: SdkTypes.CreatePrivateKeyTagRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -1531,7 +1533,7 @@ export class TurnkeySDKClientBase { }; stampCreatePrivateKeyTag = async ( - input: SdkApiTypes.TCreatePrivateKeyTagBody, + input: SdkTypes.CreatePrivateKeyTagRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -1551,9 +1553,9 @@ export class TurnkeySDKClientBase { }; createPrivateKeys = async ( - input: SdkApiTypes.TCreatePrivateKeysBody, + input: SdkTypes.CreatePrivateKeysRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -1575,7 +1577,7 @@ export class TurnkeySDKClientBase { }; stampCreatePrivateKeys = async ( - input: SdkApiTypes.TCreatePrivateKeysBody, + input: SdkTypes.CreatePrivateKeysRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -1595,9 +1597,9 @@ export class TurnkeySDKClientBase { }; createReadOnlySession = async ( - input: SdkApiTypes.TCreateReadOnlySessionBody, + input: SdkTypes.CreateReadOnlySessionRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -1619,7 +1621,7 @@ export class TurnkeySDKClientBase { }; stampCreateReadOnlySession = async ( - input: SdkApiTypes.TCreateReadOnlySessionBody, + input: SdkTypes.CreateReadOnlySessionRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -1639,9 +1641,9 @@ export class TurnkeySDKClientBase { }; createReadWriteSession = async ( - input: SdkApiTypes.TCreateReadWriteSessionBody, + input: SdkTypes.CreateReadWriteSessionRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -1663,7 +1665,7 @@ export class TurnkeySDKClientBase { }; stampCreateReadWriteSession = async ( - input: SdkApiTypes.TCreateReadWriteSessionBody, + input: SdkTypes.CreateReadWriteSessionRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -1683,9 +1685,9 @@ export class TurnkeySDKClientBase { }; createSubOrganization = async ( - input: SdkApiTypes.TCreateSubOrganizationBody, + input: SdkTypes.CreateSubOrganizationRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -1707,7 +1709,7 @@ export class TurnkeySDKClientBase { }; stampCreateSubOrganization = async ( - input: SdkApiTypes.TCreateSubOrganizationBody, + input: SdkTypes.CreateSubOrganizationRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -1727,9 +1729,9 @@ export class TurnkeySDKClientBase { }; createUserTag = async ( - input: SdkApiTypes.TCreateUserTagBody, + input: SdkTypes.CreateUserTagRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -1751,7 +1753,7 @@ export class TurnkeySDKClientBase { }; stampCreateUserTag = async ( - input: SdkApiTypes.TCreateUserTagBody, + input: SdkTypes.CreateUserTagRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -1771,9 +1773,9 @@ export class TurnkeySDKClientBase { }; createUsers = async ( - input: SdkApiTypes.TCreateUsersBody, + input: SdkTypes.CreateUsersRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -1795,7 +1797,7 @@ export class TurnkeySDKClientBase { }; stampCreateUsers = async ( - input: SdkApiTypes.TCreateUsersBody, + input: SdkTypes.CreateUsersRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -1814,9 +1816,9 @@ export class TurnkeySDKClientBase { }; createWallet = async ( - input: SdkApiTypes.TCreateWalletBody, + input: SdkTypes.CreateWalletRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -1838,7 +1840,7 @@ export class TurnkeySDKClientBase { }; stampCreateWallet = async ( - input: SdkApiTypes.TCreateWalletBody, + input: SdkTypes.CreateWalletRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -1857,9 +1859,9 @@ export class TurnkeySDKClientBase { }; createWalletAccounts = async ( - input: SdkApiTypes.TCreateWalletAccountsBody, + input: SdkTypes.CreateWalletAccountsRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -1881,7 +1883,7 @@ export class TurnkeySDKClientBase { }; stampCreateWalletAccounts = async ( - input: SdkApiTypes.TCreateWalletAccountsBody, + input: SdkTypes.CreateWalletAccountsRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -1901,9 +1903,9 @@ export class TurnkeySDKClientBase { }; deleteApiKeys = async ( - input: SdkApiTypes.TDeleteApiKeysBody, + input: SdkTypes.DeleteApiKeysRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -1925,7 +1927,7 @@ export class TurnkeySDKClientBase { }; stampDeleteApiKeys = async ( - input: SdkApiTypes.TDeleteApiKeysBody, + input: SdkTypes.DeleteApiKeysRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -1945,9 +1947,9 @@ export class TurnkeySDKClientBase { }; deleteAuthenticators = async ( - input: SdkApiTypes.TDeleteAuthenticatorsBody, + input: SdkTypes.DeleteAuthenticatorsRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -1969,7 +1971,7 @@ export class TurnkeySDKClientBase { }; stampDeleteAuthenticators = async ( - input: SdkApiTypes.TDeleteAuthenticatorsBody, + input: SdkTypes.DeleteAuthenticatorsRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -1989,9 +1991,9 @@ export class TurnkeySDKClientBase { }; deleteInvitation = async ( - input: SdkApiTypes.TDeleteInvitationBody, + input: SdkTypes.DeleteInvitationRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -2013,7 +2015,7 @@ export class TurnkeySDKClientBase { }; stampDeleteInvitation = async ( - input: SdkApiTypes.TDeleteInvitationBody, + input: SdkTypes.DeleteInvitationRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -2033,9 +2035,9 @@ export class TurnkeySDKClientBase { }; deleteOauthProviders = async ( - input: SdkApiTypes.TDeleteOauthProvidersBody, + input: SdkTypes.DeleteOauthProvidersRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -2057,7 +2059,7 @@ export class TurnkeySDKClientBase { }; stampDeleteOauthProviders = async ( - input: SdkApiTypes.TDeleteOauthProvidersBody, + input: SdkTypes.DeleteOauthProvidersRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -2077,9 +2079,9 @@ export class TurnkeySDKClientBase { }; deletePolicy = async ( - input: SdkApiTypes.TDeletePolicyBody, + input: SdkTypes.DeletePolicyRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -2101,7 +2103,7 @@ export class TurnkeySDKClientBase { }; stampDeletePolicy = async ( - input: SdkApiTypes.TDeletePolicyBody, + input: SdkTypes.DeletePolicyRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -2120,9 +2122,9 @@ export class TurnkeySDKClientBase { }; deletePrivateKeyTags = async ( - input: SdkApiTypes.TDeletePrivateKeyTagsBody, + input: SdkTypes.DeletePrivateKeyTagsRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -2144,7 +2146,7 @@ export class TurnkeySDKClientBase { }; stampDeletePrivateKeyTags = async ( - input: SdkApiTypes.TDeletePrivateKeyTagsBody, + input: SdkTypes.DeletePrivateKeyTagsRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -2164,9 +2166,9 @@ export class TurnkeySDKClientBase { }; deletePrivateKeys = async ( - input: SdkApiTypes.TDeletePrivateKeysBody, + input: SdkTypes.DeletePrivateKeysRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -2188,7 +2190,7 @@ export class TurnkeySDKClientBase { }; stampDeletePrivateKeys = async ( - input: SdkApiTypes.TDeletePrivateKeysBody, + input: SdkTypes.DeletePrivateKeysRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -2208,9 +2210,9 @@ export class TurnkeySDKClientBase { }; deleteSubOrganization = async ( - input: SdkApiTypes.TDeleteSubOrganizationBody, + input: SdkTypes.DeleteSubOrganizationRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -2232,7 +2234,7 @@ export class TurnkeySDKClientBase { }; stampDeleteSubOrganization = async ( - input: SdkApiTypes.TDeleteSubOrganizationBody, + input: SdkTypes.DeleteSubOrganizationRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -2252,9 +2254,9 @@ export class TurnkeySDKClientBase { }; deleteUserTags = async ( - input: SdkApiTypes.TDeleteUserTagsBody, + input: SdkTypes.DeleteUserTagsRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -2276,7 +2278,7 @@ export class TurnkeySDKClientBase { }; stampDeleteUserTags = async ( - input: SdkApiTypes.TDeleteUserTagsBody, + input: SdkTypes.DeleteUserTagsRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -2296,9 +2298,9 @@ export class TurnkeySDKClientBase { }; deleteUsers = async ( - input: SdkApiTypes.TDeleteUsersBody, + input: SdkTypes.DeleteUsersRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -2320,7 +2322,7 @@ export class TurnkeySDKClientBase { }; stampDeleteUsers = async ( - input: SdkApiTypes.TDeleteUsersBody, + input: SdkTypes.DeleteUsersRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -2339,9 +2341,9 @@ export class TurnkeySDKClientBase { }; deleteWallets = async ( - input: SdkApiTypes.TDeleteWalletsBody, + input: SdkTypes.DeleteWalletsRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -2363,7 +2365,7 @@ export class TurnkeySDKClientBase { }; stampDeleteWallets = async ( - input: SdkApiTypes.TDeleteWalletsBody, + input: SdkTypes.DeleteWalletsRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -2382,9 +2384,9 @@ export class TurnkeySDKClientBase { }; emailAuth = async ( - input: SdkApiTypes.TEmailAuthBody, + input: SdkTypes.EmailAuthRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -2406,7 +2408,7 @@ export class TurnkeySDKClientBase { }; stampEmailAuth = async ( - input: SdkApiTypes.TEmailAuthBody, + input: SdkTypes.EmailAuthRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -2425,9 +2427,9 @@ export class TurnkeySDKClientBase { }; exportPrivateKey = async ( - input: SdkApiTypes.TExportPrivateKeyBody, + input: SdkTypes.ExportPrivateKeyRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -2449,7 +2451,7 @@ export class TurnkeySDKClientBase { }; stampExportPrivateKey = async ( - input: SdkApiTypes.TExportPrivateKeyBody, + input: SdkTypes.ExportPrivateKeyRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -2469,9 +2471,9 @@ export class TurnkeySDKClientBase { }; exportWallet = async ( - input: SdkApiTypes.TExportWalletBody, + input: SdkTypes.ExportWalletRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -2493,7 +2495,7 @@ export class TurnkeySDKClientBase { }; stampExportWallet = async ( - input: SdkApiTypes.TExportWalletBody, + input: SdkTypes.ExportWalletRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -2512,9 +2514,9 @@ export class TurnkeySDKClientBase { }; exportWalletAccount = async ( - input: SdkApiTypes.TExportWalletAccountBody, + input: SdkTypes.ExportWalletAccountRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -2536,7 +2538,7 @@ export class TurnkeySDKClientBase { }; stampExportWalletAccount = async ( - input: SdkApiTypes.TExportWalletAccountBody, + input: SdkTypes.ExportWalletAccountRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -2556,9 +2558,9 @@ export class TurnkeySDKClientBase { }; importPrivateKey = async ( - input: SdkApiTypes.TImportPrivateKeyBody, + input: SdkTypes.ImportPrivateKeyRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -2580,7 +2582,7 @@ export class TurnkeySDKClientBase { }; stampImportPrivateKey = async ( - input: SdkApiTypes.TImportPrivateKeyBody, + input: SdkTypes.ImportPrivateKeyRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -2600,9 +2602,9 @@ export class TurnkeySDKClientBase { }; importWallet = async ( - input: SdkApiTypes.TImportWalletBody, + input: SdkTypes.ImportWalletRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -2624,7 +2626,7 @@ export class TurnkeySDKClientBase { }; stampImportWallet = async ( - input: SdkApiTypes.TImportWalletBody, + input: SdkTypes.ImportWalletRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -2643,9 +2645,9 @@ export class TurnkeySDKClientBase { }; initImportPrivateKey = async ( - input: SdkApiTypes.TInitImportPrivateKeyBody, + input: SdkTypes.InitImportPrivateKeyRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -2667,7 +2669,7 @@ export class TurnkeySDKClientBase { }; stampInitImportPrivateKey = async ( - input: SdkApiTypes.TInitImportPrivateKeyBody, + input: SdkTypes.InitImportPrivateKeyRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -2687,9 +2689,9 @@ export class TurnkeySDKClientBase { }; initImportWallet = async ( - input: SdkApiTypes.TInitImportWalletBody, + input: SdkTypes.InitImportWalletRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -2711,7 +2713,7 @@ export class TurnkeySDKClientBase { }; stampInitImportWallet = async ( - input: SdkApiTypes.TInitImportWalletBody, + input: SdkTypes.InitImportWalletRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -2731,9 +2733,9 @@ export class TurnkeySDKClientBase { }; initOtp = async ( - input: SdkApiTypes.TInitOtpBody, + input: SdkTypes.InitOtpRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -2755,7 +2757,7 @@ export class TurnkeySDKClientBase { }; stampInitOtp = async ( - input: SdkApiTypes.TInitOtpBody, + input: SdkTypes.InitOtpRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -2774,9 +2776,9 @@ export class TurnkeySDKClientBase { }; initOtpAuth = async ( - input: SdkApiTypes.TInitOtpAuthBody, + input: SdkTypes.InitOtpAuthRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -2798,7 +2800,7 @@ export class TurnkeySDKClientBase { }; stampInitOtpAuth = async ( - input: SdkApiTypes.TInitOtpAuthBody, + input: SdkTypes.InitOtpAuthRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -2817,9 +2819,9 @@ export class TurnkeySDKClientBase { }; initUserEmailRecovery = async ( - input: SdkApiTypes.TInitUserEmailRecoveryBody, + input: SdkTypes.InitUserEmailRecoveryRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -2841,7 +2843,7 @@ export class TurnkeySDKClientBase { }; stampInitUserEmailRecovery = async ( - input: SdkApiTypes.TInitUserEmailRecoveryBody, + input: SdkTypes.InitUserEmailRecoveryRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -2861,9 +2863,9 @@ export class TurnkeySDKClientBase { }; oauth = async ( - input: SdkApiTypes.TOauthBody, + input: SdkTypes.OauthRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -2885,7 +2887,7 @@ export class TurnkeySDKClientBase { }; stampOauth = async ( - input: SdkApiTypes.TOauthBody, + input: SdkTypes.OauthRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -2904,9 +2906,9 @@ export class TurnkeySDKClientBase { }; oauthLogin = async ( - input: SdkApiTypes.TOauthLoginBody, + input: SdkTypes.OauthLoginRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -2928,7 +2930,7 @@ export class TurnkeySDKClientBase { }; stampOauthLogin = async ( - input: SdkApiTypes.TOauthLoginBody, + input: SdkTypes.OauthLoginRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -2947,9 +2949,9 @@ export class TurnkeySDKClientBase { }; otpAuth = async ( - input: SdkApiTypes.TOtpAuthBody, + input: SdkTypes.OtpAuthRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -2971,7 +2973,7 @@ export class TurnkeySDKClientBase { }; stampOtpAuth = async ( - input: SdkApiTypes.TOtpAuthBody, + input: SdkTypes.OtpAuthRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -2990,9 +2992,9 @@ export class TurnkeySDKClientBase { }; otpLogin = async ( - input: SdkApiTypes.TOtpLoginBody, + input: SdkTypes.OtpLoginRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -3014,7 +3016,7 @@ export class TurnkeySDKClientBase { }; stampOtpLogin = async ( - input: SdkApiTypes.TOtpLoginBody, + input: SdkTypes.OtpLoginRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -3033,9 +3035,9 @@ export class TurnkeySDKClientBase { }; recoverUser = async ( - input: SdkApiTypes.TRecoverUserBody, + input: SdkTypes.RecoverUserRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -3057,7 +3059,7 @@ export class TurnkeySDKClientBase { }; stampRecoverUser = async ( - input: SdkApiTypes.TRecoverUserBody, + input: SdkTypes.RecoverUserRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -3076,9 +3078,9 @@ export class TurnkeySDKClientBase { }; rejectActivity = async ( - input: SdkApiTypes.TRejectActivityBody, + input: SdkTypes.RejectActivityRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -3098,7 +3100,7 @@ export class TurnkeySDKClientBase { }; stampRejectActivity = async ( - input: SdkApiTypes.TRejectActivityBody, + input: SdkTypes.RejectActivityRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -3118,9 +3120,9 @@ export class TurnkeySDKClientBase { }; removeOrganizationFeature = async ( - input: SdkApiTypes.TRemoveOrganizationFeatureBody, + input: SdkTypes.RemoveOrganizationFeatureRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -3142,7 +3144,7 @@ export class TurnkeySDKClientBase { }; stampRemoveOrganizationFeature = async ( - input: SdkApiTypes.TRemoveOrganizationFeatureBody, + input: SdkTypes.RemoveOrganizationFeatureRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -3162,9 +3164,9 @@ export class TurnkeySDKClientBase { }; setOrganizationFeature = async ( - input: SdkApiTypes.TSetOrganizationFeatureBody, + input: SdkTypes.SetOrganizationFeatureRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -3186,7 +3188,7 @@ export class TurnkeySDKClientBase { }; stampSetOrganizationFeature = async ( - input: SdkApiTypes.TSetOrganizationFeatureBody, + input: SdkTypes.SetOrganizationFeatureRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -3206,9 +3208,9 @@ export class TurnkeySDKClientBase { }; signRawPayload = async ( - input: SdkApiTypes.TSignRawPayloadBody, + input: SdkTypes.SignRawPayloadRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -3230,7 +3232,7 @@ export class TurnkeySDKClientBase { }; stampSignRawPayload = async ( - input: SdkApiTypes.TSignRawPayloadBody, + input: SdkTypes.SignRawPayloadRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -3250,9 +3252,9 @@ export class TurnkeySDKClientBase { }; signRawPayloads = async ( - input: SdkApiTypes.TSignRawPayloadsBody, + input: SdkTypes.SignRawPayloadsRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -3274,7 +3276,7 @@ export class TurnkeySDKClientBase { }; stampSignRawPayloads = async ( - input: SdkApiTypes.TSignRawPayloadsBody, + input: SdkTypes.SignRawPayloadsRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -3294,9 +3296,9 @@ export class TurnkeySDKClientBase { }; signTransaction = async ( - input: SdkApiTypes.TSignTransactionBody, + input: SdkTypes.SignTransactionRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -3318,7 +3320,7 @@ export class TurnkeySDKClientBase { }; stampSignTransaction = async ( - input: SdkApiTypes.TSignTransactionBody, + input: SdkTypes.SignTransactionRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -3338,9 +3340,9 @@ export class TurnkeySDKClientBase { }; stampLogin = async ( - input: SdkApiTypes.TStampLoginBody, + input: SdkTypes.StampLoginRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -3362,7 +3364,7 @@ export class TurnkeySDKClientBase { }; stampStampLogin = async ( - input: SdkApiTypes.TStampLoginBody, + input: SdkTypes.StampLoginRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -3381,9 +3383,9 @@ export class TurnkeySDKClientBase { }; updatePolicy = async ( - input: SdkApiTypes.TUpdatePolicyBody, + input: SdkTypes.UpdatePolicyRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -3405,7 +3407,7 @@ export class TurnkeySDKClientBase { }; stampUpdatePolicy = async ( - input: SdkApiTypes.TUpdatePolicyBody, + input: SdkTypes.UpdatePolicyRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -3424,9 +3426,9 @@ export class TurnkeySDKClientBase { }; updatePrivateKeyTag = async ( - input: SdkApiTypes.TUpdatePrivateKeyTagBody, + input: SdkTypes.UpdatePrivateKeyTagRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -3448,7 +3450,7 @@ export class TurnkeySDKClientBase { }; stampUpdatePrivateKeyTag = async ( - input: SdkApiTypes.TUpdatePrivateKeyTagBody, + input: SdkTypes.UpdatePrivateKeyTagRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -3468,9 +3470,9 @@ export class TurnkeySDKClientBase { }; updateRootQuorum = async ( - input: SdkApiTypes.TUpdateRootQuorumBody, + input: SdkTypes.UpdateRootQuorumRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -3492,7 +3494,7 @@ export class TurnkeySDKClientBase { }; stampUpdateRootQuorum = async ( - input: SdkApiTypes.TUpdateRootQuorumBody, + input: SdkTypes.UpdateRootQuorumRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -3512,9 +3514,9 @@ export class TurnkeySDKClientBase { }; updateUser = async ( - input: SdkApiTypes.TUpdateUserBody, + input: SdkTypes.UpdateUserRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -3536,7 +3538,7 @@ export class TurnkeySDKClientBase { }; stampUpdateUser = async ( - input: SdkApiTypes.TUpdateUserBody, + input: SdkTypes.UpdateUserRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -3555,9 +3557,9 @@ export class TurnkeySDKClientBase { }; updateUserTag = async ( - input: SdkApiTypes.TUpdateUserTagBody, + input: SdkTypes.UpdateUserTagRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -3579,7 +3581,7 @@ export class TurnkeySDKClientBase { }; stampUpdateUserTag = async ( - input: SdkApiTypes.TUpdateUserTagBody, + input: SdkTypes.UpdateUserTagRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -3599,9 +3601,9 @@ export class TurnkeySDKClientBase { }; updateWallet = async ( - input: SdkApiTypes.TUpdateWalletBody, + input: SdkTypes.UpdateWalletRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -3623,7 +3625,7 @@ export class TurnkeySDKClientBase { }; stampUpdateWallet = async ( - input: SdkApiTypes.TUpdateWalletBody, + input: SdkTypes.UpdateWalletRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -3642,9 +3644,9 @@ export class TurnkeySDKClientBase { }; verifyOtp = async ( - input: SdkApiTypes.TVerifyOtpBody, + input: SdkTypes.VerifyOtpRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -3666,7 +3668,7 @@ export class TurnkeySDKClientBase { }; stampVerifyOtp = async ( - input: SdkApiTypes.TVerifyOtpBody, + input: SdkTypes.VerifyOtpRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -3685,9 +3687,9 @@ export class TurnkeySDKClientBase { }; testRateLimits = async ( - input: SdkApiTypes.TTestRateLimitsBody, + input: SdkTypes.TestRateLimitsRequest, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -3704,7 +3706,7 @@ export class TurnkeySDKClientBase { }; stampTestRateLimits = async ( - input: SdkApiTypes.TTestRateLimitsBody, + input: SdkTypes.TestRateLimitsRequest, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); diff --git a/packages/sdk-js/src/__types__/base.ts b/packages/sdk-js/src/__types__/base.ts index ec706b353..a8554df6a 100644 --- a/packages/sdk-js/src/__types__/base.ts +++ b/packages/sdk-js/src/__types__/base.ts @@ -4,9 +4,9 @@ import type { WebauthnStamper } from "@turnkey/webauthn-stamper"; import type { IndexedDbStamper } from "@turnkey/indexed-db-stamper"; import type { SessionType, - User, - Wallet, - WalletAccount, + v1User, + v1Wallet, + v1WalletAccount, } from "@turnkey/sdk-types"; import { StorageBase } from "../__storage__/base"; import { TPasskeyStamperConfig } from "../__stampers__/passkey/base"; @@ -165,10 +165,10 @@ export interface LoginWithWalletParams { publicKey?: string; } -export type TUser = User; // TODO (Amir): I dunno if we need this. We may want to add more stuff to the user type in the future, so let's keep it for now since +export type TUser = v1User; // TODO (Amir): I dunno if we need this. We may want to add more stuff to the user type in the future, so let's keep it for now since -export type TWallet = Wallet & { - accounts?: WalletAccount[] | undefined; +export type TWallet = v1Wallet & { + accounts?: v1WalletAccount[] | undefined; }; /** diff --git a/packages/sdk-types/scripts/codegen.js b/packages/sdk-types/scripts/codegen.js index b4ee5d79b..029b042fa 100644 --- a/packages/sdk-types/scripts/codegen.js +++ b/packages/sdk-types/scripts/codegen.js @@ -31,6 +31,20 @@ const VERSIONED_ACTIVITY_TYPES = { ACTIVITY_TYPE_INIT_OTP_AUTH: "ACTIVITY_TYPE_INIT_OTP_AUTH_V2", }; +const METHODS_WITH_ONLY_OPTIONAL_PARAMETERS = [ + "getActivities", + "getApiKeys", + "getOrganization", + "getPolicies", + "getPrivateKeys", + "getSubOrgIds", + "getUsers", + "getWallets", + "getWhoami", + "listPrivateKeys", + "listUserTags", +]; + // Helper: Convert Swagger type to TS type /** * @param {string} type @@ -74,75 +88,41 @@ function refToTs(ref) { return ref.replace(/^#\/definitions\//, ""); } -/** - * Maps activity types to their most recent versions in VERSIONED_ACTIVITY_TYPES. - * If a type has multiple versions, it will return the latest one based on the versioning scheme. - * @param {object} definitions - Swagger definitions object - * @returns {object} - Map of base type to most recent versioned type - */ -function buildLatestVersionMap(definitions) { - const versionMap = {}; - - // Group definitions by their base name (without version) - const groupedDefs = {}; - for (const defName of Object.keys(definitions)) { - if (!defName.match(/^v\d+/)) { - continue; - } - - const baseName = stripVersionPrefixAndSuffix(defName); - - if (!groupedDefs[baseName]) { - groupedDefs[baseName] = []; - } - groupedDefs[baseName].push(defName); - } - - // For each group, find the latest versioned type - for (const [baseName, defNames] of Object.entries(groupedDefs)) { - // Remove REQUEST/RESPONSE/RESULT/INTENT suffix for activityTypeKey - const activityBase = baseName.replace( - /(Request|Response|Result|Intent)$/, - "", - ); - const activityTypeKey = `ACTIVITY_TYPE_${activityBase.replace(/([a-z])([A-Z])/g, "$1_$2").toUpperCase()}`; - const mappedVersion = VERSIONED_ACTIVITY_TYPES[activityTypeKey]; - if (mappedVersion) { - const versionSuffixMatch = mappedVersion.match(/(V\d+)$/); - const versionSuffix = versionSuffixMatch ? versionSuffixMatch[1] : ""; - // Try to find a defName that ends with the version suffix (e.g., V2) - const matchedDef = defNames.find((name) => name.endsWith(versionSuffix)); - if (matchedDef) { - versionMap[baseName] = matchedDef; - continue; - } - } - let latest = defNames[0]; - let latestVersion = 1; - for (const name of defNames) { - const match = name.match(/V(\d+)$/); - const version = match ? parseInt(match[1], 10) : 1; - if (version > latestVersion) { - latest = name; - latestVersion = version; +// Helper that takes in swagger definitions and returns a map containing the latest version of a field. +// The intent is to consolidate a field with multiple versions (e.g. v1CreateSubOrganizationResult, v1CreateSubOrganizationResultV2...) +// in order to get just the latest (v1CreateSubOrganizationResultV4). +function extractLatestVersions(definitions) { + const latestVersions = {}; + + // Regex to separate the version prefix, base activity details, and (optional) activity version + const keyVersionRegex = /^(v\d+)([A-Z][a-z]+(?:[A-Z][a-z]+)*)(V\d+)?$/; + + Object.keys(definitions).forEach((key) => { + const match = key.match(keyVersionRegex); + if (match) { + const fullName = match[0]; + const baseName = match[2]; // Field without any version-related prefixes or suffixes + const versionSuffix = match[3]; // Version (optional) + const formattedKeyName = + baseName.charAt(0).toLowerCase() + + baseName.slice(1) + + (versionSuffix || ""); // Reconstruct the original key with version + + // Determine if this version is newer or if no version was previously stored + if ( + !latestVersions[baseName] || + versionSuffix > (latestVersions[baseName].versionSuffix || "") + ) { + latestVersions[baseName] = { + fullName, + formattedKeyName, + versionSuffix, + }; } } - versionMap[baseName] = latest; - } + }); - return versionMap; -} - -/** - * Strip both prefix and suffix version numbers - * @param {string} name - Type name with version info - * @returns {string} - Clean base name - */ -function stripVersionPrefixAndSuffix(name) { - let baseName = stripVersionPrefix(name); - baseName = baseName.replace(/V\d+$/, ""); - - return baseName; + return latestVersions; } /** @@ -153,6 +133,29 @@ function isValidIdentifier(name) { return /^[$A-Z_][0-9A-Z_$]*$/i.test(name); } +/** + * @param {string} methodName + * @returns {string} + */ +function methodTypeFromMethodName(methodName) { + if (["approveActivity", "rejectActivity"].includes(methodName)) { + return "activityDecision"; + } + if (methodName.startsWith("nOOP")) { + return "noop"; + } + // TODO: filter out unnecessary client methods, whether here or from the source + if ( + methodName.startsWith("get") || + methodName.startsWith("list") || + methodName.startsWith("test") + ) { + return "query"; + } + // Rename to submit? + return "command"; +} + /** * @param {string} name * @param {object} def @@ -191,7 +194,229 @@ function generateTsType(name, def) { if (def.type === "string" && def.enum) { return `export type ${name} =\n ${def.enum.map((e) => `"${e}"`).join(" |\n ")};\n`; } - return `export type ${name} = any;\n`; + return `export type ${name} = {};\n`; +} + +function generateInlineProperties(def, isAllOptional = false) { + let out = ""; + if (def && def.properties) { + const requiredProps = Array.isArray(def.required) ? def.required : []; + for (const [prop, schema] of Object.entries(def.properties)) { + let type = "any"; + if (schema.$ref) { + type = refToTs(schema.$ref); + } else if (schema.type) { + type = swaggerTypeToTs(schema.type, schema); + } + const desc = schema.description ? ` /** ${schema.description} */\n` : ""; + const propName = isValidIdentifier(prop) ? prop : `"${prop}"`; + const required = isAllOptional + ? "?" + : requiredProps.includes(prop) + ? "" + : "?"; + out += `${desc} ${propName}${required}: ${type};\n`; + } + } + return out; +} + +function generateApiTypes(swagger) { + const namespace = swagger.tags?.find((item) => item.name != null)?.name; + let output = ""; + const latestVersions = extractLatestVersions(swagger.definitions); + const definitions = swagger.definitions; + + for (const [path, methods] of Object.entries(swagger.paths)) { + const methodMap = swagger.paths[path]; + const operation = methodMap.post; + const operationId = operation && operation.operationId; + + const operationNameWithoutNamespace = operationId.replace( + new RegExp(`${namespace}_`), + "", + ); + const methodName = + operationNameWithoutNamespace.charAt(0).toLowerCase() + + operationNameWithoutNamespace.slice(1); + const methodType = methodTypeFromMethodName(methodName); + + // Get response schema $ref + const responseSchema = + operation.responses && + operation.responses["200"] && + operation.responses["200"].schema && + operation.responses["200"].schema.$ref; + const responseTypeName = responseSchema ? refToTs(responseSchema) : null; + + // Compose API Response type name + const apiTypeName = + operationNameWithoutNamespace.replace(/^./, (c) => c.toUpperCase()) + + "Response"; + const apiRequestTypeName = + operationNameWithoutNamespace.replace(/^./, (c) => c.toUpperCase()) + + "Request"; + + // --- RESPONSE TYPE GENERATION --- + if (methodType === "command") { + // Try to find the corresponding Result type from the response schema or activity type + let resultTypeName = null; + let activityTypeKey = null; + let versionSuffix = null; + + const parameters = operation.parameters || []; + for (const param of parameters) { + if ( + param.in === "body" && + param.schema && + param.schema.$ref && + definitions[refToTs(param.schema.$ref)] + ) { + const reqDef = definitions[refToTs(param.schema.$ref)]; + if ( + reqDef.properties && + reqDef.properties.type && + reqDef.properties.type.enum && + reqDef.properties.type.enum.length > 0 + ) { + // Compose the activity type key from the request type + // Example: v1CreatePoliciesRequest -> ACTIVITY_TYPE_CREATE_POLICIES + const reqTypeName = refToTs(param.schema.$ref); + const baseActivity = reqTypeName + .replace(/^v\d+/, "") + .replace(/Request(V\d+)?$/, ""); + activityTypeKey = reqDef.properties.type.enum[0]; + const mapped = VERSIONED_ACTIVITY_TYPES[activityTypeKey]; + if (mapped) { + // Extract version suffix from mapped value + const mappedVersionSuffixMatch = mapped.match(/(V\d+)$/); + versionSuffix = mappedVersionSuffixMatch + ? mappedVersionSuffixMatch[1] + : ""; + } + // Now, find the latest version of the Result type using latestVersions + const resultBase = baseActivity + "Result"; + let resultKey = null; + if (latestVersions[resultBase]) { + // If versionSuffix is present, use it to pick the correct version + if (versionSuffix) { + const candidate = Object.keys(definitions).find( + (k) => + k.startsWith("v1" + baseActivity + "Result") && + k.endsWith(versionSuffix), + ); + if (candidate) { + resultKey = candidate; + } + } + // Fallback to latest version if not found + if (!resultKey) { + resultKey = latestVersions[resultBase].fullName; + } + } + if (resultKey) { + resultTypeName = resultKey; + } + } + } + } + + // Compose the type + output += `export type ${apiTypeName} = {\n activity: v1Activity;\n`; + if (resultTypeName && definitions[resultTypeName]) { + output += generateInlineProperties(definitions[resultTypeName]); + } + output += "}\n\n"; + } else if (methodType === "query" || methodType === "noop") { + const respDef = definitions[responseTypeName]; + if (respDef) { + if (respDef.properties) { + output += `export type ${apiTypeName} = {\n`; + output += generateInlineProperties(respDef); + output += "}\n\n"; + } else { + output += `export type ${apiTypeName} = {};\n\n`; + } + } + } else if (methodType === "activityDecision") { + const activityType = definitions[responseTypeName]; + if (activityType && activityType.properties) { + output += `export type ${apiTypeName} = {\n`; + output += generateInlineProperties(activityType); + output += "}\n\n"; + } + } + + // --- REQUEST TYPE GENERATION --- + // Find the request type definition + let requestTypeDef = null; + let requestTypeName = null; + const parameters = operation.parameters || []; + for (const param of parameters) { + if ( + param.in === "body" && + param.schema && + param.schema.$ref && + definitions[refToTs(param.schema.$ref)] + ) { + requestTypeName = refToTs(param.schema.$ref); + requestTypeDef = definitions[requestTypeName]; + } + } + + if (!requestTypeDef) continue; + + output += `export type ${apiRequestTypeName} = {\n`; + + if (methodType === "command" || methodType === "activityDecision") { + output += ` timestampMs?: string;\n organizationId?: string;\n`; + if ( + requestTypeDef.properties && + requestTypeDef.properties.parameters && + requestTypeDef.properties.parameters.$ref + ) { + const isAllOptional = + METHODS_WITH_ONLY_OPTIONAL_PARAMETERS.includes(methodName); + const intentTypeName = refToTs( + requestTypeDef.properties.parameters.$ref, + ); + const intentDef = definitions[intentTypeName]; + output += generateInlineProperties(intentDef, isAllOptional); + } + } else if (methodType === "query" || methodType === "noop") { + output += ` organizationId?: string;\n`; + if (requestTypeDef.properties) { + const isAllOptional = + METHODS_WITH_ONLY_OPTIONAL_PARAMETERS.includes(methodName); + const requiredProps = Array.isArray(requestTypeDef.required) + ? requestTypeDef.required + : []; + for (const [prop, schema] of Object.entries( + requestTypeDef.properties, + )) { + if (prop === "organizationId") continue; + let type = "any"; + if (schema.$ref) { + type = refToTs(schema.$ref); + } else if (schema.type) { + type = swaggerTypeToTs(schema.type, schema); + } + const desc = schema.description + ? ` /** ${schema.description} */\n` + : ""; + const propName = isValidIdentifier(prop) ? prop : `"${prop}"`; + const required = isAllOptional + ? "?" + : requiredProps.includes(prop) + ? "" + : "?"; + output += `${desc} ${propName}${required}: ${type};\n`; + } + } + } + output += "}\n\n"; + } + return output; } function main() { @@ -215,122 +440,21 @@ function main() { // --- Base Types --- output += `// --- Base Types from Swagger Definitions ---\n`; - // First generate all versioned types for (const [defName, def] of Object.entries(swagger.definitions)) { - // Only parse object and enum types if ( (def.type === "object" && def.properties) || (def.type === "string" && def.enum) ) { output += generateTsType(defName, def) + "\n"; } else { - output += `export type ${defName} = any;\n`; + output += `export type ${defName} = {};\n`; } } - // Build a map of base types to their latest versioned counterparts - const latestVersionMap = buildLatestVersionMap(swagger.definitions); - - // Check all Request types for organizationId, if present modify their respective Intent types and add optional organizationId - // Also check Result types and add Response type for them - for (const [baseName, latestVersionName] of Object.entries( - latestVersionMap, - )) { - const def = swagger.definitions[latestVersionName]; - if (def && def.type === "object" && def.properties) { - // If the baseName ends with "Request", check for organizationId - - if (baseName.endsWith("Request") && def.properties.organizationId) { - // Modify the corresponding Intent type to make organizationId optional - const intentTypeName = latestVersionName.replace(/Request$/, "Intent"); - if ( - swagger.definitions[intentTypeName] && - swagger.definitions[intentTypeName].properties - ) { - if (swagger.definitions[intentTypeName]?.organizationId) { - swagger.definitions[intentTypeName].organizationId = { - ...swagger.definitions[intentTypeName]?.properties.organizationId, - required: false, - }; - } - // Add organizationId if it doesn't exist - if (!swagger.definitions[intentTypeName]?.organizationId) { - swagger.definitions[intentTypeName].properties.organizationId = { - type: "string", - description: "Unique identifier for a given Organization.", - }; - } - // Always make it optional - swagger.definitions[intentTypeName].required = ( - swagger.definitions[intentTypeName].required || [] - ).filter((r) => r !== "organizationId"); - } - } else if ( - baseName.endsWith("Result") && - !/^v\d+Result$/.test(latestVersionName) - ) { - // If baseName ends with "Result" and not just vXResult, create a corresponding Response type - if (swagger.definitions[latestVersionName]) { - const responseTypeName = stripVersionPrefixAndSuffix( - latestVersionName.replace( - /(.+)Result$/, - (m, p1) => `${p1}Response`, - ), - ); - - swagger.definitions[responseTypeName] = { - type: "object", - properties: { - activity: { - $ref: `#/definitions/v1Activity`, - description: "The activity that was processed.", - }, - ...swagger.definitions[latestVersionName].properties, - }, - required: [ - "activity", - ...(Array.isArray(swagger.definitions[latestVersionName].required) - ? swagger.definitions[latestVersionName].required - : []), - ], - }; - - console.log(swagger.definitions[responseTypeName]); - - // Add the new Response type to latestVersionMap - latestVersionMap[responseTypeName] = responseTypeName; - } - } - } - } + // -- Api Types -- + output += "\n// --- API Types from Swagger Paths ---\n"; - // Then generate the abstracted types that reference the correct versioned types - output += "\n// --- Latest Version Type Aliases ---\n"; - for (const [baseName, latestVersionName] of Object.entries( - latestVersionMap, - )) { - const def = swagger.definitions[latestVersionName]; - - if ( - /(.+)Intent$/.test(baseName) && - def && - def.type === "object" && - def.properties - ) { - const requestTypeName = baseName.replace(/Intent$/, "Request"); - output += generateTsType(requestTypeName, def) + "\n"; - } - - if (/(.+)Intent$/.test(baseName) || /(.+)Request$/.test(baseName)) { - continue; - } - - if (def && def.type === "object" && def.properties) { - output += generateTsType(baseName, def) + "\n"; - } else { - output += `export type ${baseName} = ${latestVersionName};\n`; - } - } + output += generateApiTypes(swagger); fs.writeFileSync(outputPath, output); } diff --git a/packages/sdk-types/src/__generated__/types.ts b/packages/sdk-types/src/__generated__/types.ts index ce3665f7f..aa9f679ba 100644 --- a/packages/sdk-types/src/__generated__/types.ts +++ b/packages/sdk-types/src/__generated__/types.ts @@ -268,7 +268,11 @@ export type v1ActivityType = | "ACTIVITY_TYPE_VERIFY_OTP" | "ACTIVITY_TYPE_OTP_LOGIN" | "ACTIVITY_TYPE_STAMP_LOGIN" - | "ACTIVITY_TYPE_OAUTH_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"; export type v1AddressFormat = | "ADDRESS_FORMAT_UNCOMPRESSED" @@ -690,7 +694,7 @@ export type v1CreatePrivateKeysResultV2 = { privateKeys: v1PrivateKeyResult[]; }; -export type v1CreateReadOnlySessionIntent = any; +export type v1CreateReadOnlySessionIntent = {}; export type v1CreateReadOnlySessionRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ @@ -1431,6 +1435,73 @@ export type v1FeatureName = | "FEATURE_NAME_SMS_AUTH" | "FEATURE_NAME_OTP_EMAIL_AUTH"; +export type v1FiatOnRampBlockchainNetwork = + | "FIAT_ON_RAMP_BLOCKCHAIN_NETWORK_BITCOIN" + | "FIAT_ON_RAMP_BLOCKCHAIN_NETWORK_ETHEREUM" + | "FIAT_ON_RAMP_BLOCKCHAIN_NETWORK_SOLANA" + | "FIAT_ON_RAMP_BLOCKCHAIN_NETWORK_BASE"; + +export type v1FiatOnRampCryptoCurrency = + | "FIAT_ON_RAMP_CRYPTO_CURRENCY_BTC" + | "FIAT_ON_RAMP_CRYPTO_CURRENCY_ETH" + | "FIAT_ON_RAMP_CRYPTO_CURRENCY_SOL" + | "FIAT_ON_RAMP_CRYPTO_CURRENCY_USDC"; + +export type v1FiatOnRampCurrency = + | "FIAT_ON_RAMP_CURRENCY_AUD" + | "FIAT_ON_RAMP_CURRENCY_BGN" + | "FIAT_ON_RAMP_CURRENCY_BRL" + | "FIAT_ON_RAMP_CURRENCY_CAD" + | "FIAT_ON_RAMP_CURRENCY_CHF" + | "FIAT_ON_RAMP_CURRENCY_COP" + | "FIAT_ON_RAMP_CURRENCY_CZK" + | "FIAT_ON_RAMP_CURRENCY_DKK" + | "FIAT_ON_RAMP_CURRENCY_DOP" + | "FIAT_ON_RAMP_CURRENCY_EGP" + | "FIAT_ON_RAMP_CURRENCY_EUR" + | "FIAT_ON_RAMP_CURRENCY_GBP" + | "FIAT_ON_RAMP_CURRENCY_HKD" + | "FIAT_ON_RAMP_CURRENCY_IDR" + | "FIAT_ON_RAMP_CURRENCY_ILS" + | "FIAT_ON_RAMP_CURRENCY_JOD" + | "FIAT_ON_RAMP_CURRENCY_KES" + | "FIAT_ON_RAMP_CURRENCY_KWD" + | "FIAT_ON_RAMP_CURRENCY_LKR" + | "FIAT_ON_RAMP_CURRENCY_MXN" + | "FIAT_ON_RAMP_CURRENCY_NGN" + | "FIAT_ON_RAMP_CURRENCY_NOK" + | "FIAT_ON_RAMP_CURRENCY_NZD" + | "FIAT_ON_RAMP_CURRENCY_OMR" + | "FIAT_ON_RAMP_CURRENCY_PEN" + | "FIAT_ON_RAMP_CURRENCY_PLN" + | "FIAT_ON_RAMP_CURRENCY_RON" + | "FIAT_ON_RAMP_CURRENCY_SEK" + | "FIAT_ON_RAMP_CURRENCY_THB" + | "FIAT_ON_RAMP_CURRENCY_TRY" + | "FIAT_ON_RAMP_CURRENCY_TWD" + | "FIAT_ON_RAMP_CURRENCY_USD" + | "FIAT_ON_RAMP_CURRENCY_VND" + | "FIAT_ON_RAMP_CURRENCY_ZAR"; + +export type v1FiatOnRampPaymentMethod = + | "FIAT_ON_RAMP_PAYMENT_METHOD_CREDIT_DEBIT_CARD" + | "FIAT_ON_RAMP_PAYMENT_METHOD_APPLE_PAY" + | "FIAT_ON_RAMP_PAYMENT_METHOD_GBP_BANK_TRANSFER" + | "FIAT_ON_RAMP_PAYMENT_METHOD_GBP_OPEN_BANKING_PAYMENT" + | "FIAT_ON_RAMP_PAYMENT_METHOD_GOOGLE_PAY" + | "FIAT_ON_RAMP_PAYMENT_METHOD_SEPA_BANK_TRANSFER" + | "FIAT_ON_RAMP_PAYMENT_METHOD_PIX_INSTANT_PAYMENT" + | "FIAT_ON_RAMP_PAYMENT_METHOD_PAYPAL" + | "FIAT_ON_RAMP_PAYMENT_METHOD_VENMO" + | "FIAT_ON_RAMP_PAYMENT_METHOD_MOONPAY_BALANCE" + | "FIAT_ON_RAMP_PAYMENT_METHOD_CRYPTO_ACCOUNT" + | "FIAT_ON_RAMP_PAYMENT_METHOD_FIAT_WALLET" + | "FIAT_ON_RAMP_PAYMENT_METHOD_ACH_BANK_ACCOUNT"; + +export type v1FiatOnRampProvider = + | "FIAT_ON_RAMP_PROVIDER_COINBASE" + | "FIAT_ON_RAMP_PROVIDER_MOONPAY"; + export type v1GetActivitiesRequest = { /** Unique identifier for a given Organization. */ organizationId: string; @@ -1774,6 +1845,43 @@ export type v1ImportWalletResult = { addresses: string[]; }; +export type v1InitFiatOnRampIntent = { + /** Enum to specifiy which on-ramp provider to use */ + onrampProvider: v1FiatOnRampProvider; + /** Destination wallet address for the buy transaction. */ + walletAddress: string; + /** Blockchain network to be used for the transaction, e.g., bitcoin, ethereum. Maps to MoonPay's network or Coinbase's defaultNetwork. */ + network: v1FiatOnRampBlockchainNetwork; + /** Code for the cryptocurrency to be purchased, e.g., btc, eth. Maps to MoonPay's currencyCode or Coinbase's defaultAsset. */ + cryptoCurrencyCode: v1FiatOnRampCryptoCurrency; + /** Code for the fiat currency to be used in the transaction, e.g., USD, EUR. */ + fiatCurrencyCode?: v1FiatOnRampCurrency; + /** Specifies a preset fiat amount for the transaction, e.g., '100'. Must be greater than '20'. If not provided, the user will be prompted to enter an amount. */ + fiatCurrencyAmount?: string; + /** Pre-selected payment method, e.g., CREDIT_DEBIT_CARD, APPLE_PAY. Validated against the chosen provider. */ + paymentMethod?: v1FiatOnRampPaymentMethod; + /** ISO 3166-1 two-digit country code for Coinbase representing the purchasing user’s country of residence, e.g., US, GB. */ + countryCode?: string; + /** ISO 3166-2 two-digit country subdivision code for Coinbase representing the purchasing user’s subdivision of residence within their country, e.g. NY. Required if country_code=US. */ + countrySubdivisionCode?: string; +}; + +export type v1InitFiatOnRampRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: v1InitFiatOnRampIntent; +}; + +export type v1InitFiatOnRampResult = { + /** Unique URL for a given fiat on-ramp flow. */ + onRampUrl: string; + /** Unique identifier used to retrieve transaction statuses for a given fiat on-ramp flow. */ + onRampTransactionId: string; +}; + export type v1InitImportPrivateKeyIntent = { /** The ID of the User importing a Private Key. */ userId: string; @@ -2026,6 +2134,10 @@ export type v1Intent = { otpLoginIntent?: v1OtpLoginIntent; stampLoginIntent?: v1StampLoginIntent; oauthLoginIntent?: v1OauthLoginIntent; + updateUserNameIntent?: v1UpdateUserNameIntent; + updateUserEmailIntent?: v1UpdateUserEmailIntent; + updateUserPhoneNumberIntent?: v1UpdateUserPhoneNumberIntent; + initFiatOnRampIntent?: v1InitFiatOnRampIntent; }; export type v1Invitation = { @@ -2468,6 +2580,10 @@ export type v1Result = { otpLoginResult?: v1OtpLoginResult; stampLoginResult?: v1StampLoginResult; oauthLoginResult?: v1OauthLoginResult; + updateUserNameResult?: v1UpdateUserNameResult; + updateUserEmailResult?: v1UpdateUserEmailResult; + updateUserPhoneNumberResult?: v1UpdateUserPhoneNumberResult; + initFiatOnRampResult?: v1InitFiatOnRampResult; }; export type v1RootUserParams = { @@ -2693,7 +2809,7 @@ export type v1TestRateLimitsRequest = { limit: number; }; -export type v1TestRateLimitsResponse = any; +export type v1TestRateLimitsResponse = {}; export type v1TransactionType = | "TRANSACTION_TYPE_ETHEREUM" | "TRANSACTION_TYPE_SOLANA" @@ -2704,7 +2820,7 @@ export type v1UpdateAllowedOriginsIntent = { allowedOrigins: string[]; }; -export type v1UpdateAllowedOriginsResult = any; +export type v1UpdateAllowedOriginsResult = {}; export type v1UpdatePolicyIntent = { /** Unique identifier for a given Policy. */ policyId: string; @@ -2795,7 +2911,30 @@ export type v1UpdateRootQuorumRequest = { parameters: v1UpdateRootQuorumIntent; }; -export type v1UpdateRootQuorumResult = any; +export type v1UpdateRootQuorumResult = {}; +export type v1UpdateUserEmailIntent = { + /** Unique identifier for a given User. */ + userId: string; + /** The user's email address. Setting this to an empty string will remove the user's email. */ + userEmail: string; + /** Signed JWT containing a unique id, expiry, verification type, contact */ + verificationToken?: string; +}; + +export type v1UpdateUserEmailRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: v1UpdateUserEmailIntent; +}; + +export type v1UpdateUserEmailResult = { + /** Unique identifier of the User whose email was updated. */ + userId: string; +}; + export type v1UpdateUserIntent = { /** Unique identifier for a given User. */ userId: string; @@ -2809,6 +2948,50 @@ export type v1UpdateUserIntent = { userPhoneNumber?: string; }; +export type v1UpdateUserNameIntent = { + /** Unique identifier for a given User. */ + userId: string; + /** Human-readable name for a User. */ + userName: string; +}; + +export type v1UpdateUserNameRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: v1UpdateUserNameIntent; +}; + +export type v1UpdateUserNameResult = { + /** Unique identifier of the User whose name was updated. */ + userId: string; +}; + +export type v1UpdateUserPhoneNumberIntent = { + /** Unique identifier for a given User. */ + userId: string; + /** The user's phone number in E.164 format e.g. +13214567890. Setting this to an empty string will remove the user's phone number. */ + userPhoneNumber: string; + /** Signed JWT containing a unique id, expiry, verification type, contact */ + verificationToken?: string; +}; + +export type v1UpdateUserPhoneNumberRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: v1UpdateUserPhoneNumberIntent; +}; + +export type v1UpdateUserPhoneNumberResult = { + /** Unique identifier of the User whose phone number was updated. */ + userId: string; +}; + export type v1UpdateUserRequest = { type: string; /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ @@ -3052,1832 +3235,405 @@ export type v1WebAuthnStamp = { signature: string; }; -// --- Latest Version Type Aliases --- -export type AcceptInvitationRequest = { - /** Unique identifier for a given Invitation object. */ - invitationId: string; - /** Unique identifier for a given User. */ - userId: string; - /** WebAuthN hardware devices that can be used to log in to the Turnkey web app. */ - authenticator: v1AuthenticatorParamsV2; -}; - -export type AcceptInvitationResult = { - /** Unique identifier for a given Invitation. */ - invitationId: string; - /** Unique identifier for a given User. */ - userId: string; +// --- API Types from Swagger Paths --- +export type GetActivityResponse = { + /** An action that can that can be taken within the Turnkey infrastructure. */ + activity: v1Activity; }; -export type AccessType = v1AccessType; -export type Activity = { +export type GetActivityRequest = { + organizationId?: string; /** Unique identifier for a given Activity object. */ - id: string; - /** Unique identifier for a given Organization. */ - organizationId: string; - /** The current processing status of a specified Activity. */ - status: v1ActivityStatus; - /** Type of Activity, such as Add User, or Sign Transaction. */ - type: v1ActivityType; - /** Intent object crafted by Turnkey based on the user request, used to assess the permissibility of an action. */ - intent: v1Intent; - /** Result of the intended action. */ - result: v1Result; - /** A list of objects representing a particular User's approval or rejection of a Consensus request, including all relevant metadata. */ - votes: v1Vote[]; - /** An artifact verifying a User's action. */ - fingerprint: string; - canApprove: boolean; - canReject: boolean; - createdAt: externaldatav1Timestamp; - updatedAt: externaldatav1Timestamp; - /** Failure reason of the intended action. */ - failure?: rpcStatus; + activityId: string; }; -export type ActivityResponse = { - /** An action that can that can be taken within the Turnkey infrastructure. */ - activity: v1Activity; +export type GetApiKeyResponse = { + /** An API key. */ + apiKey: v1ApiKey; }; -export type ActivityStatus = v1ActivityStatus; -export type ActivityType = v1ActivityType; -export type AddressFormat = v1AddressFormat; -export type ApiKey = { - /** A User credential that can be used to authenticate to Turnkey. */ - credential: externaldatav1Credential; - /** Unique identifier for a given API Key. */ +export type GetApiKeyRequest = { + organizationId?: string; + /** Unique identifier for a given API key. */ apiKeyId: string; - /** Human-readable name for an API Key. */ - apiKeyName: string; - createdAt: externaldatav1Timestamp; - updatedAt: externaldatav1Timestamp; - /** Optional window (in seconds) indicating how long the API Key should last. */ - expirationSeconds?: string; }; -export type ApiKeyCurve = v1ApiKeyCurve; -export type ApiKeyParams = { - /** Human-readable name for an API Key. */ - apiKeyName: string; - /** The public component of a cryptographic key pair used to sign messages and transactions. */ - publicKey: string; - /** The curve type to be used for processing API key signatures. */ - curveType: v1ApiKeyCurve; - /** Optional window (in seconds) indicating how long the API Key should last. */ - expirationSeconds?: string; +export type GetApiKeysResponse = { + /** A list of API keys. */ + apiKeys: v1ApiKey[]; }; -export type ApiOnlyUserParams = { - /** The name of the new API-only User. */ - userName: string; - /** The email address for this API-only User (optional). */ - userEmail?: string; - /** A list of tags assigned to the new API-only User. This field, if not needed, should be an empty array in your request body. */ - userTags: string[]; - /** A list of API Key parameters. This field, if not needed, should be an empty array in your request body. */ - apiKeys: apiApiKeyParams[]; +export type GetApiKeysRequest = { + organizationId?: string; + /** Unique identifier for a given User. */ + userId?: string; }; -export type ApproveActivityRequest = { - /** An artifact verifying a User's action. */ - fingerprint: string; - /** Unique identifier for a given Organization. */ +export type GetAttestationDocumentResponse = { + /** Raw (CBOR-encoded) attestation document */ + attestationDocument: string; +}; + +export type GetAttestationDocumentRequest = { organizationId?: string; + /** The enclave type, one of: ump, notarizer, signer, evm-parser */ + enclaveType: string; }; -export type Attestation = { - /** The cbor encoded then base64 url encoded id of the credential. */ - credentialId: string; - /** A base64 url encoded payload containing metadata about the signing context and the challenge. */ - clientDataJson: string; - /** A base64 url encoded payload containing authenticator data and any attestation the webauthn provider chooses. */ - attestationObject: string; - /** The type of authenticator transports. */ - transports: v1AuthenticatorTransport[]; +export type GetAuthenticatorResponse = { + /** An authenticator. */ + authenticator: v1Authenticator; }; -export type Authenticator = { - /** Types of transports that may be used by an Authenticator (e.g., USB, NFC, BLE). */ - transports: v1AuthenticatorTransport[]; - attestationType: string; - /** Identifier indicating the type of the Security Key. */ - aaguid: string; - /** Unique identifier for a WebAuthn credential. */ - credentialId: string; - /** The type of Authenticator device. */ - model: string; - /** A User credential that can be used to authenticate to Turnkey. */ - credential: externaldatav1Credential; +export type GetAuthenticatorRequest = { + organizationId?: string; /** Unique identifier for a given Authenticator. */ authenticatorId: string; - /** Human-readable name for an Authenticator. */ - authenticatorName: string; - createdAt: externaldatav1Timestamp; - updatedAt: externaldatav1Timestamp; }; -export type AuthenticatorAttestationResponse = { - clientDataJson: string; - attestationObject: string; - transports?: v1AuthenticatorTransport[]; - authenticatorAttachment?: string; +export type GetAuthenticatorsResponse = { + /** A list of authenticators. */ + authenticators: v1Authenticator[]; }; -export type AuthenticatorParams = { - /** Human-readable name for an Authenticator. */ - authenticatorName: string; - /** Challenge presented for authentication purposes. */ - challenge: string; - /** The attestation that proves custody of the authenticator and provides metadata about it. */ - attestation: v1Attestation; +export type GetAuthenticatorsRequest = { + organizationId?: string; + /** Unique identifier for a given User. */ + userId: string; }; -export type AuthenticatorTransport = v1AuthenticatorTransport; -export type Config = { - features?: v1Feature[]; - quorum?: externaldatav1Quorum; +export type GetOauthProvidersResponse = { + /** A list of Oauth Providers */ + oauthProviders: v1OauthProvider[]; }; -export type CreateApiKeysRequest = { - /** A list of API Keys. */ - apiKeys: v1ApiKeyParamsV2[]; +export type GetOauthProvidersRequest = { + organizationId?: string; /** Unique identifier for a given User. */ - userId: string; + userId?: string; }; -export type CreateApiKeysResult = { - /** A list of API Key IDs. */ - apiKeyIds: string[]; +export type GetOrganizationResponse = { + /** Object representing the full current and deleted / disabled collection of Users, Policies, Private Keys, and Invitations attributable to a particular Organization. */ + organizationData: v1OrganizationData; }; -export type CreateApiOnlyUsersRequest = { - /** A list of API-only Users to create. */ - apiOnlyUsers: v1ApiOnlyUserParams[]; - /** Unique identifier for a given Organization. */ +export type GetOrganizationRequest = { organizationId?: string; }; -export type CreateApiOnlyUsersResult = { - /** A list of API-only User IDs. */ - userIds: string[]; +export type GetOrganizationConfigsResponse = { + /** Organization configs including quorum settings and organization features */ + configs: v1Config; }; -export type CreateAuthenticatorsRequest = { - /** A list of Authenticators. */ - authenticators: v1AuthenticatorParamsV2[]; - /** Unique identifier for a given User. */ - userId: string; +export type GetOrganizationConfigsRequest = { + organizationId?: string; }; -export type CreateAuthenticatorsResult = { - /** A list of Authenticator IDs. */ - authenticatorIds: string[]; +export type GetPolicyResponse = { + /** Object that codifies rules defining the actions that are permissible within an Organization. */ + policy: v1Policy; }; -export type CreateInvitationsRequest = { - /** A list of Invitations. */ - invitations: v1InvitationParams[]; - /** Unique identifier for a given Organization. */ +export type GetPolicyRequest = { organizationId?: string; + /** Unique identifier for a given Policy. */ + policyId: string; }; -export type CreateInvitationsResult = { - /** A list of Invitation IDs */ - invitationIds: string[]; +export type GetPrivateKeyResponse = { + /** Cryptographic public/private key pair that can be used for cryptocurrency needs or more generalized encryption. */ + privateKey: v1PrivateKey; }; -export type CreateOauthProvidersRequest = { - /** The ID of the User to add an Oauth provider to */ - userId: string; - /** A list of Oauth providers. */ - oauthProviders: v1OauthProviderParams[]; - /** Unique identifier for a given Organization. */ +export type GetPrivateKeyRequest = { organizationId?: string; + /** Unique identifier for a given Private Key. */ + privateKeyId: string; }; -export type CreateOauthProvidersResult = { - /** A list of unique identifiers for Oauth Providers */ - providerIds: string[]; +export type GetUserResponse = { + /** Web and/or API user within your Organization. */ + user: v1User; }; -export type CreateOrganizationRequest = { - /** Human-readable name for an Organization. */ - organizationName: string; - /** The root user's email address. */ - rootEmail: string; - /** The root user's Authenticator. */ - rootAuthenticator: v1AuthenticatorParamsV2; - /** Unique identifier for the root user object. */ - rootUserId?: string; +export type GetUserRequest = { + organizationId?: string; + /** Unique identifier for a given User. */ + userId: string; }; -export type CreateOrganizationResult = { - /** Unique identifier for a given Organization. */ - organizationId: string; -}; - -export type CreatePoliciesRequest = { - /** An array of policy intents to be created. */ - policies: v1CreatePolicyIntentV3[]; - /** Unique identifier for a given Organization. */ - organizationId?: string; -}; - -export type CreatePoliciesResult = { - /** A list of unique identifiers for the created policies. */ - policyIds: string[]; -}; - -export type CreatePolicyRequest = { - /** Human-readable name for a Policy. */ - policyName: string; - /** The instruction to DENY or ALLOW an activity. */ - effect: v1Effect; - /** The condition expression that triggers the Effect */ - condition?: string; - /** The consensus expression that triggers the Effect */ - consensus?: string; - notes?: string; -}; - -export type CreatePolicyResult = { - /** Unique identifier for a given Policy. */ - policyId: string; -}; - -export type CreatePrivateKeyTagRequest = { - /** Human-readable name for a Private Key Tag. */ - privateKeyTagName: string; - /** A list of Private Key IDs. */ - privateKeyIds: string[]; - /** Unique identifier for a given Organization. */ - organizationId?: string; -}; - -export type CreatePrivateKeyTagResult = { - /** Unique identifier for a given Private Key Tag. */ - privateKeyTagId: string; - /** A list of Private Key IDs. */ - privateKeyIds: string[]; -}; - -export type CreatePrivateKeysRequest = { - /** A list of Private Keys. */ - privateKeys: v1PrivateKeyParams[]; -}; - -export type CreatePrivateKeysResult = { - /** The activity that was processed. */ - activity: v1Activity; - /** A list of Private Key IDs and addresses. */ - privateKeys: v1PrivateKeyResult[]; -}; - -export type CreateReadOnlySessionResult = { - /** Unique identifier for a given Organization. If the request is being made by a user and their Sub-Organization ID is unknown, this can be the Parent Organization ID. However, using the Sub-Organization ID is preferred due to performance reasons. */ - organizationId: string; - /** Human-readable name for an Organization. */ - organizationName: string; - /** Unique identifier for a given User. */ - userId: string; - /** Human-readable name for a User. */ - username: string; - /** String representing a read only session */ - session: string; - /** UTC timestamp in seconds representing the expiry time for the read only session. */ - sessionExpiry: string; -}; - -export type CreateReadWriteSessionRequest = { - /** Client-side public key generated by the user, to which the read write session bundle (credentials) will be encrypted. */ - targetPublicKey: string; - /** Unique identifier for a given User. */ - userId?: string; - /** Optional human-readable name for an API Key. If none provided, default to Read Write Session - */ - apiKeyName?: string; - /** Expiration window (in seconds) indicating how long the API key is valid for. If not provided, a default of 15 minutes will be used. */ - expirationSeconds?: string; - /** Invalidate all other previously generated ReadWriteSession API keys */ - invalidateExisting?: boolean; -}; - -export type CreateReadWriteSessionResult = { - /** The activity that was processed. */ - activity: v1Activity; - /** Unique identifier for a given Organization. If the request is being made by a user and their Sub-Organization ID is unknown, this can be the Parent Organization ID. However, using the Sub-Organization ID is preferred due to performance reasons. */ - organizationId: string; - /** Human-readable name for an Organization. */ - organizationName: string; - /** Unique identifier for a given User. */ - userId: string; - /** Human-readable name for a User. */ - username: string; - /** Unique identifier for the created API key. */ - apiKeyId: string; - /** HPKE encrypted credential bundle */ - credentialBundle: string; -}; - -export type CreateSubOrganizationRequest = { - /** Name for this sub-organization */ - subOrganizationName: string; - /** Root users to create within this sub-organization */ - rootUsers: v1RootUserParamsV4[]; - /** The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users */ - rootQuorumThreshold: number; - /** The wallet to create for the sub-organization */ - wallet?: v1WalletParams; - /** Disable email recovery for the sub-organization */ - disableEmailRecovery?: boolean; - /** Disable email auth for the sub-organization */ - disableEmailAuth?: boolean; - /** Disable OTP SMS auth for the sub-organization */ - disableSmsAuth?: boolean; - /** Disable OTP email auth for the sub-organization */ - disableOtpEmailAuth?: boolean; -}; - -export type CreateSubOrganizationResult = { - /** The activity that was processed. */ - activity: v1Activity; - subOrganizationId: string; - wallet?: v1WalletResult; - rootUserIds?: string[]; +export type GetWalletResponse = { + /** A collection of deterministically generated cryptographic public / private key pairs that share a common seed */ + wallet: v1Wallet; }; -export type CreateUserTagRequest = { - /** Human-readable name for a User Tag. */ - userTagName: string; - /** A list of User IDs. */ - userIds: string[]; - /** Unique identifier for a given Organization. */ +export type GetWalletRequest = { organizationId?: string; -}; - -export type CreateUserTagResult = { - /** Unique identifier for a given User Tag. */ - userTagId: string; - /** A list of User IDs. */ - userIds: string[]; -}; - -export type CreateUsersRequest = { - /** A list of Users. */ - users: v1UserParamsV3[]; -}; - -export type CreateUsersResult = { - /** A list of User IDs. */ - userIds: string[]; -}; - -export type CreateWalletAccountsRequest = { /** Unique identifier for a given Wallet. */ walletId: string; - /** A list of wallet Accounts. */ - accounts: v1WalletAccountParams[]; - /** Unique identifier for a given Organization. */ - organizationId?: string; }; -export type CreateWalletAccountsResult = { - /** A list of derived addresses. */ - addresses: string[]; +export type GetWalletAccountResponse = { + /** The resulting Wallet Account. */ + account: v1WalletAccount; }; -export type CreateWalletRequest = { - /** Human-readable name for a Wallet. */ - walletName: string; - /** A list of wallet Accounts. This field, if not needed, should be an empty array in your request body. */ - accounts: v1WalletAccountParams[]; - /** Length of mnemonic to generate the Wallet seed. Defaults to 12. Accepted values: 12, 15, 18, 21, 24. */ - mnemonicLength?: number; - /** Unique identifier for a given Organization. */ +export type GetWalletAccountRequest = { organizationId?: string; -}; - -export type CreateWalletResult = { - /** Unique identifier for a Wallet. */ + /** Unique identifier for a given Wallet. */ walletId: string; - /** A list of account addresses. */ - addresses: string[]; + /** Address corresponding to a Wallet Account. */ + address?: string; + /** Path corresponding to a Wallet Account. */ + path?: string; }; -export type CredPropsAuthenticationExtensionsClientOutputs = { - rk: boolean; +export type GetActivitiesResponse = { + /** A list of Activities. */ + activities: v1Activity[]; }; -export type CredentialType = v1CredentialType; -export type Curve = v1Curve; -export type DeleteApiKeysRequest = { - /** Unique identifier for a given User. */ - userId: string; - /** A list of API Key IDs. */ - apiKeyIds: string[]; - /** Unique identifier for a given Organization. */ +export type GetActivitiesRequest = { organizationId?: string; + /** Array of Activity Statuses filtering which Activities will be listed in the response. */ + filterByStatus?: v1ActivityStatus[]; + /** Parameters used for cursor-based pagination. */ + paginationOptions?: v1Pagination; + /** Array of Activity Types filtering which Activities will be listed in the response. */ + filterByType?: v1ActivityType[]; }; -export type DeleteApiKeysResult = { - /** A list of API Key IDs. */ - apiKeyIds: string[]; +export type GetPoliciesResponse = { + /** A list of Policies. */ + policies: v1Policy[]; }; -export type DeleteAuthenticatorsRequest = { - /** Unique identifier for a given User. */ - userId: string; - /** A list of Authenticator IDs. */ - authenticatorIds: string[]; - /** Unique identifier for a given Organization. */ +export type GetPoliciesRequest = { organizationId?: string; }; -export type DeleteAuthenticatorsResult = { - /** Unique identifier for a given Authenticator. */ - authenticatorIds: string[]; +export type ListPrivateKeyTagsResponse = { + /** A list of Private Key Tags */ + privateKeyTags: datav1Tag[]; }; -export type DeleteInvitationRequest = { - /** Unique identifier for a given Invitation object. */ - invitationId: string; - /** Unique identifier for a given Organization. */ +export type ListPrivateKeyTagsRequest = { organizationId?: string; }; -export type DeleteInvitationResult = { - /** Unique identifier for a given Invitation. */ - invitationId: string; +export type GetPrivateKeysResponse = { + /** A list of Private Keys. */ + privateKeys: v1PrivateKey[]; }; -export type DeleteOauthProvidersRequest = { - /** The ID of the User to remove an Oauth provider from */ - userId: string; - /** Unique identifier for a given Provider. */ - providerIds: string[]; - /** Unique identifier for a given Organization. */ +export type GetPrivateKeysRequest = { organizationId?: string; }; -export type DeleteOauthProvidersResult = { - /** A list of unique identifiers for Oauth Providers */ - providerIds: string[]; +export type GetSubOrgIdsResponse = { + /** List of unique identifiers for the matching sub-organizations. */ + organizationIds: string[]; }; -export type DeleteOrganizationRequest = { - /** Unique identifier for a given Organization. */ - organizationId: string; +export type GetSubOrgIdsRequest = { + organizationId?: string; + /** Specifies the type of filter to apply, i.e 'CREDENTIAL_ID', 'NAME', 'USERNAME', 'EMAIL', 'PHONE_NUMBER', 'OIDC_TOKEN' or 'PUBLIC_KEY' */ + filterType?: string; + /** The value of the filter to apply for the specified type. For example, a specific email or name string. */ + filterValue?: string; + /** Parameters used for cursor-based pagination. */ + paginationOptions?: v1Pagination; }; -export type DeleteOrganizationResult = { - /** Unique identifier for a given Organization. */ - organizationId: string; +export type ListUserTagsResponse = { + /** A list of User Tags */ + userTags: datav1Tag[]; }; -export type DeletePolicyRequest = { - /** Unique identifier for a given Policy. */ - policyId: string; - /** Unique identifier for a given Organization. */ +export type ListUserTagsRequest = { organizationId?: string; }; -export type DeletePolicyResult = { - /** Unique identifier for a given Policy. */ - policyId: string; +export type GetUsersResponse = { + /** A list of Users. */ + users: v1User[]; }; -export type DeletePrivateKeyTagsRequest = { - /** A list of Private Key Tag IDs. */ - privateKeyTagIds: string[]; - /** Unique identifier for a given Organization. */ +export type GetUsersRequest = { organizationId?: string; }; -export type DeletePrivateKeyTagsResult = { - /** A list of Private Key Tag IDs. */ - privateKeyTagIds: string[]; - /** A list of Private Key IDs. */ - privateKeyIds: string[]; -}; - -export type DeletePrivateKeysRequest = { - /** List of unique identifiers for private keys within an organization */ - privateKeyIds: string[]; - /** Optional parameter for deleting the private keys, even if any have not been previously exported. If they have been exported, this field is ignored. */ - deleteWithoutExport?: boolean; - /** Unique identifier for a given Organization. */ - organizationId?: string; -}; - -export type DeletePrivateKeysResult = { - /** A list of private key unique identifiers that were removed */ - privateKeyIds: string[]; -}; - -export type DeleteSubOrganizationRequest = { - /** Sub-organization deletion, by default, requires associated wallets and private keys to be exported for security reasons. Set this boolean to true to force sub-organization deletion even if some wallets or private keys within it have not been exported yet. Default: false. */ - deleteWithoutExport?: boolean; - /** Unique identifier for a given Organization. */ - organizationId?: string; -}; - -export type DeleteSubOrganizationResult = { - /** Unique identifier of the sub organization that was removed */ - subOrganizationUuid: string; -}; - -export type DeleteUserTagsRequest = { - /** A list of User Tag IDs. */ - userTagIds: string[]; - /** Unique identifier for a given Organization. */ - organizationId?: string; -}; - -export type DeleteUserTagsResult = { - /** A list of User Tag IDs. */ - userTagIds: string[]; - /** A list of User IDs. */ - userIds: string[]; -}; - -export type DeleteUsersRequest = { - /** A list of User IDs. */ - userIds: string[]; - /** Unique identifier for a given Organization. */ - organizationId?: string; -}; - -export type DeleteUsersResult = { - /** A list of User IDs. */ - userIds: string[]; -}; - -export type DeleteWalletsRequest = { - /** List of unique identifiers for wallets within an organization */ - walletIds: string[]; - /** Optional parameter for deleting the wallets, even if any have not been previously exported. If they have been exported, this field is ignored. */ - deleteWithoutExport?: boolean; - /** Unique identifier for a given Organization. */ - organizationId?: string; -}; - -export type DeleteWalletsResult = { - /** A list of wallet unique identifiers that were removed */ - walletIds: string[]; -}; - -export type DisablePrivateKeyRequest = { - /** Unique identifier for a given Private Key. */ - privateKeyId: string; -}; - -export type DisablePrivateKeyResult = { - /** Unique identifier for a given Private Key. */ - privateKeyId: string; -}; - -export type Effect = v1Effect; -export type EmailAuthRequest = { - /** Email of the authenticating user. */ - email: string; - /** Client-side public key generated by the user, to which the email auth bundle (credentials) will be encrypted. */ - targetPublicKey: string; - /** Optional human-readable name for an API Key. If none provided, default to Email Auth - */ - apiKeyName?: string; - /** Expiration window (in seconds) indicating how long the API key is valid for. If not provided, a default of 15 minutes will be used. */ - expirationSeconds?: string; - /** Optional parameters for customizing emails. If not provided, the default email will be used. */ - emailCustomization?: v1EmailCustomizationParams; - /** Invalidate all other previously generated Email Auth API keys */ - invalidateExisting?: boolean; - /** Optional custom email address from which to send the email */ - sendFromEmailAddress?: string; - /** Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications' */ - sendFromEmailSenderName?: string; - /** Optional custom email address to use as reply-to */ - replyToEmailAddress?: string; -}; - -export type EmailAuthResult = { - /** Unique identifier for the authenticating User. */ - userId: string; - /** Unique identifier for the created API key. */ - apiKeyId: string; -}; - -export type EmailCustomizationParams = { - /** The name of the application. */ - appName?: string; - /** A URL pointing to a logo in PNG format. Note this logo will be resized to fit into 340px x 124px. */ - logoUrl?: string; - /** A template for the URL to be used in a magic link button, e.g. `https://dapp.xyz/%s`. The auth bundle will be interpolated into the `%s`. */ - magicLinkTemplate?: string; - /** JSON object containing key/value pairs to be used with custom templates. */ - templateVariables?: string; - /** Unique identifier for a given Email Template. If not specified, the default is the most recent Email Template. */ - templateId?: string; -}; - -export type ExportPrivateKeyRequest = { - /** Unique identifier for a given Private Key. */ - privateKeyId: string; - /** Client-side public key generated by the user, to which the export bundle will be encrypted. */ - targetPublicKey: string; - /** Unique identifier for a given Organization. */ - organizationId?: string; -}; - -export type ExportPrivateKeyResult = { - /** Unique identifier for a given Private Key. */ - privateKeyId: string; - /** Export bundle containing a private key encrypted to the client's target public key. */ - exportBundle: string; -}; - -export type ExportWalletAccountRequest = { - /** Address to identify Wallet Account. */ - address: string; - /** Client-side public key generated by the user, to which the export bundle will be encrypted. */ - targetPublicKey: string; - /** Unique identifier for a given Organization. */ - organizationId?: string; -}; - -export type ExportWalletAccountResult = { - /** Address to identify Wallet Account. */ - address: string; - /** Export bundle containing a private key encrypted by the client's target public key. */ - exportBundle: string; -}; - -export type ExportWalletRequest = { - /** Unique identifier for a given Wallet. */ - walletId: string; - /** Client-side public key generated by the user, to which the export bundle will be encrypted. */ - targetPublicKey: string; - /** The language of the mnemonic to export. Defaults to English. */ - language?: v1MnemonicLanguage; - /** Unique identifier for a given Organization. */ - organizationId?: string; -}; - -export type ExportWalletResult = { - /** Unique identifier for a given Wallet. */ - walletId: string; - /** Export bundle containing a wallet mnemonic + optional newline passphrase encrypted by the client's target public key. */ - exportBundle: string; -}; - -export type Feature = { - name?: v1FeatureName; - value?: string; -}; - -export type FeatureName = v1FeatureName; -export type GetActivitiesResponse = { - /** A list of Activities. */ - activities: v1Activity[]; -}; - -export type GetApiKeyResponse = { - /** An API key. */ - apiKey: v1ApiKey; -}; - -export type GetApiKeysResponse = { - /** A list of API keys. */ - apiKeys: v1ApiKey[]; -}; - -export type GetAttestationDocumentResponse = { - /** Raw (CBOR-encoded) attestation document */ - attestationDocument: string; -}; - -export type GetAuthenticatorResponse = { - /** An authenticator. */ - authenticator: v1Authenticator; -}; - -export type GetAuthenticatorsResponse = { - /** A list of authenticators. */ - authenticators: v1Authenticator[]; -}; - -export type GetOauthProvidersResponse = { - /** A list of Oauth Providers */ - oauthProviders: v1OauthProvider[]; -}; - -export type GetOrganizationConfigsResponse = { - /** Organization configs including quorum settings and organization features */ - configs: v1Config; -}; - -export type GetOrganizationResponse = { - /** Object representing the full current and deleted / disabled collection of Users, Policies, Private Keys, and Invitations attributable to a particular Organization. */ - organizationData: v1OrganizationData; -}; - -export type GetPoliciesResponse = { - /** A list of Policies. */ - policies: v1Policy[]; -}; - -export type GetPolicyResponse = { - /** Object that codifies rules defining the actions that are permissible within an Organization. */ - policy: v1Policy; -}; - -export type GetPrivateKeyResponse = { - /** Cryptographic public/private key pair that can be used for cryptocurrency needs or more generalized encryption. */ - privateKey: v1PrivateKey; -}; - -export type GetPrivateKeysResponse = { - /** A list of Private Keys. */ - privateKeys: v1PrivateKey[]; -}; - -export type GetSubOrgIdsResponse = { - /** List of unique identifiers for the matching sub-organizations. */ - organizationIds: string[]; -}; - -export type GetUserResponse = { - /** Web and/or API user within your Organization. */ - user: v1User; -}; - -export type GetUsersResponse = { - /** A list of Users. */ - users: v1User[]; -}; - export type GetVerifiedSubOrgIdsResponse = { /** List of unique identifiers for the matching sub-organizations. */ organizationIds: string[]; }; -export type GetWalletAccountResponse = { - /** The resulting Wallet Account. */ - account: v1WalletAccount; -}; - -export type GetWalletAccountsResponse = { - /** A list of Accounts generated from a Wallet that share a common seed. */ - accounts: v1WalletAccount[]; -}; - -export type GetWalletResponse = { - /** A collection of deterministically generated cryptographic public / private key pairs that share a common seed */ - wallet: v1Wallet; -}; - -export type GetWalletsResponse = { - /** A list of Wallets. */ - wallets: v1Wallet[]; -}; - -export type GetWhoamiResponse = { - /** Unique identifier for a given Organization. */ - organizationId: string; - /** Human-readable name for an Organization. */ - organizationName: string; - /** Unique identifier for a given User. */ - userId: string; - /** Human-readable name for a User. */ - username: string; -}; - -export type HashFunction = v1HashFunction; -export type ImportPrivateKeyRequest = { - /** The ID of the User importing a Private Key. */ - userId: string; - /** Human-readable name for a Private Key. */ - privateKeyName: string; - /** Bundle containing a raw private key encrypted to the enclave's target public key. */ - encryptedBundle: string; - /** Cryptographic Curve used to generate a given Private Key. */ - curve: v1Curve; - /** Cryptocurrency-specific formats for a derived address (e.g., Ethereum). */ - addressFormats: v1AddressFormat[]; - /** Unique identifier for a given Organization. */ - organizationId?: string; -}; - -export type ImportPrivateKeyResult = { - /** Unique identifier for a Private Key. */ - privateKeyId: string; - /** A list of addresses. */ - addresses: immutableactivityv1Address[]; -}; - -export type ImportWalletRequest = { - /** The ID of the User importing a Wallet. */ - userId: string; - /** Human-readable name for a Wallet. */ - walletName: string; - /** Bundle containing a wallet mnemonic encrypted to the enclave's target public key. */ - encryptedBundle: string; - /** A list of wallet Accounts. */ - accounts: v1WalletAccountParams[]; - /** Unique identifier for a given Organization. */ - organizationId?: string; -}; - -export type ImportWalletResult = { - /** Unique identifier for a Wallet. */ - walletId: string; - /** A list of account addresses. */ - addresses: string[]; -}; - -export type InitImportPrivateKeyRequest = { - /** The ID of the User importing a Private Key. */ - userId: string; - /** Unique identifier for a given Organization. */ - organizationId?: string; -}; - -export type InitImportPrivateKeyResult = { - /** Import bundle containing a public key and signature to use for importing client data. */ - importBundle: string; -}; - -export type InitImportWalletRequest = { - /** The ID of the User importing a Wallet. */ - userId: string; - /** Unique identifier for a given Organization. */ - organizationId?: string; -}; - -export type InitImportWalletResult = { - /** Import bundle containing a public key and signature to use for importing client data. */ - importBundle: string; -}; - -export type InitOtpAuthRequest = { - /** Enum to specifiy whether to send OTP via SMS or email */ - otpType: string; - /** Email or phone number to send the OTP code to */ - contact: string; - /** Optional length of the OTP code. Default = 9 */ - otpLength?: number; - /** Optional parameters for customizing emails. If not provided, the default email will be used. */ - emailCustomization?: v1EmailCustomizationParams; - /** Optional parameters for customizing SMS message. If not provided, the default sms message will be used. */ - smsCustomization?: v1SmsCustomizationParams; - /** 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. */ - userIdentifier?: string; - /** Optional custom email address from which to send the OTP email */ - sendFromEmailAddress?: string; - /** Optional flag to specify if the OTP code should be alphanumeric (Crockford’s Base32). Default = true */ - alphanumeric?: boolean; - /** Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications' */ - sendFromEmailSenderName?: string; - /** Optional custom email address to use as reply-to */ - replyToEmailAddress?: string; -}; - -export type InitOtpAuthResult = { - /** The activity that was processed. */ - activity: v1Activity; - /** Unique identifier for an OTP authentication */ - otpId: string; -}; - -export type InitOtpRequest = { - /** Whether to send OTP via SMS or email. Possible values: OTP_TYPE_SMS, OTP_TYPE_EMAIL */ - otpType: string; - /** Email or phone number to send the OTP code to */ - contact: string; - /** Optional length of the OTP code. Default = 9 */ - otpLength?: number; - /** Optional parameters for customizing emails. If not provided, the default email will be used. */ - emailCustomization?: v1EmailCustomizationParams; - /** Optional parameters for customizing SMS message. If not provided, the default sms message will be used. */ - smsCustomization?: v1SmsCustomizationParams; - /** 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. */ - userIdentifier?: string; - /** Optional custom email address from which to send the OTP email */ - sendFromEmailAddress?: string; - /** Optional flag to specify if the OTP code should be alphanumeric (Crockford’s Base32). Default = true */ - alphanumeric?: boolean; - /** Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications' */ - sendFromEmailSenderName?: string; - /** 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) */ - expirationSeconds?: string; - /** Optional custom email address to use as reply-to */ - replyToEmailAddress?: string; - /** Unique identifier for a given Organization. */ - organizationId?: string; -}; - -export type InitOtpResult = { - /** Unique identifier for an OTP authentication */ - otpId: string; -}; - -export type InitUserEmailRecoveryRequest = { - /** Email of the user starting recovery */ - email: string; - /** Client-side public key generated by the user, to which the recovery bundle will be encrypted. */ - targetPublicKey: string; - /** Expiration window (in seconds) indicating how long the recovery credential is valid for. If not provided, a default of 15 minutes will be used. */ - expirationSeconds?: string; - /** Optional parameters for customizing emails. If not provided, the default email will be used. */ - emailCustomization?: v1EmailCustomizationParams; - /** Unique identifier for a given Organization. */ - organizationId?: string; -}; - -export type InitUserEmailRecoveryResult = { - /** Unique identifier for the user being recovered. */ - userId: string; -}; - -export type Intent = { - createOrganizationIntent?: v1CreateOrganizationIntent; - createAuthenticatorsIntent?: v1CreateAuthenticatorsIntent; - createUsersIntent?: v1CreateUsersIntent; - createPrivateKeysIntent?: v1CreatePrivateKeysIntent; - signRawPayloadIntent?: v1SignRawPayloadIntent; - createInvitationsIntent?: v1CreateInvitationsIntent; - acceptInvitationIntent?: v1AcceptInvitationIntent; - createPolicyIntent?: v1CreatePolicyIntent; - disablePrivateKeyIntent?: v1DisablePrivateKeyIntent; - deleteUsersIntent?: v1DeleteUsersIntent; - deleteAuthenticatorsIntent?: v1DeleteAuthenticatorsIntent; - deleteInvitationIntent?: v1DeleteInvitationIntent; - deleteOrganizationIntent?: v1DeleteOrganizationIntent; - deletePolicyIntent?: v1DeletePolicyIntent; - createUserTagIntent?: v1CreateUserTagIntent; - deleteUserTagsIntent?: v1DeleteUserTagsIntent; - signTransactionIntent?: v1SignTransactionIntent; - createApiKeysIntent?: v1CreateApiKeysIntent; - deleteApiKeysIntent?: v1DeleteApiKeysIntent; - approveActivityIntent?: v1ApproveActivityIntent; - rejectActivityIntent?: v1RejectActivityIntent; - createPrivateKeyTagIntent?: v1CreatePrivateKeyTagIntent; - deletePrivateKeyTagsIntent?: v1DeletePrivateKeyTagsIntent; - createPolicyIntentV2?: v1CreatePolicyIntentV2; - setPaymentMethodIntent?: billingSetPaymentMethodIntent; - activateBillingTierIntent?: billingActivateBillingTierIntent; - deletePaymentMethodIntent?: billingDeletePaymentMethodIntent; - createPolicyIntentV3?: v1CreatePolicyIntentV3; - createApiOnlyUsersIntent?: v1CreateApiOnlyUsersIntent; - updateRootQuorumIntent?: v1UpdateRootQuorumIntent; - updateUserTagIntent?: v1UpdateUserTagIntent; - updatePrivateKeyTagIntent?: v1UpdatePrivateKeyTagIntent; - createAuthenticatorsIntentV2?: v1CreateAuthenticatorsIntentV2; - acceptInvitationIntentV2?: v1AcceptInvitationIntentV2; - createOrganizationIntentV2?: v1CreateOrganizationIntentV2; - createUsersIntentV2?: v1CreateUsersIntentV2; - createSubOrganizationIntent?: v1CreateSubOrganizationIntent; - createSubOrganizationIntentV2?: v1CreateSubOrganizationIntentV2; - updateAllowedOriginsIntent?: v1UpdateAllowedOriginsIntent; - createPrivateKeysIntentV2?: v1CreatePrivateKeysIntentV2; - updateUserIntent?: v1UpdateUserIntent; - updatePolicyIntent?: v1UpdatePolicyIntent; - setPaymentMethodIntentV2?: billingSetPaymentMethodIntentV2; - createSubOrganizationIntentV3?: v1CreateSubOrganizationIntentV3; - createWalletIntent?: v1CreateWalletIntent; - createWalletAccountsIntent?: v1CreateWalletAccountsIntent; - initUserEmailRecoveryIntent?: v1InitUserEmailRecoveryIntent; - recoverUserIntent?: v1RecoverUserIntent; - setOrganizationFeatureIntent?: v1SetOrganizationFeatureIntent; - removeOrganizationFeatureIntent?: v1RemoveOrganizationFeatureIntent; - signRawPayloadIntentV2?: v1SignRawPayloadIntentV2; - signTransactionIntentV2?: v1SignTransactionIntentV2; - exportPrivateKeyIntent?: v1ExportPrivateKeyIntent; - exportWalletIntent?: v1ExportWalletIntent; - createSubOrganizationIntentV4?: v1CreateSubOrganizationIntentV4; - emailAuthIntent?: v1EmailAuthIntent; - exportWalletAccountIntent?: v1ExportWalletAccountIntent; - initImportWalletIntent?: v1InitImportWalletIntent; - importWalletIntent?: v1ImportWalletIntent; - initImportPrivateKeyIntent?: v1InitImportPrivateKeyIntent; - importPrivateKeyIntent?: v1ImportPrivateKeyIntent; - createPoliciesIntent?: v1CreatePoliciesIntent; - signRawPayloadsIntent?: v1SignRawPayloadsIntent; - createReadOnlySessionIntent?: v1CreateReadOnlySessionIntent; - createOauthProvidersIntent?: v1CreateOauthProvidersIntent; - deleteOauthProvidersIntent?: v1DeleteOauthProvidersIntent; - createSubOrganizationIntentV5?: v1CreateSubOrganizationIntentV5; - oauthIntent?: v1OauthIntent; - createApiKeysIntentV2?: v1CreateApiKeysIntentV2; - createReadWriteSessionIntent?: v1CreateReadWriteSessionIntent; - emailAuthIntentV2?: v1EmailAuthIntentV2; - createSubOrganizationIntentV6?: v1CreateSubOrganizationIntentV6; - deletePrivateKeysIntent?: v1DeletePrivateKeysIntent; - deleteWalletsIntent?: v1DeleteWalletsIntent; - createReadWriteSessionIntentV2?: v1CreateReadWriteSessionIntentV2; - deleteSubOrganizationIntent?: v1DeleteSubOrganizationIntent; - initOtpAuthIntent?: v1InitOtpAuthIntent; - otpAuthIntent?: v1OtpAuthIntent; - createSubOrganizationIntentV7?: v1CreateSubOrganizationIntentV7; - updateWalletIntent?: v1UpdateWalletIntent; - updatePolicyIntentV2?: v1UpdatePolicyIntentV2; - createUsersIntentV3?: v1CreateUsersIntentV3; - initOtpAuthIntentV2?: v1InitOtpAuthIntentV2; - initOtpIntent?: v1InitOtpIntent; - verifyOtpIntent?: v1VerifyOtpIntent; - otpLoginIntent?: v1OtpLoginIntent; - stampLoginIntent?: v1StampLoginIntent; - oauthLoginIntent?: v1OauthLoginIntent; -}; - -export type Invitation = { - /** Unique identifier for a given Invitation object. */ - invitationId: string; - /** The name of the intended Invitation recipient. */ - receiverUserName: string; - /** The email address of the intended Invitation recipient. */ - receiverEmail: string; - /** A list of tags assigned to the Invitation recipient. */ - receiverUserTags: string[]; - /** The User's permissible access method(s). */ - accessType: v1AccessType; - /** The current processing status of a specified Invitation. */ - status: v1InvitationStatus; - createdAt: externaldatav1Timestamp; - updatedAt: externaldatav1Timestamp; - /** Unique identifier for the Sender of an Invitation. */ - senderUserId: string; -}; - -export type InvitationParams = { - /** The name of the intended Invitation recipient. */ - receiverUserName: string; - /** The email address of the intended Invitation recipient. */ - receiverUserEmail: string; - /** A list of tags assigned to the Invitation recipient. This field, if not needed, should be an empty array in your request body. */ - receiverUserTags: string[]; - /** The User's permissible access method(s). */ - accessType: v1AccessType; - /** Unique identifier for the Sender of an Invitation. */ - senderUserId: string; -}; - -export type InvitationStatus = v1InvitationStatus; -export type ListPrivateKeyTagsResponse = { - /** A list of Private Key Tags */ - privateKeyTags: datav1Tag[]; -}; - -export type ListUserTagsResponse = { - /** A list of User Tags */ - userTags: datav1Tag[]; -}; - -export type MnemonicLanguage = v1MnemonicLanguage; -export type NOOPCodegenAnchorResponse = { - stamp: v1WebAuthnStamp; -}; - -export type OauthRequest = { - /** Base64 encoded OIDC token */ - oidcToken: string; - /** Client-side public key generated by the user, to which the oauth bundle (credentials) will be encrypted. */ - targetPublicKey: string; - /** Optional human-readable name for an API Key. If none provided, default to Oauth - */ - apiKeyName?: string; - /** Expiration window (in seconds) indicating how long the API key is valid for. If not provided, a default of 15 minutes will be used. */ - expirationSeconds?: string; - /** Invalidate all other previously generated Oauth API keys */ - invalidateExisting?: boolean; - /** Unique identifier for a given Organization. */ - organizationId?: string; -}; - -export type OauthLoginRequest = { - /** Base64 encoded OIDC token */ - oidcToken: string; - /** 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 */ - publicKey: string; - /** Expiration window (in seconds) indicating how long the Session is valid for. If not provided, a default of 15 minutes will be used. */ - expirationSeconds?: string; - /** Invalidate all other previously generated Login API keys */ - invalidateExisting?: boolean; - /** Unique identifier for a given Organization. */ - organizationId?: string; -}; - -export type OauthLoginResult = { - /** Signed JWT containing an expiry, public key, session type, user id, and organization id */ - session: string; -}; - -export type OauthProvider = { - /** Unique identifier for an OAuth Provider */ - providerId: string; - /** Human-readable name to identify a Provider. */ - providerName: string; - /** The issuer of the token, typically a URL indicating the authentication server, e.g https://accounts.google.com */ - issuer: string; - /** Expected audience ('aud' attribute of the signed token) which represents the app ID */ - audience: string; - /** Expected subject ('sub' attribute of the signed token) which represents the user ID */ - subject: string; - createdAt: externaldatav1Timestamp; - updatedAt: externaldatav1Timestamp; -}; - -export type OauthProviderParams = { - /** Human-readable name to identify a Provider. */ - providerName: string; - /** Base64 encoded OIDC token */ - oidcToken: string; -}; - -export type OauthResult = { - /** Unique identifier for the authenticating User. */ - userId: string; - /** Unique identifier for the created API key. */ - apiKeyId: string; - /** HPKE encrypted credential bundle */ - credentialBundle: string; -}; - -export type Operator = v1Operator; -export type OrganizationData = { - organizationId?: string; - name?: string; - users?: v1User[]; - policies?: v1Policy[]; - privateKeys?: v1PrivateKey[]; - invitations?: v1Invitation[]; - tags?: datav1Tag[]; - rootQuorum?: externaldatav1Quorum; - features?: v1Feature[]; - wallets?: v1Wallet[]; -}; - -export type OtpAuthRequest = { - /** ID representing the result of an init OTP activity. */ - otpId: string; - /** OTP sent out to a user's contact (email or SMS) */ - otpCode: string; - /** Client-side public key generated by the user, to which the OTP bundle (credentials) will be encrypted. */ - targetPublicKey: string; - /** Optional human-readable name for an API Key. If none provided, default to OTP Auth - */ - apiKeyName?: string; - /** Expiration window (in seconds) indicating how long the API key is valid for. If not provided, a default of 15 minutes will be used. */ - expirationSeconds?: string; - /** Invalidate all other previously generated OTP Auth API keys */ - invalidateExisting?: boolean; - /** Unique identifier for a given Organization. */ - organizationId?: string; -}; - -export type OtpAuthResult = { - /** Unique identifier for the authenticating User. */ - userId: string; - /** Unique identifier for the created API key. */ - apiKeyId?: string; - /** HPKE encrypted credential bundle */ - credentialBundle?: string; -}; - -export type OtpLoginRequest = { - /** Signed JWT containing a unique id, expiry, verification type, contact */ - verificationToken: string; - /** Client-side public key generated by the user, which will be conditionally added to org data based on the validity of the verification token */ - publicKey: string; - /** Expiration window (in seconds) indicating how long the Session is valid for. If not provided, a default of 15 minutes will be used. */ - expirationSeconds?: string; - /** Invalidate all other previously generated Login API keys */ - invalidateExisting?: boolean; - /** Unique identifier for a given Organization. */ - organizationId?: string; -}; - -export type OtpLoginResult = { - /** Signed JWT containing an expiry, public key, session type, user id, and organization id */ - session: string; -}; - -export type Pagination = { - /** A limit of the number of object to be returned, between 1 and 100. Defaults to 10. */ - limit?: string; - /** A pagination cursor. This is an object ID that enables you to fetch all objects before this ID. */ - before?: string; - /** A pagination cursor. This is an object ID that enables you to fetch all objects after this ID. */ - after?: string; -}; - -export type PathFormat = v1PathFormat; -export type PayloadEncoding = v1PayloadEncoding; -export type Policy = { - /** Unique identifier for a given Policy. */ - policyId: string; - /** Human-readable name for a Policy. */ - policyName: string; - /** The instruction to DENY or ALLOW a particular activity following policy selector(s). */ - effect: v1Effect; - createdAt: externaldatav1Timestamp; - updatedAt: externaldatav1Timestamp; - /** Human-readable notes added by a User to describe a particular policy. */ - notes: string; - /** A consensus expression that evalutes to true or false. */ - consensus: string; - /** A condition expression that evalutes to true or false. */ - condition: string; -}; - -export type PrivateKey = { - /** Unique identifier for a given Private Key. */ - privateKeyId: string; - /** The public component of a cryptographic key pair used to sign messages and transactions. */ - publicKey: string; - /** Human-readable name for a Private Key. */ - privateKeyName: string; - /** Cryptographic Curve used to generate a given Private Key. */ - curve: v1Curve; - /** Derived cryptocurrency addresses for a given Private Key. */ - addresses: externaldatav1Address[]; - /** A list of Private Key Tag IDs. */ - privateKeyTags: string[]; - createdAt: externaldatav1Timestamp; - updatedAt: externaldatav1Timestamp; - /** True when a given Private Key is exported, false otherwise. */ - exported: boolean; - /** True when a given Private Key is imported, false otherwise. */ - imported: boolean; -}; - -export type PrivateKeyParams = { - /** Human-readable name for a Private Key. */ - privateKeyName: string; - /** Cryptographic Curve used to generate a given Private Key. */ - curve: v1Curve; - /** A list of Private Key Tag IDs. This field, if not needed, should be an empty array in your request body. */ - privateKeyTags: string[]; - /** Cryptocurrency-specific formats for a derived address (e.g., Ethereum). */ - addressFormats: v1AddressFormat[]; -}; - -export type PrivateKeyResult = { - privateKeyId?: string; - addresses?: immutableactivityv1Address[]; -}; - -export type PublicKeyCredentialWithAttestation = { - id: string; - type: string; - rawId: string; - authenticatorAttachment?: string; - response: v1AuthenticatorAttestationResponse; - clientExtensionResults: v1SimpleClientExtensionResults; -}; - -export type RecoverUserRequest = { - /** The new authenticator to register. */ - authenticator: v1AuthenticatorParamsV2; - /** Unique identifier for the user performing recovery. */ - userId: string; - /** Unique identifier for a given Organization. */ - organizationId?: string; -}; - -export type RecoverUserResult = { - /** ID of the authenticator created. */ - authenticatorId: string[]; -}; - -export type RejectActivityRequest = { - /** An artifact verifying a User's action. */ - fingerprint: string; - /** Unique identifier for a given Organization. */ - organizationId?: string; -}; - -export type RemoveOrganizationFeatureRequest = { - /** Name of the feature to remove */ - name: v1FeatureName; - /** Unique identifier for a given Organization. */ - organizationId?: string; -}; - -export type RemoveOrganizationFeatureResult = { - /** Resulting list of organization features. */ - features: v1Feature[]; -}; - -export type Result = { - createOrganizationResult?: v1CreateOrganizationResult; - createAuthenticatorsResult?: v1CreateAuthenticatorsResult; - createUsersResult?: v1CreateUsersResult; - createPrivateKeysResult?: v1CreatePrivateKeysResult; - createInvitationsResult?: v1CreateInvitationsResult; - acceptInvitationResult?: v1AcceptInvitationResult; - signRawPayloadResult?: v1SignRawPayloadResult; - createPolicyResult?: v1CreatePolicyResult; - disablePrivateKeyResult?: v1DisablePrivateKeyResult; - deleteUsersResult?: v1DeleteUsersResult; - deleteAuthenticatorsResult?: v1DeleteAuthenticatorsResult; - deleteInvitationResult?: v1DeleteInvitationResult; - deleteOrganizationResult?: v1DeleteOrganizationResult; - deletePolicyResult?: v1DeletePolicyResult; - createUserTagResult?: v1CreateUserTagResult; - deleteUserTagsResult?: v1DeleteUserTagsResult; - signTransactionResult?: v1SignTransactionResult; - deleteApiKeysResult?: v1DeleteApiKeysResult; - createApiKeysResult?: v1CreateApiKeysResult; - createPrivateKeyTagResult?: v1CreatePrivateKeyTagResult; - deletePrivateKeyTagsResult?: v1DeletePrivateKeyTagsResult; - setPaymentMethodResult?: billingSetPaymentMethodResult; - activateBillingTierResult?: billingActivateBillingTierResult; - deletePaymentMethodResult?: billingDeletePaymentMethodResult; - createApiOnlyUsersResult?: v1CreateApiOnlyUsersResult; - updateRootQuorumResult?: v1UpdateRootQuorumResult; - updateUserTagResult?: v1UpdateUserTagResult; - updatePrivateKeyTagResult?: v1UpdatePrivateKeyTagResult; - createSubOrganizationResult?: v1CreateSubOrganizationResult; - updateAllowedOriginsResult?: v1UpdateAllowedOriginsResult; - createPrivateKeysResultV2?: v1CreatePrivateKeysResultV2; - updateUserResult?: v1UpdateUserResult; - updatePolicyResult?: v1UpdatePolicyResult; - createSubOrganizationResultV3?: v1CreateSubOrganizationResultV3; - createWalletResult?: v1CreateWalletResult; - createWalletAccountsResult?: v1CreateWalletAccountsResult; - initUserEmailRecoveryResult?: v1InitUserEmailRecoveryResult; - recoverUserResult?: v1RecoverUserResult; - setOrganizationFeatureResult?: v1SetOrganizationFeatureResult; - removeOrganizationFeatureResult?: v1RemoveOrganizationFeatureResult; - exportPrivateKeyResult?: v1ExportPrivateKeyResult; - exportWalletResult?: v1ExportWalletResult; - createSubOrganizationResultV4?: v1CreateSubOrganizationResultV4; - emailAuthResult?: v1EmailAuthResult; - exportWalletAccountResult?: v1ExportWalletAccountResult; - initImportWalletResult?: v1InitImportWalletResult; - importWalletResult?: v1ImportWalletResult; - initImportPrivateKeyResult?: v1InitImportPrivateKeyResult; - importPrivateKeyResult?: v1ImportPrivateKeyResult; - createPoliciesResult?: v1CreatePoliciesResult; - signRawPayloadsResult?: v1SignRawPayloadsResult; - createReadOnlySessionResult?: v1CreateReadOnlySessionResult; - createOauthProvidersResult?: v1CreateOauthProvidersResult; - deleteOauthProvidersResult?: v1DeleteOauthProvidersResult; - createSubOrganizationResultV5?: v1CreateSubOrganizationResultV5; - oauthResult?: v1OauthResult; - createReadWriteSessionResult?: v1CreateReadWriteSessionResult; - createSubOrganizationResultV6?: v1CreateSubOrganizationResultV6; - deletePrivateKeysResult?: v1DeletePrivateKeysResult; - deleteWalletsResult?: v1DeleteWalletsResult; - createReadWriteSessionResultV2?: v1CreateReadWriteSessionResultV2; - deleteSubOrganizationResult?: v1DeleteSubOrganizationResult; - initOtpAuthResult?: v1InitOtpAuthResult; - otpAuthResult?: v1OtpAuthResult; - createSubOrganizationResultV7?: v1CreateSubOrganizationResultV7; - updateWalletResult?: v1UpdateWalletResult; - updatePolicyResultV2?: v1UpdatePolicyResultV2; - initOtpAuthResultV2?: v1InitOtpAuthResultV2; - initOtpResult?: v1InitOtpResult; - verifyOtpResult?: v1VerifyOtpResult; - otpLoginResult?: v1OtpLoginResult; - stampLoginResult?: v1StampLoginResult; - oauthLoginResult?: v1OauthLoginResult; -}; - -export type RootUserParams = { - /** Human-readable name for a User. */ - userName: string; - /** The user's email address. */ - userEmail?: string; - /** The user's phone number in E.164 format e.g. +13214567890 */ - userPhoneNumber?: string; - /** A list of API Key parameters. This field, if not needed, should be an empty array in your request body. */ - apiKeys: v1ApiKeyParamsV2[]; - /** A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. */ - authenticators: v1AuthenticatorParamsV2[]; - /** A list of Oauth providers. This field, if not needed, should be an empty array in your request body. */ - oauthProviders: v1OauthProviderParams[]; -}; - -export type Selector = { - subject?: string; - operator?: v1Operator; - targets?: string[]; -}; - -export type SetOrganizationFeatureRequest = { - /** Name of the feature to set */ - name: v1FeatureName; - /** Optional value for the feature. Will override existing values if feature is already set. */ - value: string; - /** Unique identifier for a given Organization. */ - organizationId?: string; -}; - -export type SetOrganizationFeatureResult = { - /** Resulting list of organization features. */ - features: v1Feature[]; -}; - -export type SignRawPayloadRequest = { - /** A Wallet account address, Private Key address, or Private Key identifier. */ - signWith: string; - /** Raw unsigned payload to be signed. */ - payload: string; - /** Encoding of the `payload` string. Turnkey uses this information to convert `payload` into bytes with the correct decoder (e.g. hex, utf8). */ - encoding: v1PayloadEncoding; - /** Hash function to apply to payload bytes before signing. This field must be set to HASH_FUNCTION_NOT_APPLICABLE for EdDSA/ed25519 signature requests; configurable payload hashing is not supported by RFC 8032. */ - hashFunction: v1HashFunction; -}; - -export type SignRawPayloadResult = { - /** Component of an ECSDA signature. */ - r: string; - /** Component of an ECSDA signature. */ - s: string; - /** Component of an ECSDA signature. */ - v: string; -}; - -export type SignRawPayloadsRequest = { - /** A Wallet account address, Private Key address, or Private Key identifier. */ - signWith: string; - /** An array of raw unsigned payloads to be signed. */ - payloads: string[]; - /** Encoding of the `payload` string. Turnkey uses this information to convert `payload` into bytes with the correct decoder (e.g. hex, utf8). */ - encoding: v1PayloadEncoding; - /** Hash function to apply to payload bytes before signing. This field must be set to HASH_FUNCTION_NOT_APPLICABLE for EdDSA/ed25519 signature requests; configurable payload hashing is not supported by RFC 8032. */ - hashFunction: v1HashFunction; - /** Unique identifier for a given Organization. */ - organizationId?: string; -}; - -export type SignRawPayloadsResult = { - signatures?: v1SignRawPayloadResult[]; -}; - -export type SignTransactionRequest = { - /** A Wallet account address, Private Key address, or Private Key identifier. */ - signWith: string; - /** Raw unsigned transaction to be signed */ - unsignedTransaction: string; - type: v1TransactionType; -}; - -export type SignTransactionResult = { - signedTransaction: string; -}; - -export type SimpleClientExtensionResults = { - appid?: boolean; - appidExclude?: boolean; - credProps?: v1CredPropsAuthenticationExtensionsClientOutputs; -}; - -export type SmsCustomizationParams = { - /** Template containing references to .OtpCode i.e Your OTP is {{.OtpCode}} */ - template?: string; -}; - -export type StampLoginRequest = { - /** Client-side public key generated by the user, which will be conditionally added to org data based on the passkey stamp associated with this request */ - publicKey: string; - /** Expiration window (in seconds) indicating how long the Session is valid for. If not provided, a default of 15 minutes will be used. */ - expirationSeconds?: string; - /** Invalidate all other previously generated Login API keys */ - invalidateExisting?: boolean; - /** Unique identifier for a given Organization. */ - organizationId?: string; -}; - -export type StampLoginResult = { - /** Signed JWT containing an expiry, public key, session type, user id, and organization id */ - session: string; -}; - -export type TagType = v1TagType; -export type TestRateLimitsResponse = v1TestRateLimitsResponse; -export type TransactionType = v1TransactionType; -export type UpdateAllowedOriginsRequest = { - /** Additional origins requests are allowed from besides Turnkey origins */ - allowedOrigins: string[]; -}; - -export type UpdateAllowedOriginsResult = v1UpdateAllowedOriginsResult; -export type UpdatePolicyRequest = { - /** Unique identifier for a given Policy. */ - policyId: string; - /** Human-readable name for a Policy. */ - policyName?: string; - /** The instruction to DENY or ALLOW an activity (optional). */ - policyEffect?: v1Effect; - /** The condition expression that triggers the Effect (optional). */ - policyCondition?: string; - /** The consensus expression that triggers the Effect (optional). */ - policyConsensus?: string; - /** Accompanying notes for a Policy (optional). */ - policyNotes?: string; -}; - -export type UpdatePolicyResult = { - /** The activity that was processed. */ - activity: v1Activity; - /** Unique identifier for a given Policy. */ - policyId: string; -}; - -export type UpdatePrivateKeyTagRequest = { - /** Unique identifier for a given Private Key Tag. */ - privateKeyTagId: string; - /** The new, human-readable name for the tag with the given ID. */ - newPrivateKeyTagName?: string; - /** A list of Private Keys IDs to add this tag to. */ - addPrivateKeyIds: string[]; - /** A list of Private Key IDs to remove this tag from. */ - removePrivateKeyIds: string[]; - /** Unique identifier for a given Organization. */ - organizationId?: string; -}; - -export type UpdatePrivateKeyTagResult = { - /** Unique identifier for a given Private Key Tag. */ - privateKeyTagId: string; -}; - -export type UpdateRootQuorumRequest = { - /** The threshold of unique approvals to reach quorum. */ - threshold: number; - /** The unique identifiers of users who comprise the quorum set. */ - userIds: string[]; - /** Unique identifier for a given Organization. */ - organizationId?: string; -}; - -export type UpdateRootQuorumResult = v1UpdateRootQuorumResult; -export type UpdateUserRequest = { - /** Unique identifier for a given User. */ - userId: string; - /** Human-readable name for a User. */ - userName?: string; - /** The user's email address. */ - userEmail?: string; - /** An updated list of User Tags to apply to this User. This field, if not needed, should be an empty array in your request body. */ - userTagIds?: string[]; - /** The user's phone number in E.164 format e.g. +13214567890 */ - userPhoneNumber?: string; - /** Unique identifier for a given Organization. */ - organizationId?: string; -}; - -export type UpdateUserResult = { - /** A User ID. */ - userId: string; -}; - -export type UpdateUserTagRequest = { - /** Unique identifier for a given User Tag. */ - userTagId: string; - /** The new, human-readable name for the tag with the given ID. */ - newUserTagName?: string; - /** A list of User IDs to add this tag to. */ - addUserIds: string[]; - /** A list of User IDs to remove this tag from. */ - removeUserIds: string[]; - /** Unique identifier for a given Organization. */ - organizationId?: string; -}; - -export type UpdateUserTagResult = { - /** Unique identifier for a given User Tag. */ - userTagId: string; -}; - -export type UpdateWalletRequest = { - /** Unique identifier for a given Wallet. */ - walletId: string; - /** Human-readable name for a Wallet. */ - walletName?: string; - /** Unique identifier for a given Organization. */ - organizationId?: string; -}; - -export type UpdateWalletResult = { - /** A Wallet ID. */ - walletId: string; -}; - -export type User = { - /** Unique identifier for a given User. */ - userId: string; - /** Human-readable name for a User. */ - userName: string; - /** The user's email address. */ - userEmail?: string; - /** The user's phone number in E.164 format e.g. +13214567890 */ - userPhoneNumber?: string; - /** A list of Authenticator parameters. */ - authenticators: v1Authenticator[]; - /** A list of API Key parameters. This field, if not needed, should be an empty array in your request body. */ - apiKeys: v1ApiKey[]; - /** A list of User Tag IDs. */ - userTags: string[]; - /** A list of Oauth Providers. */ - oauthProviders: v1OauthProvider[]; - createdAt: externaldatav1Timestamp; - updatedAt: externaldatav1Timestamp; -}; - -export type UserParams = { - /** Human-readable name for a User. */ - userName: string; - /** The user's email address. */ - userEmail?: string; - /** The user's phone number in E.164 format e.g. +13214567890 */ - userPhoneNumber?: string; - /** A list of API Key parameters. This field, if not needed, should be an empty array in your request body. */ - apiKeys: v1ApiKeyParamsV2[]; - /** A list of Authenticator parameters. This field, if not needed, should be an empty array in your request body. */ - authenticators: v1AuthenticatorParamsV2[]; - /** A list of Oauth providers. This field, if not needed, should be an empty array in your request body. */ - oauthProviders: v1OauthProviderParams[]; - /** A list of User Tag IDs. This field, if not needed, should be an empty array in your request body. */ - userTags: string[]; -}; - -export type VerifyOtpRequest = { - /** ID representing the result of an init OTP activity. */ - otpId: string; - /** OTP sent out to a user's contact (email or SMS) */ - otpCode: string; - /** Expiration window (in seconds) indicating how long the verification token is valid for. If not provided, a default of 1 hour will be used. Maximum value is 86400 seconds (24 hours) */ - expirationSeconds?: string; - /** Unique identifier for a given Organization. */ - organizationId?: string; -}; - -export type VerifyOtpResult = { - /** Signed JWT containing a unique id, expiry, verification type, contact. Verification status of a user is updated when the token is consumed (in OTP_LOGIN requests) */ - verificationToken: string; -}; - -export type Vote = { - /** Unique identifier for a given Vote object. */ - id: string; - /** Unique identifier for a given User. */ - userId: string; - /** Web and/or API user within your Organization. */ - user: v1User; - /** Unique identifier for a given Activity object. */ - activityId: string; - selection: string; - /** The raw message being signed within a Vote. */ - message: string; - /** The public component of a cryptographic key pair used to sign messages and transactions. */ - publicKey: string; - /** The signature applied to a particular vote. */ - signature: string; - /** Method used to produce a signature. */ - scheme: string; - createdAt: externaldatav1Timestamp; -}; - -export type Wallet = { - /** Unique identifier for a given Wallet. */ - walletId: string; - /** Human-readable name for a Wallet. */ - walletName: string; - createdAt: externaldatav1Timestamp; - updatedAt: externaldatav1Timestamp; - /** True when a given Wallet is exported, false otherwise. */ - exported: boolean; - /** True when a given Wallet is imported, false otherwise. */ - imported: boolean; -}; - -export type WalletAccount = { - /** Unique identifier for a given Wallet Account. */ - walletAccountId: string; - /** The Organization the Account belongs to. */ - organizationId: string; - /** The Wallet the Account was derived from. */ - walletId: string; - /** Cryptographic curve used to generate the Account. */ - curve: v1Curve; - /** Path format used to generate the Account. */ - pathFormat: v1PathFormat; - /** Path used to generate the Account. */ - path: string; - /** Address format used to generate the Account. */ - addressFormat: v1AddressFormat; - /** Address generated using the Wallet seed and Account parameters. */ - address: string; - createdAt: externaldatav1Timestamp; - updatedAt: externaldatav1Timestamp; - /** The public component of this wallet account's underlying cryptographic key pair. */ - publicKey?: string; -}; - -export type WalletAccountParams = { - /** Cryptographic curve used to generate a wallet Account. */ - curve: v1Curve; - /** Path format used to generate a wallet Account. */ - pathFormat: v1PathFormat; - /** Path used to generate a wallet Account. */ - path: string; - /** Address format used to generate a wallet Acccount. */ - addressFormat: v1AddressFormat; +export type GetVerifiedSubOrgIdsRequest = { + organizationId?: string; + /** Specifies the type of filter to apply, i.e 'EMAIL', 'PHONE_NUMBER' */ + filterType?: string; + /** The value of the filter to apply for the specified type. For example, a specific email or phone number string. */ + filterValue?: string; + /** Parameters used for cursor-based pagination. */ + paginationOptions?: v1Pagination; }; -export type WalletParams = { - /** Human-readable name for a Wallet. */ - walletName: string; - /** A list of wallet Accounts. This field, if not needed, should be an empty array in your request body. */ - accounts: v1WalletAccountParams[]; - /** Length of mnemonic to generate the Wallet seed. Defaults to 12. Accepted values: 12, 15, 18, 21, 24. */ - mnemonicLength?: number; +export type GetWalletAccountsResponse = { + /** A list of Accounts generated from a Wallet that share a common seed. */ + accounts: v1WalletAccount[]; }; -export type WalletResult = { +export type GetWalletAccountsRequest = { + organizationId?: string; + /** Unique identifier for a given Wallet. */ walletId: string; - /** A list of account addresses. */ - addresses: string[]; + /** Parameters used for cursor-based pagination. */ + paginationOptions?: v1Pagination; }; -export type WebAuthnStamp = { - /** A base64 url encoded Unique identifier for a given credential. */ - credentialId: string; - /** A base64 encoded payload containing metadata about the signing context and the challenge. */ - clientDataJson: string; - /** A base64 encoded payload containing metadata about the authenticator. */ - authenticatorData: string; - /** The base64 url encoded signature bytes contained within the WebAuthn assertion response. */ - signature: string; +export type GetWalletsResponse = { + /** A list of Wallets. */ + wallets: v1Wallet[]; }; -export type AcceptInvitationResponse = { - /** The activity that was processed. */ - activity: v1Activity; - /** Unique identifier for a given Invitation. */ - invitationId: string; +export type GetWalletsRequest = { + organizationId?: string; +}; + +export type GetWhoamiResponse = { + /** Unique identifier for a given Organization. */ + organizationId: string; + /** Human-readable name for an Organization. */ + organizationName: string; /** Unique identifier for a given User. */ userId: string; + /** Human-readable name for a User. */ + username: string; +}; + +export type GetWhoamiRequest = { + organizationId?: string; +}; + +export type ApproveActivityResponse = { + /** An action that can that can be taken within the Turnkey infrastructure. */ + activity: v1Activity; +}; + +export type ApproveActivityRequest = { + timestampMs?: string; + organizationId?: string; + /** An artifact verifying a User's action. */ + fingerprint: string; }; export type CreateApiKeysResponse = { - /** The activity that was processed. */ activity: v1Activity; /** A list of API Key IDs. */ apiKeyIds: string[]; }; +export type CreateApiKeysRequest = { + timestampMs?: string; + organizationId?: string; + /** A list of API Keys. */ + apiKeys: v1ApiKeyParamsV2[]; + /** Unique identifier for a given User. */ + userId: string; +}; + export type CreateApiOnlyUsersResponse = { - /** The activity that was processed. */ activity: v1Activity; /** A list of API-only User IDs. */ userIds: string[]; }; +export type CreateApiOnlyUsersRequest = { + timestampMs?: string; + organizationId?: string; + /** A list of API-only Users to create. */ + apiOnlyUsers: v1ApiOnlyUserParams[]; +}; + export type CreateAuthenticatorsResponse = { - /** The activity that was processed. */ activity: v1Activity; /** A list of Authenticator IDs. */ authenticatorIds: string[]; }; +export type CreateAuthenticatorsRequest = { + timestampMs?: string; + organizationId?: string; + /** A list of Authenticators. */ + authenticators: v1AuthenticatorParamsV2[]; + /** Unique identifier for a given User. */ + userId: string; +}; + export type CreateInvitationsResponse = { - /** The activity that was processed. */ activity: v1Activity; /** A list of Invitation IDs */ invitationIds: string[]; }; +export type CreateInvitationsRequest = { + timestampMs?: string; + organizationId?: string; + /** A list of Invitations. */ + invitations: v1InvitationParams[]; +}; + export type CreateOauthProvidersResponse = { - /** The activity that was processed. */ activity: v1Activity; /** A list of unique identifiers for Oauth Providers */ providerIds: string[]; }; -export type CreateOrganizationResponse = { - /** The activity that was processed. */ - activity: v1Activity; - /** Unique identifier for a given Organization. */ - organizationId: string; +export type CreateOauthProvidersRequest = { + timestampMs?: string; + organizationId?: string; + /** The ID of the User to add an Oauth provider to */ + userId: string; + /** A list of Oauth providers. */ + oauthProviders: v1OauthProviderParams[]; }; export type CreatePoliciesResponse = { - /** The activity that was processed. */ activity: v1Activity; /** A list of unique identifiers for the created policies. */ policyIds: string[]; }; +export type CreatePoliciesRequest = { + timestampMs?: string; + organizationId?: string; + /** An array of policy intents to be created. */ + policies: v1CreatePolicyIntentV3[]; +}; + export type CreatePolicyResponse = { - /** The activity that was processed. */ activity: v1Activity; /** Unique identifier for a given Policy. */ policyId: string; }; +export type CreatePolicyRequest = { + timestampMs?: string; + organizationId?: string; + /** Human-readable name for a Policy. */ + policyName: string; + /** The instruction to DENY or ALLOW an activity. */ + effect: v1Effect; + /** The condition expression that triggers the Effect */ + condition?: string; + /** The consensus expression that triggers the Effect */ + consensus?: string; + notes?: string; +}; + export type CreatePrivateKeyTagResponse = { - /** The activity that was processed. */ activity: v1Activity; /** Unique identifier for a given Private Key Tag. */ privateKeyTagId: string; @@ -4885,8 +3641,29 @@ export type CreatePrivateKeyTagResponse = { privateKeyIds: string[]; }; +export type CreatePrivateKeyTagRequest = { + timestampMs?: string; + organizationId?: string; + /** Human-readable name for a Private Key Tag. */ + privateKeyTagName: string; + /** A list of Private Key IDs. */ + privateKeyIds: string[]; +}; + +export type CreatePrivateKeysResponse = { + activity: v1Activity; + /** A list of Private Key IDs and addresses. */ + privateKeys: v1PrivateKeyResult[]; +}; + +export type CreatePrivateKeysRequest = { + timestampMs?: string; + organizationId?: string; + /** A list of Private Keys. */ + privateKeys: v1PrivateKeyParams[]; +}; + export type CreateReadOnlySessionResponse = { - /** The activity that was processed. */ activity: v1Activity; /** Unique identifier for a given Organization. If the request is being made by a user and their Sub-Organization ID is unknown, this can be the Parent Organization ID. However, using the Sub-Organization ID is preferred due to performance reasons. */ organizationId: string; @@ -4902,8 +3679,71 @@ export type CreateReadOnlySessionResponse = { sessionExpiry: string; }; +export type CreateReadOnlySessionRequest = { + timestampMs?: string; + organizationId?: string; +}; + +export type CreateReadWriteSessionResponse = { + activity: v1Activity; + /** Unique identifier for a given Organization. If the request is being made by a user and their Sub-Organization ID is unknown, this can be the Parent Organization ID. However, using the Sub-Organization ID is preferred due to performance reasons. */ + organizationId: string; + /** Human-readable name for an Organization. */ + organizationName: string; + /** Unique identifier for a given User. */ + userId: string; + /** Human-readable name for a User. */ + username: string; + /** Unique identifier for the created API key. */ + apiKeyId: string; + /** HPKE encrypted credential bundle */ + credentialBundle: string; +}; + +export type CreateReadWriteSessionRequest = { + timestampMs?: string; + organizationId?: string; + /** Client-side public key generated by the user, to which the read write session bundle (credentials) will be encrypted. */ + targetPublicKey: string; + /** Unique identifier for a given User. */ + userId?: string; + /** Optional human-readable name for an API Key. If none provided, default to Read Write Session - */ + apiKeyName?: string; + /** Expiration window (in seconds) indicating how long the API key is valid for. If not provided, a default of 15 minutes will be used. */ + expirationSeconds?: string; + /** Invalidate all other previously generated ReadWriteSession API keys */ + invalidateExisting?: boolean; +}; + +export type CreateSubOrganizationResponse = { + activity: v1Activity; + subOrganizationId: string; + wallet?: v1WalletResult; + rootUserIds?: string[]; +}; + +export type CreateSubOrganizationRequest = { + timestampMs?: string; + organizationId?: string; + /** Name for this sub-organization */ + subOrganizationName: string; + /** Root users to create within this sub-organization */ + rootUsers: v1RootUserParamsV4[]; + /** The threshold of unique approvals to reach root quorum. This value must be less than or equal to the number of root users */ + rootQuorumThreshold: number; + /** The wallet to create for the sub-organization */ + wallet?: v1WalletParams; + /** Disable email recovery for the sub-organization */ + disableEmailRecovery?: boolean; + /** Disable email auth for the sub-organization */ + disableEmailAuth?: boolean; + /** Disable OTP SMS auth for the sub-organization */ + disableSmsAuth?: boolean; + /** Disable OTP email auth for the sub-organization */ + disableOtpEmailAuth?: boolean; +}; + export type CreateUserTagResponse = { - /** The activity that was processed. */ activity: v1Activity; /** Unique identifier for a given User Tag. */ userTagId: string; @@ -4911,22 +3751,29 @@ export type CreateUserTagResponse = { userIds: string[]; }; +export type CreateUserTagRequest = { + timestampMs?: string; + organizationId?: string; + /** Human-readable name for a User Tag. */ + userTagName: string; + /** A list of User IDs. */ + userIds: string[]; +}; + export type CreateUsersResponse = { - /** The activity that was processed. */ activity: v1Activity; /** A list of User IDs. */ userIds: string[]; }; -export type CreateWalletAccountsResponse = { - /** The activity that was processed. */ - activity: v1Activity; - /** A list of derived addresses. */ - addresses: string[]; +export type CreateUsersRequest = { + timestampMs?: string; + organizationId?: string; + /** A list of Users. */ + users: v1UserParamsV3[]; }; export type CreateWalletResponse = { - /** The activity that was processed. */ activity: v1Activity; /** Unique identifier for a Wallet. */ walletId: string; @@ -4934,50 +3781,104 @@ export type CreateWalletResponse = { addresses: string[]; }; +export type CreateWalletRequest = { + timestampMs?: string; + organizationId?: string; + /** Human-readable name for a Wallet. */ + walletName: string; + /** A list of wallet Accounts. This field, if not needed, should be an empty array in your request body. */ + accounts: v1WalletAccountParams[]; + /** Length of mnemonic to generate the Wallet seed. Defaults to 12. Accepted values: 12, 15, 18, 21, 24. */ + mnemonicLength?: number; +}; + +export type CreateWalletAccountsResponse = { + activity: v1Activity; + /** A list of derived addresses. */ + addresses: string[]; +}; + +export type CreateWalletAccountsRequest = { + timestampMs?: string; + organizationId?: string; + /** Unique identifier for a given Wallet. */ + walletId: string; + /** A list of wallet Accounts. */ + accounts: v1WalletAccountParams[]; +}; + export type DeleteApiKeysResponse = { - /** The activity that was processed. */ activity: v1Activity; /** A list of API Key IDs. */ apiKeyIds: string[]; }; +export type DeleteApiKeysRequest = { + timestampMs?: string; + organizationId?: string; + /** Unique identifier for a given User. */ + userId: string; + /** A list of API Key IDs. */ + apiKeyIds: string[]; +}; + export type DeleteAuthenticatorsResponse = { - /** The activity that was processed. */ activity: v1Activity; /** Unique identifier for a given Authenticator. */ authenticatorIds: string[]; }; +export type DeleteAuthenticatorsRequest = { + timestampMs?: string; + organizationId?: string; + /** Unique identifier for a given User. */ + userId: string; + /** A list of Authenticator IDs. */ + authenticatorIds: string[]; +}; + export type DeleteInvitationResponse = { - /** The activity that was processed. */ activity: v1Activity; /** Unique identifier for a given Invitation. */ invitationId: string; }; +export type DeleteInvitationRequest = { + timestampMs?: string; + organizationId?: string; + /** Unique identifier for a given Invitation object. */ + invitationId: string; +}; + export type DeleteOauthProvidersResponse = { - /** The activity that was processed. */ activity: v1Activity; /** A list of unique identifiers for Oauth Providers */ providerIds: string[]; }; -export type DeleteOrganizationResponse = { - /** The activity that was processed. */ - activity: v1Activity; - /** Unique identifier for a given Organization. */ - organizationId: string; +export type DeleteOauthProvidersRequest = { + timestampMs?: string; + organizationId?: string; + /** The ID of the User to remove an Oauth provider from */ + userId: string; + /** Unique identifier for a given Provider. */ + providerIds: string[]; }; export type DeletePolicyResponse = { - /** The activity that was processed. */ activity: v1Activity; /** Unique identifier for a given Policy. */ policyId: string; }; +export type DeletePolicyRequest = { + timestampMs?: string; + organizationId?: string; + /** Unique identifier for a given Policy. */ + policyId: string; +}; + export type DeletePrivateKeyTagsResponse = { - /** The activity that was processed. */ activity: v1Activity; /** A list of Private Key Tag IDs. */ privateKeyTagIds: string[]; @@ -4985,22 +3886,42 @@ export type DeletePrivateKeyTagsResponse = { privateKeyIds: string[]; }; +export type DeletePrivateKeyTagsRequest = { + timestampMs?: string; + organizationId?: string; + /** A list of Private Key Tag IDs. */ + privateKeyTagIds: string[]; +}; + export type DeletePrivateKeysResponse = { - /** The activity that was processed. */ activity: v1Activity; /** A list of private key unique identifiers that were removed */ privateKeyIds: string[]; }; +export type DeletePrivateKeysRequest = { + timestampMs?: string; + organizationId?: string; + /** List of unique identifiers for private keys within an organization */ + privateKeyIds: string[]; + /** Optional parameter for deleting the private keys, even if any have not been previously exported. If they have been exported, this field is ignored. */ + deleteWithoutExport?: boolean; +}; + export type DeleteSubOrganizationResponse = { - /** The activity that was processed. */ activity: v1Activity; /** Unique identifier of the sub organization that was removed */ subOrganizationUuid: string; }; +export type DeleteSubOrganizationRequest = { + timestampMs?: string; + organizationId?: string; + /** Sub-organization deletion, by default, requires associated wallets and private keys to be exported for security reasons. Set this boolean to true to force sub-organization deletion even if some wallets or private keys within it have not been exported yet. Default: false. */ + deleteWithoutExport?: boolean; +}; + export type DeleteUserTagsResponse = { - /** The activity that was processed. */ activity: v1Activity; /** A list of User Tag IDs. */ userTagIds: string[]; @@ -5008,29 +3929,42 @@ export type DeleteUserTagsResponse = { userIds: string[]; }; +export type DeleteUserTagsRequest = { + timestampMs?: string; + organizationId?: string; + /** A list of User Tag IDs. */ + userTagIds: string[]; +}; + export type DeleteUsersResponse = { - /** The activity that was processed. */ activity: v1Activity; /** A list of User IDs. */ userIds: string[]; }; +export type DeleteUsersRequest = { + timestampMs?: string; + organizationId?: string; + /** A list of User IDs. */ + userIds: string[]; +}; + export type DeleteWalletsResponse = { - /** The activity that was processed. */ activity: v1Activity; /** A list of wallet unique identifiers that were removed */ walletIds: string[]; }; -export type DisablePrivateKeyResponse = { - /** The activity that was processed. */ - activity: v1Activity; - /** Unique identifier for a given Private Key. */ - privateKeyId: string; +export type DeleteWalletsRequest = { + timestampMs?: string; + organizationId?: string; + /** List of unique identifiers for wallets within an organization */ + walletIds: string[]; + /** Optional parameter for deleting the wallets, even if any have not been previously exported. If they have been exported, this field is ignored. */ + deleteWithoutExport?: boolean; }; export type EmailAuthResponse = { - /** The activity that was processed. */ activity: v1Activity; /** Unique identifier for the authenticating User. */ userId: string; @@ -5038,8 +3972,30 @@ export type EmailAuthResponse = { apiKeyId: string; }; +export type EmailAuthRequest = { + timestampMs?: string; + organizationId?: string; + /** Email of the authenticating user. */ + email: string; + /** Client-side public key generated by the user, to which the email auth bundle (credentials) will be encrypted. */ + targetPublicKey: string; + /** Optional human-readable name for an API Key. If none provided, default to Email Auth - */ + apiKeyName?: string; + /** Expiration window (in seconds) indicating how long the API key is valid for. If not provided, a default of 15 minutes will be used. */ + expirationSeconds?: string; + /** Optional parameters for customizing emails. If not provided, the default email will be used. */ + emailCustomization?: v1EmailCustomizationParams; + /** Invalidate all other previously generated Email Auth API keys */ + invalidateExisting?: boolean; + /** Optional custom email address from which to send the email */ + sendFromEmailAddress?: string; + /** Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications' */ + sendFromEmailSenderName?: string; + /** Optional custom email address to use as reply-to */ + replyToEmailAddress?: string; +}; + export type ExportPrivateKeyResponse = { - /** The activity that was processed. */ activity: v1Activity; /** Unique identifier for a given Private Key. */ privateKeyId: string; @@ -5047,17 +4003,16 @@ export type ExportPrivateKeyResponse = { exportBundle: string; }; -export type ExportWalletAccountResponse = { - /** The activity that was processed. */ - activity: v1Activity; - /** Address to identify Wallet Account. */ - address: string; - /** Export bundle containing a private key encrypted by the client's target public key. */ - exportBundle: string; +export type ExportPrivateKeyRequest = { + timestampMs?: string; + organizationId?: string; + /** Unique identifier for a given Private Key. */ + privateKeyId: string; + /** Client-side public key generated by the user, to which the export bundle will be encrypted. */ + targetPublicKey: string; }; export type ExportWalletResponse = { - /** The activity that was processed. */ activity: v1Activity; /** Unique identifier for a given Wallet. */ walletId: string; @@ -5065,8 +4020,35 @@ export type ExportWalletResponse = { exportBundle: string; }; +export type ExportWalletRequest = { + timestampMs?: string; + organizationId?: string; + /** Unique identifier for a given Wallet. */ + walletId: string; + /** Client-side public key generated by the user, to which the export bundle will be encrypted. */ + targetPublicKey: string; + /** The language of the mnemonic to export. Defaults to English. */ + language?: v1MnemonicLanguage; +}; + +export type ExportWalletAccountResponse = { + activity: v1Activity; + /** Address to identify Wallet Account. */ + address: string; + /** Export bundle containing a private key encrypted by the client's target public key. */ + exportBundle: string; +}; + +export type ExportWalletAccountRequest = { + timestampMs?: string; + organizationId?: string; + /** Address to identify Wallet Account. */ + address: string; + /** Client-side public key generated by the user, to which the export bundle will be encrypted. */ + targetPublicKey: string; +}; + export type ImportPrivateKeyResponse = { - /** The activity that was processed. */ activity: v1Activity; /** Unique identifier for a Private Key. */ privateKeyId: string; @@ -5074,8 +4056,22 @@ export type ImportPrivateKeyResponse = { addresses: immutableactivityv1Address[]; }; +export type ImportPrivateKeyRequest = { + timestampMs?: string; + organizationId?: string; + /** The ID of the User importing a Private Key. */ + userId: string; + /** Human-readable name for a Private Key. */ + privateKeyName: string; + /** Bundle containing a raw private key encrypted to the enclave's target public key. */ + encryptedBundle: string; + /** Cryptographic Curve used to generate a given Private Key. */ + curve: v1Curve; + /** Cryptocurrency-specific formats for a derived address (e.g., Ethereum). */ + addressFormats: v1AddressFormat[]; +}; + export type ImportWalletResponse = { - /** The activity that was processed. */ activity: v1Activity; /** Unique identifier for a Wallet. */ walletId: string; @@ -5083,54 +4079,204 @@ export type ImportWalletResponse = { addresses: string[]; }; +export type ImportWalletRequest = { + timestampMs?: string; + organizationId?: string; + /** The ID of the User importing a Wallet. */ + userId: string; + /** Human-readable name for a Wallet. */ + walletName: string; + /** Bundle containing a wallet mnemonic encrypted to the enclave's target public key. */ + encryptedBundle: string; + /** A list of wallet Accounts. */ + accounts: v1WalletAccountParams[]; +}; + +export type InitFiatOnRampResponse = { + activity: v1Activity; + /** Unique URL for a given fiat on-ramp flow. */ + onRampUrl: string; + /** Unique identifier used to retrieve transaction statuses for a given fiat on-ramp flow. */ + onRampTransactionId: string; +}; + +export type InitFiatOnRampRequest = { + timestampMs?: string; + organizationId?: string; + /** Enum to specifiy which on-ramp provider to use */ + onrampProvider: v1FiatOnRampProvider; + /** Destination wallet address for the buy transaction. */ + walletAddress: string; + /** Blockchain network to be used for the transaction, e.g., bitcoin, ethereum. Maps to MoonPay's network or Coinbase's defaultNetwork. */ + network: v1FiatOnRampBlockchainNetwork; + /** Code for the cryptocurrency to be purchased, e.g., btc, eth. Maps to MoonPay's currencyCode or Coinbase's defaultAsset. */ + cryptoCurrencyCode: v1FiatOnRampCryptoCurrency; + /** Code for the fiat currency to be used in the transaction, e.g., USD, EUR. */ + fiatCurrencyCode?: v1FiatOnRampCurrency; + /** Specifies a preset fiat amount for the transaction, e.g., '100'. Must be greater than '20'. If not provided, the user will be prompted to enter an amount. */ + fiatCurrencyAmount?: string; + /** Pre-selected payment method, e.g., CREDIT_DEBIT_CARD, APPLE_PAY. Validated against the chosen provider. */ + paymentMethod?: v1FiatOnRampPaymentMethod; + /** ISO 3166-1 two-digit country code for Coinbase representing the purchasing user’s country of residence, e.g., US, GB. */ + countryCode?: string; + /** ISO 3166-2 two-digit country subdivision code for Coinbase representing the purchasing user’s subdivision of residence within their country, e.g. NY. Required if country_code=US. */ + countrySubdivisionCode?: string; +}; + export type InitImportPrivateKeyResponse = { - /** The activity that was processed. */ activity: v1Activity; /** Import bundle containing a public key and signature to use for importing client data. */ importBundle: string; }; +export type InitImportPrivateKeyRequest = { + timestampMs?: string; + organizationId?: string; + /** The ID of the User importing a Private Key. */ + userId: string; +}; + export type InitImportWalletResponse = { - /** The activity that was processed. */ activity: v1Activity; /** Import bundle containing a public key and signature to use for importing client data. */ importBundle: string; }; +export type InitImportWalletRequest = { + timestampMs?: string; + organizationId?: string; + /** The ID of the User importing a Wallet. */ + userId: string; +}; + export type InitOtpResponse = { - /** The activity that was processed. */ activity: v1Activity; /** Unique identifier for an OTP authentication */ otpId: string; }; +export type InitOtpRequest = { + timestampMs?: string; + organizationId?: string; + /** Whether to send OTP via SMS or email. Possible values: OTP_TYPE_SMS, OTP_TYPE_EMAIL */ + otpType: string; + /** Email or phone number to send the OTP code to */ + contact: string; + /** Optional length of the OTP code. Default = 9 */ + otpLength?: number; + /** Optional parameters for customizing emails. If not provided, the default email will be used. */ + emailCustomization?: v1EmailCustomizationParams; + /** Optional parameters for customizing SMS message. If not provided, the default sms message will be used. */ + smsCustomization?: v1SmsCustomizationParams; + /** 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. */ + userIdentifier?: string; + /** Optional custom email address from which to send the OTP email */ + sendFromEmailAddress?: string; + /** Optional flag to specify if the OTP code should be alphanumeric (Crockford’s Base32). Default = true */ + alphanumeric?: boolean; + /** Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications' */ + sendFromEmailSenderName?: string; + /** 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) */ + expirationSeconds?: string; + /** Optional custom email address to use as reply-to */ + replyToEmailAddress?: string; +}; + +export type InitOtpAuthResponse = { + activity: v1Activity; + /** Unique identifier for an OTP authentication */ + otpId: string; +}; + +export type InitOtpAuthRequest = { + timestampMs?: string; + organizationId?: string; + /** Enum to specifiy whether to send OTP via SMS or email */ + otpType: string; + /** Email or phone number to send the OTP code to */ + contact: string; + /** Optional length of the OTP code. Default = 9 */ + otpLength?: number; + /** Optional parameters for customizing emails. If not provided, the default email will be used. */ + emailCustomization?: v1EmailCustomizationParams; + /** Optional parameters for customizing SMS message. If not provided, the default sms message will be used. */ + smsCustomization?: v1SmsCustomizationParams; + /** 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. */ + userIdentifier?: string; + /** Optional custom email address from which to send the OTP email */ + sendFromEmailAddress?: string; + /** Optional flag to specify if the OTP code should be alphanumeric (Crockford’s Base32). Default = true */ + alphanumeric?: boolean; + /** Optional custom sender name for use with sendFromEmailAddress; if left empty, will default to 'Notifications' */ + sendFromEmailSenderName?: string; + /** Optional custom email address to use as reply-to */ + replyToEmailAddress?: string; +}; + export type InitUserEmailRecoveryResponse = { - /** The activity that was processed. */ activity: v1Activity; /** Unique identifier for the user being recovered. */ userId: string; }; +export type InitUserEmailRecoveryRequest = { + timestampMs?: string; + organizationId?: string; + /** Email of the user starting recovery */ + email: string; + /** Client-side public key generated by the user, to which the recovery bundle will be encrypted. */ + targetPublicKey: string; + /** Expiration window (in seconds) indicating how long the recovery credential is valid for. If not provided, a default of 15 minutes will be used. */ + expirationSeconds?: string; + /** Optional parameters for customizing emails. If not provided, the default email will be used. */ + emailCustomization?: v1EmailCustomizationParams; +}; + +export type OauthResponse = { + activity: v1Activity; + /** Unique identifier for the authenticating User. */ + userId: string; + /** Unique identifier for the created API key. */ + apiKeyId: string; + /** HPKE encrypted credential bundle */ + credentialBundle: string; +}; + +export type OauthRequest = { + timestampMs?: string; + organizationId?: string; + /** Base64 encoded OIDC token */ + oidcToken: string; + /** Client-side public key generated by the user, to which the oauth bundle (credentials) will be encrypted. */ + targetPublicKey: string; + /** Optional human-readable name for an API Key. If none provided, default to Oauth - */ + apiKeyName?: string; + /** Expiration window (in seconds) indicating how long the API key is valid for. If not provided, a default of 15 minutes will be used. */ + expirationSeconds?: string; + /** Invalidate all other previously generated Oauth API keys */ + invalidateExisting?: boolean; +}; + export type OauthLoginResponse = { - /** The activity that was processed. */ activity: v1Activity; /** Signed JWT containing an expiry, public key, session type, user id, and organization id */ session: string; }; -export type OauthResponse = { - /** The activity that was processed. */ - activity: v1Activity; - /** Unique identifier for the authenticating User. */ - userId: string; - /** Unique identifier for the created API key. */ - apiKeyId: string; - /** HPKE encrypted credential bundle */ - credentialBundle: string; +export type OauthLoginRequest = { + timestampMs?: string; + organizationId?: string; + /** Base64 encoded OIDC token */ + oidcToken: string; + /** 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 */ + publicKey: string; + /** Expiration window (in seconds) indicating how long the Session is valid for. If not provided, a default of 15 minutes will be used. */ + expirationSeconds?: string; + /** Invalidate all other previously generated Login API keys */ + invalidateExisting?: boolean; }; export type OtpAuthResponse = { - /** The activity that was processed. */ activity: v1Activity; /** Unique identifier for the authenticating User. */ userId: string; @@ -5140,43 +4286,98 @@ export type OtpAuthResponse = { credentialBundle?: string; }; +export type OtpAuthRequest = { + timestampMs?: string; + organizationId?: string; + /** ID representing the result of an init OTP activity. */ + otpId: string; + /** OTP sent out to a user's contact (email or SMS) */ + otpCode: string; + /** Client-side public key generated by the user, to which the OTP bundle (credentials) will be encrypted. */ + targetPublicKey: string; + /** Optional human-readable name for an API Key. If none provided, default to OTP Auth - */ + apiKeyName?: string; + /** Expiration window (in seconds) indicating how long the API key is valid for. If not provided, a default of 15 minutes will be used. */ + expirationSeconds?: string; + /** Invalidate all other previously generated OTP Auth API keys */ + invalidateExisting?: boolean; +}; + export type OtpLoginResponse = { - /** The activity that was processed. */ activity: v1Activity; /** Signed JWT containing an expiry, public key, session type, user id, and organization id */ session: string; }; -export type PrivateKeyResponse = { - /** The activity that was processed. */ - activity: v1Activity; - privateKeyId?: string; - addresses?: immutableactivityv1Address[]; +export type OtpLoginRequest = { + timestampMs?: string; + organizationId?: string; + /** Signed JWT containing a unique id, expiry, verification type, contact */ + verificationToken: string; + /** Client-side public key generated by the user, which will be conditionally added to org data based on the validity of the verification token */ + publicKey: string; + /** Expiration window (in seconds) indicating how long the Session is valid for. If not provided, a default of 15 minutes will be used. */ + expirationSeconds?: string; + /** Invalidate all other previously generated Login API keys */ + invalidateExisting?: boolean; }; export type RecoverUserResponse = { - /** The activity that was processed. */ activity: v1Activity; /** ID of the authenticator created. */ authenticatorId: string[]; }; +export type RecoverUserRequest = { + timestampMs?: string; + organizationId?: string; + /** The new authenticator to register. */ + authenticator: v1AuthenticatorParamsV2; + /** Unique identifier for the user performing recovery. */ + userId: string; +}; + +export type RejectActivityResponse = { + /** An action that can that can be taken within the Turnkey infrastructure. */ + activity: v1Activity; +}; + +export type RejectActivityRequest = { + timestampMs?: string; + organizationId?: string; + /** An artifact verifying a User's action. */ + fingerprint: string; +}; + export type RemoveOrganizationFeatureResponse = { - /** The activity that was processed. */ activity: v1Activity; /** Resulting list of organization features. */ features: v1Feature[]; }; +export type RemoveOrganizationFeatureRequest = { + timestampMs?: string; + organizationId?: string; + /** Name of the feature to remove */ + name: v1FeatureName; +}; + export type SetOrganizationFeatureResponse = { - /** The activity that was processed. */ activity: v1Activity; /** Resulting list of organization features. */ features: v1Feature[]; }; +export type SetOrganizationFeatureRequest = { + timestampMs?: string; + organizationId?: string; + /** Name of the feature to set */ + name: v1FeatureName; + /** Optional value for the feature. Will override existing values if feature is already set. */ + value: string; +}; + export type SignRawPayloadResponse = { - /** The activity that was processed. */ activity: v1Activity; /** Component of an ECSDA signature. */ r: string; @@ -5186,64 +4387,255 @@ export type SignRawPayloadResponse = { v: string; }; +export type SignRawPayloadRequest = { + timestampMs?: string; + organizationId?: string; + /** A Wallet account address, Private Key address, or Private Key identifier. */ + signWith: string; + /** Raw unsigned payload to be signed. */ + payload: string; + /** Encoding of the `payload` string. Turnkey uses this information to convert `payload` into bytes with the correct decoder (e.g. hex, utf8). */ + encoding: v1PayloadEncoding; + /** Hash function to apply to payload bytes before signing. This field must be set to HASH_FUNCTION_NOT_APPLICABLE for EdDSA/ed25519 signature requests; configurable payload hashing is not supported by RFC 8032. */ + hashFunction: v1HashFunction; +}; + export type SignRawPayloadsResponse = { - /** The activity that was processed. */ activity: v1Activity; signatures?: v1SignRawPayloadResult[]; }; +export type SignRawPayloadsRequest = { + timestampMs?: string; + organizationId?: string; + /** A Wallet account address, Private Key address, or Private Key identifier. */ + signWith: string; + /** An array of raw unsigned payloads to be signed. */ + payloads: string[]; + /** Encoding of the `payload` string. Turnkey uses this information to convert `payload` into bytes with the correct decoder (e.g. hex, utf8). */ + encoding: v1PayloadEncoding; + /** Hash function to apply to payload bytes before signing. This field must be set to HASH_FUNCTION_NOT_APPLICABLE for EdDSA/ed25519 signature requests; configurable payload hashing is not supported by RFC 8032. */ + hashFunction: v1HashFunction; +}; + export type SignTransactionResponse = { - /** The activity that was processed. */ activity: v1Activity; signedTransaction: string; }; +export type SignTransactionRequest = { + timestampMs?: string; + organizationId?: string; + /** A Wallet account address, Private Key address, or Private Key identifier. */ + signWith: string; + /** Raw unsigned transaction to be signed */ + unsignedTransaction: string; + type: v1TransactionType; +}; + export type StampLoginResponse = { - /** The activity that was processed. */ activity: v1Activity; /** Signed JWT containing an expiry, public key, session type, user id, and organization id */ session: string; }; +export type StampLoginRequest = { + timestampMs?: string; + organizationId?: string; + /** Client-side public key generated by the user, which will be conditionally added to org data based on the passkey stamp associated with this request */ + publicKey: string; + /** Expiration window (in seconds) indicating how long the Session is valid for. If not provided, a default of 15 minutes will be used. */ + expirationSeconds?: string; + /** Invalidate all other previously generated Login API keys */ + invalidateExisting?: boolean; +}; + +export type UpdatePolicyResponse = { + activity: v1Activity; + /** Unique identifier for a given Policy. */ + policyId: string; +}; + +export type UpdatePolicyRequest = { + timestampMs?: string; + organizationId?: string; + /** Unique identifier for a given Policy. */ + policyId: string; + /** Human-readable name for a Policy. */ + policyName?: string; + /** The instruction to DENY or ALLOW an activity (optional). */ + policyEffect?: v1Effect; + /** The condition expression that triggers the Effect (optional). */ + policyCondition?: string; + /** The consensus expression that triggers the Effect (optional). */ + policyConsensus?: string; + /** Accompanying notes for a Policy (optional). */ + policyNotes?: string; +}; + export type UpdatePrivateKeyTagResponse = { - /** The activity that was processed. */ activity: v1Activity; /** Unique identifier for a given Private Key Tag. */ privateKeyTagId: string; }; +export type UpdatePrivateKeyTagRequest = { + timestampMs?: string; + organizationId?: string; + /** Unique identifier for a given Private Key Tag. */ + privateKeyTagId: string; + /** The new, human-readable name for the tag with the given ID. */ + newPrivateKeyTagName?: string; + /** A list of Private Keys IDs to add this tag to. */ + addPrivateKeyIds: string[]; + /** A list of Private Key IDs to remove this tag from. */ + removePrivateKeyIds: string[]; +}; + +export type UpdateRootQuorumResponse = { + activity: v1Activity; +}; + +export type UpdateRootQuorumRequest = { + timestampMs?: string; + organizationId?: string; + /** The threshold of unique approvals to reach quorum. */ + threshold: number; + /** The unique identifiers of users who comprise the quorum set. */ + userIds: string[]; +}; + export type UpdateUserResponse = { - /** The activity that was processed. */ activity: v1Activity; /** A User ID. */ userId: string; }; +export type UpdateUserRequest = { + timestampMs?: string; + organizationId?: string; + /** Unique identifier for a given User. */ + userId: string; + /** Human-readable name for a User. */ + userName?: string; + /** The user's email address. */ + userEmail?: string; + /** An updated list of User Tags to apply to this User. This field, if not needed, should be an empty array in your request body. */ + userTagIds?: string[]; + /** The user's phone number in E.164 format e.g. +13214567890 */ + userPhoneNumber?: string; +}; + +export type UpdateUserEmailResponse = { + activity: v1Activity; + /** Unique identifier of the User whose email was updated. */ + userId: string; +}; + +export type UpdateUserEmailRequest = { + timestampMs?: string; + organizationId?: string; + /** Unique identifier for a given User. */ + userId: string; + /** The user's email address. Setting this to an empty string will remove the user's email. */ + userEmail: string; + /** Signed JWT containing a unique id, expiry, verification type, contact */ + verificationToken?: string; +}; + +export type UpdateUserNameResponse = { + activity: v1Activity; + /** Unique identifier of the User whose name was updated. */ + userId: string; +}; + +export type UpdateUserNameRequest = { + timestampMs?: string; + organizationId?: string; + /** Unique identifier for a given User. */ + userId: string; + /** Human-readable name for a User. */ + userName: string; +}; + +export type UpdateUserPhoneNumberResponse = { + activity: v1Activity; + /** Unique identifier of the User whose phone number was updated. */ + userId: string; +}; + +export type UpdateUserPhoneNumberRequest = { + timestampMs?: string; + organizationId?: string; + /** Unique identifier for a given User. */ + userId: string; + /** The user's phone number in E.164 format e.g. +13214567890. Setting this to an empty string will remove the user's phone number. */ + userPhoneNumber: string; + /** Signed JWT containing a unique id, expiry, verification type, contact */ + verificationToken?: string; +}; + export type UpdateUserTagResponse = { - /** The activity that was processed. */ activity: v1Activity; /** Unique identifier for a given User Tag. */ userTagId: string; }; +export type UpdateUserTagRequest = { + timestampMs?: string; + organizationId?: string; + /** Unique identifier for a given User Tag. */ + userTagId: string; + /** The new, human-readable name for the tag with the given ID. */ + newUserTagName?: string; + /** A list of User IDs to add this tag to. */ + addUserIds: string[]; + /** A list of User IDs to remove this tag from. */ + removeUserIds: string[]; +}; + export type UpdateWalletResponse = { - /** The activity that was processed. */ activity: v1Activity; /** A Wallet ID. */ walletId: string; }; +export type UpdateWalletRequest = { + timestampMs?: string; + organizationId?: string; + /** Unique identifier for a given Wallet. */ + walletId: string; + /** Human-readable name for a Wallet. */ + walletName?: string; +}; + export type VerifyOtpResponse = { - /** The activity that was processed. */ activity: v1Activity; /** Signed JWT containing a unique id, expiry, verification type, contact. Verification status of a user is updated when the token is consumed (in OTP_LOGIN requests) */ verificationToken: string; }; -export type WalletResponse = { - /** The activity that was processed. */ - activity: v1Activity; - walletId: string; - /** A list of account addresses. */ - addresses: string[]; +export type VerifyOtpRequest = { + timestampMs?: string; + organizationId?: string; + /** ID representing the result of an init OTP activity. */ + otpId: string; + /** OTP sent out to a user's contact (email or SMS) */ + otpCode: string; + /** Expiration window (in seconds) indicating how long the verification token is valid for. If not provided, a default of 1 hour will be used. Maximum value is 86400 seconds (24 hours) */ + expirationSeconds?: string; +}; + +export type NOOPCodegenAnchorResponse = { + stamp: v1WebAuthnStamp; +}; + +export type TestRateLimitsResponse = {}; + +export type TestRateLimitsRequest = { + organizationId?: string; + /** Whether or not to set a limit on this request. */ + isSetLimit: boolean; + /** Rate limit to set for org, if is_set_limit is set to true */ + limit: number; }; diff --git a/packages/sdk-types/src/__inputs__/public_api.swagger.json b/packages/sdk-types/src/__inputs__/public_api.swagger.json index b5e0170ad..07da96ef1 100644 --- a/packages/sdk-types/src/__inputs__/public_api.swagger.json +++ b/packages/sdk-types/src/__inputs__/public_api.swagger.json @@ -1956,6 +1956,38 @@ "tags": ["Wallets"] } }, + "/public/v1/submit/init_fiat_on_ramp": { + "post": { + "summary": "Init Fiat On Ramp", + "description": "Initiate a fiat on ramp flow", + "operationId": "PublicApiService_InitFiatOnRamp", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1InitFiatOnRampRequest" + } + } + ], + "tags": ["On Ramp"] + } + }, "/public/v1/submit/init_import_private_key": { "post": { "summary": "Init Import Private Key", @@ -2628,6 +2660,102 @@ "tags": ["Users"] } }, + "/public/v1/submit/update_user_email": { + "post": { + "summary": "Update User's Email", + "description": "Update a User's email in an existing Organization", + "operationId": "PublicApiService_UpdateUserEmail", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1UpdateUserEmailRequest" + } + } + ], + "tags": ["Users"] + } + }, + "/public/v1/submit/update_user_name": { + "post": { + "summary": "Update User's Name", + "description": "Update a User's name in an existing Organization", + "operationId": "PublicApiService_UpdateUserName", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1UpdateUserNameRequest" + } + } + ], + "tags": ["Users"] + } + }, + "/public/v1/submit/update_user_phone_number": { + "post": { + "summary": "Update User's Phone Number", + "description": "Update a User's phone number in an existing Organization", + "operationId": "PublicApiService_UpdateUserPhoneNumber", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1UpdateUserPhoneNumberRequest" + } + } + ], + "tags": ["Users"] + } + }, "/public/v1/submit/update_user_tag": { "post": { "summary": "Update User Tag", @@ -3261,7 +3389,11 @@ "ACTIVITY_TYPE_VERIFY_OTP", "ACTIVITY_TYPE_OTP_LOGIN", "ACTIVITY_TYPE_STAMP_LOGIN", - "ACTIVITY_TYPE_OAUTH_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" ] }, "v1AddressFormat": { @@ -5954,6 +6086,88 @@ "FEATURE_NAME_OTP_EMAIL_AUTH" ] }, + "v1FiatOnRampBlockchainNetwork": { + "type": "string", + "enum": [ + "FIAT_ON_RAMP_BLOCKCHAIN_NETWORK_BITCOIN", + "FIAT_ON_RAMP_BLOCKCHAIN_NETWORK_ETHEREUM", + "FIAT_ON_RAMP_BLOCKCHAIN_NETWORK_SOLANA", + "FIAT_ON_RAMP_BLOCKCHAIN_NETWORK_BASE" + ] + }, + "v1FiatOnRampCryptoCurrency": { + "type": "string", + "enum": [ + "FIAT_ON_RAMP_CRYPTO_CURRENCY_BTC", + "FIAT_ON_RAMP_CRYPTO_CURRENCY_ETH", + "FIAT_ON_RAMP_CRYPTO_CURRENCY_SOL", + "FIAT_ON_RAMP_CRYPTO_CURRENCY_USDC" + ] + }, + "v1FiatOnRampCurrency": { + "type": "string", + "enum": [ + "FIAT_ON_RAMP_CURRENCY_AUD", + "FIAT_ON_RAMP_CURRENCY_BGN", + "FIAT_ON_RAMP_CURRENCY_BRL", + "FIAT_ON_RAMP_CURRENCY_CAD", + "FIAT_ON_RAMP_CURRENCY_CHF", + "FIAT_ON_RAMP_CURRENCY_COP", + "FIAT_ON_RAMP_CURRENCY_CZK", + "FIAT_ON_RAMP_CURRENCY_DKK", + "FIAT_ON_RAMP_CURRENCY_DOP", + "FIAT_ON_RAMP_CURRENCY_EGP", + "FIAT_ON_RAMP_CURRENCY_EUR", + "FIAT_ON_RAMP_CURRENCY_GBP", + "FIAT_ON_RAMP_CURRENCY_HKD", + "FIAT_ON_RAMP_CURRENCY_IDR", + "FIAT_ON_RAMP_CURRENCY_ILS", + "FIAT_ON_RAMP_CURRENCY_JOD", + "FIAT_ON_RAMP_CURRENCY_KES", + "FIAT_ON_RAMP_CURRENCY_KWD", + "FIAT_ON_RAMP_CURRENCY_LKR", + "FIAT_ON_RAMP_CURRENCY_MXN", + "FIAT_ON_RAMP_CURRENCY_NGN", + "FIAT_ON_RAMP_CURRENCY_NOK", + "FIAT_ON_RAMP_CURRENCY_NZD", + "FIAT_ON_RAMP_CURRENCY_OMR", + "FIAT_ON_RAMP_CURRENCY_PEN", + "FIAT_ON_RAMP_CURRENCY_PLN", + "FIAT_ON_RAMP_CURRENCY_RON", + "FIAT_ON_RAMP_CURRENCY_SEK", + "FIAT_ON_RAMP_CURRENCY_THB", + "FIAT_ON_RAMP_CURRENCY_TRY", + "FIAT_ON_RAMP_CURRENCY_TWD", + "FIAT_ON_RAMP_CURRENCY_USD", + "FIAT_ON_RAMP_CURRENCY_VND", + "FIAT_ON_RAMP_CURRENCY_ZAR" + ] + }, + "v1FiatOnRampPaymentMethod": { + "type": "string", + "enum": [ + "FIAT_ON_RAMP_PAYMENT_METHOD_CREDIT_DEBIT_CARD", + "FIAT_ON_RAMP_PAYMENT_METHOD_APPLE_PAY", + "FIAT_ON_RAMP_PAYMENT_METHOD_GBP_BANK_TRANSFER", + "FIAT_ON_RAMP_PAYMENT_METHOD_GBP_OPEN_BANKING_PAYMENT", + "FIAT_ON_RAMP_PAYMENT_METHOD_GOOGLE_PAY", + "FIAT_ON_RAMP_PAYMENT_METHOD_SEPA_BANK_TRANSFER", + "FIAT_ON_RAMP_PAYMENT_METHOD_PIX_INSTANT_PAYMENT", + "FIAT_ON_RAMP_PAYMENT_METHOD_PAYPAL", + "FIAT_ON_RAMP_PAYMENT_METHOD_VENMO", + "FIAT_ON_RAMP_PAYMENT_METHOD_MOONPAY_BALANCE", + "FIAT_ON_RAMP_PAYMENT_METHOD_CRYPTO_ACCOUNT", + "FIAT_ON_RAMP_PAYMENT_METHOD_FIAT_WALLET", + "FIAT_ON_RAMP_PAYMENT_METHOD_ACH_BANK_ACCOUNT" + ] + }, + "v1FiatOnRampProvider": { + "type": "string", + "enum": [ + "FIAT_ON_RAMP_PROVIDER_COINBASE", + "FIAT_ON_RAMP_PROVIDER_MOONPAY" + ] + }, "v1GetActivitiesRequest": { "type": "object", "properties": { @@ -6712,6 +6926,88 @@ }, "required": ["walletId", "addresses"] }, + "v1InitFiatOnRampIntent": { + "type": "object", + "properties": { + "onrampProvider": { + "$ref": "#/definitions/v1FiatOnRampProvider", + "description": "Enum to specifiy which on-ramp provider to use" + }, + "walletAddress": { + "type": "string", + "description": "Destination wallet address for the buy transaction." + }, + "network": { + "$ref": "#/definitions/v1FiatOnRampBlockchainNetwork", + "description": "Blockchain network to be used for the transaction, e.g., bitcoin, ethereum. Maps to MoonPay's network or Coinbase's defaultNetwork." + }, + "cryptoCurrencyCode": { + "$ref": "#/definitions/v1FiatOnRampCryptoCurrency", + "description": "Code for the cryptocurrency to be purchased, e.g., btc, eth. Maps to MoonPay's currencyCode or Coinbase's defaultAsset." + }, + "fiatCurrencyCode": { + "$ref": "#/definitions/v1FiatOnRampCurrency", + "description": "Code for the fiat currency to be used in the transaction, e.g., USD, EUR." + }, + "fiatCurrencyAmount": { + "type": "string", + "description": "Specifies a preset fiat amount for the transaction, e.g., '100'. Must be greater than '20'. If not provided, the user will be prompted to enter an amount." + }, + "paymentMethod": { + "$ref": "#/definitions/v1FiatOnRampPaymentMethod", + "description": "Pre-selected payment method, e.g., CREDIT_DEBIT_CARD, APPLE_PAY. Validated against the chosen provider." + }, + "countryCode": { + "type": "string", + "description": "ISO 3166-1 two-digit country code for Coinbase representing the purchasing user’s country of residence, e.g., US, GB." + }, + "countrySubdivisionCode": { + "type": "string", + "description": "ISO 3166-2 two-digit country subdivision code for Coinbase representing the purchasing user’s subdivision of residence within their country, e.g. NY. Required if country_code=US." + } + }, + "required": [ + "onrampProvider", + "walletAddress", + "network", + "cryptoCurrencyCode" + ] + }, + "v1InitFiatOnRampRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_INIT_FIAT_ON_RAMP"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1InitFiatOnRampIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1InitFiatOnRampResult": { + "type": "object", + "properties": { + "onRampUrl": { + "type": "string", + "description": "Unique URL for a given fiat on-ramp flow." + }, + "onRampTransactionId": { + "type": "string", + "description": "Unique identifier used to retrieve transaction statuses for a given fiat on-ramp flow." + } + }, + "required": ["onRampUrl", "onRampTransactionId"] + }, "v1InitImportPrivateKeyIntent": { "type": "object", "properties": { @@ -7321,6 +7617,18 @@ }, "oauthLoginIntent": { "$ref": "#/definitions/v1OauthLoginIntent" + }, + "updateUserNameIntent": { + "$ref": "#/definitions/v1UpdateUserNameIntent" + }, + "updateUserEmailIntent": { + "$ref": "#/definitions/v1UpdateUserEmailIntent" + }, + "updateUserPhoneNumberIntent": { + "$ref": "#/definitions/v1UpdateUserPhoneNumberIntent" + }, + "initFiatOnRampIntent": { + "$ref": "#/definitions/v1InitFiatOnRampIntent" } } }, @@ -8416,6 +8724,18 @@ }, "oauthLoginResult": { "$ref": "#/definitions/v1OauthLoginResult" + }, + "updateUserNameResult": { + "$ref": "#/definitions/v1UpdateUserNameResult" + }, + "updateUserEmailResult": { + "$ref": "#/definitions/v1UpdateUserEmailResult" + }, + "updateUserPhoneNumberResult": { + "$ref": "#/definitions/v1UpdateUserPhoneNumberResult" + }, + "initFiatOnRampResult": { + "$ref": "#/definitions/v1InitFiatOnRampResult" } } }, @@ -9176,6 +9496,55 @@ "v1UpdateRootQuorumResult": { "type": "object" }, + "v1UpdateUserEmailIntent": { + "type": "object", + "properties": { + "userId": { + "type": "string", + "description": "Unique identifier for a given User." + }, + "userEmail": { + "type": "string", + "description": "The user's email address. Setting this to an empty string will remove the user's email." + }, + "verificationToken": { + "type": "string", + "description": "Signed JWT containing a unique id, expiry, verification type, contact" + } + }, + "required": ["userId", "userEmail"] + }, + "v1UpdateUserEmailRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_UPDATE_USER_EMAIL"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1UpdateUserEmailIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1UpdateUserEmailResult": { + "type": "object", + "properties": { + "userId": { + "type": "string", + "description": "Unique identifier of the User whose email was updated." + } + }, + "required": ["userId"] + }, "v1UpdateUserIntent": { "type": "object", "properties": { @@ -9205,6 +9574,100 @@ }, "required": ["userId"] }, + "v1UpdateUserNameIntent": { + "type": "object", + "properties": { + "userId": { + "type": "string", + "description": "Unique identifier for a given User." + }, + "userName": { + "type": "string", + "description": "Human-readable name for a User." + } + }, + "required": ["userId", "userName"] + }, + "v1UpdateUserNameRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_UPDATE_USER_NAME"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1UpdateUserNameIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1UpdateUserNameResult": { + "type": "object", + "properties": { + "userId": { + "type": "string", + "description": "Unique identifier of the User whose name was updated." + } + }, + "required": ["userId"] + }, + "v1UpdateUserPhoneNumberIntent": { + "type": "object", + "properties": { + "userId": { + "type": "string", + "description": "Unique identifier for a given User." + }, + "userPhoneNumber": { + "type": "string", + "description": "The user's phone number in E.164 format e.g. +13214567890. Setting this to an empty string will remove the user's phone number." + }, + "verificationToken": { + "type": "string", + "description": "Signed JWT containing a unique id, expiry, verification type, contact" + } + }, + "required": ["userId", "userPhoneNumber"] + }, + "v1UpdateUserPhoneNumberRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_UPDATE_USER_PHONE_NUMBER"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1UpdateUserPhoneNumberIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1UpdateUserPhoneNumberResult": { + "type": "object", + "properties": { + "userId": { + "type": "string", + "description": "Unique identifier of the User whose phone number was updated." + } + }, + "required": ["userId"] + }, "v1UpdateUserRequest": { "type": "object", "properties": { diff --git a/packages/sdk-types/src/__inputs__/public_api.types.ts b/packages/sdk-types/src/__inputs__/public_api.types.ts index 4ac44fc8f..c57280bdc 100644 --- a/packages/sdk-types/src/__inputs__/public_api.types.ts +++ b/packages/sdk-types/src/__inputs__/public_api.types.ts @@ -240,6 +240,10 @@ export type paths = { /** Imports a wallet */ post: operations["PublicApiService_ImportWallet"]; }; + "/public/v1/submit/init_fiat_on_ramp": { + /** Initiate a fiat on ramp flow */ + post: operations["PublicApiService_InitFiatOnRamp"]; + }; "/public/v1/submit/init_import_private_key": { /** Initializes a new private key import */ post: operations["PublicApiService_InitImportPrivateKey"]; @@ -324,6 +328,18 @@ export type paths = { /** Update a User in an existing Organization */ post: operations["PublicApiService_UpdateUser"]; }; + "/public/v1/submit/update_user_email": { + /** Update a User's email in an existing Organization */ + post: operations["PublicApiService_UpdateUserEmail"]; + }; + "/public/v1/submit/update_user_name": { + /** Update a User's name in an existing Organization */ + post: operations["PublicApiService_UpdateUserName"]; + }; + "/public/v1/submit/update_user_phone_number": { + /** Update a User's phone number in an existing Organization */ + post: operations["PublicApiService_UpdateUserPhoneNumber"]; + }; "/public/v1/submit/update_user_tag": { /** Update human-readable name or associated users. Note that this activity is atomic: all of the updates will succeed at once, or all of them will fail. */ post: operations["PublicApiService_UpdateUserTag"]; @@ -593,7 +609,11 @@ export type definitions = { | "ACTIVITY_TYPE_VERIFY_OTP" | "ACTIVITY_TYPE_OTP_LOGIN" | "ACTIVITY_TYPE_STAMP_LOGIN" - | "ACTIVITY_TYPE_OAUTH_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"; /** @enum {string} */ v1AddressFormat: | "ADDRESS_FORMAT_UNCOMPRESSED" @@ -1680,6 +1700,73 @@ export type definitions = { | "FEATURE_NAME_WEBHOOK" | "FEATURE_NAME_SMS_AUTH" | "FEATURE_NAME_OTP_EMAIL_AUTH"; + /** @enum {string} */ + v1FiatOnRampBlockchainNetwork: + | "FIAT_ON_RAMP_BLOCKCHAIN_NETWORK_BITCOIN" + | "FIAT_ON_RAMP_BLOCKCHAIN_NETWORK_ETHEREUM" + | "FIAT_ON_RAMP_BLOCKCHAIN_NETWORK_SOLANA" + | "FIAT_ON_RAMP_BLOCKCHAIN_NETWORK_BASE"; + /** @enum {string} */ + v1FiatOnRampCryptoCurrency: + | "FIAT_ON_RAMP_CRYPTO_CURRENCY_BTC" + | "FIAT_ON_RAMP_CRYPTO_CURRENCY_ETH" + | "FIAT_ON_RAMP_CRYPTO_CURRENCY_SOL" + | "FIAT_ON_RAMP_CRYPTO_CURRENCY_USDC"; + /** @enum {string} */ + v1FiatOnRampCurrency: + | "FIAT_ON_RAMP_CURRENCY_AUD" + | "FIAT_ON_RAMP_CURRENCY_BGN" + | "FIAT_ON_RAMP_CURRENCY_BRL" + | "FIAT_ON_RAMP_CURRENCY_CAD" + | "FIAT_ON_RAMP_CURRENCY_CHF" + | "FIAT_ON_RAMP_CURRENCY_COP" + | "FIAT_ON_RAMP_CURRENCY_CZK" + | "FIAT_ON_RAMP_CURRENCY_DKK" + | "FIAT_ON_RAMP_CURRENCY_DOP" + | "FIAT_ON_RAMP_CURRENCY_EGP" + | "FIAT_ON_RAMP_CURRENCY_EUR" + | "FIAT_ON_RAMP_CURRENCY_GBP" + | "FIAT_ON_RAMP_CURRENCY_HKD" + | "FIAT_ON_RAMP_CURRENCY_IDR" + | "FIAT_ON_RAMP_CURRENCY_ILS" + | "FIAT_ON_RAMP_CURRENCY_JOD" + | "FIAT_ON_RAMP_CURRENCY_KES" + | "FIAT_ON_RAMP_CURRENCY_KWD" + | "FIAT_ON_RAMP_CURRENCY_LKR" + | "FIAT_ON_RAMP_CURRENCY_MXN" + | "FIAT_ON_RAMP_CURRENCY_NGN" + | "FIAT_ON_RAMP_CURRENCY_NOK" + | "FIAT_ON_RAMP_CURRENCY_NZD" + | "FIAT_ON_RAMP_CURRENCY_OMR" + | "FIAT_ON_RAMP_CURRENCY_PEN" + | "FIAT_ON_RAMP_CURRENCY_PLN" + | "FIAT_ON_RAMP_CURRENCY_RON" + | "FIAT_ON_RAMP_CURRENCY_SEK" + | "FIAT_ON_RAMP_CURRENCY_THB" + | "FIAT_ON_RAMP_CURRENCY_TRY" + | "FIAT_ON_RAMP_CURRENCY_TWD" + | "FIAT_ON_RAMP_CURRENCY_USD" + | "FIAT_ON_RAMP_CURRENCY_VND" + | "FIAT_ON_RAMP_CURRENCY_ZAR"; + /** @enum {string} */ + v1FiatOnRampPaymentMethod: + | "FIAT_ON_RAMP_PAYMENT_METHOD_CREDIT_DEBIT_CARD" + | "FIAT_ON_RAMP_PAYMENT_METHOD_APPLE_PAY" + | "FIAT_ON_RAMP_PAYMENT_METHOD_GBP_BANK_TRANSFER" + | "FIAT_ON_RAMP_PAYMENT_METHOD_GBP_OPEN_BANKING_PAYMENT" + | "FIAT_ON_RAMP_PAYMENT_METHOD_GOOGLE_PAY" + | "FIAT_ON_RAMP_PAYMENT_METHOD_SEPA_BANK_TRANSFER" + | "FIAT_ON_RAMP_PAYMENT_METHOD_PIX_INSTANT_PAYMENT" + | "FIAT_ON_RAMP_PAYMENT_METHOD_PAYPAL" + | "FIAT_ON_RAMP_PAYMENT_METHOD_VENMO" + | "FIAT_ON_RAMP_PAYMENT_METHOD_MOONPAY_BALANCE" + | "FIAT_ON_RAMP_PAYMENT_METHOD_CRYPTO_ACCOUNT" + | "FIAT_ON_RAMP_PAYMENT_METHOD_FIAT_WALLET" + | "FIAT_ON_RAMP_PAYMENT_METHOD_ACH_BANK_ACCOUNT"; + /** @enum {string} */ + v1FiatOnRampProvider: + | "FIAT_ON_RAMP_PROVIDER_COINBASE" + | "FIAT_ON_RAMP_PROVIDER_MOONPAY"; v1GetActivitiesRequest: { /** @description Unique identifier for a given Organization. */ organizationId: string; @@ -1977,6 +2064,41 @@ export type definitions = { /** @description A list of account addresses. */ addresses: string[]; }; + v1InitFiatOnRampIntent: { + /** @description Enum to specifiy which on-ramp provider to use */ + onrampProvider: definitions["v1FiatOnRampProvider"]; + /** @description Destination wallet address for the buy transaction. */ + walletAddress: string; + /** @description Blockchain network to be used for the transaction, e.g., bitcoin, ethereum. Maps to MoonPay's network or Coinbase's defaultNetwork. */ + network: definitions["v1FiatOnRampBlockchainNetwork"]; + /** @description Code for the cryptocurrency to be purchased, e.g., btc, eth. Maps to MoonPay's currencyCode or Coinbase's defaultAsset. */ + cryptoCurrencyCode: definitions["v1FiatOnRampCryptoCurrency"]; + /** @description Code for the fiat currency to be used in the transaction, e.g., USD, EUR. */ + fiatCurrencyCode?: definitions["v1FiatOnRampCurrency"]; + /** @description Specifies a preset fiat amount for the transaction, e.g., '100'. Must be greater than '20'. If not provided, the user will be prompted to enter an amount. */ + fiatCurrencyAmount?: string; + /** @description Pre-selected payment method, e.g., CREDIT_DEBIT_CARD, APPLE_PAY. Validated against the chosen provider. */ + paymentMethod?: definitions["v1FiatOnRampPaymentMethod"]; + /** @description ISO 3166-1 two-digit country code for Coinbase representing the purchasing user’s country of residence, e.g., US, GB. */ + countryCode?: string; + /** @description ISO 3166-2 two-digit country subdivision code for Coinbase representing the purchasing user’s subdivision of residence within their country, e.g. NY. Required if country_code=US. */ + countrySubdivisionCode?: string; + }; + v1InitFiatOnRampRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_INIT_FIAT_ON_RAMP"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1InitFiatOnRampIntent"]; + }; + v1InitFiatOnRampResult: { + /** @description Unique URL for a given fiat on-ramp flow. */ + onRampUrl: string; + /** @description Unique identifier used to retrieve transaction statuses for a given fiat on-ramp flow. */ + onRampTransactionId: string; + }; v1InitImportPrivateKeyIntent: { /** @description The ID of the User importing a Private Key. */ userId: string; @@ -2223,6 +2345,10 @@ export type definitions = { otpLoginIntent?: definitions["v1OtpLoginIntent"]; stampLoginIntent?: definitions["v1StampLoginIntent"]; oauthLoginIntent?: definitions["v1OauthLoginIntent"]; + updateUserNameIntent?: definitions["v1UpdateUserNameIntent"]; + updateUserEmailIntent?: definitions["v1UpdateUserEmailIntent"]; + updateUserPhoneNumberIntent?: definitions["v1UpdateUserPhoneNumberIntent"]; + initFiatOnRampIntent?: definitions["v1InitFiatOnRampIntent"]; }; v1Invitation: { /** @description Unique identifier for a given Invitation object. */ @@ -2637,6 +2763,10 @@ export type definitions = { otpLoginResult?: definitions["v1OtpLoginResult"]; stampLoginResult?: definitions["v1StampLoginResult"]; oauthLoginResult?: definitions["v1OauthLoginResult"]; + updateUserNameResult?: definitions["v1UpdateUserNameResult"]; + updateUserEmailResult?: definitions["v1UpdateUserEmailResult"]; + updateUserPhoneNumberResult?: definitions["v1UpdateUserPhoneNumberResult"]; + initFiatOnRampResult?: definitions["v1InitFiatOnRampResult"]; }; v1RootUserParams: { /** @description Human-readable name for a User. */ @@ -2941,6 +3071,27 @@ export type definitions = { parameters: definitions["v1UpdateRootQuorumIntent"]; }; v1UpdateRootQuorumResult: { [key: string]: unknown }; + v1UpdateUserEmailIntent: { + /** @description Unique identifier for a given User. */ + userId: string; + /** @description The user's email address. Setting this to an empty string will remove the user's email. */ + userEmail: string; + /** @description Signed JWT containing a unique id, expiry, verification type, contact */ + verificationToken?: string; + }; + v1UpdateUserEmailRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_UPDATE_USER_EMAIL"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1UpdateUserEmailIntent"]; + }; + v1UpdateUserEmailResult: { + /** @description Unique identifier of the User whose email was updated. */ + userId: string; + }; v1UpdateUserIntent: { /** @description Unique identifier for a given User. */ userId: string; @@ -2953,6 +3104,46 @@ export type definitions = { /** @description The user's phone number in E.164 format e.g. +13214567890 */ userPhoneNumber?: string; }; + v1UpdateUserNameIntent: { + /** @description Unique identifier for a given User. */ + userId: string; + /** @description Human-readable name for a User. */ + userName: string; + }; + v1UpdateUserNameRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_UPDATE_USER_NAME"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1UpdateUserNameIntent"]; + }; + v1UpdateUserNameResult: { + /** @description Unique identifier of the User whose name was updated. */ + userId: string; + }; + v1UpdateUserPhoneNumberIntent: { + /** @description Unique identifier for a given User. */ + userId: string; + /** @description The user's phone number in E.164 format e.g. +13214567890. Setting this to an empty string will remove the user's phone number. */ + userPhoneNumber: string; + /** @description Signed JWT containing a unique id, expiry, verification type, contact */ + verificationToken?: string; + }; + v1UpdateUserPhoneNumberRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_UPDATE_USER_PHONE_NUMBER"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1UpdateUserPhoneNumberIntent"]; + }; + v1UpdateUserPhoneNumberResult: { + /** @description Unique identifier of the User whose phone number was updated. */ + userId: string; + }; v1UpdateUserRequest: { /** @enum {string} */ type: "ACTIVITY_TYPE_UPDATE_USER"; @@ -4247,6 +4438,24 @@ export type operations = { }; }; }; + /** Initiate a fiat on ramp flow */ + PublicApiService_InitFiatOnRamp: { + parameters: { + body: { + body: definitions["v1InitFiatOnRampRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; /** Initializes a new private key import */ PublicApiService_InitImportPrivateKey: { parameters: { @@ -4625,6 +4834,60 @@ export type operations = { }; }; }; + /** Update a User's email in an existing Organization */ + PublicApiService_UpdateUserEmail: { + parameters: { + body: { + body: definitions["v1UpdateUserEmailRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Update a User's name in an existing Organization */ + PublicApiService_UpdateUserName: { + parameters: { + body: { + body: definitions["v1UpdateUserNameRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; + /** Update a User's phone number in an existing Organization */ + PublicApiService_UpdateUserPhoneNumber: { + parameters: { + body: { + body: definitions["v1UpdateUserPhoneNumberRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; /** Update human-readable name or associated users. Note that this activity is atomic: all of the updates will succeed at once, or all of them will fail. */ PublicApiService_UpdateUserTag: { parameters: { From a0b8b56655988dae8b21013176db9c9d79b5b04d Mon Sep 17 00:00:00 2001 From: Ethan Konkolowicz Date: Tue, 17 Jun 2025 10:01:57 -0400 Subject: [PATCH 015/184] updated typing in sdk-js --- examples/with-sdk-js/src/app/page.tsx | 23 +++++++++++++++++ packages/sdk-js/src/__clients__/core.ts | 33 +++++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/examples/with-sdk-js/src/app/page.tsx b/examples/with-sdk-js/src/app/page.tsx index 65d9eb706..f250a1104 100644 --- a/examples/with-sdk-js/src/app/page.tsx +++ b/examples/with-sdk-js/src/app/page.tsx @@ -62,6 +62,15 @@ export default function AuthPage() { } }; + const getUser = async () => { + const res = await client?.fetchUser({}); + if (res) { + console.log("Users:", res); + } else { + console.error("Failed to fetch users"); + } + }; + useEffect(() => {}); return ( @@ -140,6 +149,20 @@ export default function AuthPage() { Get Wallets ) : null} + + {client?.storageManager?.getActiveSession() ? ( + + ) : null} ); } diff --git a/packages/sdk-js/src/__clients__/core.ts b/packages/sdk-js/src/__clients__/core.ts index f7b8a5ace..12939700e 100644 --- a/packages/sdk-js/src/__clients__/core.ts +++ b/packages/sdk-js/src/__clients__/core.ts @@ -3,6 +3,7 @@ import { GetWalletAccountsResponse, SessionType, v1SignRawPayloadResult, + v1User, v1WalletAccount, } from "@turnkey/sdk-types"; import { @@ -278,6 +279,38 @@ export class TurnkeyClient { return response.activity.result .signRawPayloadResult as v1SignRawPayloadResult; }; + + fetchUser = async (params: { + organizationId?: string; + userId?: string; + }): Promise => { + const session = await this.storageManager.getActiveSession(); + if (!session) { + throw new Error("No active session found. Please log in first."); + } + + const userId = params.userId || session.userId; + if (!userId) { + throw new Error("User ID must be provided to fetch user"); + } + + const organizationId = params.organizationId || session.organizationId; + + try { + const userResponse = await this.httpClient.getUser( + { organizationId, userId }, + StamperType.ApiKey, + ); + + if (!userResponse || !userResponse.user) { + throw new Error("No user found in the response"); + } + + return userResponse.user as v1User; + } catch (error) { + throw new Error(`Failed to fetch user: ${error}`); + } + }; } // TO IMPLEMENT: fetchUser From bdec9d8ad80a8955e3e9f051f068923f7ccd4677 Mon Sep 17 00:00:00 2001 From: Ethan Konkolowicz Date: Wed, 18 Jun 2025 16:34:53 -0400 Subject: [PATCH 016/184] added sugared wallet functions and started auth stuff --- examples/with-sdk-js/src/app/page.tsx | 127 ++++- packages/sdk-js/scripts/codegen.js | 2 +- packages/sdk-js/src/__clients__/core.ts | 405 +++++++++++++- .../src/__generated__/sdk-client-base.ts | 2 - packages/sdk-js/src/__types__/base.ts | 21 +- packages/sdk-js/src/turnkey-helpers.ts | 527 ++++++++++++++++++ packages/sdk-js/src/utils.ts | 179 +++++- 7 files changed, 1216 insertions(+), 47 deletions(-) create mode 100644 packages/sdk-js/src/turnkey-helpers.ts diff --git a/examples/with-sdk-js/src/app/page.tsx b/examples/with-sdk-js/src/app/page.tsx index f250a1104..3b12f3b0e 100644 --- a/examples/with-sdk-js/src/app/page.tsx +++ b/examples/with-sdk-js/src/app/page.tsx @@ -2,18 +2,16 @@ import Image from "next/image"; import styles from "./index.module.css"; -import { StamperType, TurnkeyClient, TWallet } from "@turnkey/sdk-js"; +import { StamperType, TurnkeyClient, Wallet } from "@turnkey/sdk-js"; import { server } from "@turnkey/sdk-server"; import { useEffect, useState } from "react"; -import { Session } from "@turnkey/sdk-types"; -import { get } from "http"; -import { set } from "react-hook-form"; +import { Session, v1AddressFormat } from "@turnkey/sdk-types"; export default function AuthPage() { const [client, setClient] = useState(null); const [session, setSession] = useState(null); - const [wallets, setWallets] = useState([]); + const [wallets, setWallets] = useState([]); useEffect(() => { const initializeClient = async () => { @@ -71,7 +69,94 @@ export default function AuthPage() { } }; - useEffect(() => {}); + const signMessage = async () => { + if ( + (wallets.length === 0 && !wallets[0]) || + !wallets[0].accounts || + wallets[0].accounts.length < 2 + ) { + console.error("No wallets available to sign message"); + return; + } + + for (const walletAccount of wallets[0].accounts) { + const res = await client?.signMessage({ + message: "Hello, Turnkey!", + wallet: walletAccount, + }); + + console.log("Signed message response:", res); + } + }; + + const createWallet = async (walletName: string) => { + // List of all v1AddressFormat values + const allAddressFormats = [ + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + ]; + + const res = await client?.createWallet({ + walletName, + accounts: allAddressFormats, + }); + + console.log("Created wallet response:", res); + }; return (
@@ -150,11 +235,25 @@ export default function AuthPage() { ) : null} + {client?.storageManager?.getActiveSession() ? ( + + ) : null} + {client?.storageManager?.getActiveSession() ? ( + )}
); } diff --git a/packages/sdk-js/scripts/codegen.js b/packages/sdk-js/scripts/codegen.js index 1b3d8e5d3..bb0bf1772 100644 --- a/packages/sdk-js/scripts/codegen.js +++ b/packages/sdk-js/scripts/codegen.js @@ -264,7 +264,7 @@ const generateSDKClientFromSwagger = async (swaggerSpec, targetPath) => { imports.push('import { VERSION } from "../__generated__/version";'); - imports.push('import type * as SdkApiTypes from "./sdk_api_types";'); + // imports.push('import type * as SdkApiTypes from "./sdk_api_types";'); imports.push('import type * as SdkTypes from "@turnkey/sdk-types";'); diff --git a/packages/sdk-js/src/__clients__/core.ts b/packages/sdk-js/src/__clients__/core.ts index 12939700e..90509095f 100644 --- a/packages/sdk-js/src/__clients__/core.ts +++ b/packages/sdk-js/src/__clients__/core.ts @@ -1,19 +1,36 @@ import { TurnkeySDKClientBase } from "../__generated__/sdk-client-base"; import { + CreateSubOrganizationResponse, + DeleteSubOrganizationResponse, GetWalletAccountsResponse, SessionType, + SignTransactionResponse, + v1AddressFormat, + v1Attestation, + v1AuthenticatorParamsV2, + v1Pagination, v1SignRawPayloadResult, + v1TransactionType, v1User, v1WalletAccount, } from "@turnkey/sdk-types"; import { DEFAULT_SESSION_EXPIRATION_IN_SECONDS, + ExportBundle, StamperType, - TUser, - TWallet, + User, TurnkeySDKClientConfig, + WalletAccount, + Provider, + Wallet, } from "@types"; // AHHHH, SDK-TYPES -import { getMessageHashAndEncodingType, isReactNative, isWeb } from "@utils"; +import { + generateWalletAccountsFromAddressFormat, + getMessageHashAndEncodingType, + isReactNative, + isWalletAccountArray, + isWeb, +} from "@utils"; import { createStorageManager, StorageBase, @@ -21,14 +38,20 @@ import { } from "../__storage__/base"; import { CrossPlatformApiKeyStamper } from "../__stampers__/api/base"; import { CrossPlatformPasskeyStamper } from "../__stampers__/passkey/base"; +import { + DEFAULT_ETHEREUM_ACCOUNTS, + DEFAULT_SOLANA_ACCOUNTS, +} from "../turnkey-helpers"; +import { WalletType } from "@turnkey/wallet-stamper"; +import { v1 } from "uuid"; export class TurnkeyClient { config: TurnkeySDKClientConfig; // Type TBD httpClient!: TurnkeySDKClientBase; // public session?: Session | undefined; // TODO (Amir): Define session type. Or not maybe??? - public user?: TUser; // TO IMPLEMENT: fetchUser - public wallets?: TWallet[]; + public user?: User; // TO IMPLEMENT: fetchUser + public wallets?: Wallet[]; apiKeyStamper?: CrossPlatformApiKeyStamper | undefined; // TODO (Amir): TEMPORARILY PUBLIC, MAKE PRIVATE LATER private passkeyStamper?: CrossPlatformPasskeyStamper | undefined; @@ -177,10 +200,91 @@ export class TurnkeyClient { } }; + signUpWithPasskey = async (params: { + subOrgName?: string; + userName?: string; + userEmail?: string; + userPhoneNumber?: string; + sessionType?: SessionType; + expirationSeconds?: string | undefined; + passkeyName?: string; + passkeyDisplayName?: string; + wallet?: { + publicKey: string; + type: WalletType; + }; + }): Promise => { + const { + subOrgName, + userName, + userEmail, + userPhoneNumber, + sessionType, + expirationSeconds, + passkeyName, + passkeyDisplayName, + wallet, + } = params; + + try { + let encodedChallenge: string | undefined; + let attestation: v1Attestation | undefined; + + if (isWeb()) { + const res = await this.passkeyStamper?.createWebPasskey({ + publicKey: { + user: { + name: passkeyName, + displayName: passkeyDisplayName, + }, + }, + }); + + if (!res) { + throw new Error("No encoded challenge returned from passkey stamper"); + } + encodedChallenge = res.encodedChallenge; + attestation = res.attestation; + } else if (isReactNative()) { + const res = await this.passkeyStamper?.createReactNativePasskey({ + name: passkeyName, + displayName: passkeyDisplayName, + }); + + if (!res) { + throw new Error("No encoded challenge returned from passkey stamper"); + } + encodedChallenge = res.challenge; + attestation = res.attestation; + } + + if (!encodedChallenge || !attestation) { + throw new Error( + "Failed to create passkey: encoded challenge or attestation is missing", + ); + } + + const response = await this.createSubOrganization({ + userEmail: userEmail, + userName: userName, + userPhoneNumber: userPhoneNumber, + subOrgName: subOrgName, + wallet: wallet, + passkey: { + authenticatorName: "First Passkey", + challenge: encodedChallenge, + attestation: attestation as v1Attestation, + } + }); + } catch (error) { + throw new Error(`Failed to sign up with passkey: ${error}`); + } + }; + fetchWallets = async (params: { stamperType?: StamperType; saveInClient?: boolean; - }): Promise => { + }): Promise => { const { stamperType, saveInClient = true } = params; const session = await this.storageManager.getActiveSession(); if (!session) { @@ -196,7 +300,7 @@ export class TurnkeyClient { throw new Error("No wallets found in the response"); } - const wallets: TWallet[] = res.wallets; + const wallets: Wallet[] = res.wallets; let i = 0; for (const wallet of wallets) { const walletAccounts = await this.fetchWalletAccounts({ @@ -222,8 +326,9 @@ export class TurnkeyClient { fetchWalletAccounts = async (params: { walletId: string; stamperType?: StamperType; + paginationOptions?: v1Pagination; }): Promise => { - const { walletId, stamperType } = params; + const { walletId, stamperType, paginationOptions } = params; const session = await this.storageManager.getActiveSession(); if (!session) { throw new Error("No active session found. Please log in first."); @@ -235,7 +340,11 @@ export class TurnkeyClient { try { return await this.httpClient.getWalletAccounts( - { walletId, organizationId: session.organizationId }, + { + walletId, + organizationId: session.organizationId, + paginationOptions: paginationOptions || { limit: "100" }, + }, stamperType, ); } catch (error) { @@ -258,21 +367,20 @@ export class TurnkeyClient { } // Get the proper encoding and hash function for the address format - const { hashFunction, payloadEncoding } = getMessageHashAndEncodingType( - wallet.addressFormat, - ); + const { hashFunction, payloadEncoding, encodedMessage } = + getMessageHashAndEncodingType(wallet.addressFormat, message); const response = await this.httpClient.signRawPayload( { signWith: wallet.address, - payload: message, + payload: encodedMessage, encoding: payloadEncoding, hashFunction, }, stampWith, ); - if (!response.activity.failure) { + if (response.activity.failure) { throw new Error("Failed to sign message, no signed payload returned"); } @@ -280,6 +388,36 @@ export class TurnkeyClient { .signRawPayloadResult as v1SignRawPayloadResult; }; + signTransaction = async (params: { + signWith: string; + unsignedTransaction: string; + type: v1TransactionType; + stampWith?: StamperType; + }): Promise => { + const { signWith, unsignedTransaction, type, stampWith } = params; + + if (!signWith) { + throw new Error("A wallet account must be provided for signing"); + } + + if (!unsignedTransaction) { + throw new Error("An unsigned transaction must be provided for signing"); + } + + try { + return await this.httpClient.signTransaction( + { + signWith, + unsignedTransaction, + type, + }, + stampWith, + ); + } catch (error) { + throw new Error(`Failed to sign transaction: ${error}`); + } + }; + fetchUser = async (params: { organizationId?: string; userId?: string; @@ -306,11 +444,248 @@ export class TurnkeyClient { throw new Error("No user found in the response"); } - return userResponse.user as v1User; + return userResponse.user as User; } catch (error) { throw new Error(`Failed to fetch user: ${error}`); } }; + + createWallet = async (params: { + walletName: string; + accounts?: WalletAccount[] | v1AddressFormat[]; + organizationId?: string; + mnemonicLength?: number; + stampWith?: StamperType; + }) => { + const { walletName, accounts, organizationId, mnemonicLength, stampWith } = + params; + const session = await this.storageManager.getActiveSession(); + if (!session) { + throw new Error("No active session found. Please log in first."); + } + + let walletAccounts: WalletAccount[] = []; + if (accounts && !isWalletAccountArray(accounts)) { + walletAccounts = generateWalletAccountsFromAddressFormat(accounts); + } else { + walletAccounts = (accounts as WalletAccount[]) || [ + ...DEFAULT_ETHEREUM_ACCOUNTS, + ...DEFAULT_SOLANA_ACCOUNTS, + ]; + } + + try { + const res = await this.httpClient.createWallet( + { + organizationId: organizationId || session.organizationId, + walletName, + accounts: walletAccounts, + mnemonicLength: mnemonicLength || 12, + }, + stampWith, + ); + + if (!res || !res.walletId) { + throw new Error("No wallet ID found in the create wallet response"); + } + return res.walletId; + } catch (error) { + throw new Error(`Failed to create wallet: ${error}`); + } + }; + + createWalletAccounts = async (params: { + accounts: WalletAccount[]; + walletId: string; + organizationId?: string; + stampWith?: StamperType; + }): Promise => { + const { accounts, walletId, organizationId, stampWith } = params; + const session = await this.storageManager.getActiveSession(); + if (!session) { + throw new Error("No active session found. Please log in first."); + } + + if (!walletId) { + throw new Error("Wallet ID must be provided to create an account"); + } + + try { + const res = await this.httpClient.createWalletAccounts( + { + organizationId: organizationId || session.organizationId, + walletId, + accounts: accounts, + }, + stampWith, + ); + + if (!res || !res.addresses) { + throw new Error( + "No account found in the create wallet account response", + ); + } + return res.addresses; + } catch (error) { + throw new Error(`Failed to create wallet account: ${error}`); + } + }; + + exportWallet = async (params: { + walletId: string; + targetPublicKey: string; + organizationId?: string; + stamperType?: StamperType; + }): Promise => { + const { walletId, targetPublicKey, stamperType, organizationId } = params; + const session = await this.storageManager.getActiveSession(); + if (!session) { + throw new Error("No active session found. Please log in first."); + } + + if (!walletId) { + throw new Error("Wallet ID must be provided to export wallet"); + } + + try { + const res = await this.httpClient.exportWallet( + { + walletId, + targetPublicKey, + organizationId: organizationId || session.organizationId, + }, + stamperType, + ); + + if (!res.exportBundle) { + throw new Error("No export bundle found in the response"); + } + return res.exportBundle as ExportBundle; + } catch (error) { + throw new Error(`Failed to export wallet: ${error}`); + } + }; + + importWallet = async (params: { + encryptedBundle: string; + walletName: string; + accounts?: WalletAccount[]; + userId?: string; + }): Promise => { + const { encryptedBundle, accounts, walletName, userId } = params; + + const session = await this.storageManager.getActiveSession(); + if (!session) { + throw new Error("No active session found. Please log in first."); + } + + try { + const res = await this.httpClient.importWallet({ + organizationId: session.organizationId, + userId: userId || session.userId, + encryptedBundle, + walletName, + accounts: accounts || [ + ...DEFAULT_ETHEREUM_ACCOUNTS, + ...DEFAULT_SOLANA_ACCOUNTS, + ], + }); + + if (!res || !res.walletId) { + throw new Error("No wallet ID found in the import response"); + } + return res.walletId; + } catch (error) { + throw new Error(`Failed to import wallet: ${error}`); + } + }; + + deleteSubOrganization = async (params: { + deleteWithoutExport?: boolean; + stamperWith?: StamperType; + }): Promise => { + const { deleteWithoutExport = false, stamperWith } = params; + const session = await this.storageManager.getActiveSession(); + if (!session) { + throw new Error("No active session found. Please log in first."); + } + + try { + return await this.httpClient.deleteSubOrganization( + { deleteWithoutExport }, + stamperWith, + ); + } catch (error) { + throw new Error(`Failed to delete sub-organization: ${error}`); + } + }; + + createSubOrganization = async (params: { + oauthProviders?: Provider[] | undefined; + userEmail?: string | undefined; + userPhoneNumber?: string | undefined; + userName?: string | undefined; + subOrgName?: string | undefined; + passkey?: v1AuthenticatorParamsV2 | undefined; + customAccounts?: WalletAccount[] | undefined; + wallet?: { + publicKey: string; + type: WalletType; + } | undefined; + }): Promise => { + const { + oauthProviders, + passkey, + customAccounts, + wallet, + subOrgName, + userName, + userEmail, + userPhoneNumber, + } = params; + + try { + const response = await this.httpClient.createSubOrganization({ + subOrganizationName: subOrgName || `sub-org-${Date.now()}`, + rootQuorumThreshold: 1, + rootUsers: [ + { + userName: userName ?? userEmail ?? "", + userEmail: userEmail ?? "", + ...(userPhoneNumber ? { userPhoneNumber } : {}), + apiKeys: wallet + ? [ + { + apiKeyName: `wallet-auth:${wallet.publicKey}`, + publicKey: wallet.publicKey, + curveType: + wallet.type === WalletType.Ethereum + ? ("API_KEY_CURVE_SECP256K1" as const) + : ("API_KEY_CURVE_ED25519" as const), + }, + ] + : [], + authenticators: passkey ? [passkey] : [], + oauthProviders: oauthProviders || [], + }, + ], + wallet: { + walletName: `Wallet 1`, + accounts: customAccounts ?? [ + ...DEFAULT_ETHEREUM_ACCOUNTS, + ...DEFAULT_SOLANA_ACCOUNTS, + ], + }, + }); + + if (!response.subOrganizationId) { + throw new Error("Expected a non-null subOrganizationId in response"); + } + return response as CreateSubOrganizationResponse; + } catch (error) { + throw new Error(`Failed to create sub-organization: ${error}`); + } + }; } // TO IMPLEMENT: fetchUser diff --git a/packages/sdk-js/src/__generated__/sdk-client-base.ts b/packages/sdk-js/src/__generated__/sdk-client-base.ts index f8bf275c7..343b8b8a5 100644 --- a/packages/sdk-js/src/__generated__/sdk-client-base.ts +++ b/packages/sdk-js/src/__generated__/sdk-client-base.ts @@ -18,8 +18,6 @@ import { import { VERSION } from "../__generated__/version"; -import type * as SdkApiTypes from "./sdk_api_types"; - import type * as SdkTypes from "@turnkey/sdk-types"; import { StorageBase } from "../__storage__/base"; diff --git a/packages/sdk-js/src/__types__/base.ts b/packages/sdk-js/src/__types__/base.ts index a8554df6a..ec0abc8d8 100644 --- a/packages/sdk-js/src/__types__/base.ts +++ b/packages/sdk-js/src/__types__/base.ts @@ -4,9 +4,13 @@ import type { WebauthnStamper } from "@turnkey/webauthn-stamper"; import type { IndexedDbStamper } from "@turnkey/indexed-db-stamper"; import type { SessionType, + v1AddressFormat, + v1Curve, + v1PathFormat, v1User, v1Wallet, v1WalletAccount, + v1WalletAccountParams, } from "@turnkey/sdk-types"; import { StorageBase } from "../__storage__/base"; import { TPasskeyStamperConfig } from "../__stampers__/passkey/base"; @@ -165,12 +169,25 @@ export interface LoginWithWalletParams { publicKey?: string; } -export type TUser = v1User; // TODO (Amir): I dunno if we need this. We may want to add more stuff to the user type in the future, so let's keep it for now since +export type User = v1User; // TODO (Amir): I dunno if we need this. We may want to add more stuff to the user type in the future, so let's keep it for now since -export type TWallet = v1Wallet & { +export type ExportBundle = string; + +export type Wallet = v1Wallet & { accounts?: v1WalletAccount[] | undefined; }; +export type WalletAccount = v1WalletAccountParams; + +export type Provider = { + providerName: string; + oidcToken: string; +}; + +export type CreateSuborgResponse = { + subOrganizationId: string; +}; + /** * The Client used to authenticate the user. */ diff --git a/packages/sdk-js/src/turnkey-helpers.ts b/packages/sdk-js/src/turnkey-helpers.ts new file mode 100644 index 000000000..c4804a7c9 --- /dev/null +++ b/packages/sdk-js/src/turnkey-helpers.ts @@ -0,0 +1,527 @@ +import { WalletAccount } from "./__types__/base"; + +// ---------------------------- +// CURVE_SECP256K1 Accounts +// ---------------------------- + +// Ethereum +export const defaultEthereumAccountAtIndex = ( + pathIndex: number, +): WalletAccount => { + return { + curve: "CURVE_SECP256K1", + pathFormat: "PATH_FORMAT_BIP32", + path: `m/44'/60'/${pathIndex}'/0/0`, + addressFormat: "ADDRESS_FORMAT_ETHEREUM", + }; +}; + +export const DEFAULT_ETHEREUM_ACCOUNTS: WalletAccount[] = [ + defaultEthereumAccountAtIndex(0), +]; + +// Cosmos +export const defaultCosmosAccountAtIndex = ( + pathIndex: number, +): WalletAccount => { + return { + curve: "CURVE_SECP256K1", + pathFormat: "PATH_FORMAT_BIP32", + path: `m/44'/118'/${pathIndex}'/0/0`, + addressFormat: "ADDRESS_FORMAT_COSMOS", + }; +}; + +export const DEFAULT_COSMOS_ACCOUNTS: WalletAccount[] = [ + defaultCosmosAccountAtIndex(0), +]; + +// Tron +export const defaultTronAccountAtIndex = (pathIndex: number): WalletAccount => { + return { + curve: "CURVE_SECP256K1", + pathFormat: "PATH_FORMAT_BIP32", + path: `m/44'/195'/${pathIndex}'`, + addressFormat: "ADDRESS_FORMAT_TRON", + }; +}; + +export const DEFAULT_TRON_ACCOUNTS: WalletAccount[] = [ + defaultTronAccountAtIndex(0), +]; + +// Bitcoin Mainnet P2PKH +export const defaultBitcoinMainnetP2PKHAccountAtIndex = ( + pathIndex: number, +): WalletAccount => { + return { + curve: "CURVE_SECP256K1", + pathFormat: "PATH_FORMAT_BIP32", + path: `m/44'/0'/${pathIndex}'/0/0`, + addressFormat: "ADDRESS_FORMAT_BITCOIN_MAINNET_P2PKH", + }; +}; + +export const DEFAULT_BITCOIN_MAINNET_P2PKH_ACCOUNTS: WalletAccount[] = [ + defaultBitcoinMainnetP2PKHAccountAtIndex(0), +]; + +// Bitcoin Mainnet P2WPKH +export const defaultBitcoinMainnetP2WPKHAccountAtIndex = ( + pathIndex: number, +): WalletAccount => { + return { + curve: "CURVE_SECP256K1", + pathFormat: "PATH_FORMAT_BIP32", + path: `m/84'/0'/${pathIndex}'/0/0`, + addressFormat: "ADDRESS_FORMAT_BITCOIN_MAINNET_P2WPKH", + }; +}; + +export const DEFAULT_BITCOIN_MAINNET_P2WPKH_ACCOUNTS: WalletAccount[] = [ + defaultBitcoinMainnetP2WPKHAccountAtIndex(0), +]; + +// Bitcoin Mainnet P2WSH +export const defaultBitcoinMainnetP2WSHAccountAtIndex = ( + pathIndex: number, +): WalletAccount => { + return { + curve: "CURVE_SECP256K1", + pathFormat: "PATH_FORMAT_BIP32", + path: `m/48'/0'/${pathIndex}'/2'/0/0`, + addressFormat: "ADDRESS_FORMAT_BITCOIN_MAINNET_P2WSH", + }; +}; + +export const DEFAULT_BITCOIN_MAINNET_P2WSH_ACCOUNTS: WalletAccount[] = [ + defaultBitcoinMainnetP2WSHAccountAtIndex(0), +]; + +// Bitcoin Mainnet P2TR +export const defaultBitcoinMainnetP2TRAccountAtIndex = ( + pathIndex: number, +): WalletAccount => { + return { + curve: "CURVE_SECP256K1", + pathFormat: "PATH_FORMAT_BIP32", + path: `m/86'/0'/${pathIndex}'/0/0`, + addressFormat: "ADDRESS_FORMAT_BITCOIN_MAINNET_P2TR", + }; +}; + +export const DEFAULT_BITCOIN_MAINNET_P2TR_ACCOUNTS: WalletAccount[] = [ + defaultBitcoinMainnetP2TRAccountAtIndex(0), +]; + +// Bitcoin Mainnet P2SH +export const defaultBitcoinMainnetP2SHAccountAtIndex = ( + pathIndex: number, +): WalletAccount => { + return { + curve: "CURVE_SECP256K1", + pathFormat: "PATH_FORMAT_BIP32", + path: `m/44'/0'/${pathIndex}'/0/0`, + addressFormat: "ADDRESS_FORMAT_BITCOIN_MAINNET_P2SH", + }; +}; + +export const DEFAULT_BITCOIN_MAINNET_P2SH_ACCOUNTS: WalletAccount[] = [ + defaultBitcoinMainnetP2SHAccountAtIndex(0), +]; + +// Bitcoin Testnet P2PKH +export const defaultBitcoinTestnetP2PKHAccountAtIndex = ( + pathIndex: number, +): WalletAccount => { + return { + curve: "CURVE_SECP256K1", + pathFormat: "PATH_FORMAT_BIP32", + path: `m/44'/1'/${pathIndex}'/0/0`, + addressFormat: "ADDRESS_FORMAT_BITCOIN_TESTNET_P2PKH", + }; +}; + +export const DEFAULT_BITCOIN_TESTNET_P2PKH_ACCOUNTS: WalletAccount[] = [ + defaultBitcoinTestnetP2PKHAccountAtIndex(0), +]; + +// Bitcoin Testnet P2WPKH +export const defaultBitcoinTestnetP2WPKHAccountAtIndex = ( + pathIndex: number, +): WalletAccount => { + return { + curve: "CURVE_SECP256K1", + pathFormat: "PATH_FORMAT_BIP32", + path: `m/84'/1'/${pathIndex}'/0/0`, + addressFormat: "ADDRESS_FORMAT_BITCOIN_TESTNET_P2WPKH", + }; +}; + +export const DEFAULT_BITCOIN_TESTNET_P2WPKH_ACCOUNTS: WalletAccount[] = [ + defaultBitcoinTestnetP2WPKHAccountAtIndex(0), +]; + +// Bitcoin Testnet P2WSH +export const defaultBitcoinTestnetP2WSHAccountAtIndex = ( + pathIndex: number, +): WalletAccount => { + return { + curve: "CURVE_SECP256K1", + pathFormat: "PATH_FORMAT_BIP32", + path: `m/48'/1'/${pathIndex}'/2'/0/0`, + addressFormat: "ADDRESS_FORMAT_BITCOIN_TESTNET_P2WSH", + }; +}; + +export const DEFAULT_BITCOIN_TESTNET_P2WSH_ACCOUNTS: WalletAccount[] = [ + defaultBitcoinTestnetP2WSHAccountAtIndex(0), +]; + +// Bitcoin Testnet P2TR +export const defaultBitcoinTestnetP2TRAccountAtIndex = ( + pathIndex: number, +): WalletAccount => { + return { + curve: "CURVE_SECP256K1", + pathFormat: "PATH_FORMAT_BIP32", + path: `m/86'/1'/${pathIndex}'/0/0`, + addressFormat: "ADDRESS_FORMAT_BITCOIN_TESTNET_P2TR", + }; +}; + +export const DEFAULT_BITCOIN_TESTNET_P2TR_ACCOUNTS: WalletAccount[] = [ + defaultBitcoinTestnetP2TRAccountAtIndex(0), +]; + +// Bitcoin Testnet P2SH +export const defaultBitcoinTestnetP2SHAccountAtIndex = ( + pathIndex: number, +): WalletAccount => { + return { + curve: "CURVE_SECP256K1", + pathFormat: "PATH_FORMAT_BIP32", + path: `m/44'/1'/${pathIndex}'/0/0`, + addressFormat: "ADDRESS_FORMAT_BITCOIN_TESTNET_P2SH", + }; +}; + +export const DEFAULT_BITCOIN_TESTNET_P2SH_ACCOUNTS: WalletAccount[] = [ + defaultBitcoinTestnetP2SHAccountAtIndex(0), +]; + +// Bitcoin Signet P2PKH +export const defaultBitcoinSignetP2PKHAccountAtIndex = ( + pathIndex: number, +): WalletAccount => { + return { + curve: "CURVE_SECP256K1", + pathFormat: "PATH_FORMAT_BIP32", + path: `m/44'/1'/${pathIndex}'/0/0`, + addressFormat: "ADDRESS_FORMAT_BITCOIN_SIGNET_P2PKH", + }; +}; + +export const DEFAULT_BITCOIN_SIGNET_P2PKH_ACCOUNTS: WalletAccount[] = [ + defaultBitcoinSignetP2PKHAccountAtIndex(0), +]; + +// Bitcoin Signet P2WPKH +export const defaultBitcoinSignetP2WPKHAccountAtIndex = ( + pathIndex: number, +): WalletAccount => { + return { + curve: "CURVE_SECP256K1", + pathFormat: "PATH_FORMAT_BIP32", + path: `m/84'/1'/${pathIndex}'/0/0`, + addressFormat: "ADDRESS_FORMAT_BITCOIN_SIGNET_P2WPKH", + }; +}; + +export const DEFAULT_BITCOIN_SIGNET_P2WPKH_ACCOUNTS: WalletAccount[] = [ + defaultBitcoinSignetP2WPKHAccountAtIndex(0), +]; + +// Bitcoin Signet P2WSH +export const defaultBitcoinSignetP2WSHAccountAtIndex = ( + pathIndex: number, +): WalletAccount => { + return { + curve: "CURVE_SECP256K1", + pathFormat: "PATH_FORMAT_BIP32", + path: `m/48'/1'/${pathIndex}'/2'/0/0`, + addressFormat: "ADDRESS_FORMAT_BITCOIN_SIGNET_P2WSH", + }; +}; + +export const DEFAULT_BITCOIN_SIGNET_P2WSH_ACCOUNTS: WalletAccount[] = [ + defaultBitcoinSignetP2WSHAccountAtIndex(0), +]; + +// Bitcoin Signet P2TR +export const defaultBitcoinSignetP2TRAccountAtIndex = ( + pathIndex: number, +): WalletAccount => { + return { + curve: "CURVE_SECP256K1", + pathFormat: "PATH_FORMAT_BIP32", + path: `m/86'/1'/${pathIndex}'/0/0`, + addressFormat: "ADDRESS_FORMAT_BITCOIN_SIGNET_P2TR", + }; +}; + +export const DEFAULT_BITCOIN_SIGNET_P2TR_ACCOUNTS: WalletAccount[] = [ + defaultBitcoinSignetP2TRAccountAtIndex(0), +]; + +// Bitcoin Signet P2SH +export const defaultBitcoinSignetP2SHAccountAtIndex = ( + pathIndex: number, +): WalletAccount => { + return { + curve: "CURVE_SECP256K1", + pathFormat: "PATH_FORMAT_BIP32", + path: `m/44'/1'/${pathIndex}'/0/0`, + addressFormat: "ADDRESS_FORMAT_BITCOIN_SIGNET_P2SH", + }; +}; + +export const DEFAULT_BITCOIN_SIGNET_P2SH_ACCOUNTS: WalletAccount[] = [ + defaultBitcoinSignetP2SHAccountAtIndex(0), +]; + +// Bitcoin Regtest P2PKH +export const defaultBitcoinRegtestP2PKHAccountAtIndex = ( + pathIndex: number, +): WalletAccount => { + return { + curve: "CURVE_SECP256K1", + pathFormat: "PATH_FORMAT_BIP32", + path: `m/44'/1'/${pathIndex}'/0/0`, + addressFormat: "ADDRESS_FORMAT_BITCOIN_REGTEST_P2PKH", + }; +}; + +export const DEFAULT_BITCOIN_REGTEST_P2PKH_ACCOUNTS: WalletAccount[] = [ + defaultBitcoinRegtestP2PKHAccountAtIndex(0), +]; + +// Bitcoin Regtest P2WPKH +export const defaultBitcoinRegtestP2WPKHAccountAtIndex = ( + pathIndex: number, +): WalletAccount => { + return { + curve: "CURVE_SECP256K1", + pathFormat: "PATH_FORMAT_BIP32", + path: `m/84'/1'/${pathIndex}'/0/0`, + addressFormat: "ADDRESS_FORMAT_BITCOIN_REGTEST_P2WPKH", + }; +}; + +export const DEFAULT_BITCOIN_REGTEST_P2WPKH_ACCOUNTS: WalletAccount[] = [ + defaultBitcoinRegtestP2WPKHAccountAtIndex(0), +]; + +// Bitcoin Regtest P2WSH +export const defaultBitcoinRegtestP2WSHAccountAtIndex = ( + pathIndex: number, +): WalletAccount => { + return { + curve: "CURVE_SECP256K1", + pathFormat: "PATH_FORMAT_BIP32", + path: `m/48'/1'/${pathIndex}'/2'/0/0`, + addressFormat: "ADDRESS_FORMAT_BITCOIN_REGTEST_P2WSH", + }; +}; + +export const DEFAULT_BITCOIN_REGTEST_P2WSH_ACCOUNTS: WalletAccount[] = [ + defaultBitcoinRegtestP2WSHAccountAtIndex(0), +]; + +// Bitcoin Regtest P2TR +export const defaultBitcoinRegtestP2TRAccountAtIndex = ( + pathIndex: number, +): WalletAccount => { + return { + curve: "CURVE_SECP256K1", + pathFormat: "PATH_FORMAT_BIP32", + path: `m/86'/1'/${pathIndex}'/0/0`, + addressFormat: "ADDRESS_FORMAT_BITCOIN_REGTEST_P2TR", + }; +}; + +export const DEFAULT_BITCOIN_REGTEST_P2TR_ACCOUNTS: WalletAccount[] = [ + defaultBitcoinRegtestP2TRAccountAtIndex(0), +]; + +// Bitcoin Regtest P2SH +export const defaultBitcoinRegtestP2SHAccountAtIndex = ( + pathIndex: number, +): WalletAccount => { + return { + curve: "CURVE_SECP256K1", + pathFormat: "PATH_FORMAT_BIP32", + path: `m/44'/1'/${pathIndex}'/0/0`, + addressFormat: "ADDRESS_FORMAT_BITCOIN_REGTEST_P2SH", + }; +}; + +export const DEFAULT_BITCOIN_REGTEST_P2SH_ACCOUNTS: WalletAccount[] = [ + defaultBitcoinRegtestP2SHAccountAtIndex(0), +]; + +// Dogecoin Mainnet +export const defaultDogeMainnetAccountAtIndex = ( + pathIndex: number, +): WalletAccount => { + return { + curve: "CURVE_SECP256K1", + pathFormat: "PATH_FORMAT_BIP32", + path: `m/44'/3'/${pathIndex}'/0/0`, + addressFormat: "ADDRESS_FORMAT_DOGE_MAINNET", + }; +}; + +export const DEFAULT_DOGE_MAINNET_ACCOUNTS: WalletAccount[] = [ + defaultDogeMainnetAccountAtIndex(0), +]; + +// Dogecoin Testnet +export const defaultDogeTestnetAccountAtIndex = ( + pathIndex: number, +): WalletAccount => { + return { + curve: "CURVE_SECP256K1", + pathFormat: "PATH_FORMAT_BIP32", + path: `m/44'/3'/${pathIndex}'/0/0`, + addressFormat: "ADDRESS_FORMAT_DOGE_TESTNET", + }; +}; + +export const DEFAULT_DOGE_TESTNET_ACCOUNTS: WalletAccount[] = [ + defaultDogeTestnetAccountAtIndex(0), +]; + +// Sei +export const defaultSeiAccountAtIndex = (pathIndex: number): WalletAccount => { + return { + curve: "CURVE_SECP256K1", + pathFormat: "PATH_FORMAT_BIP32", + path: `m/44'/118'/${pathIndex}'/0'/0'`, + addressFormat: "ADDRESS_FORMAT_SEI", + }; +}; + +export const DEFAULT_SEI_ACCOUNTS: WalletAccount[] = [ + defaultSeiAccountAtIndex(0), +]; + +// Xrp +export const defaultXrpAccountAtIndex = (pathIndex: number): WalletAccount => { + return { + curve: "CURVE_SECP256K1", + pathFormat: "PATH_FORMAT_BIP32", + path: `m/44'/144'/${pathIndex}'/0'/0'`, + addressFormat: "ADDRESS_FORMAT_XRP", + }; +}; + +export const DEFAULT_XRP_ACCOUNTS: WalletAccount[] = [ + defaultXrpAccountAtIndex(0), +]; + +// ---------------------------- +// CURVE_ED25519 Accounts +// ---------------------------- + +// Solana +export const defaultSolanaAccountAtIndex = ( + pathIndex: number, +): WalletAccount => { + return { + curve: "CURVE_ED25519", + pathFormat: "PATH_FORMAT_BIP32", + path: `m/44'/501'/${pathIndex}'/0'`, + addressFormat: "ADDRESS_FORMAT_SOLANA", + }; +}; + +export const DEFAULT_SOLANA_ACCOUNTS: WalletAccount[] = [ + defaultSolanaAccountAtIndex(0), +]; + +// SUI +export const defaultSuiAccountAtIndex = (pathIndex: number): WalletAccount => { + return { + curve: "CURVE_ED25519", + pathFormat: "PATH_FORMAT_BIP32", + path: `m/44'/784'/${pathIndex}'/0'/0'`, + addressFormat: "ADDRESS_FORMAT_SUI", + }; +}; + +export const DEFAULT_SUI_ACCOUNTS: WalletAccount[] = [ + defaultSuiAccountAtIndex(0), +]; + +// Aptos +export const defaultAptosAccountAtIndex = ( + pathIndex: number, +): WalletAccount => { + return { + curve: "CURVE_ED25519", + pathFormat: "PATH_FORMAT_BIP32", + path: `m/44'/637'/${pathIndex}'/0'/0'`, + addressFormat: "ADDRESS_FORMAT_APTOS", + }; +}; + +export const DEFAULT_APTOS_ACCOUNTS: WalletAccount[] = [ + defaultAptosAccountAtIndex(0), +]; + +// Stellar (XLM) +export const defaultXlmAccountAtIndex = (pathIndex: number): WalletAccount => { + return { + curve: "CURVE_ED25519", + pathFormat: "PATH_FORMAT_BIP32", + path: `m/44'/148'/${pathIndex}'`, + addressFormat: "ADDRESS_FORMAT_XLM", + }; +}; + +export const DEFAULT_XLM_ACCOUNTS: WalletAccount[] = [ + defaultXlmAccountAtIndex(0), +]; + +// TON V3R2 +export const defaultTonV3r2AccountAtIndex = ( + pathIndex: number, +): WalletAccount => { + return { + curve: "CURVE_ED25519", + pathFormat: "PATH_FORMAT_BIP32", + path: `m/44'/607'/${pathIndex}'/0'/0'`, + addressFormat: "ADDRESS_FORMAT_TON_V3R2", + }; +}; + +export const DEFAULT_TON_V3R2_ACCOUNTS: WalletAccount[] = [ + defaultTonV3r2AccountAtIndex(0), +]; + +// TON V4R2 +export const defaultTonV4r2AccountAtIndex = ( + pathIndex: number, +): WalletAccount => { + return { + curve: "CURVE_ED25519", + pathFormat: "PATH_FORMAT_BIP32", + path: `m/44'/607'/${pathIndex}'/0'/0'`, + addressFormat: "ADDRESS_FORMAT_TON_V4R2", + }; +}; + +export const DEFAULT_TON_V4R2_ACCOUNTS: WalletAccount[] = [ + defaultTonV4r2AccountAtIndex(0), +]; diff --git a/packages/sdk-js/src/utils.ts b/packages/sdk-js/src/utils.ts index 45742cea8..440012957 100644 --- a/packages/sdk-js/src/utils.ts +++ b/packages/sdk-js/src/utils.ts @@ -1,165 +1,233 @@ -import { Buffer } from "buffer"; - import type { - AddressFormat, - HashFunction, - PayloadEncoding, + v1AddressFormat, + v1HashFunction, + v1PayloadEncoding, Session, } from "@turnkey/sdk-types"; +import { WalletAccount } from "@types"; +// Import all defaultAccountAtIndex functions for each address format +import { + DEFAULT_ETHEREUM_ACCOUNTS, + DEFAULT_COSMOS_ACCOUNTS, + DEFAULT_TRON_ACCOUNTS, + DEFAULT_BITCOIN_MAINNET_P2PKH_ACCOUNTS, + DEFAULT_BITCOIN_MAINNET_P2SH_ACCOUNTS, + DEFAULT_BITCOIN_MAINNET_P2WPKH_ACCOUNTS, + DEFAULT_BITCOIN_MAINNET_P2WSH_ACCOUNTS, + DEFAULT_BITCOIN_MAINNET_P2TR_ACCOUNTS, + DEFAULT_BITCOIN_TESTNET_P2PKH_ACCOUNTS, + DEFAULT_BITCOIN_TESTNET_P2SH_ACCOUNTS, + DEFAULT_BITCOIN_TESTNET_P2WPKH_ACCOUNTS, + DEFAULT_BITCOIN_TESTNET_P2WSH_ACCOUNTS, + DEFAULT_BITCOIN_TESTNET_P2TR_ACCOUNTS, + DEFAULT_BITCOIN_SIGNET_P2PKH_ACCOUNTS, + DEFAULT_BITCOIN_SIGNET_P2SH_ACCOUNTS, + DEFAULT_BITCOIN_SIGNET_P2WPKH_ACCOUNTS, + DEFAULT_BITCOIN_SIGNET_P2WSH_ACCOUNTS, + DEFAULT_BITCOIN_SIGNET_P2TR_ACCOUNTS, + DEFAULT_BITCOIN_REGTEST_P2PKH_ACCOUNTS, + DEFAULT_BITCOIN_REGTEST_P2SH_ACCOUNTS, + DEFAULT_BITCOIN_REGTEST_P2WPKH_ACCOUNTS, + DEFAULT_BITCOIN_REGTEST_P2WSH_ACCOUNTS, + DEFAULT_BITCOIN_REGTEST_P2TR_ACCOUNTS, + DEFAULT_DOGE_MAINNET_ACCOUNTS, + DEFAULT_DOGE_TESTNET_ACCOUNTS, + DEFAULT_SEI_ACCOUNTS, + DEFAULT_XRP_ACCOUNTS, + DEFAULT_SOLANA_ACCOUNTS, + DEFAULT_SUI_ACCOUNTS, + DEFAULT_APTOS_ACCOUNTS, + DEFAULT_XLM_ACCOUNTS, + DEFAULT_TON_V3R2_ACCOUNTS, + DEFAULT_TON_V4R2_ACCOUNTS, +} from "./turnkey-helpers"; type AddressFormatConfig = { - encoding: "PAYLOAD_ENCODING_HEXADECIMAL" | "PAYLOAD_ENCODING_TEXT_UTF8"; - hashFunction: - | "HASH_FUNCTION_NOT_APPLICABLE" - | "HASH_FUNCTION_NO_OP" - | "HASH_FUNCTION_SHA256" - | "HASH_FUNCTION_KECCAK256"; + encoding: v1PayloadEncoding; + hashFunction: v1HashFunction; + defaultAccounts: WalletAccount[] | null; }; -const addressFormatConfig: Record = { +const addressFormatConfig: Record = { ADDRESS_FORMAT_UNCOMPRESSED: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256", + defaultAccounts: null, }, ADDRESS_FORMAT_COMPRESSED: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256", + defaultAccounts: null, }, ADDRESS_FORMAT_ETHEREUM: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_KECCAK256", + defaultAccounts: DEFAULT_ETHEREUM_ACCOUNTS, }, ADDRESS_FORMAT_SOLANA: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_NOT_APPLICABLE", + defaultAccounts: DEFAULT_SOLANA_ACCOUNTS, }, ADDRESS_FORMAT_COSMOS: { encoding: "PAYLOAD_ENCODING_TEXT_UTF8", hashFunction: "HASH_FUNCTION_SHA256", + defaultAccounts: DEFAULT_COSMOS_ACCOUNTS, }, ADDRESS_FORMAT_TRON: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256", + defaultAccounts: DEFAULT_TRON_ACCOUNTS, }, ADDRESS_FORMAT_SUI: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", - hashFunction: "HASH_FUNCTION_SHA256", + hashFunction: "HASH_FUNCTION_NOT_APPLICABLE", + defaultAccounts: DEFAULT_SUI_ACCOUNTS, }, ADDRESS_FORMAT_APTOS: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_NOT_APPLICABLE", + defaultAccounts: DEFAULT_APTOS_ACCOUNTS, }, ADDRESS_FORMAT_BITCOIN_MAINNET_P2PKH: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256", + defaultAccounts: DEFAULT_BITCOIN_MAINNET_P2PKH_ACCOUNTS, }, ADDRESS_FORMAT_BITCOIN_MAINNET_P2SH: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256", + defaultAccounts: DEFAULT_BITCOIN_MAINNET_P2SH_ACCOUNTS, }, ADDRESS_FORMAT_BITCOIN_MAINNET_P2WPKH: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256", + defaultAccounts: DEFAULT_BITCOIN_MAINNET_P2WPKH_ACCOUNTS, }, ADDRESS_FORMAT_BITCOIN_MAINNET_P2WSH: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256", + defaultAccounts: DEFAULT_BITCOIN_MAINNET_P2WSH_ACCOUNTS, }, ADDRESS_FORMAT_BITCOIN_MAINNET_P2TR: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256", + defaultAccounts: DEFAULT_BITCOIN_MAINNET_P2TR_ACCOUNTS, }, ADDRESS_FORMAT_BITCOIN_TESTNET_P2PKH: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256", + defaultAccounts: DEFAULT_BITCOIN_TESTNET_P2PKH_ACCOUNTS, }, ADDRESS_FORMAT_BITCOIN_TESTNET_P2SH: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256", + defaultAccounts: DEFAULT_BITCOIN_TESTNET_P2SH_ACCOUNTS, }, ADDRESS_FORMAT_BITCOIN_TESTNET_P2WPKH: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256", + defaultAccounts: DEFAULT_BITCOIN_TESTNET_P2WPKH_ACCOUNTS, }, ADDRESS_FORMAT_BITCOIN_TESTNET_P2WSH: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256", + defaultAccounts: DEFAULT_BITCOIN_TESTNET_P2WSH_ACCOUNTS, }, ADDRESS_FORMAT_BITCOIN_TESTNET_P2TR: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256", + defaultAccounts: DEFAULT_BITCOIN_TESTNET_P2TR_ACCOUNTS, }, ADDRESS_FORMAT_BITCOIN_SIGNET_P2PKH: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256", + defaultAccounts: DEFAULT_BITCOIN_SIGNET_P2PKH_ACCOUNTS, }, ADDRESS_FORMAT_BITCOIN_SIGNET_P2SH: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256", + defaultAccounts: DEFAULT_BITCOIN_SIGNET_P2SH_ACCOUNTS, }, ADDRESS_FORMAT_BITCOIN_SIGNET_P2WPKH: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256", + defaultAccounts: DEFAULT_BITCOIN_SIGNET_P2WPKH_ACCOUNTS, }, ADDRESS_FORMAT_BITCOIN_SIGNET_P2WSH: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256", + defaultAccounts: DEFAULT_BITCOIN_SIGNET_P2WSH_ACCOUNTS, }, ADDRESS_FORMAT_BITCOIN_SIGNET_P2TR: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256", + defaultAccounts: DEFAULT_BITCOIN_SIGNET_P2TR_ACCOUNTS, }, ADDRESS_FORMAT_BITCOIN_REGTEST_P2PKH: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256", + defaultAccounts: DEFAULT_BITCOIN_REGTEST_P2PKH_ACCOUNTS, }, ADDRESS_FORMAT_BITCOIN_REGTEST_P2SH: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256", + defaultAccounts: DEFAULT_BITCOIN_REGTEST_P2SH_ACCOUNTS, }, ADDRESS_FORMAT_BITCOIN_REGTEST_P2WPKH: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256", + defaultAccounts: DEFAULT_BITCOIN_REGTEST_P2WPKH_ACCOUNTS, }, ADDRESS_FORMAT_BITCOIN_REGTEST_P2WSH: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256", + defaultAccounts: DEFAULT_BITCOIN_REGTEST_P2WSH_ACCOUNTS, }, ADDRESS_FORMAT_BITCOIN_REGTEST_P2TR: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256", + defaultAccounts: DEFAULT_BITCOIN_REGTEST_P2TR_ACCOUNTS, }, ADDRESS_FORMAT_SEI: { encoding: "PAYLOAD_ENCODING_TEXT_UTF8", hashFunction: "HASH_FUNCTION_SHA256", + defaultAccounts: DEFAULT_SEI_ACCOUNTS, }, ADDRESS_FORMAT_XLM: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", - hashFunction: "HASH_FUNCTION_SHA256", + hashFunction: "HASH_FUNCTION_NOT_APPLICABLE", + defaultAccounts: DEFAULT_XLM_ACCOUNTS, }, ADDRESS_FORMAT_DOGE_MAINNET: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256", + defaultAccounts: DEFAULT_DOGE_MAINNET_ACCOUNTS, }, ADDRESS_FORMAT_DOGE_TESTNET: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256", + defaultAccounts: DEFAULT_DOGE_TESTNET_ACCOUNTS, }, ADDRESS_FORMAT_TON_V3R2: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", - hashFunction: "HASH_FUNCTION_SHA256", + hashFunction: "HASH_FUNCTION_NOT_APPLICABLE", + defaultAccounts: DEFAULT_TON_V3R2_ACCOUNTS, }, ADDRESS_FORMAT_TON_V4R2: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", - hashFunction: "HASH_FUNCTION_SHA256", + hashFunction: "HASH_FUNCTION_NOT_APPLICABLE", + defaultAccounts: DEFAULT_TON_V4R2_ACCOUNTS, }, ADDRESS_FORMAT_TON_V5R1: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", - hashFunction: "HASH_FUNCTION_SHA256", + hashFunction: "HASH_FUNCTION_NOT_APPLICABLE", + defaultAccounts: null, }, ADDRESS_FORMAT_XRP: { encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: "HASH_FUNCTION_SHA256", + defaultAccounts: DEFAULT_XRP_ACCOUNTS, }, }; @@ -231,16 +299,87 @@ export function parseSession(token: string | Session): Session { }; } -export function getMessageHashAndEncodingType(addressFormat: AddressFormat): { - hashFunction: HashFunction; - payloadEncoding: PayloadEncoding; +export function getMessageHashAndEncodingType( + addressFormat: v1AddressFormat, + rawMessage: string, +): { + hashFunction: v1HashFunction; + payloadEncoding: v1PayloadEncoding; + encodedMessage: string; } { const config = addressFormatConfig[addressFormat]; if (!config) { throw new Error(`Unsupported address format: ${addressFormat}`); } + + let encodedMessage: string; + if (config.encoding === "PAYLOAD_ENCODING_HEXADECIMAL") { + encodedMessage = + "0x" + + Array.from(new TextEncoder().encode(rawMessage)) + .map((b) => b.toString(16).padStart(2, "0")) + .join(""); + } else { + encodedMessage = rawMessage; + } + return { hashFunction: config.hashFunction, payloadEncoding: config.encoding, + encodedMessage, }; } + +// Type guard to check if accounts is WalletAccount[] +export function isWalletAccountArray(arr: any[]): arr is WalletAccount[] { + return ( + arr.length === 0 || + (typeof arr[0] === "object" && + "address" in arr[0] && + "addressFormat" in arr[0]) + ); +} + +export function createWalletAccountFromAddressFormat( + addressFormat: v1AddressFormat, +): WalletAccount { + const walletAccount = addressFormatConfig[addressFormat].defaultAccounts; + if (!walletAccount) { + throw new Error(`Unsupported address format: ${addressFormat}`); + } + + if (walletAccount[0]) { + return walletAccount[0]; + } + + throw new Error( + `No default accounts defined for address format: ${addressFormat}`, + ); +} + +export function generateWalletAccountsFromAddressFormat( + addresses: v1AddressFormat[], +) { + let walletAccounts: WalletAccount[] = []; + const pathMap = new Map(); + walletAccounts = addresses.map((addressFormat) => { + const account = createWalletAccountFromAddressFormat(addressFormat); + const pathIndex = pathMap.get(account.path) ?? 0; + // Replace the number after the first 3 slashes (the 4th segment) + const pathWithIndex = account.path.replace( + /^((?:[^\/]*\/){3})(\d+)/, + (_, prefix, _oldIdx) => `${prefix}${pathIndex}`, + ); + pathMap.set(account.path, pathIndex + 1); + const newAccount: WalletAccount = { + curve: account.curve, + pathFormat: account.pathFormat, + path: pathWithIndex, + addressFormat: account.addressFormat, + }; + return newAccount; + }); + + console.log(walletAccounts); + return walletAccounts; +} From 4b70eeb57dc9937201551bac50817b601ee5023b Mon Sep 17 00:00:00 2001 From: Ethan Konkolowicz Date: Fri, 20 Jun 2025 16:56:17 -0400 Subject: [PATCH 017/184] added signup with passkey --- examples/with-sdk-js/.env.local.example | 5 +- examples/with-sdk-js/src/app/layout.tsx | 2 + examples/with-sdk-js/src/app/page.tsx | 40 ++++ packages/sdk-js/src/__clients__/core.ts | 224 ++++++++++++------- packages/sdk-js/src/__stampers__/api/base.ts | 34 ++- packages/sdk-js/src/__types__/base.ts | 2 + 6 files changed, 219 insertions(+), 88 deletions(-) diff --git a/examples/with-sdk-js/.env.local.example b/examples/with-sdk-js/.env.local.example index 0a0c162bd..d257a410e 100644 --- a/examples/with-sdk-js/.env.local.example +++ b/examples/with-sdk-js/.env.local.example @@ -1,4 +1,7 @@ TURNKEY_API_PUBLIC_KEY="" TURNKEY_API_PRIVATE_KEY="" NEXT_PUBLIC_BASE_URL="https://api.turnkey.com" -NEXT_PUBLIC_ORGANIZATION_ID="" \ No newline at end of file +NEXT_PUBLIC_ORGANIZATION_ID="" + +NEXT_PUBLIC_AUTH_PROXY_URL="http://localhost:8090" +NEXT_PUBLIC_AUTH_PROXY_ID="" \ No newline at end of file diff --git a/examples/with-sdk-js/src/app/layout.tsx b/examples/with-sdk-js/src/app/layout.tsx index 3a32c39eb..137b3648a 100644 --- a/examples/with-sdk-js/src/app/layout.tsx +++ b/examples/with-sdk-js/src/app/layout.tsx @@ -4,6 +4,8 @@ import { TurnkeyProvider } from "@turnkey/sdk-react"; const turnkeyConfig = { apiBaseUrl: process.env.NEXT_PUBLIC_BASE_URL!, + authProxyUrl: process.env.NEXT_PUBLIC_AUTH_PROXY_URL!, + authProxyId: process.env.NEXT_PUBLIC_AUTH_PROXY_ID!, defaultOrganizationId: process.env.NEXT_PUBLIC_ORGANIZATION_ID!, rpId: process.env.NEXT_PUBLIC_RPID!, }; diff --git a/examples/with-sdk-js/src/app/page.tsx b/examples/with-sdk-js/src/app/page.tsx index 3b12f3b0e..ef3abf07d 100644 --- a/examples/with-sdk-js/src/app/page.tsx +++ b/examples/with-sdk-js/src/app/page.tsx @@ -17,6 +17,8 @@ export default function AuthPage() { const initializeClient = async () => { const turnkeyClient = new TurnkeyClient({ apiBaseUrl: process.env.NEXT_PUBLIC_BASE_URL!, + authProxyUrl: process.env.NEXT_PUBLIC_AUTH_PROXY_URL!, + authProxyId: process.env.NEXT_PUBLIC_AUTH_PROXY_ID!, organizationId: process.env.NEXT_PUBLIC_ORGANIZATION_ID!, passkeyConfig: { rpId: process.env.NEXT_PUBLIC_RPID!, @@ -89,6 +91,15 @@ export default function AuthPage() { } }; + const signUpWithPasskey = async () => { + const res = await client?.signUpWithPasskey({ + passkeyDisplayName: `local-shmocal-passkey_${Date.now()}`, + passkeyName: `local-shmocal-passkey_${Date.now()}`, + }) + + console.log(res); + } + const createWallet = async (walletName: string) => { // List of all v1AddressFormat values const allAddressFormats = [ @@ -158,6 +169,11 @@ export default function AuthPage() { console.log("Created wallet response:", res); }; + const logout = async () => { + client?.logout({sessionKey: "session-1"}); + window.location.reload(); + }; + return (
+ + + + + { + setEmail(e.target.value); + }} + /> + + + { + setOtpCode(e.target.value); + }} + /> + + + + ) : null} + + {client?.storageManager?.getActiveSession() ? ( + + ) : null} + {client?.storageManager?.getActiveSession() ? ( - { setEmail(e.target.value); }} - /> + /> - - { - setEmail(e.target.value); - }} - /> - - - { - setOtpCode(e.target.value); - }} - /> - - - - - - - - - - - - {client?.storageManager?.getActiveSession() ? ( - ) : null} - {client?.storageManager?.getActiveSession() ? ( + { + setEmail(e.target.value); + }} + /> - ) : null} - {client?.storageManager?.getActiveSession() ? ( + { + setOtpCode(e.target.value); + }} + /> + - ) : null} - {client?.storageManager?.getActiveSession() ? ( - ) : null} - {client?.storageManager?.getActiveSession() ? ( - ) : null} - {wallets.length > 0 && ( + + - )} + + {client?.storageManager?.getActiveSession() ? ( + + ) : null} + + {client?.storageManager?.getActiveSession() ? ( + + ) : null} + + {client?.storageManager?.getActiveSession() ? ( + + ) : null} + + {client?.storageManager?.getActiveSession() ? ( + + ) : null} + + {client?.storageManager?.getActiveSession() ? ( + + ) : null} + + {wallets.length > 0 && ( + + )} +
); } diff --git a/packages/sdk-js/src/__clients__/core.ts b/packages/sdk-js/src/__clients__/core.ts index 8af6c0d8d..1f33db011 100644 --- a/packages/sdk-js/src/__clients__/core.ts +++ b/packages/sdk-js/src/__clients__/core.ts @@ -9,6 +9,7 @@ import { v1Attestation, v1AuthenticatorParamsV2, v1InitOtpResult, + v1OauthLoginResult, v1OtpLoginResult, v1Pagination, v1SignRawPayloadResult, @@ -242,6 +243,126 @@ export class TurnkeyClient { } }; + signUpWithPasskey = async (params: { + createSubOrgParams?: CreateSubOrgParams; + sessionType?: SessionType; + sessionExpirationSeconds?: string | undefined; + sessionKey?: string | undefined; + passkeyDisplayName?: string; + }): Promise => { + const { + createSubOrgParams, + passkeyDisplayName, + sessionExpirationSeconds, + sessionKey, + } = params; + + let generatedKeyPair = null; + try { + generatedKeyPair = await this.apiKeyStamper?.createKeyPair(); + const passkey = await this.createPasskey({ + ...(createSubOrgParams?.passkeyName && { + name: createSubOrgParams?.passkeyName, + }), + ...(passkeyDisplayName && { displayName: passkeyDisplayName }), + }); + + if (!passkey) { + throw new Error( + "Failed to create passkey: encoded challenge or attestation is missing" + ); + } + + // Build the request body for OTP init + const signUpBody = { + userName: + createSubOrgParams?.userName || + createSubOrgParams?.userEmail || + `user-${Date.now()}`, + userEmail: createSubOrgParams?.userEmail, + authenticators: [ + { + authenticatorName: + createSubOrgParams?.passkeyName || "Default Passkey", + challenge: passkey.encodedChallenge, + attestation: passkey.attestation, + }, + ], + userPhoneNumber: createSubOrgParams?.userPhoneNumber, + userTag: createSubOrgParams?.userTag, + subOrgName: createSubOrgParams?.subOrgName || `sub-org-${Date.now()}`, + apiKeys: [ + { + apiKeyName: `passkey-auth-${generatedKeyPair}`, + publicKey: generatedKeyPair, + curveType: "API_KEY_CURVE_P256", + expirationSeconds: "60", + }, + ], + oauthProviders: createSubOrgParams?.oauthProviders, + ...(createSubOrgParams?.customWallet && { + wallet: { + walletName: createSubOrgParams?.customWallet.walletName, + accounts: createSubOrgParams?.customWallet.walletAccounts, + }, + }), + }; + + // Set up headers, including X-Proxy-ID if needed + const headers: Record = { + "Content-Type": "application/json", + }; + if (this.config.authProxyId) { + headers["X-Proxy-ID"] = this.config.authProxyId; + } + + const res = await fetch(`${this.config.authProxyUrl}/v1/signup`, { + method: "POST", + headers, + body: JSON.stringify(signUpBody), + }); + + if (!res.ok) { + const errorText = await res.text(); + throw new Error(`Sign up failed: ${res.status} ${errorText}`); + } + + const newGeneratedKeyPair = await this.apiKeyStamper?.createKeyPair(); + this.apiKeyStamper?.setPublicKeyOverride(generatedKeyPair!); + + const sessionResponse = await this.httpClient.stampLogin({ + publicKey: newGeneratedKeyPair!, + ...(sessionExpirationSeconds && { + expirationSeconds: sessionExpirationSeconds, + }), + organizationId: this.config.organizationId, + }); + + await this.apiKeyStamper?.deleteKeyPair(generatedKeyPair!); + + await this.storageManager.storeSession( + sessionResponse.session, + sessionKey + ); + + generatedKeyPair = null; // Key pair was successfully used, set to null to prevent cleanup + } catch (error) { + throw new Error(`Failed to sign up with passkey: ${error}`); + } finally { + // Clean up the generated key pair if it wasn't successfully used + this.apiKeyStamper?.clearOverridePublicKey(); + if (generatedKeyPair) { + try { + await this.apiKeyStamper?.deleteKeyPair(generatedKeyPair); + } catch (cleanupError) { + throw new Error( + `Failed to clean up generated key pair: ${cleanupError}` + ); + } + } + } + }; + initOtp = async (params: { otpType: OtpType; contact: string; @@ -436,124 +557,162 @@ export class TurnkeyClient { }); }; - signUpWithPasskey = async (params: { - createSubOrgParams?: CreateSubOrgParams; - sessionType?: SessionType; - sessionExpirationSeconds?: string | undefined; - sessionKey?: string | undefined; - passkeyDisplayName?: string; - }): Promise => { - const { - createSubOrgParams, - passkeyDisplayName, - sessionExpirationSeconds, - sessionKey, - } = params; + handleGoogleOauthLogin = async (params: { + oidcToken: string; + }): Promise => { + const { oidcToken } = params; - let generatedKeyPair = null; + const headers: Record = { + "Content-Type": "application/json", + }; + if (this.config.authProxyId) { + headers["X-Proxy-ID"] = this.config.authProxyId; + } try { - generatedKeyPair = await this.apiKeyStamper?.createKeyPair(); - const passkey = await this.createPasskey({ - ...(createSubOrgParams?.passkeyName && { - name: createSubOrgParams?.passkeyName, - }), - ...(passkeyDisplayName && { displayName: passkeyDisplayName }), + const url = new URL(`${this.config.authProxyUrl}/v1/account`); + url.searchParams.append("filterType", "OIDC_TOKEN"); + url.searchParams.append("filterValue", oidcToken); + + const accountRes = await fetch(url.toString(), { + method: "GET", + headers, }); - if (!passkey) { - throw new Error( - "Failed to create passkey: encoded challenge or attestation is missing" - ); + if (!accountRes.ok && accountRes.status !== 404) { + const error = await accountRes.text(); + throw new Error(`Account fetch failed: ${accountRes.status} ${error}`); } - // Build the request body for OTP init - const signUpBody = { - userName: - createSubOrgParams?.userName || - createSubOrgParams?.userEmail || - `user-${Date.now()}`, - userEmail: createSubOrgParams?.userEmail, - authenticators: [ - { - authenticatorName: - createSubOrgParams?.passkeyName || "Default Passkey", - challenge: passkey.encodedChallenge, - attestation: passkey.attestation, - }, - ], - userPhoneNumber: createSubOrgParams?.userPhoneNumber, - userTag: createSubOrgParams?.userTag, - subOrgName: createSubOrgParams?.subOrgName || `sub-org-${Date.now()}`, - apiKeys: [ - { - apiKeyName: `passkey-auth-${generatedKeyPair}`, - publicKey: generatedKeyPair, - curveType: "API_KEY_CURVE_P256", - expirationSeconds: "60", - }, - ], - oauthProviders: createSubOrgParams?.oauthProviders, - ...(createSubOrgParams?.customWallet && { - wallet: { - walletName: createSubOrgParams?.customWallet.walletName, - accounts: createSubOrgParams?.customWallet.walletAccounts, - }, - }), - }; + let subOrganizationId: string | undefined = undefined; + const accountText = (await accountRes.text()).trim(); + if (accountText != "account not found") { + const res = await JSON.parse(accountText); + subOrganizationId = res.organizationId; + } - // Set up headers, including X-Proxy-ID if needed - const headers: Record = { - "Content-Type": "application/json", - }; - if (this.config.authProxyId) { - headers["X-Proxy-ID"] = this.config.authProxyId; + if (subOrganizationId) { + return this.loginWithOauth({ + oidcToken, + invalidateExisting: true, + sessionKey: SessionKey.DefaultSessionkey, + }); + } else { + return this.signUpWithOauth({ + oidcToken, + providerName: "google", + createSubOrgParams: { + userName: `user-${Date.now()}`, + subOrgName: `sub-org-${Date.now()}`, + oauthProviders: [{ providerName: "google", oidcToken }], + }, + }); } - const res = await fetch(`${this.config.authProxyUrl}/v1/signup`, { + } catch (error) { + throw new Error(`Failed to handle Google OAuth login: ${error}`); + } + } + + loginWithOauth = async (params: { + oidcToken: string; + publicKey?: string; + invalidateExisting?: boolean; + sessionKey?: string | undefined; + }): Promise => { + const { + oidcToken, + invalidateExisting = false, + publicKey = await this.apiKeyStamper?.createKeyPair(), + sessionKey = SessionKey.DefaultSessionkey, + } = params; + + const headers: Record = { + "Content-Type": "application/json", + }; + if (this.config.authProxyId) { + headers["X-Proxy-ID"] = this.config.authProxyId; + } + + try { + const res = await fetch(`${this.config.authProxyUrl}/v1/oauth_login`, { method: "POST", headers, - body: JSON.stringify(signUpBody), + body: JSON.stringify({ + oidcToken, + publicKey, + invalidateExisting, + }), }); if (!res.ok) { const errorText = await res.text(); - throw new Error(`Sign up failed: ${res.status} ${errorText}`); + throw new Error(`oauth login failed: ${res.status} ${errorText}`); } - const newGeneratedKeyPair = await this.apiKeyStamper?.createKeyPair(); - this.apiKeyStamper?.setPublicKeyOverride(generatedKeyPair!); + const loginRes: v1OauthLoginResult = await res.json(); + if (!loginRes.session) { + throw new Error("No session returned from oauth login"); + } - const sessionResponse = await this.httpClient.stampLogin({ - publicKey: newGeneratedKeyPair!, - ...(sessionExpirationSeconds && { - expirationSeconds: sessionExpirationSeconds, - }), - organizationId: this.config.organizationId, - }); + // // Store the session in the storage manager + await this.storageManager.storeSession(loginRes.session, sessionKey); - await this.apiKeyStamper?.deleteKeyPair(generatedKeyPair!); + return loginRes.session; + } catch (error) { + throw new Error(`Failed to log in with oauth: ${error}`); + } + }; - await this.storageManager.storeSession( - sessionResponse.session, - sessionKey - ); + signUpWithOauth = async (params: { + oidcToken: string; + providerName: string; + createSubOrgParams?: CreateSubOrgParams; + sessionType?: SessionType; + sessionExpirationSeconds?: string | undefined; + sessionKey?: string | undefined; + }): Promise => { + const { oidcToken, providerName, createSubOrgParams } = params; - generatedKeyPair = null; // Key pair was successfully used, set to null to prevent cleanup - } catch (error) { - throw new Error(`Failed to sign up with passkey: ${error}`); - } finally { - // Clean up the generated key pair if it wasn't successfully used - this.apiKeyStamper?.clearOverridePublicKey(); - if (generatedKeyPair) { - try { - await this.apiKeyStamper?.deleteKeyPair(generatedKeyPair); - } catch (cleanupError) { - throw new Error( - `Failed to clean up generated key pair: ${cleanupError}` - ); - } - } + const signUpBody = { + userName: + createSubOrgParams?.userName || + createSubOrgParams?.userEmail || + `user-${Date.now()}`, + userTag: createSubOrgParams?.userTag, + subOrgName: createSubOrgParams?.subOrgName || `sub-org-${Date.now()}`, + oauthProviders: [ + { + providerName: providerName, + oidcToken, + }, + ...(createSubOrgParams?.oauthProviders || []) + ], + }; + + // Set up headers, including X-Proxy-ID if needed + const headers: Record = { + "Content-Type": "application/json", + }; + if (this.config.authProxyId) { + headers["X-Proxy-ID"] = this.config.authProxyId; } + + const res = await fetch(`${this.config.authProxyUrl}/v1/signup`, { + method: "POST", + headers, + body: JSON.stringify(signUpBody), + }); + + if (!res.ok) { + const errorText = await res.text(); + throw new Error(`Sign up failed: ${res.status} ${errorText}`); + } + + const generatedKeyPair = await this.apiKeyStamper?.createKeyPair(); + return await this.loginWithOauth({ + oidcToken, + publicKey: generatedKeyPair!, + }); }; fetchWallets = async (params: { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1e3667e4c..94da115c9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1296,6 +1296,9 @@ importers: examples/with-sdk-js: dependencies: + '@react-oauth/google': + specifier: ^0.12.1 + version: 0.12.1(react-dom@18.2.0)(react@18.2.0) '@turnkey/sdk-js': specifier: workspace:* version: link:../../packages/sdk-js From 9e4bad44d36b056a8dcb4e95d502420364266219 Mon Sep 17 00:00:00 2001 From: Mohammad Cheikh Date: Tue, 24 Jun 2025 17:24:08 -0400 Subject: [PATCH 023/184] fix double oauth providers --- packages/sdk-js/src/__clients__/core.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/sdk-js/src/__clients__/core.ts b/packages/sdk-js/src/__clients__/core.ts index 1f33db011..22b1a1ce8 100644 --- a/packages/sdk-js/src/__clients__/core.ts +++ b/packages/sdk-js/src/__clients__/core.ts @@ -603,7 +603,6 @@ export class TurnkeyClient { createSubOrgParams: { userName: `user-${Date.now()}`, subOrgName: `sub-org-${Date.now()}`, - oauthProviders: [{ providerName: "google", oidcToken }], }, }); } @@ -685,7 +684,6 @@ export class TurnkeyClient { providerName: providerName, oidcToken, }, - ...(createSubOrgParams?.oauthProviders || []) ], }; From 74fdb037dd4f957651f564f8585028b9da6aeb52 Mon Sep 17 00:00:00 2001 From: Ethan Konkolowicz Date: Wed, 25 Jun 2025 14:12:56 -0400 Subject: [PATCH 024/184] fixed sdk side oauth --- examples/with-sdk-js/package.json | 1 + examples/with-sdk-js/src/app/page.tsx | 428 ++++++++++-------- examples/with-sdk-js/src/assets/google.svg | 1 + .../with-sdk-js/src/components/Google.tsx | 133 ++++++ .../src/components/Socials.module.css | 53 +++ .../with-sdk-js/src/components/constants.ts | 55 +++ packages/sdk-js/src/__clients__/core.ts | 79 ++-- packages/sdk-js/src/__stampers__/api/base.ts | 12 +- .../sdk-js/src/__storage__/web/storage.ts | 10 +- pnpm-lock.yaml | 23 + 10 files changed, 566 insertions(+), 229 deletions(-) create mode 100644 examples/with-sdk-js/src/assets/google.svg create mode 100644 examples/with-sdk-js/src/components/Google.tsx create mode 100644 examples/with-sdk-js/src/components/Socials.module.css create mode 100644 examples/with-sdk-js/src/components/constants.ts diff --git a/examples/with-sdk-js/package.json b/examples/with-sdk-js/package.json index fdf9c36d4..9c0155d63 100644 --- a/examples/with-sdk-js/package.json +++ b/examples/with-sdk-js/package.json @@ -21,6 +21,7 @@ "typecheck": "tsc --noEmit" }, "dependencies": { + "@noble/hashes": "1.4.0", "@react-oauth/google": "^0.12.1", "@turnkey/sdk-js": "workspace:*", "@turnkey/sdk-react": "workspace:*", diff --git a/examples/with-sdk-js/src/app/page.tsx b/examples/with-sdk-js/src/app/page.tsx index dffaadc29..caee4303c 100644 --- a/examples/with-sdk-js/src/app/page.tsx +++ b/examples/with-sdk-js/src/app/page.tsx @@ -4,12 +4,10 @@ import Image from "next/image"; import styles from "./index.module.css"; import { StamperType, TurnkeyClient, Wallet } from "@turnkey/sdk-js"; -import { server } from "@turnkey/sdk-server"; import { useEffect, useState } from "react"; import { Session, v1AddressFormat } from "@turnkey/sdk-types"; -import { init } from "next/dist/compiled/webpack/webpack"; import { OtpType } from "@turnkey/sdk-js"; -import { GoogleLogin, GoogleOAuthProvider } from "@react-oauth/google"; +import GoogleAuthButton from "@/components/Google"; export default function AuthPage() { const [client, setClient] = useState(null); @@ -18,6 +16,7 @@ export default function AuthPage() { const [email, setEmail] = useState(""); const [otpCode, setOtpCode] = useState(""); const [otpId, setOtpId] = useState(""); + const [oauthPublicKey, setOauthPublicKey] = useState(""); useEffect(() => { const initializeClient = async () => { @@ -127,7 +126,7 @@ export default function AuthPage() { if ( (wallets.length === 0 && !wallets[0]) || !wallets[0].accounts || - wallets[0].accounts.length < 2 + wallets[0].accounts.length < 1 ) { console.error("No wallets available to sign message"); return; @@ -152,9 +151,18 @@ export default function AuthPage() { }); }; - const handleGoogleLoginSuccess = async (credentialResponse: string) => { - const res = await client?.handleGoogleOauthLogin({ + const handleGoogleLogin = async ( + credentialResponse: string, + publicKey: string, + ) => { + if (!publicKey) { + console.error("Public key is not set. Please create a passkey first."); + return; + } + + const res = await client?.handleOauthLogin({ oidcToken: credentialResponse, + publicKey, }); console.log("Google login response:", res); @@ -162,7 +170,59 @@ export default function AuthPage() { const createWallet = async (walletName: string) => { // List of all v1AddressFormat values - const allAddressFormats = ["ADDRESS_FORMAT_ETHEREUM"]; + const allAddressFormats = [ + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_ETHEREUM", + ]; const res = await client?.createWallet({ walletName, @@ -183,238 +243,236 @@ export default function AuthPage() { return (
- - - Turnkey Logo - - - { - if (!credentialResponse.credential) { - console.error("No credential received from Google login"); - return; - } - await handleGoogleLoginSuccess(credentialResponse.credential); - }} + + Turnkey Logo + + + + handleGoogleLogin(response.idToken, response.publicKey) + } + layout="stacked" + client={client} + /> + + + + { + setEmail(e.target.value); + }} + /> + + + { + setOtpCode(e.target.value); + }} + /> + + + + + + + + + + + + {client?.storageManager?.getActiveSession() ? ( + ) : null} - { - setEmail(e.target.value); - }} - /> + {client?.storageManager?.getActiveSession() ? ( + ) : null} - { - setOtpCode(e.target.value); - }} - /> - + {client?.storageManager?.getActiveSession() ? ( + ) : null} + {client?.storageManager?.getActiveSession() ? ( + ) : null} + {client?.storageManager?.getActiveSession() ? ( + ) : null} + {wallets.length > 0 && ( - - - - {client?.storageManager?.getActiveSession() ? ( - - ) : null} - - {client?.storageManager?.getActiveSession() ? ( - - ) : null} - - {client?.storageManager?.getActiveSession() ? ( - - ) : null} - - {client?.storageManager?.getActiveSession() ? ( - - ) : null} - - {client?.storageManager?.getActiveSession() ? ( - - ) : null} - - {wallets.length > 0 && ( - - )} - + )}
); } diff --git a/examples/with-sdk-js/src/assets/google.svg b/examples/with-sdk-js/src/assets/google.svg new file mode 100644 index 000000000..fb226ca2d --- /dev/null +++ b/examples/with-sdk-js/src/assets/google.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/examples/with-sdk-js/src/components/Google.tsx b/examples/with-sdk-js/src/components/Google.tsx new file mode 100644 index 000000000..04f11dc1b --- /dev/null +++ b/examples/with-sdk-js/src/components/Google.tsx @@ -0,0 +1,133 @@ +"use client"; + +import { sha256 } from "@noble/hashes/sha2"; +import { bytesToHex } from "@noble/hashes/utils"; +import styles from "./Socials.module.css"; +import googleIcon from "../assets/google.svg"; +import { GOOGLE_AUTH_URL, popupHeight, popupWidth } from "./constants"; +import { useState, useEffect } from "react"; +import { TurnkeyClient } from "@turnkey/sdk-js"; + +interface GoogleAuthButtonProps { + client: TurnkeyClient | null; + clientId: string; + onSuccess: (response: any) => void; + layout: "inline" | "stacked"; + openInPage?: boolean | undefined; +} + +declare global { + interface Window { + google: any; + } +} + +const GoogleAuthButton: React.FC = ({ + clientId, + onSuccess, + layout, + openInPage = false, + client, +}) => { + const [loading, setLoading] = useState(false); + + // Handle redirect-based auth + useEffect(() => { + if (window.location.hash) { + const hashParams = new URLSearchParams(window.location.hash.substring(1)); + const idToken = hashParams.get("id_token"); + const state = hashParams.get("state"); + + const stateParams = new URLSearchParams(state || ""); + const provider = stateParams.get("provider"); + const flow = stateParams.get("flow"); + + if (idToken && provider === "google" && flow === "redirect") { + onSuccess({ idToken }); + window.history.replaceState( + null, + document.title, + window.location.pathname + window.location.search, + ); + } + } + }, [onSuccess]); + + const handleLogin = () => { + const width = popupWidth; + const height = popupHeight; + const left = window.screenX + (window.innerWidth - width) / 2; + const top = window.screenY + (window.innerHeight - height) / 2; + + const flow = openInPage ? "redirect" : "popup"; + + const authWindow = window.open( + "about:blank", + "_blank", + `width=${width},height=${height},top=${top},left=${left},scrollbars=yes,resizable=yes`, + ); + + if (!authWindow) { + console.error("Failed to open Google login window."); + return; + } + + setLoading(true); + + (async () => { + const publicKey = await client?.apiKeyStamper?.createKeyPair(); + if (!publicKey) return; + await client?.apiKeyStamper?.setPublicKeyOverride(publicKey); + + const nonce = bytesToHex(sha256(publicKey)); + const redirectURI = process.env.NEXT_PUBLIC_OAUTH_REDIRECT_URI!.replace( + /\/$/, + "", + ); + + const googleAuthUrl = new URL(GOOGLE_AUTH_URL); + googleAuthUrl.searchParams.set("client_id", clientId); + googleAuthUrl.searchParams.set("redirect_uri", redirectURI); + googleAuthUrl.searchParams.set("response_type", "id_token"); + googleAuthUrl.searchParams.set("scope", "openid email profile"); + googleAuthUrl.searchParams.set("nonce", nonce); + googleAuthUrl.searchParams.set("prompt", "select_account"); + googleAuthUrl.searchParams.set("state", `provider=google&flow=${flow}`); + + authWindow.location.href = googleAuthUrl.toString(); + + const interval = setInterval(() => { + try { + const url = authWindow.location.href || ""; + if (url.startsWith(window.location.origin)) { + const hashParams = new URLSearchParams(url.split("#")[1]); + const idToken = hashParams.get("id_token"); + if (idToken) { + authWindow.close(); + clearInterval(interval); + onSuccess({ idToken, publicKey }); + } + } + } catch { + // Ignore cross-origin errors + } + + if (authWindow.closed) { + setLoading(false); + clearInterval(interval); + } + }, 500); + })(); + }; + + return ( + + ); +}; + +export default GoogleAuthButton; diff --git a/examples/with-sdk-js/src/components/Socials.module.css b/examples/with-sdk-js/src/components/Socials.module.css new file mode 100644 index 000000000..fdfb5a96b --- /dev/null +++ b/examples/with-sdk-js/src/components/Socials.module.css @@ -0,0 +1,53 @@ +.socialButton { + letter-spacing: -0.01em; + padding: 10px 16px; + gap: 8px; + color: var(--button-text); + width: 100%; + font-size: 1rem; + background: var(--button-bg); + border: 1px solid var(--button-border); + border-radius: 8px; + cursor: pointer; + text-align: center; + display: flex; + align-items: center; + justify-content: center; + transition: background-color 0.2s ease; +} + +.iconButton { + padding: 10px 16px; + gap: 8px; + color: var(--button-text); + width: 100%; + font-size: 1rem; + background: var(--button-bg); + border: 1px solid var(--button-border); + border-radius: 8px; + cursor: pointer; + text-align: center; + display: flex; + align-items: center; + justify-content: center; + transition: background-color 0.2s ease; +} + +.socialButton:hover { + background-color: var(--button-hover-bg); +} + +.iconButton:hover { + background-color: var(--button-hover-bg); +} + +.iconSmall { + width: 20px; + height: 20px; + margin-right: 4px; +} + +.iconLarge { + width: 24px; + height: 24px; +} diff --git a/examples/with-sdk-js/src/components/constants.ts b/examples/with-sdk-js/src/components/constants.ts new file mode 100644 index 000000000..1b1702057 --- /dev/null +++ b/examples/with-sdk-js/src/components/constants.ts @@ -0,0 +1,55 @@ +export const GOOGLE_AUTH_URL = "https://accounts.google.com/o/oauth2/v2/auth"; +export const APPLE_AUTH_URL = "https://appleid.apple.com/auth/authorize"; +export const APPLE_AUTH_SCRIPT_URL = + "https://appleid.cdn-apple.com/appleauth/static/jsapi/appleid/1/en_US/appleid.auth.js"; +export const FACEBOOK_AUTH_URL = "https://www.facebook.com/v11.0/dialog/oauth"; +export const FACEBOOK_GRAPH_URL = + "https://graph.facebook.com/v11.0/oauth/access_token"; +export const popupWidth = 500; +export const popupHeight = 600; + +export const authErrors = { + // Passkey-related errors + passkey: { + createFailed: "Passkey not created. Please try again.", + loginFailed: "Failed to login with passkey. Please try again.", + timeoutOrNotAllowed: + "The operation either timed out or was not allowed. Please try again.", + }, + + // OTP-related errors + otp: { + sendFailed: "Failed to send OTP", + invalidEmail: "Invalid email address.", + invalidPhone: "Invalid phone number.", + }, + + // OAuth-related errors + oauth: { + loginFailed: "Failed to login with OAuth provider", + }, + + // Wallet-related errors + wallet: { + loginFailed: "Failed to login with wallet", + noPublicKey: "No public key found", + }, + + // Sub-organization-related errors + suborg: { + fetchFailed: "Failed to fetch account", + createFailed: "Failed to create account.", + }, +}; + +export enum OtpType { + Email = "OTP_TYPE_EMAIL", + Sms = "OTP_TYPE_SMS", +} + +export enum FilterType { + Email = "EMAIL", + PhoneNumber = "PHONE_NUMBER", + OidcToken = "OIDC_TOKEN", + PublicKey = "PUBLIC_KEY", +} diff --git a/packages/sdk-js/src/__clients__/core.ts b/packages/sdk-js/src/__clients__/core.ts index 22b1a1ce8..8ff124e44 100644 --- a/packages/sdk-js/src/__clients__/core.ts +++ b/packages/sdk-js/src/__clients__/core.ts @@ -69,7 +69,7 @@ export class TurnkeyClient { // Users can pass in their own stampers, or we will create them. Should we remove this? apiKeyStamper?: CrossPlatformApiKeyStamper, - passkeyStamper?: CrossPlatformPasskeyStamper + passkeyStamper?: CrossPlatformPasskeyStamper, ) { this.config = config; @@ -91,7 +91,7 @@ export class TurnkeyClient { if (this.config.passkeyConfig) { this.passkeyStamper = new CrossPlatformPasskeyStamper( - this.config.passkeyConfig + this.config.passkeyConfig, ); await this.passkeyStamper.init(); } @@ -190,7 +190,7 @@ export class TurnkeyClient { await this.storageManager.storeSession( readOnlySessionResult.session, - sessionKey + sessionKey, ); // Key pair was successfully used, set to null to prevent cleanup generatedKeyPair = null; @@ -199,7 +199,7 @@ export class TurnkeyClient { } else if (sessionType === SessionType.READ_WRITE) { if (!publicKey) { throw new Error( - "You must provide a publicKey to create a passkey read write session." + "You must provide a publicKey to create a passkey read write session.", ); } const sessionResponse = await this.httpClient.stampLogin( @@ -208,7 +208,7 @@ export class TurnkeyClient { expirationSeconds, organizationId: this.config.organizationId, }, - StamperType.Passkey + StamperType.Passkey, ); // TODO (Amir): This should be done in a helper or something. It's very strange that we have to delete the key pair here @@ -220,7 +220,7 @@ export class TurnkeyClient { await this.storageManager.storeSession( sessionResponse.session, - sessionKey + sessionKey, ); // Key pair was successfully used, set to null to prevent cleanup generatedKeyPair = null; @@ -236,7 +236,7 @@ export class TurnkeyClient { await this.apiKeyStamper?.deleteKeyPair(generatedKeyPair); } catch (cleanupError) { throw new Error( - `Failed to clean up generated key pair: ${cleanupError}` + `Failed to clean up generated key pair: ${cleanupError}`, ); } } @@ -269,7 +269,7 @@ export class TurnkeyClient { if (!passkey) { throw new Error( - "Failed to create passkey: encoded challenge or attestation is missing" + "Failed to create passkey: encoded challenge or attestation is missing", ); } @@ -342,7 +342,7 @@ export class TurnkeyClient { await this.storageManager.storeSession( sessionResponse.session, - sessionKey + sessionKey, ); generatedKeyPair = null; // Key pair was successfully used, set to null to prevent cleanup @@ -356,7 +356,7 @@ export class TurnkeyClient { await this.apiKeyStamper?.deleteKeyPair(generatedKeyPair); } catch (cleanupError) { throw new Error( - `Failed to clean up generated key pair: ${cleanupError}` + `Failed to clean up generated key pair: ${cleanupError}`, ); } } @@ -430,12 +430,12 @@ export class TurnkeyClient { otpId: otpId, otpCode: otpCode, }), - } + }, ); if (!verifyRes.ok) { const error = await verifyRes.text(); throw new Error( - `OTP verification failed: ${verifyRes.status} ${error}` + `OTP verification failed: ${verifyRes.status} ${error}`, ); } const verifyOtpRes: v1VerifyOtpResult = await verifyRes.json(); @@ -557,10 +557,12 @@ export class TurnkeyClient { }); }; - handleGoogleOauthLogin = async (params: { + handleOauthLogin = async (params: { oidcToken: string; + publicKey: string; + createSubOrgParams?: CreateSubOrgParams | undefined; }): Promise => { - const { oidcToken } = params; + const { oidcToken, publicKey, createSubOrgParams } = params; const headers: Record = { "Content-Type": "application/json", @@ -593,35 +595,35 @@ export class TurnkeyClient { if (subOrganizationId) { return this.loginWithOauth({ oidcToken, + publicKey, invalidateExisting: true, sessionKey: SessionKey.DefaultSessionkey, }); } else { return this.signUpWithOauth({ oidcToken, + publicKey, providerName: "google", - createSubOrgParams: { - userName: `user-${Date.now()}`, - subOrgName: `sub-org-${Date.now()}`, - }, + ...(createSubOrgParams && { + createSubOrgParams, + }), }); } - } catch (error) { throw new Error(`Failed to handle Google OAuth login: ${error}`); } - } + }; loginWithOauth = async (params: { oidcToken: string; - publicKey?: string; + publicKey: string; invalidateExisting?: boolean; sessionKey?: string | undefined; }): Promise => { const { oidcToken, invalidateExisting = false, - publicKey = await this.apiKeyStamper?.createKeyPair(), + publicKey, sessionKey = SessionKey.DefaultSessionkey, } = params; @@ -632,6 +634,12 @@ export class TurnkeyClient { headers["X-Proxy-ID"] = this.config.authProxyId; } + if (!publicKey) { + throw new Error( + "Public key must be provided to log in with OAuth. Please create a key pair first.", + ); + } + try { const res = await fetch(`${this.config.authProxyUrl}/v1/oauth_login`, { method: "POST", @@ -664,13 +672,14 @@ export class TurnkeyClient { signUpWithOauth = async (params: { oidcToken: string; + publicKey: string; providerName: string; createSubOrgParams?: CreateSubOrgParams; sessionType?: SessionType; sessionExpirationSeconds?: string | undefined; sessionKey?: string | undefined; }): Promise => { - const { oidcToken, providerName, createSubOrgParams } = params; + const { oidcToken, publicKey, providerName, createSubOrgParams } = params; const signUpBody = { userName: @@ -684,6 +693,7 @@ export class TurnkeyClient { providerName: providerName, oidcToken, }, + ...(createSubOrgParams?.oauthProviders || []), ], }; @@ -706,10 +716,9 @@ export class TurnkeyClient { throw new Error(`Sign up failed: ${res.status} ${errorText}`); } - const generatedKeyPair = await this.apiKeyStamper?.createKeyPair(); return await this.loginWithOauth({ oidcToken, - publicKey: generatedKeyPair!, + publicKey: publicKey!, }); }; @@ -725,7 +734,7 @@ export class TurnkeyClient { try { const res = await this.httpClient.getWallets( { organizationId: session.organizationId }, - stamperType + stamperType, ); if (!res || !res.wallets) { @@ -777,7 +786,7 @@ export class TurnkeyClient { organizationId: session.organizationId, paginationOptions: paginationOptions || { limit: "100" }, }, - stamperType + stamperType, ); } catch (error) { throw new Error(`Failed to fetch wallet accounts: ${error}`); @@ -809,7 +818,7 @@ export class TurnkeyClient { encoding: payloadEncoding, hashFunction, }, - stampWith + stampWith, ); if (response.activity.failure) { @@ -843,7 +852,7 @@ export class TurnkeyClient { unsignedTransaction, type, }, - stampWith + stampWith, ); } catch (error) { throw new Error(`Failed to sign transaction: ${error}`); @@ -869,7 +878,7 @@ export class TurnkeyClient { try { const userResponse = await this.httpClient.getUser( { organizationId, userId }, - StamperType.ApiKey + StamperType.ApiKey, ); if (!userResponse || !userResponse.user) { @@ -914,7 +923,7 @@ export class TurnkeyClient { accounts: walletAccounts, mnemonicLength: mnemonicLength || 12, }, - stampWith + stampWith, ); if (!res || !res.walletId) { @@ -949,12 +958,12 @@ export class TurnkeyClient { walletId, accounts: accounts, }, - stampWith + stampWith, ); if (!res || !res.addresses) { throw new Error( - "No account found in the create wallet account response" + "No account found in the create wallet account response", ); } return res.addresses; @@ -986,7 +995,7 @@ export class TurnkeyClient { targetPublicKey, organizationId: organizationId || session.organizationId, }, - stamperType + stamperType, ); if (!res.exportBundle) { @@ -1045,7 +1054,7 @@ export class TurnkeyClient { try { return await this.httpClient.deleteSubOrganization( { deleteWithoutExport }, - stamperWith + stamperWith, ); } catch (error) { throw new Error(`Failed to delete sub-organization: ${error}`); diff --git a/packages/sdk-js/src/__stampers__/api/base.ts b/packages/sdk-js/src/__stampers__/api/base.ts index b8da7d37b..a2f5e4ed6 100644 --- a/packages/sdk-js/src/__stampers__/api/base.ts +++ b/packages/sdk-js/src/__stampers__/api/base.ts @@ -6,7 +6,7 @@ import { TStamp, TStamper } from "@types"; export interface ApiKeyStamperBase { listKeyPairs(): Promise; createKeyPair( - externalKeyPair?: CryptoKeyPair | { publicKey: string; privateKey: string } + externalKeyPair?: CryptoKeyPair | { publicKey: string; privateKey: string }, ): Promise; deleteKeyPair(publicKeyHex: string): Promise; clearKeyPairs(): Promise; @@ -30,7 +30,7 @@ export class CrossPlatformApiKeyStamper implements TStamper { this.stamper = new ReactNativeKeychainStamper(); } catch (error) { throw new Error( - `Failed to load keychain stamper for react-native: ${error}` + `Failed to load keychain stamper for react-native: ${error}`, ); } } else { @@ -44,7 +44,7 @@ export class CrossPlatformApiKeyStamper implements TStamper { } createKeyPair( - externalKeyPair?: CryptoKeyPair | { publicKey: string; privateKey: string } + externalKeyPair?: CryptoKeyPair | { publicKey: string; privateKey: string }, ): Promise { return this.stamper.createKeyPair(externalKeyPair); } @@ -62,6 +62,10 @@ export class CrossPlatformApiKeyStamper implements TStamper { this.publicKeyOverride = publicKeyHex; } + getPublicKeyOverride(): string | undefined { + return this.publicKeyOverride; + } + clearOverridePublicKey(): void { this.publicKeyOverride = undefined; } @@ -78,4 +82,4 @@ export class CrossPlatformApiKeyStamper implements TStamper { return this.stamper.stamp(payload, publicKeyHex); } -} \ No newline at end of file +} diff --git a/packages/sdk-js/src/__storage__/web/storage.ts b/packages/sdk-js/src/__storage__/web/storage.ts index ff390bdbf..19f1179b8 100644 --- a/packages/sdk-js/src/__storage__/web/storage.ts +++ b/packages/sdk-js/src/__storage__/web/storage.ts @@ -17,7 +17,7 @@ export class WebStorageManager implements StorageBase { setStorageValue = async ( sessionKey: string, - storageValue: any + storageValue: any, ): Promise => { browserStorage.setItem(sessionKey, JSON.stringify(storageValue)); }; @@ -25,7 +25,7 @@ export class WebStorageManager implements StorageBase { setActiveSessionKey = async (sessionKey: string): Promise => { await this.setStorageValue( WebStorageManager.ACTIVE_SESSION_KEY, - sessionKey + sessionKey, ); }; @@ -35,7 +35,7 @@ export class WebStorageManager implements StorageBase { storeSession = async ( session: string, - sessionKey: string = SessionKey.DefaultSessionkey + sessionKey: string = SessionKey.DefaultSessionkey, ): Promise => { const sessionWithMetadata = parseSession(session); @@ -52,12 +52,12 @@ export class WebStorageManager implements StorageBase { // Set the active session key await this.setStorageValue( WebStorageManager.ACTIVE_SESSION_KEY, - sessionKey + sessionKey, ); }; getSession = async ( - sessionKey: string = SessionKey.DefaultSessionkey + sessionKey: string = SessionKey.DefaultSessionkey, ): Promise => { return this.getStorageValue(sessionKey); }; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 94da115c9..adbd5d2c4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1296,6 +1296,9 @@ importers: examples/with-sdk-js: dependencies: + '@noble/hashes': + specifier: 1.4.0 + version: 1.4.0 '@react-oauth/google': specifier: ^0.12.1 version: 0.12.1(react-dom@18.2.0)(react@18.2.0) @@ -8597,6 +8600,26 @@ packages: peerDependenciesMeta: '@typescript-eslint/parser': optional: true +<<<<<<< HEAD +======= + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + dependencies: + '@typescript-eslint/parser': 5.62.0(eslint@8.56.0)(typescript@5.1.3) + debug: 3.2.7 + eslint: 8.56.0 + eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-typescript: 3.5.5(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.56.0) + transitivePeerDependencies: + - supports-color + dev: false +>>>>>>> 1ca1a68a (fixed sdk side oauth) eslint-plugin-jsx-a11y@6.10.2: resolution: {integrity: sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==} From bf8a8e411e6c547dd7cac442f78cfe6e9d1b1f45 Mon Sep 17 00:00:00 2001 From: Ethan Konkolowicz Date: Wed, 25 Jun 2025 16:56:27 -0400 Subject: [PATCH 025/184] fixed auth keypair cleanup in one tap passkey sign up and failed auth attempts --- packages/sdk-js/src/__clients__/core.ts | 79 ++++++++++++++++++++----- 1 file changed, 65 insertions(+), 14 deletions(-) diff --git a/packages/sdk-js/src/__clients__/core.ts b/packages/sdk-js/src/__clients__/core.ts index 8ff124e44..0d28e446b 100644 --- a/packages/sdk-js/src/__clients__/core.ts +++ b/packages/sdk-js/src/__clients__/core.ts @@ -215,6 +215,7 @@ export class TurnkeyClient { const sessionToReplace = await this.storageManager.getSession(sessionKey); if (sessionToReplace) { + console.log(sessionToReplace.token); await this.apiKeyStamper?.deleteKeyPair(sessionToReplace.token); } @@ -340,6 +341,11 @@ export class TurnkeyClient { await this.apiKeyStamper?.deleteKeyPair(generatedKeyPair!); + const sessionToReplace = await this.storageManager.getSession(sessionKey); + if (sessionToReplace) { + await this.apiKeyStamper?.deleteKeyPair(sessionToReplace.token); + } + await this.storageManager.storeSession( sessionResponse.session, sessionKey, @@ -350,6 +356,7 @@ export class TurnkeyClient { throw new Error(`Failed to sign up with passkey: ${error}`); } finally { // Clean up the generated key pair if it wasn't successfully used + console.log("Cleaning up generated key pair if any"); this.apiKeyStamper?.clearOverridePublicKey(); if (generatedKeyPair) { try { @@ -497,11 +504,26 @@ export class TurnkeyClient { throw new Error("No session returned from OTP login"); } + const sessionToReplace = await this.storageManager.getSession(sessionKey); + if (sessionToReplace) { + await this.apiKeyStamper?.deleteKeyPair(sessionToReplace.token); + } // // Store the session in the storage manager await this.storageManager.storeSession(loginRes.session, sessionKey); return loginRes.session; } catch (error) { + // Clean up the generated key pair if it wasn't successfully used + console.log("Cleaning up generated key pair if any"); + if (publicKey) { + try { + await this.apiKeyStamper?.deleteKeyPair(publicKey); + } catch (cleanupError) { + throw new Error( + `Failed to clean up generated key pair: ${cleanupError}`, + ); + } + } throw new Error(`Failed to log in with OTP: ${error}`); } }; @@ -538,23 +560,37 @@ export class TurnkeyClient { if (this.config.authProxyId) { headers["X-Proxy-ID"] = this.config.authProxyId; } + const generatedKeyPair = await this.apiKeyStamper?.createKeyPair(); + try { + const res = await fetch(`${this.config.authProxyUrl}/v1/signup`, { + method: "POST", + headers, + body: JSON.stringify(signUpBody), + }); - const res = await fetch(`${this.config.authProxyUrl}/v1/signup`, { - method: "POST", - headers, - body: JSON.stringify(signUpBody), - }); + if (!res.ok) { + const errorText = await res.text(); + throw new Error(`Sign up failed: ${res.status} ${errorText}`); + } - if (!res.ok) { - const errorText = await res.text(); - throw new Error(`Sign up failed: ${res.status} ${errorText}`); + await this.loginWithOtp({ + verificationToken, + publicKey: generatedKeyPair!, + }); + } catch (error) { + throw new Error(`Failed to sign up with OTP: ${error}`); + } finally { + // Clean up the generated key pair if it wasn't successfully used + if (generatedKeyPair) { + try { + await this.apiKeyStamper?.deleteKeyPair(generatedKeyPair); + } catch (cleanupError) { + throw new Error( + `Failed to clean up generated key pair: ${cleanupError}`, + ); + } + } } - - const generatedKeyPair = await this.apiKeyStamper?.createKeyPair(); - await this.loginWithOtp({ - verificationToken, - publicKey: generatedKeyPair!, - }); }; handleOauthLogin = async (params: { @@ -661,11 +697,26 @@ export class TurnkeyClient { throw new Error("No session returned from oauth login"); } + const sessionToReplace = await this.storageManager.getSession(sessionKey); + if (sessionToReplace) { + await this.apiKeyStamper?.deleteKeyPair(sessionToReplace.token); + } // // Store the session in the storage manager await this.storageManager.storeSession(loginRes.session, sessionKey); return loginRes.session; } catch (error) { + // Clean up the generated key pair if it wasn't successfully used + console.log("Cleaning up generated key pair if any"); + if (publicKey) { + try { + await this.apiKeyStamper?.deleteKeyPair(publicKey); + } catch (cleanupError) { + throw new Error( + `Failed to clean up generated key pair: ${cleanupError}`, + ); + } + } throw new Error(`Failed to log in with oauth: ${error}`); } }; From b227007e49461a6c280628d139d53f02944213ff Mon Sep 17 00:00:00 2001 From: Amir Cheikh Date: Mon, 23 Jun 2025 17:58:21 -0400 Subject: [PATCH 026/184] React wallet kit init. Modal init --- examples/with-sdk-js/package.json | 1 + examples/with-sdk-js/src/app/global.css | 24 + examples/with-sdk-js/src/app/index.module.css | 24 - examples/with-sdk-js/src/app/layout.tsx | 8 +- examples/with-sdk-js/src/app/page.tsx | 46 +- packages/react-wallet-kit/package.json | 46 + packages/react-wallet-kit/postcss.config.js | 6 + packages/react-wallet-kit/rollup.config.mjs | 48 + packages/react-wallet-kit/src/index.css | 3 + packages/react-wallet-kit/src/index.ts | 2 + .../react-wallet-kit/src/providers/index.ts | 2 + .../src/providers/modal/Provider.tsx | 42 + .../src/providers/modal/Root.tsx | 48 + packages/react-wallet-kit/tailwind.config.js | 8 + packages/react-wallet-kit/tsconfig.json | 26 + pnpm-lock.yaml | 1258 +++++++++++++++++ 16 files changed, 1564 insertions(+), 28 deletions(-) create mode 100644 examples/with-sdk-js/src/app/global.css create mode 100644 packages/react-wallet-kit/package.json create mode 100644 packages/react-wallet-kit/postcss.config.js create mode 100644 packages/react-wallet-kit/rollup.config.mjs create mode 100644 packages/react-wallet-kit/src/index.css create mode 100644 packages/react-wallet-kit/src/index.ts create mode 100644 packages/react-wallet-kit/src/providers/index.ts create mode 100644 packages/react-wallet-kit/src/providers/modal/Provider.tsx create mode 100644 packages/react-wallet-kit/src/providers/modal/Root.tsx create mode 100644 packages/react-wallet-kit/tailwind.config.js create mode 100644 packages/react-wallet-kit/tsconfig.json diff --git a/examples/with-sdk-js/package.json b/examples/with-sdk-js/package.json index 9c0155d63..72b7d4574 100644 --- a/examples/with-sdk-js/package.json +++ b/examples/with-sdk-js/package.json @@ -21,6 +21,7 @@ "typecheck": "tsc --noEmit" }, "dependencies": { + "@turnkey/react-wallet-kit": "workspace:*", "@noble/hashes": "1.4.0", "@react-oauth/google": "^0.12.1", "@turnkey/sdk-js": "workspace:*", diff --git a/examples/with-sdk-js/src/app/global.css b/examples/with-sdk-js/src/app/global.css new file mode 100644 index 000000000..c20bf48d6 --- /dev/null +++ b/examples/with-sdk-js/src/app/global.css @@ -0,0 +1,24 @@ +@font-face { + font-family: "Inter"; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url("/fonts/inter/Inter-Regular.woff2?v=3.19") format("woff2"); + } + + @font-face { + font-family: "Inter"; + font-style: normal; + font-weight: 600; + font-display: swap; + src: url("/fonts/inter/Inter-SemiBold.woff2?v=3.19") format("woff2"); + } + + +* { + font-family: "Inter", -apple-system, BlinkMacSystemFont, sans-serif; + } + + :root { + font-family: "Inter", -apple-system, BlinkMacSystemFont, sans-serif; + } \ No newline at end of file diff --git a/examples/with-sdk-js/src/app/index.module.css b/examples/with-sdk-js/src/app/index.module.css index 9e52fa65f..399248780 100644 --- a/examples/with-sdk-js/src/app/index.module.css +++ b/examples/with-sdk-js/src/app/index.module.css @@ -1,20 +1,3 @@ -@font-face { - font-family: "Inter"; - font-style: normal; - font-weight: 400; - font-display: swap; - src: url("../../public/fonts/inter/Inter-Regular.woff2?v=3.19") - format("woff2"); -} - -@font-face { - font-family: "Inter"; - font-style: normal; - font-weight: 600; - font-display: swap; - src: url("../../public/fonts/inter/Inter-SemiBold.woff2?v=3.19") - format("woff2"); -} .main { display: flex; @@ -34,7 +17,6 @@ border-width: 1px; border-style: solid; border-color: rgba(216, 219, 227, 1); - font-family: "Inter"; margin: 0 auto; } @@ -44,15 +26,10 @@ } .label { - font-family: "Inter"; display: block; text-align: center; } -.prompt { - font-family: "Inter"; -} - .base { display: flex; flex-direction: column; @@ -73,7 +50,6 @@ color: white; background-color: rgba(43, 47, 51, 1); border-color: rgba(63, 70, 75, 1); - font-family: "Inter"; } .form { diff --git a/examples/with-sdk-js/src/app/layout.tsx b/examples/with-sdk-js/src/app/layout.tsx index 137b3648a..ca5634f3a 100644 --- a/examples/with-sdk-js/src/app/layout.tsx +++ b/examples/with-sdk-js/src/app/layout.tsx @@ -1,6 +1,8 @@ "use client"; -import { TurnkeyProvider } from "@turnkey/sdk-react"; +import { ModalProvider } from "@turnkey/react-wallet-kit"; +import "@turnkey/react-wallet-kit/dist/styles.css"; +import "./global.css"; const turnkeyConfig = { apiBaseUrl: process.env.NEXT_PUBLIC_BASE_URL!, @@ -21,7 +23,9 @@ function RootLayout({ children }: RootLayoutProps) { A monumental leap - {children} + + {children} + ); } diff --git a/examples/with-sdk-js/src/app/page.tsx b/examples/with-sdk-js/src/app/page.tsx index caee4303c..924929201 100644 --- a/examples/with-sdk-js/src/app/page.tsx +++ b/examples/with-sdk-js/src/app/page.tsx @@ -2,11 +2,12 @@ import Image from "next/image"; import styles from "./index.module.css"; -import { StamperType, TurnkeyClient, Wallet } from "@turnkey/sdk-js"; +import { StamperType, TurnkeyClient, Wallet } from "@turnkey/sdk-js"; import { useEffect, useState } from "react"; import { Session, v1AddressFormat } from "@turnkey/sdk-types"; import { OtpType } from "@turnkey/sdk-js"; +import { ModalProvider, useModal } from "@turnkey/react-wallet-kit"; import GoogleAuthButton from "@/components/Google"; export default function AuthPage() { @@ -16,6 +17,8 @@ export default function AuthPage() { const [email, setEmail] = useState(""); const [otpCode, setOtpCode] = useState(""); const [otpId, setOtpId] = useState(""); + + const { pushPage } = useModal(); const [oauthPublicKey, setOauthPublicKey] = useState(""); useEffect(() => { @@ -153,7 +156,7 @@ export default function AuthPage() { const handleGoogleLogin = async ( credentialResponse: string, - publicKey: string, + publicKey: string ) => { if (!publicKey) { console.error("Public key is not set. Please create a passkey first."); @@ -241,6 +244,34 @@ export default function AuthPage() { await client?.setActiveSession({ sessionKey }); }; + const showModal = () => { + pushPage({ + key: "example-modal", + content: ( +
+

Example Modal

+

This is an example modal content.

+ +
+ ), + }); + }; + return (
+ {client?.storageManager?.getActiveSession() ? ( + ) : ( +
+ )} + +
+
{current.content}
+ + + ); +} diff --git a/packages/react-wallet-kit/tailwind.config.js b/packages/react-wallet-kit/tailwind.config.js new file mode 100644 index 000000000..98e995468 --- /dev/null +++ b/packages/react-wallet-kit/tailwind.config.js @@ -0,0 +1,8 @@ +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: ["./src/**/*.{js,ts,jsx,tsx}"], + theme: { + extend: {}, + }, + plugins: [], +} diff --git a/packages/react-wallet-kit/tsconfig.json b/packages/react-wallet-kit/tsconfig.json new file mode 100644 index 000000000..f7d7d2c3f --- /dev/null +++ b/packages/react-wallet-kit/tsconfig.json @@ -0,0 +1,26 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "outDir": "./dist", + "rootDir": "./src", + "tsBuildInfoFile": "./.cache/.tsbuildinfo", + "lib": ["dom"], + "jsx": "react-jsx", + "paths": { + "@polyfills/*": ["./src/__polyfills__/*"], + "@constants": ["./src/constants"], + "@models": ["./src/models"], + "@storage": ["./src/storage"], + "@types": ["./src/__types__/base"], + "@utils": ["./src/utils"] + } + }, + "include": [ + "src/**/*.ts", + "src/**/*.tsx", + "src/**/*.js", + "src/**/*.jsx", + "src/**/*.json" + ], + "exclude": ["**/__tests__/**/*", "**/__fixtures__/**/*"], +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index adbd5d2c4..dcd39d835 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -92,7 +92,11 @@ importers: version: 6.1.2(rollup@4.41.1) rollup-plugin-postcss: specifier: ^4.0.2 +<<<<<<< HEAD version: 4.0.2(postcss@8.5.3)(ts-node@10.9.2(@types/node@18.19.105)(typescript@5.4.3)) +======= + version: 4.0.2(postcss@8.5.6) +>>>>>>> 70c70d5a (React wallet kit init. Modal init) rollup-preserve-directives: specifier: ^1.1.2 version: 1.1.3(rollup@4.41.1) @@ -1296,6 +1300,9 @@ importers: examples/with-sdk-js: dependencies: + '@turnkey/react-wallet-kit': + specifier: workspace:* + version: link:../../packages/react-wallet-kit '@noble/hashes': specifier: 1.4.0 version: 1.4.0 @@ -2108,6 +2115,40 @@ importers: specifier: 5.3.0 version: 5.3.0(@babel/core@7.26.9)(@types/babel__core@7.20.5)(rollup@4.41.1) + packages/react-wallet-kit: + dependencies: + '@turnkey/sdk-js': + specifier: workspace:* + version: link:../sdk-js + '@turnkey/sdk-types': + specifier: workspace:* + version: link:../sdk-types + '@types/react': + specifier: ^18.2.75 + version: 18.3.3 + devDependencies: + '@tailwindcss/postcss': + specifier: ^4.1.10 + version: 4.1.10 + autoprefixer: + specifier: ^10.0.1 + version: 10.0.1(postcss@8.4.38) + glob: + specifier: ^8.0.3 + version: 8.1.0 + postcss: + specifier: ^8.4.38 + version: 8.4.38 + react: + specifier: ^18.2.0 + version: 18.3.1 + tailwindcss: + specifier: ^4.1.10 + version: 4.1.10 + typescript: + specifier: 5.4.3 + version: 5.4.3 + packages/sdk-browser: dependencies: '@turnkey/api-key-stamper': @@ -2280,7 +2321,11 @@ importers: devDependencies: postcss-import: specifier: ^16.1.0 +<<<<<<< HEAD version: 16.1.0(postcss@8.5.3) +======= + version: 16.1.0(postcss@8.5.6) +>>>>>>> 70c70d5a (React wallet kit init. Modal init) react: specifier: ^18.2.0 version: 18.3.1 @@ -2494,7 +2539,18 @@ packages: resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} +<<<<<<< HEAD '@aptos-labs/aptos-client@0.1.1': +======= + /@ampproject/remapping@2.3.0: + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + + /@aptos-labs/aptos-client@0.1.1: +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-kJsoy4fAPTOhzVr7Vwq8s/AUg6BQiJDa7WOqRzev4zsuIS3+JCuIZ6vUd7UBsjnxtmguJJulMRs9qWCzVBt2XA==} engines: {node: '>=15.10.0'} deprecated: <1.0.0 is no longer supported please upgrade to the latest version @@ -2514,6 +2570,27 @@ packages: '@babel/core@7.26.9': resolution: {integrity: sha512-lWBYIrF7qK5+GjY5Uy+/hEgp8OJWOD/rpy74GplYRhEauvbHDeFB8t5hPOZxCZ0Oxf4Cc36tK51/l3ymJysrKw==} engines: {node: '>=6.9.0'} +<<<<<<< HEAD +======= + dependencies: + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.26.2 + '@babel/generator': 7.26.9 + '@babel/helper-compilation-targets': 7.26.5 + '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.9) + '@babel/helpers': 7.26.9 + '@babel/parser': 7.26.9 + '@babel/template': 7.26.9 + '@babel/traverse': 7.26.9 + '@babel/types': 7.26.9 + convert-source-map: 2.0.0 + debug: 4.3.4(supports-color@8.1.1) + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 7.5.4 + transitivePeerDependencies: + - supports-color +>>>>>>> 70c70d5a (React wallet kit init. Modal init) '@babel/core@7.27.3': resolution: {integrity: sha512-hyrN8ivxfvJ4i0fIJuV4EOlV0WDMz5Ui4StRTgVaAvWeiRCilXgwVvxJKtFQ3TKtHgJscB2YiXKGNJuVwhQMtA==} @@ -4029,7 +4106,18 @@ packages: resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} +<<<<<<< HEAD '@isaacs/ttlcache@1.4.1': +======= + /@isaacs/fs-minipass@4.0.1: + resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} + engines: {node: '>=18.0.0'} + dependencies: + minipass: 7.1.2 + dev: true + + /@isaacs/ttlcache@1.4.1: +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-RQgQ4uQ+pLbqXfOmieB91ejmLwvSgv9nLx6sT6sD83s7umBypgg+OIBOBbEUiJXrfpnp9j0mRhYYdzp9uqq3lA==} engines: {node: '>=12'} @@ -6339,6 +6427,7 @@ packages: typescript: optional: true +<<<<<<< HEAD '@tanstack/query-core@5.77.2': resolution: {integrity: sha512-1lqJwPsR6GX6nZFw06erRt518O19tWU6Q+x0fJUygl4lxHCYF2nhzBPwLKk2NPjYOrpR0K567hxPc5K++xDe9Q==} @@ -6349,6 +6438,168 @@ packages: '@ton/core@0.59.1': resolution: {integrity: sha512-SxFBAvutYJaIllTkv82vbHTJhJI6NxzqUhi499CDEjJEZ9i6i9lHJiK2df4dlLAb/4SiWX6+QUzESkK4DEdnCw==} +======= + /@tailwindcss/node@4.1.10: + resolution: {integrity: sha512-2ACf1znY5fpRBwRhMgj9ZXvb2XZW8qs+oTfotJ2C5xR0/WNL7UHZ7zXl6s+rUqedL1mNi+0O+WQr5awGowS3PQ==} + dependencies: + '@ampproject/remapping': 2.3.0 + enhanced-resolve: 5.18.1 + jiti: 2.4.2 + lightningcss: 1.30.1 + magic-string: 0.30.17 + source-map-js: 1.2.1 + tailwindcss: 4.1.10 + dev: true + + /@tailwindcss/oxide-android-arm64@4.1.10: + resolution: {integrity: sha512-VGLazCoRQ7rtsCzThaI1UyDu/XRYVyH4/EWiaSX6tFglE+xZB5cvtC5Omt0OQ+FfiIVP98su16jDVHDEIuH4iQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@tailwindcss/oxide-darwin-arm64@4.1.10: + resolution: {integrity: sha512-ZIFqvR1irX2yNjWJzKCqTCcHZbgkSkSkZKbRM3BPzhDL/18idA8uWCoopYA2CSDdSGFlDAxYdU2yBHwAwx8euQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@tailwindcss/oxide-darwin-x64@4.1.10: + resolution: {integrity: sha512-eCA4zbIhWUFDXoamNztmS0MjXHSEJYlvATzWnRiTqJkcUteSjO94PoRHJy1Xbwp9bptjeIxxBHh+zBWFhttbrQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@tailwindcss/oxide-freebsd-x64@4.1.10: + resolution: {integrity: sha512-8/392Xu12R0cc93DpiJvNpJ4wYVSiciUlkiOHOSOQNH3adq9Gi/dtySK7dVQjXIOzlpSHjeCL89RUUI8/GTI6g==} + engines: {node: '>= 10'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@tailwindcss/oxide-linux-arm-gnueabihf@4.1.10: + resolution: {integrity: sha512-t9rhmLT6EqeuPT+MXhWhlRYIMSfh5LZ6kBrC4FS6/+M1yXwfCtp24UumgCWOAJVyjQwG+lYva6wWZxrfvB+NhQ==} + engines: {node: '>= 10'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@tailwindcss/oxide-linux-arm64-gnu@4.1.10: + resolution: {integrity: sha512-3oWrlNlxLRxXejQ8zImzrVLuZ/9Z2SeKoLhtCu0hpo38hTO2iL86eFOu4sVR8cZc6n3z7eRXXqtHJECa6mFOvA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@tailwindcss/oxide-linux-arm64-musl@4.1.10: + resolution: {integrity: sha512-saScU0cmWvg/Ez4gUmQWr9pvY9Kssxt+Xenfx1LG7LmqjcrvBnw4r9VjkFcqmbBb7GCBwYNcZi9X3/oMda9sqQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@tailwindcss/oxide-linux-x64-gnu@4.1.10: + resolution: {integrity: sha512-/G3ao/ybV9YEEgAXeEg28dyH6gs1QG8tvdN9c2MNZdUXYBaIY/Gx0N6RlJzfLy/7Nkdok4kaxKPHKJUlAaoTdA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@tailwindcss/oxide-linux-x64-musl@4.1.10: + resolution: {integrity: sha512-LNr7X8fTiKGRtQGOerSayc2pWJp/9ptRYAa4G+U+cjw9kJZvkopav1AQc5HHD+U364f71tZv6XamaHKgrIoVzA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@tailwindcss/oxide-wasm32-wasi@4.1.10: + resolution: {integrity: sha512-d6ekQpopFQJAcIK2i7ZzWOYGZ+A6NzzvQ3ozBvWFdeyqfOZdYHU66g5yr+/HC4ipP1ZgWsqa80+ISNILk+ae/Q==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + requiresBuild: true + dev: true + optional: true + bundledDependencies: + - '@napi-rs/wasm-runtime' + - '@emnapi/core' + - '@emnapi/runtime' + - '@tybys/wasm-util' + - '@emnapi/wasi-threads' + - tslib + + /@tailwindcss/oxide-win32-arm64-msvc@4.1.10: + resolution: {integrity: sha512-i1Iwg9gRbwNVOCYmnigWCCgow8nDWSFmeTUU5nbNx3rqbe4p0kRbEqLwLJbYZKmSSp23g4N6rCDmm7OuPBXhDA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@tailwindcss/oxide-win32-x64-msvc@4.1.10: + resolution: {integrity: sha512-sGiJTjcBSfGq2DVRtaSljq5ZgZS2SDHSIfhOylkBvHVjwOsodBhnb3HdmiKkVuUGKD0I7G63abMOVaskj1KpOA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@tailwindcss/oxide@4.1.10: + resolution: {integrity: sha512-v0C43s7Pjw+B9w21htrQwuFObSkio2aV/qPx/mhrRldbqxbWJK6KizM+q7BF1/1CmuLqZqX3CeYF7s7P9fbA8Q==} + engines: {node: '>= 10'} + requiresBuild: true + dependencies: + detect-libc: 2.0.4 + tar: 7.4.3 + optionalDependencies: + '@tailwindcss/oxide-android-arm64': 4.1.10 + '@tailwindcss/oxide-darwin-arm64': 4.1.10 + '@tailwindcss/oxide-darwin-x64': 4.1.10 + '@tailwindcss/oxide-freebsd-x64': 4.1.10 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.1.10 + '@tailwindcss/oxide-linux-arm64-gnu': 4.1.10 + '@tailwindcss/oxide-linux-arm64-musl': 4.1.10 + '@tailwindcss/oxide-linux-x64-gnu': 4.1.10 + '@tailwindcss/oxide-linux-x64-musl': 4.1.10 + '@tailwindcss/oxide-wasm32-wasi': 4.1.10 + '@tailwindcss/oxide-win32-arm64-msvc': 4.1.10 + '@tailwindcss/oxide-win32-x64-msvc': 4.1.10 + dev: true + + /@tailwindcss/postcss@4.1.10: + resolution: {integrity: sha512-B+7r7ABZbkXJwpvt2VMnS6ujcDoR2OOcFaqrLIo1xbcdxje4Vf+VgJdBzNNbrAjBj/rLZ66/tlQ1knIGNLKOBQ==} + dependencies: + '@alloc/quick-lru': 5.2.0 + '@tailwindcss/node': 4.1.10 + '@tailwindcss/oxide': 4.1.10 + postcss: 8.5.6 + tailwindcss: 4.1.10 + dev: true + + /@ton/core@0.59.0(@ton/crypto@3.3.0): + resolution: {integrity: sha512-LSIkGst7BoY7fMWshejzcH0UJnoW21JGlRrW0ch+6A7Xb/7EuekxgdKym7fHxcry6OIf6FoeFg97lJ960N/Ghg==} +>>>>>>> 70c70d5a (React wallet kit init. Modal init) peerDependencies: '@ton/crypto': '>=3.2.0' @@ -7435,6 +7686,18 @@ packages: hasBin: true peerDependencies: postcss: ^8.1.0 +<<<<<<< HEAD +======= + dependencies: + browserslist: 4.24.4 + caniuse-lite: 1.0.30001700 + colorette: 1.4.0 + normalize-range: 0.1.2 + num2fraction: 1.2.2 + postcss: 8.4.38 + postcss-value-parser: 4.2.0 + dev: true +>>>>>>> 70c70d5a (React wallet kit init. Modal init) available-typed-arrays@1.0.7: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} @@ -7677,12 +7940,26 @@ packages: resolution: {integrity: sha512-JWCZW6SKhfhjJxO8Tyiiy+XYB7cqd2S5/+WeYHsKdNKFlCBhKbblba1A/HN/90YwtxKc8tCErjffZl++UNmGiw==} engines: {node: '>= 0.12'} +<<<<<<< HEAD browserslist@4.24.5: resolution: {integrity: sha512-FDToo4Wo82hIdgc1CQ+NQD0hEhmpPjrZ3hiUgwgOG6IuTdlpr8jdjyG24P6cNP1yJpTLzS5OcGgSw0xmDU1/Tw==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true bs-logger@0.2.6: +======= + /browserslist@4.24.4: + resolution: {integrity: sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + dependencies: + caniuse-lite: 1.0.30001700 + electron-to-chromium: 1.5.102 + node-releases: 2.0.19 + update-browserslist-db: 1.1.2(browserslist@4.24.4) + + /bs-logger@0.2.6: +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==} engines: {node: '>= 6'} @@ -7793,10 +8070,22 @@ packages: caniuse-api@3.0.0: resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==} +<<<<<<< HEAD caniuse-lite@1.0.30001718: resolution: {integrity: sha512-AflseV1ahcSunK53NfEs9gFWgOEmzr0f+kaMFA4xiLZlr9Hzt7HxcSpIFcnNCUkz6R6dWKa54rUz3HUmI3nVcw==} cashaddrjs@0.4.4: +======= + /caniuse-lite@1.0.30001700: + resolution: {integrity: sha512-2S6XIXwaE7K7erT8dY+kLQcpa5ms63XlRkMkReXjle+kf6c5g38vyMl+Z5y8dSxOFDhcFe+nxnn261PLxBSQsQ==} + + /case@1.6.3: + resolution: {integrity: sha512-mzDSXIPaFwVDvZAHqZ9VlbyF4yyXRuX6IvB06WvPYkqJVO24kX1PPhv9bfpKNFZyxYFmmgo03HUiD8iklmJYRQ==} + engines: {node: '>= 0.8.0'} + dev: true + + /cashaddrjs@0.4.4: +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-xZkuWdNOh0uq/mxJIng6vYWfTowZLd9F4GMAlp2DwFHlcCqCm91NtuAc47RuV4L7r4PYcY5p6Cr2OKNb4hnkWA==} cbor-sync@1.0.4: @@ -7824,6 +8113,24 @@ packages: chokidar@3.6.0: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} +<<<<<<< HEAD +======= + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + /chownr@3.0.0: + resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} + engines: {node: '>=18'} + dev: true +>>>>>>> 70c70d5a (React wallet kit init. Modal init) chokidar@4.0.3: resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} @@ -8076,11 +8383,21 @@ packages: css-box-model@1.2.1: resolution: {integrity: sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw==} +<<<<<<< HEAD css-declaration-sorter@6.4.1: +======= + /css-declaration-sorter@6.4.1(postcss@8.5.6): +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g==} engines: {node: ^10 || ^12 || >=14} peerDependencies: postcss: ^8.0.9 +<<<<<<< HEAD +======= + dependencies: + postcss: 8.5.6 + dev: true +>>>>>>> 70c70d5a (React wallet kit init. Modal init) css-select@4.3.0: resolution: {integrity: sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==} @@ -8098,23 +8415,81 @@ packages: engines: {node: '>=4'} hasBin: true +<<<<<<< HEAD cssnano-preset-default@5.2.14: +======= + /cssnano-preset-default@5.2.14(postcss@8.5.6): +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 +<<<<<<< HEAD cssnano-utils@3.1.0: +======= + dependencies: + css-declaration-sorter: 6.4.1(postcss@8.5.6) + cssnano-utils: 3.1.0(postcss@8.5.6) + postcss: 8.5.6 + postcss-calc: 8.2.4(postcss@8.5.6) + postcss-colormin: 5.3.1(postcss@8.5.6) + postcss-convert-values: 5.1.3(postcss@8.5.6) + postcss-discard-comments: 5.1.2(postcss@8.5.6) + postcss-discard-duplicates: 5.1.0(postcss@8.5.6) + postcss-discard-empty: 5.1.1(postcss@8.5.6) + postcss-discard-overridden: 5.1.0(postcss@8.5.6) + postcss-merge-longhand: 5.1.7(postcss@8.5.6) + postcss-merge-rules: 5.1.4(postcss@8.5.6) + postcss-minify-font-values: 5.1.0(postcss@8.5.6) + postcss-minify-gradients: 5.1.1(postcss@8.5.6) + postcss-minify-params: 5.1.4(postcss@8.5.6) + postcss-minify-selectors: 5.2.1(postcss@8.5.6) + postcss-normalize-charset: 5.1.0(postcss@8.5.6) + postcss-normalize-display-values: 5.1.0(postcss@8.5.6) + postcss-normalize-positions: 5.1.1(postcss@8.5.6) + postcss-normalize-repeat-style: 5.1.1(postcss@8.5.6) + postcss-normalize-string: 5.1.0(postcss@8.5.6) + postcss-normalize-timing-functions: 5.1.0(postcss@8.5.6) + postcss-normalize-unicode: 5.1.1(postcss@8.5.6) + postcss-normalize-url: 5.1.0(postcss@8.5.6) + postcss-normalize-whitespace: 5.1.1(postcss@8.5.6) + postcss-ordered-values: 5.1.3(postcss@8.5.6) + postcss-reduce-initial: 5.1.2(postcss@8.5.6) + postcss-reduce-transforms: 5.1.0(postcss@8.5.6) + postcss-svgo: 5.1.0(postcss@8.5.6) + postcss-unique-selectors: 5.1.1(postcss@8.5.6) + dev: true + + /cssnano-utils@3.1.0(postcss@8.5.6): +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 +<<<<<<< HEAD cssnano@5.1.15: +======= + dependencies: + postcss: 8.5.6 + dev: true + + /cssnano@5.1.15(postcss@8.5.6): +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 +<<<<<<< HEAD +======= + dependencies: + cssnano-preset-default: 5.2.14(postcss@8.5.6) + lilconfig: 2.1.0 + postcss: 8.5.6 + yaml: 1.10.2 + dev: true +>>>>>>> 70c70d5a (React wallet kit init. Modal init) csso@4.2.0: resolution: {integrity: sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==} @@ -8298,6 +8673,15 @@ packages: detect-libc@2.0.4: resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==} engines: {node: '>=8'} +<<<<<<< HEAD +======= + requiresBuild: true + dev: true + + /detect-libc@2.0.4: + resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==} + engines: {node: '>=8'} +>>>>>>> 70c70d5a (React wallet kit init. Modal init) detect-newline@3.1.0: resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} @@ -8407,10 +8791,17 @@ packages: engines: {node: '>=0.10.0'} hasBin: true +<<<<<<< HEAD electron-to-chromium@1.5.160: resolution: {integrity: sha512-8yQk54/CoCQT8GX3zuxqPBwMAQuIr6dWI/qO8Aah/JAZwB5XmCbEElsqb1n4pzc2vpkTdfc/kbyNPJOjswfbgg==} elliptic@6.6.1: +======= + /electron-to-chromium@1.5.102: + resolution: {integrity: sha512-eHhqaja8tE/FNpIiBrvBjFV/SSKpyWHLvxuR9dPTdo+3V9ppdLmFB7ZZQ98qNovcngPLYIz0oOBF9P0FfZef5Q==} + + /elliptic@6.6.1: +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==} emittery@0.13.1: @@ -8450,7 +8841,25 @@ packages: resolution: {integrity: sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==} engines: {node: '>=10.0.0'} +<<<<<<< HEAD enquirer@2.4.1: +======= + /enhanced-resolve@5.18.1: + resolution: {integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==} + engines: {node: '>=10.13.0'} + dependencies: + graceful-fs: 4.2.11 + tapable: 2.2.1 + + /enquirer@2.3.6: + resolution: {integrity: sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==} + engines: {node: '>=8.6'} + dependencies: + ansi-colors: 4.1.3 + dev: false + + /enquirer@2.4.1: +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} engines: {node: '>=8.6'} @@ -8563,6 +8972,7 @@ packages: peerDependencies: eslint: '*' eslint-plugin-import: '*' +<<<<<<< HEAD eslint-plugin-import-x: '*' peerDependenciesMeta: eslint-plugin-import: @@ -8572,6 +8982,51 @@ packages: eslint-module-utils@2.12.0: resolution: {integrity: sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==} +======= + dependencies: + debug: 4.3.4(supports-color@8.1.1) + enhanced-resolve: 5.18.1 + eslint: 8.43.0 + eslint-module-utils: 2.8.0(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0) + get-tsconfig: 4.8.1 + globby: 13.2.2 + is-core-module: 2.13.1 + is-glob: 4.0.3 + synckit: 0.8.5 + transitivePeerDependencies: + - '@typescript-eslint/parser' + - eslint-import-resolver-node + - eslint-import-resolver-webpack + - supports-color + + /eslint-import-resolver-typescript@3.5.5(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.56.0): + resolution: {integrity: sha512-TdJqPHs2lW5J9Zpe17DZNQuDnox4xo2o+0tE7Pggain9Rbc19ik8kFtXdxZ250FVx2kF4vlt2RSf4qlUpG7bhw==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + eslint: '*' + eslint-plugin-import: '*' + dependencies: + debug: 4.3.4(supports-color@8.1.1) + enhanced-resolve: 5.18.1 + eslint: 8.56.0 + eslint-module-utils: 2.8.0(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.5.5)(eslint@8.56.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0) + get-tsconfig: 4.8.1 + globby: 13.2.2 + is-core-module: 2.13.1 + is-glob: 4.0.3 + synckit: 0.8.5 + transitivePeerDependencies: + - '@typescript-eslint/parser' + - eslint-import-resolver-node + - eslint-import-resolver-webpack + - supports-color + dev: false + + /eslint-module-utils@2.8.0(@typescript-eslint/parser@5.62.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0): + resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==} +>>>>>>> 70c70d5a (React wallet kit init. Modal init) engines: {node: '>=4'} peerDependencies: '@typescript-eslint/parser': '*' @@ -9024,16 +9479,49 @@ packages: resolution: {integrity: sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==} engines: {node: '>=16 || 14 >=14.17'} hasBin: true +<<<<<<< HEAD +======= + dependencies: + foreground-child: 3.1.1 + jackspeak: 2.3.6 + minimatch: 9.0.5 + minipass: 7.1.2 + path-scurry: 1.10.2 +>>>>>>> 70c70d5a (React wallet kit init. Modal init) glob@10.4.5: resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} hasBin: true +<<<<<<< HEAD +======= + dependencies: + foreground-child: 3.1.1 + jackspeak: 2.3.6 + minimatch: 9.0.5 + minipass: 7.1.2 + path-scurry: 1.10.2 +>>>>>>> 70c70d5a (React wallet kit init. Modal init) glob@7.1.7: resolution: {integrity: sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==} deprecated: Glob versions prior to v9 are no longer supported +<<<<<<< HEAD glob@7.2.3: +======= + /glob@7.2.0: + resolution: {integrity: sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==} + deprecated: Glob versions prior to v9 are no longer supported + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + /glob@7.2.3: +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} deprecated: Glob versions prior to v9 are no longer supported @@ -9095,9 +9583,29 @@ packages: resolution: {integrity: sha512-Su2qcSMIo2YO2PrmJ0/tdkf+6pSt8zf9+4URR5edMVti6+ShI8T3xhPrwugdyTOFuyj8lKHrcTZNKUFYowYiyA==} peerDependencies: hardhat: ^2.0.0 +<<<<<<< HEAD hardhat@2.24.1: resolution: {integrity: sha512-3iwrO2liEGCw1rz/l/mlB1rSNexCc4CFcMj0DlvjXGChzmD3sGUgLwWDOZPf+ya8MEm5ZhO1oprRVmb/wVi0YA==} +======= + dependencies: + chokidar: 3.6.0 + hardhat: 2.12.7(typescript@5.4.3) + dev: false + + /hardhat-watcher@2.5.0(hardhat@2.22.2): + resolution: {integrity: sha512-Su2qcSMIo2YO2PrmJ0/tdkf+6pSt8zf9+4URR5edMVti6+ShI8T3xhPrwugdyTOFuyj8lKHrcTZNKUFYowYiyA==} + peerDependencies: + hardhat: ^2.0.0 + dependencies: + chokidar: 3.6.0 + hardhat: 2.22.2(typescript@5.4.3) + dev: false + + /hardhat@2.12.7(typescript@5.4.3): + resolution: {integrity: sha512-voWoN6zn5d8BOEaczSyK/1PyfdeOeI3SbGCFb36yCHTJUt6OIqLb+ZDX30VhA1UsYKzLqG7UnWl3fKJUuANc6A==} + engines: {node: ^14.0.0 || ^16.0.0 || ^18.0.0} +>>>>>>> 70c70d5a (React wallet kit init. Modal init) hasBin: true peerDependencies: ts-node: '*' @@ -9230,11 +9738,21 @@ packages: icss-replace-symbols@1.1.0: resolution: {integrity: sha512-chIaY3Vh2mh2Q3RGXttaDIzeiPvaVXJ+C4DAh/w3c37SKZ/U6PGMmuicR2EQQp9bKG8zLMCl7I+PtIoOOPp8Gg==} +<<<<<<< HEAD icss-utils@5.1.0: +======= + /icss-utils@5.1.0(postcss@8.5.6): +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==} engines: {node: ^10 || ^12 || >= 14} peerDependencies: postcss: ^8.1.0 +<<<<<<< HEAD +======= + dependencies: + postcss: 8.5.6 + dev: true +>>>>>>> 70c70d5a (React wallet kit init. Modal init) idb-keyval@6.2.2: resolution: {integrity: sha512-yjD9nARJ/jb1g+CvD0tlhUHOrJ9Sy0P8T9MF3YaLlHnSRpwPfpTX0XIvpmw3gAJUmEu3FiICLBDPXVwyEvrleg==} @@ -9742,7 +10260,16 @@ packages: resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} hasBin: true +<<<<<<< HEAD jju@1.4.0: +======= + /jiti@2.4.2: + resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==} + hasBin: true + dev: true + + /jju@1.4.0: +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==} joycon@3.1.1: @@ -9922,7 +10449,119 @@ packages: lighthouse-logger@1.4.2: resolution: {integrity: sha512-gPWxznF6TKmUHrOQjlVo2UbaL2EJ71mb2CCeRs/2qBpi4L/g4LUVc9+3lKQ6DTUZwJswfM7ainGrLO1+fOqa2g==} +<<<<<<< HEAD lilconfig@2.1.0: +======= + /lightningcss-darwin-arm64@1.30.1: + resolution: {integrity: sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /lightningcss-darwin-x64@1.30.1: + resolution: {integrity: sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /lightningcss-freebsd-x64@1.30.1: + resolution: {integrity: sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /lightningcss-linux-arm-gnueabihf@1.30.1: + resolution: {integrity: sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /lightningcss-linux-arm64-gnu@1.30.1: + resolution: {integrity: sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /lightningcss-linux-arm64-musl@1.30.1: + resolution: {integrity: sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /lightningcss-linux-x64-gnu@1.30.1: + resolution: {integrity: sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /lightningcss-linux-x64-musl@1.30.1: + resolution: {integrity: sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /lightningcss-win32-arm64-msvc@1.30.1: + resolution: {integrity: sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /lightningcss-win32-x64-msvc@1.30.1: + resolution: {integrity: sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /lightningcss@1.30.1: + resolution: {integrity: sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==} + engines: {node: '>= 12.0.0'} + dependencies: + detect-libc: 2.0.3 + optionalDependencies: + lightningcss-darwin-arm64: 1.30.1 + lightningcss-darwin-x64: 1.30.1 + lightningcss-freebsd-x64: 1.30.1 + lightningcss-linux-arm-gnueabihf: 1.30.1 + lightningcss-linux-arm64-gnu: 1.30.1 + lightningcss-linux-arm64-musl: 1.30.1 + lightningcss-linux-x64-gnu: 1.30.1 + lightningcss-linux-x64-musl: 1.30.1 + lightningcss-win32-arm64-msvc: 1.30.1 + lightningcss-win32-x64-msvc: 1.30.1 + dev: true + + /lilconfig@2.1.0: +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} engines: {node: '>=10'} @@ -10042,7 +10681,17 @@ packages: magic-string@0.30.17: resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} +<<<<<<< HEAD make-dir@2.1.0: +======= + /magic-string@0.30.17: + resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + dev: true + + /make-dir@2.1.0: +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==} engines: {node: '>=6'} @@ -10237,6 +10886,7 @@ packages: minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} +<<<<<<< HEAD minipass@7.1.2: resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} engines: {node: '>=16 || 14 >=14.17'} @@ -10248,6 +10898,23 @@ packages: peerDependenciesMeta: typescript: optional: true +======= + /minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + + /minizlib@3.0.2: + resolution: {integrity: sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==} + engines: {node: '>= 18'} + dependencies: + minipass: 7.1.2 + dev: true + + /mixme@0.5.5: + resolution: {integrity: sha512-/6IupbRx32s7jjEwHcycXikJwFD5UujbVNuJFkeKLYje+92OvtuPniF6JhnFm5JCTDUhS+kYK3W/4BWYQYXz7w==} + engines: {node: '>= 8.0.0'} + dev: true +>>>>>>> 70c70d5a (React wallet kit init. Modal init) mkdirp@0.5.6: resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} @@ -10258,7 +10925,26 @@ packages: engines: {node: '>=10'} hasBin: true +<<<<<<< HEAD mnemonist@0.38.5: +======= + /mkdirp@3.0.1: + resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} + engines: {node: '>=10'} + hasBin: true + dev: true + + /mlly@1.7.1: + resolution: {integrity: sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==} + dependencies: + acorn: 8.12.1 + pathe: 1.1.2 + pkg-types: 1.1.3 + ufo: 1.5.4 + dev: false + + /mnemonist@0.38.5: +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg==} mocha@10.8.2: @@ -10286,11 +10972,22 @@ packages: mz@2.7.0: resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} +<<<<<<< HEAD nan@2.22.2: resolution: {integrity: sha512-DANghxFkS1plDdRsX0X9pm0Z6SJNN6gBdtXfanwoZ8hooC5gosGFSBGRYHUVPz1asKA/kMRqDRdHrluZ61SpBQ==} nanoid@3.3.11: resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} +======= + /nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + dev: true + + /nanoid@3.3.3: + resolution: {integrity: sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==} +>>>>>>> 70c70d5a (React wallet kit init. Modal init) engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true @@ -10397,10 +11094,14 @@ packages: node-int64@0.4.0: resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} +<<<<<<< HEAD node-mock-http@1.0.0: resolution: {integrity: sha512-0uGYQ1WQL1M5kKvGRXWQ3uZCHtLTO8hln3oBjIusM75WoesZ909uQJs/Hb946i2SS+Gsrhkaa6iAO17jRIv6DQ==} node-releases@2.0.19: +======= + /node-releases@2.0.19: +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} normalize-path@3.0.0: @@ -10741,9 +11442,18 @@ packages: path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} +<<<<<<< HEAD path-scurry@1.11.1: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} +======= + /path-scurry@1.10.2: + resolution: {integrity: sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + lru-cache: 10.2.0 + minipass: 7.1.2 +>>>>>>> 70c70d5a (React wallet kit init. Modal init) path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} @@ -10829,46 +11539,112 @@ packages: resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} engines: {node: '>= 0.4'} +<<<<<<< HEAD postcss-calc@8.2.4: resolution: {integrity: sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==} peerDependencies: postcss: ^8.2.2 postcss-colormin@5.3.1: +======= + /postcss-calc@8.2.4(postcss@8.5.6): + resolution: {integrity: sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==} + peerDependencies: + postcss: ^8.2.2 + dependencies: + postcss: 8.5.6 + postcss-selector-parser: 6.1.1 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-colormin@5.3.1(postcss@8.5.6): +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 +<<<<<<< HEAD postcss-convert-values@5.1.3: +======= + dependencies: + browserslist: 4.24.4 + caniuse-api: 3.0.0 + colord: 2.9.3 + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-convert-values@5.1.3(postcss@8.5.6): +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 +<<<<<<< HEAD postcss-discard-comments@5.1.2: +======= + dependencies: + browserslist: 4.24.4 + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-discard-comments@5.1.2(postcss@8.5.6): +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 +<<<<<<< HEAD postcss-discard-duplicates@5.1.0: +======= + dependencies: + postcss: 8.5.6 + dev: true + + /postcss-discard-duplicates@5.1.0(postcss@8.5.6): +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 +<<<<<<< HEAD postcss-discard-empty@5.1.1: +======= + dependencies: + postcss: 8.5.6 + dev: true + + /postcss-discard-empty@5.1.1(postcss@8.5.6): +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 +<<<<<<< HEAD postcss-discard-overridden@5.1.0: +======= + dependencies: + postcss: 8.5.6 + dev: true + + /postcss-discard-overridden@5.1.0(postcss@8.5.6): +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 +<<<<<<< HEAD +======= + dependencies: + postcss: 8.5.6 + dev: true +>>>>>>> 70c70d5a (React wallet kit init. Modal init) postcss-import@15.1.0: resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} @@ -10876,11 +11652,24 @@ packages: peerDependencies: postcss: ^8.0.0 +<<<<<<< HEAD postcss-import@16.1.0: +======= + /postcss-import@16.1.0(postcss@8.5.6): +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-7hsAZ4xGXl4MW+OKEWCnF6T5jqBw80/EE9aXg1r2yyn1RsVEU8EtKXbijEODa+rg7iih4bKf7vlvTGYR4CnPNg==} engines: {node: '>=18.0.0'} peerDependencies: postcss: ^8.0.0 +<<<<<<< HEAD +======= + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + read-cache: 1.0.0 + resolve: 1.22.8 + dev: true +>>>>>>> 70c70d5a (React wallet kit init. Modal init) postcss-js@4.0.1: resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} @@ -10900,7 +11689,28 @@ packages: ts-node: optional: true +<<<<<<< HEAD postcss-load-config@4.0.2: +======= + /postcss-load-config@3.1.4(postcss@8.5.6): + resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==} + engines: {node: '>= 10'} + peerDependencies: + postcss: '>=8.0.9' + ts-node: '>=9.0.0' + peerDependenciesMeta: + postcss: + optional: true + ts-node: + optional: true + dependencies: + lilconfig: 2.1.0 + postcss: 8.5.6 + yaml: 1.10.2 + dev: true + + /postcss-load-config@4.0.2(postcss@8.4.38): +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==} engines: {node: '>= 14'} peerDependencies: @@ -10912,47 +11722,114 @@ packages: ts-node: optional: true +<<<<<<< HEAD postcss-merge-longhand@5.1.7: +======= + /postcss-merge-longhand@5.1.7(postcss@8.5.6): +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 +<<<<<<< HEAD postcss-merge-rules@5.1.4: +======= + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + stylehacks: 5.1.1(postcss@8.5.6) + dev: true + + /postcss-merge-rules@5.1.4(postcss@8.5.6): +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 +<<<<<<< HEAD postcss-minify-font-values@5.1.0: +======= + dependencies: + browserslist: 4.24.4 + caniuse-api: 3.0.0 + cssnano-utils: 3.1.0(postcss@8.5.6) + postcss: 8.5.6 + postcss-selector-parser: 6.1.1 + dev: true + + /postcss-minify-font-values@5.1.0(postcss@8.5.6): +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 +<<<<<<< HEAD postcss-minify-gradients@5.1.1: +======= + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-minify-gradients@5.1.1(postcss@8.5.6): +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 +<<<<<<< HEAD postcss-minify-params@5.1.4: +======= + dependencies: + colord: 2.9.3 + cssnano-utils: 3.1.0(postcss@8.5.6) + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-minify-params@5.1.4(postcss@8.5.6): +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 +<<<<<<< HEAD postcss-minify-selectors@5.2.1: +======= + dependencies: + browserslist: 4.24.4 + cssnano-utils: 3.1.0(postcss@8.5.6) + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-minify-selectors@5.2.1(postcss@8.5.6): +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 +<<<<<<< HEAD postcss-modules-extract-imports@3.1.0: +======= + dependencies: + postcss: 8.5.6 + postcss-selector-parser: 6.1.1 + dev: true + + /postcss-modules-extract-imports@3.1.0(postcss@8.5.6): +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==} engines: {node: ^10 || ^12 || >= 14} peerDependencies: postcss: ^8.1.0 +<<<<<<< HEAD postcss-modules-local-by-default@4.2.0: resolution: {integrity: sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==} @@ -10967,15 +11844,67 @@ packages: postcss: ^8.1.0 postcss-modules-values@4.0.0: +======= + dependencies: + postcss: 8.5.6 + dev: true + + /postcss-modules-local-by-default@4.0.5(postcss@8.5.6): + resolution: {integrity: sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + dependencies: + icss-utils: 5.1.0(postcss@8.5.6) + postcss: 8.5.6 + postcss-selector-parser: 6.1.1 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-modules-scope@3.2.0(postcss@8.5.6): + resolution: {integrity: sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + dependencies: + postcss: 8.5.6 + postcss-selector-parser: 6.1.1 + dev: true + + /postcss-modules-values@4.0.0(postcss@8.5.6): +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==} engines: {node: ^10 || ^12 || >= 14} peerDependencies: postcss: ^8.1.0 +<<<<<<< HEAD postcss-modules@4.3.1: resolution: {integrity: sha512-ItUhSUxBBdNamkT3KzIZwYNNRFKmkJrofvC2nWab3CPKhYBQ1f27XXh1PAPE27Psx58jeelPsxWB/+og+KEH0Q==} peerDependencies: postcss: ^8.0.0 +======= + dependencies: + icss-utils: 5.1.0(postcss@8.5.6) + postcss: 8.5.6 + dev: true + + /postcss-modules@4.3.1(postcss@8.5.6): + resolution: {integrity: sha512-ItUhSUxBBdNamkT3KzIZwYNNRFKmkJrofvC2nWab3CPKhYBQ1f27XXh1PAPE27Psx58jeelPsxWB/+og+KEH0Q==} + peerDependencies: + postcss: ^8.0.0 + dependencies: + generic-names: 4.0.0 + icss-replace-symbols: 1.1.0 + lodash.camelcase: 4.3.0 + postcss: 8.5.6 + postcss-modules-extract-imports: 3.1.0(postcss@8.5.6) + postcss-modules-local-by-default: 4.0.5(postcss@8.5.6) + postcss-modules-scope: 3.2.0(postcss@8.5.6) + postcss-modules-values: 4.0.0(postcss@8.5.6) + string-hash: 1.1.3 + dev: true +>>>>>>> 70c70d5a (React wallet kit init. Modal init) postcss-nested@6.2.0: resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==} @@ -10983,77 +11912,190 @@ packages: peerDependencies: postcss: ^8.2.14 +<<<<<<< HEAD postcss-normalize-charset@5.1.0: +======= + /postcss-normalize-charset@5.1.0(postcss@8.5.6): +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 +<<<<<<< HEAD postcss-normalize-display-values@5.1.0: +======= + dependencies: + postcss: 8.5.6 + dev: true + + /postcss-normalize-display-values@5.1.0(postcss@8.5.6): +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 +<<<<<<< HEAD postcss-normalize-positions@5.1.1: +======= + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-normalize-positions@5.1.1(postcss@8.5.6): +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 +<<<<<<< HEAD postcss-normalize-repeat-style@5.1.1: +======= + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-normalize-repeat-style@5.1.1(postcss@8.5.6): +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 +<<<<<<< HEAD postcss-normalize-string@5.1.0: +======= + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-normalize-string@5.1.0(postcss@8.5.6): +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 +<<<<<<< HEAD postcss-normalize-timing-functions@5.1.0: +======= + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-normalize-timing-functions@5.1.0(postcss@8.5.6): +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 +<<<<<<< HEAD postcss-normalize-unicode@5.1.1: +======= + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-normalize-unicode@5.1.1(postcss@8.5.6): +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 +<<<<<<< HEAD postcss-normalize-url@5.1.0: +======= + dependencies: + browserslist: 4.24.4 + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-normalize-url@5.1.0(postcss@8.5.6): +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 +<<<<<<< HEAD postcss-normalize-whitespace@5.1.1: +======= + dependencies: + normalize-url: 6.1.0 + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-normalize-whitespace@5.1.1(postcss@8.5.6): +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 +<<<<<<< HEAD postcss-ordered-values@5.1.3: +======= + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-ordered-values@5.1.3(postcss@8.5.6): +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 +<<<<<<< HEAD postcss-reduce-initial@5.1.2: +======= + dependencies: + cssnano-utils: 3.1.0(postcss@8.5.6) + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-reduce-initial@5.1.2(postcss@8.5.6): +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 +<<<<<<< HEAD postcss-reduce-transforms@5.1.0: +======= + dependencies: + browserslist: 4.24.4 + caniuse-api: 3.0.0 + postcss: 8.5.6 + dev: true + + /postcss-reduce-transforms@5.1.0(postcss@8.5.6): +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 +<<<<<<< HEAD +======= + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + dev: true +>>>>>>> 70c70d5a (React wallet kit init. Modal init) postcss-selector-parser@6.1.2: resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} @@ -11063,17 +12105,38 @@ packages: resolution: {integrity: sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==} engines: {node: '>=4'} +<<<<<<< HEAD postcss-svgo@5.1.0: +======= + /postcss-svgo@5.1.0(postcss@8.5.6): +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 +<<<<<<< HEAD postcss-unique-selectors@5.1.1: +======= + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + svgo: 2.8.0 + dev: true + + /postcss-unique-selectors@5.1.1(postcss@8.5.6): +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 +<<<<<<< HEAD +======= + dependencies: + postcss: 8.5.6 + postcss-selector-parser: 6.1.1 + dev: true +>>>>>>> 70c70d5a (React wallet kit init. Modal init) postcss-value-parser@4.2.0: resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} @@ -11085,9 +12148,29 @@ packages: postcss@8.5.3: resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==} engines: {node: ^10 || ^12 || >=14} +<<<<<<< HEAD preact@10.26.7: resolution: {integrity: sha512-43xS+QYc1X1IPbw03faSgY6I6OYWcLrJRv3hU0+qMOfh/XCHcP0MX2CVjNARYR2cC/guu975sta4OcjlczxD7g==} +======= + dependencies: + nanoid: 3.3.7 + picocolors: 1.1.1 + source-map-js: 1.2.0 + + /postcss@8.5.6: + resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + dev: true + + /preact@10.4.1: + resolution: {integrity: sha512-WKrRpCSwL2t3tpOOGhf2WfTpcmbpxaWtDbdJdKdjd0aEiTkvOmS4NBkG6kzlaAHI9AkQ3iVqbFWM3Ei7mZ4o1Q==} + dev: false +>>>>>>> 70c70d5a (React wallet kit init. Modal init) prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} @@ -11369,6 +12452,11 @@ packages: react@18.3.1: resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} engines: {node: '>=0.10.0'} +<<<<<<< HEAD +======= + dependencies: + loose-envify: 1.4.0 +>>>>>>> 70c70d5a (React wallet kit init. Modal init) read-cache@1.0.0: resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} @@ -11554,11 +12642,36 @@ packages: peerDependencies: rollup: ^3.0.0 || ^4.0.0 +<<<<<<< HEAD rollup-plugin-postcss@4.0.2: +======= + /rollup-plugin-postcss@4.0.2(postcss@8.5.6): +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-05EaY6zvZdmvPUDi3uCcAQoESDcYnv8ogJJQRp6V5kZ6J6P7uAVJlrTZcaaA20wTH527YTnKfkAoPxWI/jPp4w==} engines: {node: '>=10'} peerDependencies: postcss: 8.x +<<<<<<< HEAD +======= + dependencies: + chalk: 4.1.2 + concat-with-sourcemaps: 1.1.0 + cssnano: 5.1.15(postcss@8.5.6) + import-cwd: 3.0.0 + p-queue: 6.6.2 + pify: 5.0.0 + postcss: 8.5.6 + postcss-load-config: 3.1.4(postcss@8.5.6) + postcss-modules: 4.3.1(postcss@8.5.6) + promise.series: 0.2.0 + resolve: 1.22.8 + rollup-pluginutils: 2.8.2 + safe-identifier: 0.4.2 + style-inject: 0.3.0 + transitivePeerDependencies: + - ts-node + dev: true +>>>>>>> 70c70d5a (React wallet kit init. Modal init) rollup-pluginutils@2.8.2: resolution: {integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==} @@ -11709,6 +12822,36 @@ packages: sharp@0.34.2: resolution: {integrity: sha512-lszvBmB9QURERtyKT2bNmsgxXK0ShJrL/fvqlonCo7e6xBF8nT8xU6pW+PMIbLsz0RxQk3rgH9kd8UmvOzlMJg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} +<<<<<<< HEAD +======= + requiresBuild: true + dependencies: + color: 4.2.3 + detect-libc: 2.0.4 + semver: 7.5.4 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.33.5 + '@img/sharp-darwin-x64': 0.33.5 + '@img/sharp-libvips-darwin-arm64': 1.0.4 + '@img/sharp-libvips-darwin-x64': 1.0.4 + '@img/sharp-libvips-linux-arm': 1.0.5 + '@img/sharp-libvips-linux-arm64': 1.0.4 + '@img/sharp-libvips-linux-s390x': 1.0.4 + '@img/sharp-libvips-linux-x64': 1.0.4 + '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 + '@img/sharp-libvips-linuxmusl-x64': 1.0.4 + '@img/sharp-linux-arm': 0.33.5 + '@img/sharp-linux-arm64': 0.33.5 + '@img/sharp-linux-s390x': 0.33.5 + '@img/sharp-linux-x64': 0.33.5 + '@img/sharp-linuxmusl-arm64': 0.33.5 + '@img/sharp-linuxmusl-x64': 0.33.5 + '@img/sharp-wasm32': 0.33.5 + '@img/sharp-win32-ia32': 0.33.5 + '@img/sharp-win32-x64': 0.33.5 + dev: false + optional: true +>>>>>>> 70c70d5a (React wallet kit init. Modal init) shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} @@ -11807,7 +12950,16 @@ packages: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} +<<<<<<< HEAD source-map-support@0.5.13: +======= + /source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + dev: true + + /source-map-support@0.5.13: +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} source-map-support@0.5.21: @@ -11987,11 +13139,23 @@ packages: babel-plugin-macros: optional: true +<<<<<<< HEAD stylehacks@5.1.1: +======= + /stylehacks@5.1.1(postcss@8.5.6): +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 +<<<<<<< HEAD +======= + dependencies: + browserslist: 4.24.4 + postcss: 8.5.6 + postcss-selector-parser: 6.1.1 + dev: true +>>>>>>> 70c70d5a (React wallet kit init. Modal init) stylis@4.2.0: resolution: {integrity: sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==} @@ -12059,8 +13223,58 @@ packages: resolution: {integrity: sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==} engines: {node: '>=14.0.0'} hasBin: true +<<<<<<< HEAD temp@0.8.4: +======= + dependencies: + '@alloc/quick-lru': 5.2.0 + arg: 5.0.2 + chokidar: 3.6.0 + didyoumean: 1.2.2 + dlv: 1.1.3 + fast-glob: 3.3.2 + glob-parent: 6.0.2 + is-glob: 4.0.3 + jiti: 1.21.0 + lilconfig: 2.1.0 + micromatch: 4.0.5 + normalize-path: 3.0.0 + object-hash: 3.0.0 + picocolors: 1.1.1 + postcss: 8.4.38 + postcss-import: 15.1.0(postcss@8.4.38) + postcss-js: 4.0.1(postcss@8.4.38) + postcss-load-config: 4.0.2(postcss@8.4.38) + postcss-nested: 6.2.0(postcss@8.4.38) + postcss-selector-parser: 6.1.1 + resolve: 1.22.8 + sucrase: 3.35.0 + transitivePeerDependencies: + - ts-node + + /tailwindcss@4.1.10: + resolution: {integrity: sha512-P3nr6WkvKV/ONsTzj6Gb57sWPMX29EPNPopo7+FcpkQaNsrNpZ1pv8QmrYI2RqEKD7mlGqLnGovlcYnBK0IqUA==} + dev: true + + /tapable@2.2.1: + resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} + engines: {node: '>=6'} + + /tar@7.4.3: + resolution: {integrity: sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==} + engines: {node: '>=18'} + dependencies: + '@isaacs/fs-minipass': 4.0.1 + chownr: 3.0.0 + minipass: 7.1.2 + minizlib: 3.0.2 + mkdirp: 3.0.1 + yallist: 5.0.0 + dev: true + + /temp@0.8.4: +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-s0ZZzd0BzYv5tLSptZooSjK8oj6C+c19p7Vqta9+6NPOf7r+fxq0cJe6/oN4LTC79sy5NY8ucOJNgwsKCSbfqg==} engines: {node: '>=6.0.0'} @@ -12505,6 +13719,7 @@ packages: uploadthing: optional: true +<<<<<<< HEAD update-browserslist-db@1.1.3: resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} hasBin: true @@ -12512,6 +13727,36 @@ packages: browserslist: '>= 4.21.0' uri-js@4.4.1: +======= + /untildify@4.0.0: + resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==} + engines: {node: '>=8'} + + /untun@0.1.3: + resolution: {integrity: sha512-4luGP9LMYszMRZwsvyUd9MrxgEGZdZuZgpVQHEEX0lCYFESasVRvZd0EYpCkOIbJKHMuv0LskpXc/8Un+MJzEQ==} + hasBin: true + dependencies: + citty: 0.1.6 + consola: 3.2.3 + pathe: 1.1.2 + dev: false + + /update-browserslist-db@1.1.2(browserslist@4.24.4): + resolution: {integrity: sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + dependencies: + browserslist: 4.24.4 + escalade: 3.2.0 + picocolors: 1.1.1 + + /uqr@0.1.2: + resolution: {integrity: sha512-MJu7ypHq6QasgF5YRTjqscSzQp/W11zoUk6kvmlH+fmWEs63Y0Eib13hYFwAzagRJcVY8WVnlV+eBDUGMJ5IbA==} + dev: false + + /uri-js@4.4.1: +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} url-parse@1.5.10: @@ -12923,7 +14168,20 @@ packages: yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} +<<<<<<< HEAD yaml@1.10.2: +======= + /yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + requiresBuild: true + + /yallist@5.0.0: + resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} + engines: {node: '>=18'} + dev: true + + /yaml@1.10.2: +>>>>>>> 70c70d5a (React wallet kit init. Modal init) resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} engines: {node: '>= 6'} From 74fbdd08276e29f6ecd051054a875b2b19983af5 Mon Sep 17 00:00:00 2001 From: Amir Cheikh Date: Tue, 24 Jun 2025 18:02:28 -0400 Subject: [PATCH 027/184] More modal upgrades --- examples/with-sdk-js/src/app/page.tsx | 28 +- packages/react-wallet-kit/package.json | 3 +- .../src/providers/modal/Root.tsx | 123 ++- pnpm-lock.yaml | 915 +++++++++++++++++- 4 files changed, 1019 insertions(+), 50 deletions(-) diff --git a/examples/with-sdk-js/src/app/page.tsx b/examples/with-sdk-js/src/app/page.tsx index 924929201..8c7a76e1e 100644 --- a/examples/with-sdk-js/src/app/page.tsx +++ b/examples/with-sdk-js/src/app/page.tsx @@ -248,14 +248,38 @@ export default function AuthPage() { pushPage({ key: "example-modal", content: ( -
+

Example Modal

This is an example modal content.

- ) : ( -
- )} - + + + {/* Backdrop */} + +
+ + + {/* Modal Panel */} +
+ + {/* Modal content (absolute layer) */} + +
+ {current?.content} +
+
+ + {/* White background container */} + +
+
+ {hasBack ? ( + + ) : ( +
+ )} + +
+
+ +
-
{current.content}
-
-
+
+
); } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index dcd39d835..190127c97 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2117,6 +2117,9 @@ importers: packages/react-wallet-kit: dependencies: + '@headlessui/react': + specifier: ^2.2.4 + version: 2.2.4(react-dom@18.3.1)(react@18.3.1) '@turnkey/sdk-js': specifier: workspace:* version: link:../sdk-js @@ -3845,6 +3848,7 @@ packages: '@farcaster/frame-core@0.0.26': resolution: {integrity: sha512-DqBsi+lz7WBlqcxJfYv8ZiU8+Th4Y49euq13kCxVOn6YU/rKR7Wq6E6N1bgeb625wyoIrlC3NnPRXf5SoRxNhA==} +<<<<<<< HEAD '@farcaster/frame-sdk@0.0.28': resolution: {integrity: sha512-raxJkwy9oNDTodyfcY8DNvQNkt/9wdWGIqGnXW70biBPfVxfdG9WAqy1Bm552KSynd0+hGzcrQVwkMNzvpSZBg==} @@ -3870,14 +3874,63 @@ packages: '@floating-ui/react-dom@2.1.2': resolution: {integrity: sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A==} +======= + /@floating-ui/core@1.6.0: + resolution: {integrity: sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==} + dependencies: + '@floating-ui/utils': 0.2.9 + dev: false + + /@floating-ui/dom@1.6.3: + resolution: {integrity: sha512-RnDthu3mzPlQ31Ss/BTwQ1zjzIhr3lk1gZB1OC56h/1vEtaXkESrOqL5fQVMfXpwGtRwX+YsZBdyHtJMQnkArw==} + dependencies: + '@floating-ui/core': 1.6.0 + '@floating-ui/utils': 0.2.9 + dev: false + + /@floating-ui/react-dom@2.1.3(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-huMBfiU9UnQ2oBwIhgzyIiSpVgvlDstU8CX0AF+wS+KzmYMs0J2a3GwuFHV1Lz+jlrQGeC1fF+Nv0QoumyV0bA==} +>>>>>>> 79f35590 (More modal upgrades) peerDependencies: react: '>=16.8.0' react-dom: '>=16.8.0' +<<<<<<< HEAD '@floating-ui/utils@0.2.9': resolution: {integrity: sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==} '@fractalwagmi/popup-connection@1.1.1': +======= + /@floating-ui/react-dom@2.1.3(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-huMBfiU9UnQ2oBwIhgzyIiSpVgvlDstU8CX0AF+wS+KzmYMs0J2a3GwuFHV1Lz+jlrQGeC1fF+Nv0QoumyV0bA==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + dependencies: + '@floating-ui/dom': 1.6.3 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@floating-ui/react@0.26.28(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-yORQuuAtVpiRjpMhdc0wJj06b9JFjrYF4qp96j++v2NBpbi6SEGF7donUJ3TMieerQ6qVkAv1tgr7L4r5roTqw==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + dependencies: + '@floating-ui/react-dom': 2.1.3(react-dom@18.3.1)(react@18.3.1) + '@floating-ui/utils': 0.2.9 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + tabbable: 6.2.0 + dev: false + + /@floating-ui/utils@0.2.9: + resolution: {integrity: sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==} + dev: false + + /@fractalwagmi/popup-connection@1.1.1(react-dom@18.3.1)(react@18.3.1): +>>>>>>> 79f35590 (More modal upgrades) resolution: {integrity: sha512-hYL+45iYwNbwjvP2DxP3YzVsrAGtj/RV9LOgMpJyCxsfNoyyOoi2+YrnywKkiANingiG2kJ1nKsizbu1Bd4zZw==} peerDependencies: react: ^17.0.2 || ^18 @@ -3894,7 +3947,27 @@ packages: peerDependencies: graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 +<<<<<<< HEAD '@hello-pangea/dnd@17.0.0': +======= + /@headlessui/react@2.2.4(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-lz+OGcAH1dK93rgSMzXmm1qKOJkBUqZf1L4M8TWLNplftQD3IkoEDdUFNfAn4ylsN6WOTVtWaLmvmaHOUk1dTA==} + engines: {node: '>=10'} + peerDependencies: + react: ^18 || ^19 || ^19.0.0-rc + react-dom: ^18 || ^19 || ^19.0.0-rc + dependencies: + '@floating-ui/react': 0.26.28(react-dom@18.3.1)(react@18.3.1) + '@react-aria/focus': 3.20.5(react-dom@18.3.1)(react@18.3.1) + '@react-aria/interactions': 3.25.3(react-dom@18.3.1)(react@18.3.1) + '@tanstack/react-virtual': 3.13.11(react-dom@18.3.1)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + use-sync-external-store: 1.5.0(react@18.3.1) + dev: false + + /@hello-pangea/dnd@17.0.0(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0): +>>>>>>> 79f35590 (More modal upgrades) resolution: {integrity: sha512-LDDPOix/5N0j5QZxubiW9T0M0+1PR0rTDWeZF5pu1Tz91UQnuVK4qQ/EjY83Qm2QeX0eM8qDXANfDh3VVqtR4Q==} peerDependencies: react: ^18.0.0 @@ -4826,48 +4899,673 @@ packages: '@protobufjs/codegen@2.0.4': resolution: {integrity: sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==} - '@protobufjs/eventemitter@1.1.0': - resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==} + '@protobufjs/eventemitter@1.1.0': + resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==} + + '@protobufjs/fetch@1.1.0': + resolution: {integrity: sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==} + + '@protobufjs/float@1.0.2': + resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==} + + '@protobufjs/inquire@1.1.0': + resolution: {integrity: sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==} + + '@protobufjs/path@1.1.2': + resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==} + + '@protobufjs/pool@1.1.0': + resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==} + + '@protobufjs/utf8@1.1.0': + resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} + + '@radix-ui/number@1.1.1': + resolution: {integrity: sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==} + + '@radix-ui/primitive@1.1.2': + resolution: {integrity: sha512-XnbHrrprsNqZKQhStrSwgRUQzoCI1glLzdw79xiZPoofhGICeZRSQ3dIxAKH1gb3OHfNf4d6f+vAv3kil2eggA==} + + '@radix-ui/react-arrow@1.1.7': + resolution: {integrity: sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + +<<<<<<< HEAD + '@radix-ui/react-collection@1.1.7': + resolution: {integrity: sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==} +======= + /@radix-ui/react-compose-refs@1.0.1(@types/react@18.2.14)(react@18.2.0): + resolution: {integrity: sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.26.10 + '@types/react': 18.2.14 + react: 18.2.0 + dev: false + + /@radix-ui/react-compose-refs@1.0.1(@types/react@18.3.3)(react@18.3.1): + resolution: {integrity: sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.26.10 + '@types/react': 18.3.3 + react: 18.3.1 + dev: false + + /@radix-ui/react-compose-refs@1.1.0(@types/react@18.3.3)(react@18.3.1): + resolution: {integrity: sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.3.3 + react: 18.3.1 + dev: false + + /@radix-ui/react-context@1.0.1(@types/react@18.2.14)(react@18.2.0): + resolution: {integrity: sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.26.10 + '@types/react': 18.2.14 + react: 18.2.0 + dev: false + + /@radix-ui/react-context@1.0.1(@types/react@18.3.3)(react@18.3.1): + resolution: {integrity: sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.26.10 + '@types/react': 18.3.3 + react: 18.3.1 + dev: false + + /@radix-ui/react-context@1.1.0(@types/react@18.3.3)(react@18.3.1): + resolution: {integrity: sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.3.3 + react: 18.3.1 + dev: false + + /@radix-ui/react-dialog@1.0.5(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-GjWJX/AUpB703eEBanuBnIWdIXg6NvJFCXcNlSZk4xdszCdhrJgBoUd1cGk67vFO+WdA2pfI/plOpqz/5GUP6Q==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.24.1 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-focus-guards': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-focus-scope': 1.0.4(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@types/react': 18.2.14 + '@types/react-dom': 18.2.6 + aria-hidden: 1.2.4 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-remove-scroll: 2.5.5(@types/react@18.2.14)(react@18.2.0) + dev: false + + /@radix-ui/react-dialog@1.0.5(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-GjWJX/AUpB703eEBanuBnIWdIXg6NvJFCXcNlSZk4xdszCdhrJgBoUd1cGk67vFO+WdA2pfI/plOpqz/5GUP6Q==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.24.1 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-context': 1.0.1(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-focus-guards': 1.0.1(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.0.4(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-id': 1.0.1(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-slot': 1.0.2(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.3.3)(react@18.3.1) + '@types/react': 18.3.3 + '@types/react-dom': 18.3.0 + aria-hidden: 1.2.4 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-remove-scroll: 2.5.5(@types/react@18.3.3)(react@18.3.1) + dev: false + + /@radix-ui/react-direction@1.0.1(@types/react@18.2.14)(react@18.2.0): + resolution: {integrity: sha512-RXcvnXgyvYvBEOhCBuddKecVkoMiI10Jcm5cTI7abJRAHYfFxeu+FBQs/DvdxSYucxR5mna0dNsL6QFlds5TMA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.26.10 + '@types/react': 18.2.14 + react: 18.2.0 + dev: false + + /@radix-ui/react-direction@1.0.1(@types/react@18.3.3)(react@18.3.1): + resolution: {integrity: sha512-RXcvnXgyvYvBEOhCBuddKecVkoMiI10Jcm5cTI7abJRAHYfFxeu+FBQs/DvdxSYucxR5mna0dNsL6QFlds5TMA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.26.10 + '@types/react': 18.3.3 + react: 18.3.1 + dev: false + + /@radix-ui/react-direction@1.1.0(@types/react@18.3.3)(react@18.3.1): + resolution: {integrity: sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.3.3 + react: 18.3.1 + dev: false + + /@radix-ui/react-dismissable-layer@1.0.5(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-aJeDjQhywg9LBu2t/At58hCvr7pEm0o2Ke1x33B+MhjNmmZ17sy4KImo0KPLgsnc/zN7GPdce8Cnn0SWvwZO7g==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.26.10 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-use-escape-keydown': 1.0.3(@types/react@18.2.14)(react@18.2.0) + '@types/react': 18.2.14 + '@types/react-dom': 18.2.6 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@radix-ui/react-dismissable-layer@1.0.5(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-aJeDjQhywg9LBu2t/At58hCvr7pEm0o2Ke1x33B+MhjNmmZ17sy4KImo0KPLgsnc/zN7GPdce8Cnn0SWvwZO7g==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.26.10 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-use-escape-keydown': 1.0.3(@types/react@18.3.3)(react@18.3.1) + '@types/react': 18.3.3 + '@types/react-dom': 18.3.0 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@radix-ui/react-dropdown-menu@2.0.6(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-i6TuFOoWmLWq+M/eCLGd/bQ2HfAX1RJgvrBQ6AQLmzfvsLdefxbWu8G9zczcPFfcSPehz9GcpF6K9QYreFV8hA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.24.1 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-menu': 2.0.6(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@types/react': 18.2.14 + '@types/react-dom': 18.2.6 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@radix-ui/react-focus-guards@1.0.1(@types/react@18.2.14)(react@18.2.0): + resolution: {integrity: sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.26.10 + '@types/react': 18.2.14 + react: 18.2.0 + dev: false + + /@radix-ui/react-focus-guards@1.0.1(@types/react@18.3.3)(react@18.3.1): + resolution: {integrity: sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.26.10 + '@types/react': 18.3.3 + react: 18.3.1 + dev: false + + /@radix-ui/react-focus-scope@1.0.4(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-sL04Mgvf+FmyvZeYfNu1EPAaaxD+aw7cYeIB9L9Fvq8+urhltTRaEo5ysKOpHuKPclsZcSUMKlN05x4u+CINpA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.26.10 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@types/react': 18.2.14 + '@types/react-dom': 18.2.6 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@radix-ui/react-focus-scope@1.0.4(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-sL04Mgvf+FmyvZeYfNu1EPAaaxD+aw7cYeIB9L9Fvq8+urhltTRaEo5ysKOpHuKPclsZcSUMKlN05x4u+CINpA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.26.10 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.3.3)(react@18.3.1) + '@types/react': 18.3.3 + '@types/react-dom': 18.3.0 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@radix-ui/react-icons@1.3.0(react@18.2.0): + resolution: {integrity: sha512-jQxj/0LKgp+j9BiTXz3O3sgs26RNet2iLWmsPyRz2SIcR4q/4SbazXfnYwbAr+vLYKSfc7qxzyGQA1HLlYiuNw==} + peerDependencies: + react: ^16.x || ^17.x || ^18.x + dependencies: + react: 18.2.0 + dev: false + + /@radix-ui/react-id@1.0.1(@types/react@18.2.14)(react@18.2.0): + resolution: {integrity: sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.26.10 + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@types/react': 18.2.14 + react: 18.2.0 + dev: false + + /@radix-ui/react-id@1.0.1(@types/react@18.3.3)(react@18.3.1): + resolution: {integrity: sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.26.10 + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.3.3)(react@18.3.1) + '@types/react': 18.3.3 + react: 18.3.1 + dev: false + + /@radix-ui/react-id@1.1.0(@types/react@18.3.3)(react@18.3.1): + resolution: {integrity: sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.3)(react@18.3.1) + '@types/react': 18.3.3 + react: 18.3.1 + dev: false - '@protobufjs/fetch@1.1.0': - resolution: {integrity: sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==} + /@radix-ui/react-label@2.0.2(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-N5ehvlM7qoTLx7nWPodsPYPgMzA5WM8zZChQg8nyFJKnDO5WHdba1vv5/H6IO5LtJMfD2Q3wh1qHFGNtK0w3bQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.24.8 + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.14 + '@types/react-dom': 18.2.6 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false - '@protobufjs/float@1.0.2': - resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==} + /@radix-ui/react-label@2.0.2(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-N5ehvlM7qoTLx7nWPodsPYPgMzA5WM8zZChQg8nyFJKnDO5WHdba1vv5/H6IO5LtJMfD2Q3wh1qHFGNtK0w3bQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.24.8 + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1) + '@types/react': 18.3.3 + '@types/react-dom': 18.3.0 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false - '@protobufjs/inquire@1.1.0': - resolution: {integrity: sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==} + /@radix-ui/react-menu@2.0.6(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-BVkFLS+bUC8HcImkRKPSiVumA1VPOOEC5WBMiT+QAVsPzW1FJzI9KnqgGxVDPBcql5xXrHkD3JOVoXWEXD8SYA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.26.10 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-collection': 1.0.3(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-direction': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-focus-guards': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-focus-scope': 1.0.4(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-popper': 1.1.3(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-roving-focus': 1.0.4(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@types/react': 18.2.14 + '@types/react-dom': 18.2.6 + aria-hidden: 1.2.4 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-remove-scroll: 2.5.5(@types/react@18.2.14)(react@18.2.0) + dev: false - '@protobufjs/path@1.1.2': - resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==} + /@radix-ui/react-popper@1.1.3(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-cKpopj/5RHZWjrbF2846jBNacjQVwkP068DfmgrNJXpvVWrOvlAmE9xSiy5OqeE+Gi8D9fP+oDhUnPqNMY8/5w==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.26.10 + '@floating-ui/react-dom': 2.1.3(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-arrow': 1.0.3(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-use-rect': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-use-size': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/rect': 1.0.1 + '@types/react': 18.2.14 + '@types/react-dom': 18.2.6 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false - '@protobufjs/pool@1.1.0': - resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==} + /@radix-ui/react-popper@1.1.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-cKpopj/5RHZWjrbF2846jBNacjQVwkP068DfmgrNJXpvVWrOvlAmE9xSiy5OqeE+Gi8D9fP+oDhUnPqNMY8/5w==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.26.10 + '@floating-ui/react-dom': 2.1.3(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-arrow': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-context': 1.0.1(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-use-rect': 1.0.1(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-use-size': 1.0.1(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/rect': 1.0.1 + '@types/react': 18.3.3 + '@types/react-dom': 18.3.0 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false - '@protobufjs/utf8@1.1.0': - resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} + /@radix-ui/react-portal@1.0.4(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-Qki+C/EuGUVCQTOTD5vzJzJuMUlewbzuKyUy+/iHM2uwGiru9gZeBJtHAPKAEkB5KWGi9mP/CHKcY0wt1aW45Q==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.26.10 + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.14 + '@types/react-dom': 18.2.6 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false - '@radix-ui/number@1.1.1': - resolution: {integrity: sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==} + /@radix-ui/react-portal@1.0.4(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-Qki+C/EuGUVCQTOTD5vzJzJuMUlewbzuKyUy+/iHM2uwGiru9gZeBJtHAPKAEkB5KWGi9mP/CHKcY0wt1aW45Q==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.26.10 + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1) + '@types/react': 18.3.3 + '@types/react-dom': 18.3.0 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false - '@radix-ui/primitive@1.1.2': - resolution: {integrity: sha512-XnbHrrprsNqZKQhStrSwgRUQzoCI1glLzdw79xiZPoofhGICeZRSQ3dIxAKH1gb3OHfNf4d6f+vAv3kil2eggA==} + /@radix-ui/react-presence@1.0.1(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.26.10 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@types/react': 18.2.14 + '@types/react-dom': 18.2.6 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false - '@radix-ui/react-arrow@1.1.7': - resolution: {integrity: sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==} + /@radix-ui/react-presence@1.0.1(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 peerDependenciesMeta: '@types/react': optional: true '@types/react-dom': optional: true + dependencies: + '@babel/runtime': 7.26.10 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.3.3)(react@18.3.1) + '@types/react': 18.3.3 + '@types/react-dom': 18.3.0 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false - '@radix-ui/react-collection@1.1.7': - resolution: {integrity: sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==} + /@radix-ui/react-presence@1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-Gq6wuRN/asf9H/E/VzdKoUtT8GC9PQc9z40/vEr0VCJ4u5XvvhWIrSsCB6vD2/cH7ugTdSfYq9fLJCcM00acrQ==} +>>>>>>> 79f35590 (More modal upgrades) peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -5059,6 +5757,7 @@ packages: '@types/react-dom': optional: true +<<<<<<< HEAD '@radix-ui/react-radio-group@1.3.7': resolution: {integrity: sha512-9w5XhD0KPOrm92OTTE0SysH3sYzHsSTHNvZgUBo/VZ80VdYyB5RneDbc0dKpURS24IxkoFRu/hI0i4XyfFwY6g==} peerDependencies: @@ -5261,6 +5960,65 @@ packages: resolution: {integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==} '@react-native-async-storage/async-storage@1.24.0': +======= + /@react-aria/focus@3.20.5(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-JpFtXmWQ0Oca7FcvkqgjSyo6xEP7v3oQOLUId6o0xTvm4AD5W0mU2r3lYrbhsJ+XxdUUX4AVR5473sZZ85kU4A==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + dependencies: + '@react-aria/interactions': 3.25.3(react-dom@18.3.1)(react@18.3.1) + '@react-aria/utils': 3.29.1(react-dom@18.3.1)(react@18.3.1) + '@react-types/shared': 3.30.0(react@18.3.1) + '@swc/helpers': 0.5.15 + clsx: 2.1.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@react-aria/interactions@3.25.3(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-J1bhlrNtjPS/fe5uJQ+0c7/jiXniwa4RQlP+Emjfc/iuqpW2RhbF9ou5vROcLzWIyaW8tVMZ468J68rAs/aZ5A==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + dependencies: + '@react-aria/ssr': 3.9.9(react@18.3.1) + '@react-aria/utils': 3.29.1(react-dom@18.3.1)(react@18.3.1) + '@react-stately/flags': 3.1.2 + '@react-types/shared': 3.30.0(react@18.3.1) + '@swc/helpers': 0.5.15 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@react-aria/ssr@3.9.9(react@18.3.1): + resolution: {integrity: sha512-2P5thfjfPy/np18e5wD4WPt8ydNXhij1jwA8oehxZTFqlgVMGXzcWKxTb4RtJrLFsqPO7RUQTiY8QJk0M4Vy2g==} + engines: {node: '>= 12'} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + dependencies: + '@swc/helpers': 0.5.15 + react: 18.3.1 + dev: false + + /@react-aria/utils@3.29.1(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-yXMFVJ73rbQ/yYE/49n5Uidjw7kh192WNN9PNQGV0Xoc7EJUlSOxqhnpHmYTyO0EotJ8fdM1fMH8durHjUSI8g==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + dependencies: + '@react-aria/ssr': 3.9.9(react@18.3.1) + '@react-stately/flags': 3.1.2 + '@react-stately/utils': 3.10.7(react@18.3.1) + '@react-types/shared': 3.30.0(react@18.3.1) + '@swc/helpers': 0.5.15 + clsx: 2.1.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@react-native-async-storage/async-storage@1.24.0(react-native@0.76.5): +>>>>>>> 79f35590 (More modal upgrades) resolution: {integrity: sha512-W4/vbwUOYOjco0x3toB8QCr7EjIP6nE9G7o8PMguvvjYT5Awg09lyV4enACRx4s++PPulBiBSjL0KTFx2u0Z/g==} peerDependencies: react-native: ^0.0.0-0 || >=0.60 <1.0 @@ -5384,6 +6142,7 @@ packages: peerDependencies: valtio: 1.13.2 +<<<<<<< HEAD '@reown/appkit-utils@1.7.3': resolution: {integrity: sha512-8/MNhmfri+2uu8WzBhZ5jm5llofOIa1dyXDXRC/hfrmGmCFJdrQKPpuqOFYoimo2s2g70pK4PYefvOKgZOWzgg==} peerDependencies: @@ -5403,6 +6162,33 @@ packages: '@rhinestone/module-sdk@0.1.32': resolution: {integrity: sha512-wNzeIepHPhD0jiw3UOar+dAb6VKv4p8D4+947n0SLZHBdJ5S7moRCCL082NCo7Pz8+/C9kVriJASFeLZmJLo4g==} +======= + /@react-stately/flags@3.1.2: + resolution: {integrity: sha512-2HjFcZx1MyQXoPqcBGALwWWmgFVUk2TuKVIQxCbRq7fPyWXIl6VHcakCLurdtYC2Iks7zizvz0Idv48MQ38DWg==} + dependencies: + '@swc/helpers': 0.5.15 + dev: false + + /@react-stately/utils@3.10.7(react@18.3.1): + resolution: {integrity: sha512-cWvjGAocvy4abO9zbr6PW6taHgF24Mwy/LbQ4TC4Aq3tKdKDntxyD+sh7AkSRfJRT2ccMVaHVv2+FfHThd3PKQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + dependencies: + '@swc/helpers': 0.5.15 + react: 18.3.1 + dev: false + + /@react-types/shared@3.30.0(react@18.3.1): + resolution: {integrity: sha512-COIazDAx1ncDg046cTJ8SFYsX8aS3lB/08LDnbkH/SkdYrFPWDlXMrO/sUam8j1WWM+PJ+4d1mj7tODIKNiFog==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + dependencies: + react: 18.3.1 + dev: false + + /@rhinestone/module-sdk@0.1.28(viem@2.26.2): + resolution: {integrity: sha512-Ob9qMs/scBrk6/X0dvb02kWqiCdP3Vau6PRNr3PP7PGxIIBFunJoVHuLWg4Tb/DHS3dCUXhuTk+XhObH1HjH+w==} +>>>>>>> 79f35590 (More modal upgrades) peerDependencies: viem: ^2.0.0 @@ -6597,6 +7383,21 @@ packages: tailwindcss: 4.1.10 dev: true + /@tanstack/react-virtual@3.13.11(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-u5EaOSJOq08T9NXFuDopMdxZBNDFuEMohIFFU45fBYDXXh9SjYdbpNq1OLFSOpQnDRPjqgmY96ipZTkzom9t9Q==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + dependencies: + '@tanstack/virtual-core': 3.13.11 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@tanstack/virtual-core@3.13.11: + resolution: {integrity: sha512-ORL6UyuZJ0D9X33LDR4TcgcM+K2YiS2j4xbvH1vnhhObwR1Z4dKwPTL/c0kj2Yeb4Yp2lBv1wpyVaqlohk8zpg==} + dev: false + /@ton/core@0.59.0(@ton/crypto@3.3.0): resolution: {integrity: sha512-LSIkGst7BoY7fMWshejzcH0UJnoW21JGlRrW0ch+6A7Xb/7EuekxgdKym7fHxcry6OIf6FoeFg97lJ960N/Ghg==} >>>>>>> 70c70d5a (React wallet kit init. Modal init) @@ -12404,6 +13205,16 @@ packages: optional: true redux: optional: true +<<<<<<< HEAD +======= + dependencies: + '@types/react': 18.2.14 + '@types/use-sync-external-store': 0.0.3 + react: 18.2.0 + redux: 5.0.1 + use-sync-external-store: 1.5.0(react@18.2.0) + dev: false +>>>>>>> 79f35590 (More modal upgrades) react-refresh@0.14.2: resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==} @@ -13207,7 +14018,27 @@ packages: symbol.inspect@1.0.1: resolution: {integrity: sha512-YQSL4duoHmLhsTD1Pw8RW6TZ5MaTX5rXJnqacJottr2P2LZBF/Yvrc3ku4NUpMOm8aM0KOCqM+UAkMA5HWQCzQ==} +<<<<<<< HEAD table-layout@1.0.2: +======= + /synckit@0.8.5: + resolution: {integrity: sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q==} + engines: {node: ^14.18.0 || >=16.0.0} + dependencies: + '@pkgr/utils': 2.4.2 + tslib: 2.8.1 + + /system-architecture@0.1.0: + resolution: {integrity: sha512-ulAk51I9UVUyJgxlv9M6lFot2WP3e7t8Kz9+IS6D4rVba1tR9kON+Ey69f+1R4Q8cd45Lod6a4IcJIxnzGc/zA==} + engines: {node: '>=18'} + dev: false + + /tabbable@6.2.0: + resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==} + dev: false + + /table-layout@1.0.2: +>>>>>>> 79f35590 (More modal upgrades) resolution: {integrity: sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A==} engines: {node: '>=8.0.0'} @@ -13791,6 +14622,7 @@ packages: '@types/react': optional: true +<<<<<<< HEAD use-sync-external-store@1.2.0: resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==} peerDependencies: @@ -13807,6 +14639,41 @@ packages: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 usehooks-ts@3.1.1: +======= + /use-sidecar@1.1.2(@types/react@18.3.3)(react@18.3.1): + resolution: {integrity: sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.9.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.3.3 + detect-node-es: 1.1.0 + react: 18.3.1 + tslib: 2.8.1 + dev: false + + /use-sync-external-store@1.5.0(react@18.2.0): + resolution: {integrity: sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + dependencies: + react: 18.2.0 + dev: false + + /use-sync-external-store@1.5.0(react@18.3.1): + resolution: {integrity: sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + dependencies: + react: 18.3.1 + dev: false + + /usehooks-ts@3.1.1(react@18.2.0): +>>>>>>> 79f35590 (More modal upgrades) resolution: {integrity: sha512-I4diPp9Cq6ieSUH2wu+fDAVQO43xwtulo+fKEidHUwZPnYImbtkTjzIJYcDcJqxgmX31GVqNFURodvcgHcW0pA==} engines: {node: '>=16.15.0'} peerDependencies: From 5c426a12043c8e9e56ca06f385af58de366cdf31 Mon Sep 17 00:00:00 2001 From: Amir Cheikh Date: Wed, 25 Jun 2025 13:45:50 -0400 Subject: [PATCH 028/184] Refactored modal. Icon button started --- examples/with-sdk-js/src/app/page.tsx | 4 +- .../src/components/Buttons.tsx | 21 +++++++ packages/react-wallet-kit/src/index.css | 8 ++- .../src/providers/modal/Root.tsx | 61 ++++++++----------- pnpm-lock.yaml | 6 +- 5 files changed, 59 insertions(+), 41 deletions(-) create mode 100644 packages/react-wallet-kit/src/components/Buttons.tsx diff --git a/examples/with-sdk-js/src/app/page.tsx b/examples/with-sdk-js/src/app/page.tsx index 8c7a76e1e..a180f56df 100644 --- a/examples/with-sdk-js/src/app/page.tsx +++ b/examples/with-sdk-js/src/app/page.tsx @@ -256,7 +256,6 @@ export default function AuthPage() { alignItems: "center", width: "400px", height: "600px", - padding: "20px", }} >

Example Modal

@@ -272,9 +271,8 @@ export default function AuthPage() { flexDirection: "column", justifyContent: "center", alignItems: "center", - width: "400px", + width: "600px", height: "200px", - padding: "20px", }} >

Good mronign

diff --git a/packages/react-wallet-kit/src/components/Buttons.tsx b/packages/react-wallet-kit/src/components/Buttons.tsx new file mode 100644 index 000000000..e772abb0d --- /dev/null +++ b/packages/react-wallet-kit/src/components/Buttons.tsx @@ -0,0 +1,21 @@ +import { Button } from "@headlessui/react"; + +interface IconButtonProps { + children: React.ReactNode; + onClick?: () => void; + disabled?: boolean; + className?: string; +} +export function IconButton(props: IconButtonProps) { + const { children, onClick, disabled, className } = props; + + return ( + + ); +} diff --git a/packages/react-wallet-kit/src/index.css b/packages/react-wallet-kit/src/index.css index dc8fd5d4b..3e3292eea 100644 --- a/packages/react-wallet-kit/src/index.css +++ b/packages/react-wallet-kit/src/index.css @@ -1,3 +1,9 @@ @layer theme, base, components, utilities; @import "tailwindcss/theme.css" layer(theme); -@import "tailwindcss/utilities.css" layer(utilities); \ No newline at end of file +@import "tailwindcss/utilities.css" layer(utilities); + + +@theme { + --color-modal-background-light: oklch(1 0 344); + --color-modal-background-dark: oklch(0.2084 0 344); +} \ No newline at end of file diff --git a/packages/react-wallet-kit/src/providers/modal/Root.tsx b/packages/react-wallet-kit/src/providers/modal/Root.tsx index e1205333e..ce611e214 100644 --- a/packages/react-wallet-kit/src/providers/modal/Root.tsx +++ b/packages/react-wallet-kit/src/providers/modal/Root.tsx @@ -6,6 +6,7 @@ import { TransitionChild, } from "@headlessui/react"; import { useModal } from "./Provider"; +import { IconButton } from "../../components/Buttons"; export function ModalRoot() { const { modalStack, popPage, closeModal } = useModal(); @@ -16,22 +17,26 @@ export function ModalRoot() { const innerPadding = 16; const containerRef = useRef(null); - const [height, setHeight] = useState(); - const [width, setWidth] = useState(); + const [height, setHeight] = useState(300); + const [width, setWidth] = useState(300); useEffect(() => { const resize = () => { if (containerRef.current) { - setContentBlur(10); + setContentBlur(10); // Blur the content during resize. const rect = containerRef.current.getBoundingClientRect(); + setHeight(rect.height); setWidth(rect.width); - setTimeout(() => setContentBlur(0), 100); + setTimeout(() => setContentBlur(0), 100); // Remove blur after resize } }; if (current) { requestAnimationFrame(resize); + } else { + setHeight(height / 1.3); + setWidth(width / 1.3); } }, [current]); @@ -54,37 +59,15 @@ export function ModalRoot() { {/* Modal Panel */}
- {/* Modal content (absolute layer) */} + {/* White background container */} -
- {current?.content} -
-
- - {/* White background container */} -
{hasBack ? ( - + - + ) : (
)} @@ -115,6 +98,16 @@ export function ModalRoot() { βœ•
+ +
+ {current?.content} +
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 190127c97..08e9b1997 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1300,15 +1300,15 @@ importers: examples/with-sdk-js: dependencies: - '@turnkey/react-wallet-kit': - specifier: workspace:* - version: link:../../packages/react-wallet-kit '@noble/hashes': specifier: 1.4.0 version: 1.4.0 '@react-oauth/google': specifier: ^0.12.1 version: 0.12.1(react-dom@18.2.0)(react@18.2.0) + '@turnkey/react-wallet-kit': + specifier: workspace:* + version: link:../../packages/react-wallet-kit '@turnkey/sdk-js': specifier: workspace:* version: link:../../packages/sdk-js From 004985288b6f84532c6cc6d9611b7e1f2f651f93 Mon Sep 17 00:00:00 2001 From: Amir Cheikh Date: Wed, 25 Jun 2025 18:19:19 -0400 Subject: [PATCH 029/184] Iconbutton dark/light mode functionality --- examples/with-sdk-js/src/app/global.css | 49 +++++++++++-------- examples/with-sdk-js/src/app/index.module.css | 1 - examples/with-sdk-js/src/app/page.tsx | 2 +- packages/react-wallet-kit/package.json | 3 ++ packages/react-wallet-kit/postcss.config.js | 9 ++-- .../src/components/Buttons.tsx | 34 ++++++++++--- packages/react-wallet-kit/src/global.d.ts | 11 +++++ packages/react-wallet-kit/src/index.css | 7 +-- .../src/providers/modal/Root.tsx | 13 ++--- packages/react-wallet-kit/tailwind.config.js | 2 +- packages/react-wallet-kit/tsconfig.json | 2 +- pnpm-lock.yaml | 39 +++++++++++++++ 12 files changed, 123 insertions(+), 49 deletions(-) create mode 100644 packages/react-wallet-kit/src/global.d.ts diff --git a/examples/with-sdk-js/src/app/global.css b/examples/with-sdk-js/src/app/global.css index c20bf48d6..7fa1056aa 100644 --- a/examples/with-sdk-js/src/app/global.css +++ b/examples/with-sdk-js/src/app/global.css @@ -1,24 +1,31 @@ @font-face { - font-family: "Inter"; - font-style: normal; - font-weight: 400; - font-display: swap; - src: url("/fonts/inter/Inter-Regular.woff2?v=3.19") format("woff2"); - } - - @font-face { - font-family: "Inter"; - font-style: normal; - font-weight: 600; - font-display: swap; - src: url("/fonts/inter/Inter-SemiBold.woff2?v=3.19") format("woff2"); - } - + font-family: "Inter"; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url("/fonts/inter/Inter-Regular.woff2?v=3.19") format("woff2"); +} + +@font-face { + font-family: "Inter"; + font-style: normal; + font-weight: 600; + font-display: swap; + src: url("/fonts/inter/Inter-SemiBold.woff2?v=3.19") format("woff2"); +} * { - font-family: "Inter", -apple-system, BlinkMacSystemFont, sans-serif; - } - - :root { - font-family: "Inter", -apple-system, BlinkMacSystemFont, sans-serif; - } \ No newline at end of file + font-family: + "Inter", + -apple-system, + BlinkMacSystemFont, + sans-serif; +} + +:root { + font-family: + "Inter", + -apple-system, + BlinkMacSystemFont, + sans-serif; +} diff --git a/examples/with-sdk-js/src/app/index.module.css b/examples/with-sdk-js/src/app/index.module.css index 399248780..16144f1b2 100644 --- a/examples/with-sdk-js/src/app/index.module.css +++ b/examples/with-sdk-js/src/app/index.module.css @@ -1,4 +1,3 @@ - .main { display: flex; flex-direction: column; diff --git a/examples/with-sdk-js/src/app/page.tsx b/examples/with-sdk-js/src/app/page.tsx index a180f56df..3e442213e 100644 --- a/examples/with-sdk-js/src/app/page.tsx +++ b/examples/with-sdk-js/src/app/page.tsx @@ -156,7 +156,7 @@ export default function AuthPage() { const handleGoogleLogin = async ( credentialResponse: string, - publicKey: string + publicKey: string, ) => { if (!publicKey) { console.error("Public key is not set. Please create a passkey first."); diff --git a/packages/react-wallet-kit/package.json b/packages/react-wallet-kit/package.json index 19174402a..bc7af0b18 100644 --- a/packages/react-wallet-kit/package.json +++ b/packages/react-wallet-kit/package.json @@ -21,6 +21,9 @@ ], "license": "MIT", "dependencies": { + "@fortawesome/fontawesome-svg-core": "^6.7.2", + "@fortawesome/free-solid-svg-icons": "^6.7.2", + "@fortawesome/react-fontawesome": "^0.2.2", "@headlessui/react": "^2.2.4", "@turnkey/sdk-js": "workspace:*", "@turnkey/sdk-types": "workspace:*" diff --git a/packages/react-wallet-kit/postcss.config.js b/packages/react-wallet-kit/postcss.config.js index be00b81ce..483f37854 100644 --- a/packages/react-wallet-kit/postcss.config.js +++ b/packages/react-wallet-kit/postcss.config.js @@ -1,6 +1,5 @@ module.exports = { - plugins: { - "@tailwindcss/postcss": {}, - }, - } - \ No newline at end of file + plugins: { + "@tailwindcss/postcss": {}, + }, +}; diff --git a/packages/react-wallet-kit/src/components/Buttons.tsx b/packages/react-wallet-kit/src/components/Buttons.tsx index e772abb0d..406944564 100644 --- a/packages/react-wallet-kit/src/components/Buttons.tsx +++ b/packages/react-wallet-kit/src/components/Buttons.tsx @@ -1,21 +1,39 @@ -import { Button } from "@headlessui/react"; +import type { IconDefinition } from "@fortawesome/fontawesome-svg-core"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { _internal_ComponentButton } from "@headlessui/react"; interface IconButtonProps { - children: React.ReactNode; + icon: IconDefinition; onClick?: () => void; disabled?: boolean; className?: string; } -export function IconButton(props: IconButtonProps) { - const { children, onClick, disabled, className } = props; + +export function BaseButton( + props: React.ButtonHTMLAttributes, +) { + const { children, className, disabled, ...buttonProps } = props; return ( - + + ); +} +export function IconButton(props: IconButtonProps) { + const { icon, onClick, disabled, className } = props; + // TODO (Amir): Use standardized colors. Define these and make one for light and dark mode + return ( + + + ); } diff --git a/packages/react-wallet-kit/src/global.d.ts b/packages/react-wallet-kit/src/global.d.ts new file mode 100644 index 000000000..fb9c743e1 --- /dev/null +++ b/packages/react-wallet-kit/src/global.d.ts @@ -0,0 +1,11 @@ +// For CSS modules +declare module "*.module.css" { + const classes: { [key: string]: string }; + export default classes; +} + +// For SVG files +declare module "*.svg" { + const content: string; + export default content; +} diff --git a/packages/react-wallet-kit/src/index.css b/packages/react-wallet-kit/src/index.css index 3e3292eea..2afe08277 100644 --- a/packages/react-wallet-kit/src/index.css +++ b/packages/react-wallet-kit/src/index.css @@ -2,8 +2,9 @@ @import "tailwindcss/theme.css" layer(theme); @import "tailwindcss/utilities.css" layer(utilities); +@custom-variant dark (&:where(.dark, .dark *)); @theme { - --color-modal-background-light: oklch(1 0 344); - --color-modal-background-dark: oklch(0.2084 0 344); -} \ No newline at end of file + --color-modal-background-light: oklch(1 0 344); + --color-modal-background-dark: oklch(0.2532 0.0056 285.99); +} diff --git a/packages/react-wallet-kit/src/providers/modal/Root.tsx b/packages/react-wallet-kit/src/providers/modal/Root.tsx index ce611e214..e03d416d0 100644 --- a/packages/react-wallet-kit/src/providers/modal/Root.tsx +++ b/packages/react-wallet-kit/src/providers/modal/Root.tsx @@ -7,6 +7,7 @@ import { } from "@headlessui/react"; import { useModal } from "./Provider"; import { IconButton } from "../../components/Buttons"; +import { faArrowLeft } from "@fortawesome/free-solid-svg-icons"; export function ModalRoot() { const { modalStack, popPage, closeModal } = useModal(); @@ -56,8 +57,9 @@ export function ModalRoot() {
- {/* Modal Panel */} -
+ {/* Modal Panel */ + /* NOTE (Amir): dark is applied manually here. This should be controlled in a variable. Idk why but, tailwind's default dark mode auto selecting causes so many bugs. If we have UI anywhere else, we need to add this modifer also! */} +
{/* White background container */} {hasBack ? ( - - - - + ) : (
)} diff --git a/packages/react-wallet-kit/tailwind.config.js b/packages/react-wallet-kit/tailwind.config.js index 98e995468..54331dc99 100644 --- a/packages/react-wallet-kit/tailwind.config.js +++ b/packages/react-wallet-kit/tailwind.config.js @@ -5,4 +5,4 @@ module.exports = { extend: {}, }, plugins: [], -} +}; diff --git a/packages/react-wallet-kit/tsconfig.json b/packages/react-wallet-kit/tsconfig.json index f7d7d2c3f..e63065604 100644 --- a/packages/react-wallet-kit/tsconfig.json +++ b/packages/react-wallet-kit/tsconfig.json @@ -22,5 +22,5 @@ "src/**/*.jsx", "src/**/*.json" ], - "exclude": ["**/__tests__/**/*", "**/__fixtures__/**/*"], + "exclude": ["**/__tests__/**/*", "**/__fixtures__/**/*"] } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 08e9b1997..b9a32e7db 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2117,6 +2117,15 @@ importers: packages/react-wallet-kit: dependencies: + '@fortawesome/fontawesome-svg-core': + specifier: ^6.7.2 + version: 6.7.2 + '@fortawesome/free-solid-svg-icons': + specifier: ^6.7.2 + version: 6.7.2 + '@fortawesome/react-fontawesome': + specifier: ^0.2.2 + version: 0.2.2(@fortawesome/fontawesome-svg-core@6.7.2)(react@18.3.1) '@headlessui/react': specifier: ^2.2.4 version: 2.2.4(react-dom@18.3.1)(react@18.3.1) @@ -3929,6 +3938,36 @@ packages: resolution: {integrity: sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==} dev: false + /@fortawesome/fontawesome-common-types@6.7.2: + resolution: {integrity: sha512-Zs+YeHUC5fkt7Mg1l6XTniei3k4bwG/yo3iFUtZWd/pMx9g3fdvkSK9E0FOC+++phXOka78uJcYb8JaFkW52Xg==} + engines: {node: '>=6'} + dev: false + + /@fortawesome/fontawesome-svg-core@6.7.2: + resolution: {integrity: sha512-yxtOBWDrdi5DD5o1pmVdq3WMCvnobT0LU6R8RyyVXPvFRd2o79/0NCuQoCjNTeZz9EzA9xS3JxNWfv54RIHFEA==} + engines: {node: '>=6'} + dependencies: + '@fortawesome/fontawesome-common-types': 6.7.2 + dev: false + + /@fortawesome/free-solid-svg-icons@6.7.2: + resolution: {integrity: sha512-GsBrnOzU8uj0LECDfD5zomZJIjrPhIlWU82AHwa2s40FKH+kcxQaBvBo3Z4TxyZHIyX8XTDxsyA33/Vx9eFuQA==} + engines: {node: '>=6'} + dependencies: + '@fortawesome/fontawesome-common-types': 6.7.2 + dev: false + + /@fortawesome/react-fontawesome@0.2.2(@fortawesome/fontawesome-svg-core@6.7.2)(react@18.3.1): + resolution: {integrity: sha512-EnkrprPNqI6SXJl//m29hpaNzOp1bruISWaOiRtkMi/xSvHJlzc2j2JAYS7egxt/EbjSNV/k6Xy0AQI6vB2+1g==} + peerDependencies: + '@fortawesome/fontawesome-svg-core': ~1 || ~6 + react: '>=16.3' + dependencies: + '@fortawesome/fontawesome-svg-core': 6.7.2 + prop-types: 15.8.1 + react: 18.3.1 + dev: false + /@fractalwagmi/popup-connection@1.1.1(react-dom@18.3.1)(react@18.3.1): >>>>>>> 79f35590 (More modal upgrades) resolution: {integrity: sha512-hYL+45iYwNbwjvP2DxP3YzVsrAGtj/RV9LOgMpJyCxsfNoyyOoi2+YrnywKkiANingiG2kJ1nKsizbu1Bd4zZw==} From 2391c021f2d46d4d20cf4017d812000128dc4002 Mon Sep 17 00:00:00 2001 From: Ethan Konkolowicz Date: Thu, 26 Jun 2025 15:53:07 -0400 Subject: [PATCH 030/184] added react providers to react-wallet-kit --- examples/with-sdk-js/src/app/layout.tsx | 19 +- examples/with-sdk-js/src/app/page.tsx | 137 +++-------- .../with-sdk-js/src/components/Google.tsx | 133 ----------- packages/react-wallet-kit/package.json | 1 + .../src/providers/TurnkeyProvider.tsx | 21 ++ .../src/providers/client/Provider.tsx | 221 ++++++++++++++++++ .../react-wallet-kit/src/providers/index.ts | 5 +- packages/react-wallet-kit/src/utils.ts | 55 +++++ packages/sdk-js/src/__clients__/core.ts | 184 +++++++++++---- pnpm-lock.yaml | 101 +++++++- 10 files changed, 591 insertions(+), 286 deletions(-) delete mode 100644 examples/with-sdk-js/src/components/Google.tsx create mode 100644 packages/react-wallet-kit/src/providers/TurnkeyProvider.tsx create mode 100644 packages/react-wallet-kit/src/providers/client/Provider.tsx create mode 100644 packages/react-wallet-kit/src/utils.ts diff --git a/examples/with-sdk-js/src/app/layout.tsx b/examples/with-sdk-js/src/app/layout.tsx index ca5634f3a..50561f234 100644 --- a/examples/with-sdk-js/src/app/layout.tsx +++ b/examples/with-sdk-js/src/app/layout.tsx @@ -1,6 +1,6 @@ "use client"; -import { ModalProvider } from "@turnkey/react-wallet-kit"; +import { TurnkeyProvider } from "@turnkey/react-wallet-kit"; import "@turnkey/react-wallet-kit/dist/styles.css"; import "./global.css"; @@ -24,7 +24,22 @@ function RootLayout({ children }: RootLayoutProps) { - {children} + + {children} + ); diff --git a/examples/with-sdk-js/src/app/page.tsx b/examples/with-sdk-js/src/app/page.tsx index 3e442213e..f3b99a867 100644 --- a/examples/with-sdk-js/src/app/page.tsx +++ b/examples/with-sdk-js/src/app/page.tsx @@ -4,14 +4,12 @@ import Image from "next/image"; import styles from "./index.module.css"; import { StamperType, TurnkeyClient, Wallet } from "@turnkey/sdk-js"; -import { useEffect, useState } from "react"; +import { useContext, useEffect, useState } from "react"; import { Session, v1AddressFormat } from "@turnkey/sdk-types"; import { OtpType } from "@turnkey/sdk-js"; -import { ModalProvider, useModal } from "@turnkey/react-wallet-kit"; -import GoogleAuthButton from "@/components/Google"; +import { useModal, useTurnkey } from "@turnkey/react-wallet-kit"; export default function AuthPage() { - const [client, setClient] = useState(null); const [session, setSession] = useState(null); const [wallets, setWallets] = useState([]); const [email, setEmail] = useState(""); @@ -20,28 +18,7 @@ export default function AuthPage() { const { pushPage } = useModal(); const [oauthPublicKey, setOauthPublicKey] = useState(""); - - useEffect(() => { - const initializeClient = async () => { - const turnkeyClient = new TurnkeyClient({ - apiBaseUrl: process.env.NEXT_PUBLIC_BASE_URL!, - authProxyUrl: process.env.NEXT_PUBLIC_AUTH_PROXY_URL!, - authProxyId: process.env.NEXT_PUBLIC_AUTH_PROXY_ID!, - organizationId: process.env.NEXT_PUBLIC_ORGANIZATION_ID!, - passkeyConfig: { - rpId: process.env.NEXT_PUBLIC_RPID!, - timeout: 60000, // 60 seconds - userVerification: "preferred", - allowCredentials: [], - }, - }); - - await turnkeyClient.init(); - setClient(turnkeyClient); - }; - - initializeClient(); - }, []); + const { client, handleGoogleOauth } = useTurnkey(); const createPasskey = async () => { await client?.createPasskey({}); @@ -154,77 +131,20 @@ export default function AuthPage() { }); }; - const handleGoogleLogin = async ( - credentialResponse: string, - publicKey: string, - ) => { - if (!publicKey) { - console.error("Public key is not set. Please create a passkey first."); - return; - } - - const res = await client?.handleOauthLogin({ - oidcToken: credentialResponse, - publicKey, - }); - - console.log("Google login response:", res); + const handleRefreshSession = async () => { + return await client?.refreshSession({}); }; const createWallet = async (walletName: string) => { // List of all v1AddressFormat values - const allAddressFormats = [ - "ADDRESS_FORMAT_ETHEREUM", - "ADDRESS_FORMAT_ETHEREUM", - "ADDRESS_FORMAT_ETHEREUM", - "ADDRESS_FORMAT_ETHEREUM", - "ADDRESS_FORMAT_ETHEREUM", - "ADDRESS_FORMAT_ETHEREUM", - "ADDRESS_FORMAT_ETHEREUM", - "ADDRESS_FORMAT_ETHEREUM", - "ADDRESS_FORMAT_ETHEREUM", - "ADDRESS_FORMAT_ETHEREUM", - "ADDRESS_FORMAT_ETHEREUM", - "ADDRESS_FORMAT_ETHEREUM", - "ADDRESS_FORMAT_ETHEREUM", - "ADDRESS_FORMAT_ETHEREUM", - "ADDRESS_FORMAT_ETHEREUM", - "ADDRESS_FORMAT_ETHEREUM", - "ADDRESS_FORMAT_ETHEREUM", - "ADDRESS_FORMAT_ETHEREUM", - "ADDRESS_FORMAT_ETHEREUM", - "ADDRESS_FORMAT_ETHEREUM", - "ADDRESS_FORMAT_ETHEREUM", - "ADDRESS_FORMAT_ETHEREUM", - "ADDRESS_FORMAT_ETHEREUM", - "ADDRESS_FORMAT_ETHEREUM", - "ADDRESS_FORMAT_ETHEREUM", - "ADDRESS_FORMAT_ETHEREUM", - "ADDRESS_FORMAT_ETHEREUM", - "ADDRESS_FORMAT_ETHEREUM", - "ADDRESS_FORMAT_ETHEREUM", - "ADDRESS_FORMAT_ETHEREUM", - "ADDRESS_FORMAT_ETHEREUM", - "ADDRESS_FORMAT_ETHEREUM", - "ADDRESS_FORMAT_ETHEREUM", - "ADDRESS_FORMAT_ETHEREUM", - "ADDRESS_FORMAT_ETHEREUM", - "ADDRESS_FORMAT_ETHEREUM", - "ADDRESS_FORMAT_ETHEREUM", - "ADDRESS_FORMAT_ETHEREUM", - "ADDRESS_FORMAT_ETHEREUM", - "ADDRESS_FORMAT_ETHEREUM", - "ADDRESS_FORMAT_ETHEREUM", - "ADDRESS_FORMAT_ETHEREUM", - "ADDRESS_FORMAT_ETHEREUM", - "ADDRESS_FORMAT_ETHEREUM", - "ADDRESS_FORMAT_ETHEREUM", - "ADDRESS_FORMAT_ETHEREUM", - "ADDRESS_FORMAT_ETHEREUM", - "ADDRESS_FORMAT_ETHEREUM", - "ADDRESS_FORMAT_ETHEREUM", - "ADDRESS_FORMAT_ETHEREUM", - "ADDRESS_FORMAT_ETHEREUM", + const allAddressFormats: v1AddressFormat[] = [ + "ADDRESS_FORMAT_ETHEREUM", + "ADDRESS_FORMAT_SOLANA", + "ADDRESS_FORMAT_APTOS", + "ADDRESS_FORMAT_BITCOIN_MAINNET_P2PKH", + "ADDRESS_FORMAT_XLM", + "ADDRESS_FORMAT_XRP", + "ADDRESS_FORMAT_TRON", ]; const res = await client?.createWallet({ @@ -311,14 +231,15 @@ export default function AuthPage() { /> - - handleGoogleLogin(response.idToken, response.publicKey) - } - layout="stacked" - client={client} - /> + + ) : null} + - ); -}; - -export default GoogleAuthButton; diff --git a/packages/react-wallet-kit/package.json b/packages/react-wallet-kit/package.json index bc7af0b18..b4b8e83e2 100644 --- a/packages/react-wallet-kit/package.json +++ b/packages/react-wallet-kit/package.json @@ -25,6 +25,7 @@ "@fortawesome/free-solid-svg-icons": "^6.7.2", "@fortawesome/react-fontawesome": "^0.2.2", "@headlessui/react": "^2.2.4", + "@noble/hashes": "^1.8.0", "@turnkey/sdk-js": "workspace:*", "@turnkey/sdk-types": "workspace:*" }, diff --git a/packages/react-wallet-kit/src/providers/TurnkeyProvider.tsx b/packages/react-wallet-kit/src/providers/TurnkeyProvider.tsx new file mode 100644 index 000000000..4837816ed --- /dev/null +++ b/packages/react-wallet-kit/src/providers/TurnkeyProvider.tsx @@ -0,0 +1,21 @@ +import { TurnkeySDKClientConfig } from "@turnkey/sdk-js"; +import { ClientProvider } from "./client/Provider"; +import { ModalProvider } from "./modal/Provider"; + +export interface TurnkeyProviderConfig extends TurnkeySDKClientConfig { + // TODO: Add anything else you need for the TurnkeyProvider +} + +export function TurnkeyProvider({ + children, + config, +}: { + children: React.ReactNode; + config: TurnkeyProviderConfig; +}) { + return ( + + {children} + + ); +} diff --git a/packages/react-wallet-kit/src/providers/client/Provider.tsx b/packages/react-wallet-kit/src/providers/client/Provider.tsx new file mode 100644 index 000000000..90401a573 --- /dev/null +++ b/packages/react-wallet-kit/src/providers/client/Provider.tsx @@ -0,0 +1,221 @@ +import { sha256 } from "@noble/hashes/sha2"; +import { bytesToHex } from "@noble/hashes/utils"; +import { GOOGLE_AUTH_URL, popupHeight, popupWidth } from "../../utils"; +import { TurnkeyClient, TurnkeySDKClientConfig } from "@turnkey/sdk-js"; +import { + createContext, + ReactNode, + useContext, + useEffect, + useState, +} from "react"; +import { TurnkeySDKClientBase } from "@turnkey/sdk-js/dist/__generated__/sdk-client-base"; +import { Session } from "@turnkey/sdk-types"; +import { ModalProvider, useModal } from "../modal/Provider"; +import { TurnkeyProviderConfig } from "../TurnkeyProvider"; + +interface ClientProviderProps { + children: ReactNode; + config: TurnkeyProviderConfig; +} + +export interface ClientContextType { + client: TurnkeyClient | undefined; + httpClient: TurnkeySDKClientBase | undefined; + session: Session | undefined; + handleGoogleOauth: (params: { + clientId: string; + onSuccess?: (response: { idToken: string; publicKey: string }) => void; + setLoading?: (loading: boolean) => void; + openInPage?: boolean; + }) => Promise; +} + +export const ClientContext = createContext({ + client: undefined, + httpClient: undefined, + session: undefined, + handleGoogleOauth: async () => { + throw new Error("handleGoogleOauth is not implemented"); + }, +}); + +export const useTurnkey = (): ClientContextType => { + const context = useContext(ClientContext); + if (!context) + throw new Error("useTurnkey must be used within ClientProvider"); + return context; +}; + +export const ClientProvider: React.FC = ({ + config, + children, +}) => { + const [client, setClient] = useState(undefined); + const [session, setSession] = useState(undefined); + + useEffect(() => { + const initializeClient = async () => { + const turnkeyClient = new TurnkeyClient({ + apiBaseUrl: config.apiBaseUrl, + authProxyUrl: config.authProxyUrl, + authProxyId: config.authProxyId, + organizationId: config.organizationId, + passkeyConfig: { + rpId: config.passkeyConfig?.rpId, + timeout: config.passkeyConfig?.timeout || 60000, // 60 seconds + userVerification: + config.passkeyConfig?.userVerification || "preferred", + allowCredentials: config.passkeyConfig?.allowCredentials || [], + }, + }); + + await turnkeyClient.init(); + setClient(turnkeyClient); + }; + + initializeClient(); + }, []); + + async function handleGoogleOauth(params: { + clientId: string; + onSuccess?: (response: { idToken: string; publicKey: string }) => void; + openInPage?: boolean; + }): Promise { + const { + clientId, + onSuccess = (response) => { + client?.handleOauthLoginOrSignup({ + oidcToken: response.idToken, + publicKey: response.publicKey, + }); + }, + openInPage, + } = params; + + const width = popupWidth; + const height = popupHeight; + const left = window.screenX + (window.innerWidth - width) / 2; + const top = window.screenY + (window.innerHeight - height) / 2; + + const flow = openInPage ? "redirect" : "popup"; + + const authWindow = window.open( + "about:blank", + "_blank", + `width=${width},height=${height},top=${top},left=${left},scrollbars=yes,resizable=yes`, + ); + + if (!authWindow) { + console.error("Failed to open Google login window."); + return; + } + + const publicKey = await client?.apiKeyStamper?.createKeyPair(); + if (!publicKey) return; + await client?.apiKeyStamper?.setPublicKeyOverride(publicKey); + + const nonce = bytesToHex(sha256(publicKey)); + const redirectURI = process.env.NEXT_PUBLIC_OAUTH_REDIRECT_URI!.replace( + /\/$/, + "", + ); + + const googleAuthUrl = new URL(GOOGLE_AUTH_URL); + googleAuthUrl.searchParams.set("client_id", clientId); + googleAuthUrl.searchParams.set("redirect_uri", redirectURI); + googleAuthUrl.searchParams.set("response_type", "id_token"); + googleAuthUrl.searchParams.set("scope", "openid email profile"); + googleAuthUrl.searchParams.set("nonce", nonce); + googleAuthUrl.searchParams.set("prompt", "select_account"); + googleAuthUrl.searchParams.set("state", `provider=google&flow=${flow}`); + + authWindow.location.href = googleAuthUrl.toString(); + + const interval = setInterval(() => { + try { + const url = authWindow.location.href || ""; + if (url.startsWith(window.location.origin)) { + const hashParams = new URLSearchParams(url.split("#")[1]); + const idToken = hashParams.get("id_token"); + if (idToken) { + authWindow.close(); + clearInterval(interval); + onSuccess({ idToken, publicKey }); + } + } + } catch { + // Ignore cross-origin errors + } + + if (authWindow.closed) { + clearInterval(interval); + } + }, 500); + } + + const { pushPage } = useModal(); + + useEffect(() => { + pushPage({ + key: "example-modal", + content: ( +
+

Example Modal

+

This is an example modal content.

+ +
+ ), + }); + }, []); + + return ( + + {children} + + ); +}; diff --git a/packages/react-wallet-kit/src/providers/index.ts b/packages/react-wallet-kit/src/providers/index.ts index 55f1d0416..d67d80cee 100644 --- a/packages/react-wallet-kit/src/providers/index.ts +++ b/packages/react-wallet-kit/src/providers/index.ts @@ -1,2 +1,3 @@ -export * from "./modal/Provider"; -export * from "./modal/Root"; +export { useModal } from "./modal/Provider"; +export { useTurnkey } from "./client/Provider"; +export * from "./TurnkeyProvider"; diff --git a/packages/react-wallet-kit/src/utils.ts b/packages/react-wallet-kit/src/utils.ts new file mode 100644 index 000000000..1b1702057 --- /dev/null +++ b/packages/react-wallet-kit/src/utils.ts @@ -0,0 +1,55 @@ +export const GOOGLE_AUTH_URL = "https://accounts.google.com/o/oauth2/v2/auth"; +export const APPLE_AUTH_URL = "https://appleid.apple.com/auth/authorize"; +export const APPLE_AUTH_SCRIPT_URL = + "https://appleid.cdn-apple.com/appleauth/static/jsapi/appleid/1/en_US/appleid.auth.js"; +export const FACEBOOK_AUTH_URL = "https://www.facebook.com/v11.0/dialog/oauth"; +export const FACEBOOK_GRAPH_URL = + "https://graph.facebook.com/v11.0/oauth/access_token"; +export const popupWidth = 500; +export const popupHeight = 600; + +export const authErrors = { + // Passkey-related errors + passkey: { + createFailed: "Passkey not created. Please try again.", + loginFailed: "Failed to login with passkey. Please try again.", + timeoutOrNotAllowed: + "The operation either timed out or was not allowed. Please try again.", + }, + + // OTP-related errors + otp: { + sendFailed: "Failed to send OTP", + invalidEmail: "Invalid email address.", + invalidPhone: "Invalid phone number.", + }, + + // OAuth-related errors + oauth: { + loginFailed: "Failed to login with OAuth provider", + }, + + // Wallet-related errors + wallet: { + loginFailed: "Failed to login with wallet", + noPublicKey: "No public key found", + }, + + // Sub-organization-related errors + suborg: { + fetchFailed: "Failed to fetch account", + createFailed: "Failed to create account.", + }, +}; + +export enum OtpType { + Email = "OTP_TYPE_EMAIL", + Sms = "OTP_TYPE_SMS", +} + +export enum FilterType { + Email = "EMAIL", + PhoneNumber = "PHONE_NUMBER", + OidcToken = "OIDC_TOKEN", + PublicKey = "PUBLIC_KEY", +} diff --git a/packages/sdk-js/src/__clients__/core.ts b/packages/sdk-js/src/__clients__/core.ts index 0d28e446b..1873016c8 100644 --- a/packages/sdk-js/src/__clients__/core.ts +++ b/packages/sdk-js/src/__clients__/core.ts @@ -5,6 +5,7 @@ import { GetWalletAccountsResponse, SessionType, SignTransactionResponse, + StampLoginResponse, v1AddressFormat, v1Attestation, v1AuthenticatorParamsV2, @@ -169,7 +170,6 @@ export class TurnkeyClient { loginWithPasskey = async (params: { sessionType?: SessionType; - expirationSeconds?: string | undefined; publicKey?: string; sessionKey?: string | undefined; }): Promise => { @@ -179,7 +179,6 @@ export class TurnkeyClient { const { sessionType = SessionType.READ_WRITE, publicKey = generatedKeyPair, - expirationSeconds = DEFAULT_SESSION_EXPIRATION_IN_SECONDS, sessionKey = SessionKey.DefaultSessionkey, } = params; @@ -188,10 +187,10 @@ export class TurnkeyClient { const readOnlySessionResult = await this.httpClient.createReadOnlySession({}, StamperType.Passkey); - await this.storageManager.storeSession( - readOnlySessionResult.session, + await this.storeSession({ + sessionToken: readOnlySessionResult.session, sessionKey, - ); + }); // Key pair was successfully used, set to null to prevent cleanup generatedKeyPair = null; @@ -205,24 +204,15 @@ export class TurnkeyClient { const sessionResponse = await this.httpClient.stampLogin( { publicKey, - expirationSeconds, organizationId: this.config.organizationId, }, StamperType.Passkey, ); - // TODO (Amir): This should be done in a helper or something. It's very strange that we have to delete the key pair here - const sessionToReplace = - await this.storageManager.getSession(sessionKey); - if (sessionToReplace) { - console.log(sessionToReplace.token); - await this.apiKeyStamper?.deleteKeyPair(sessionToReplace.token); - } - - await this.storageManager.storeSession( - sessionResponse.session, + await this.storeSession({ + sessionToken: sessionResponse.session, sessionKey, - ); + }); // Key pair was successfully used, set to null to prevent cleanup generatedKeyPair = null; } else { @@ -247,14 +237,13 @@ export class TurnkeyClient { signUpWithPasskey = async (params: { createSubOrgParams?: CreateSubOrgParams; sessionType?: SessionType; - sessionExpirationSeconds?: string | undefined; sessionKey?: string | undefined; passkeyDisplayName?: string; }): Promise => { const { createSubOrgParams, passkeyDisplayName, - sessionExpirationSeconds, + sessionType = SessionType.READ_WRITE, sessionKey, } = params; @@ -333,23 +322,15 @@ export class TurnkeyClient { const sessionResponse = await this.httpClient.stampLogin({ publicKey: newGeneratedKeyPair!, - ...(sessionExpirationSeconds && { - expirationSeconds: sessionExpirationSeconds, - }), organizationId: this.config.organizationId, }); await this.apiKeyStamper?.deleteKeyPair(generatedKeyPair!); - const sessionToReplace = await this.storageManager.getSession(sessionKey); - if (sessionToReplace) { - await this.apiKeyStamper?.deleteKeyPair(sessionToReplace.token); - } - - await this.storageManager.storeSession( - sessionResponse.session, + await this.storeSession({ + sessionToken: sessionResponse.session, sessionKey, - ); + }); generatedKeyPair = null; // Key pair was successfully used, set to null to prevent cleanup } catch (error) { @@ -467,6 +448,7 @@ export class TurnkeyClient { verificationToken: string; publicKey?: string; invalidateExisting?: boolean; + sessionType?: SessionType; sessionKey?: string | undefined; }): Promise => { const { @@ -474,6 +456,7 @@ export class TurnkeyClient { invalidateExisting = false, publicKey = await this.apiKeyStamper?.createKeyPair(), sessionKey = SessionKey.DefaultSessionkey, + sessionType = SessionType.READ_WRITE, } = params; const headers: Record = { @@ -504,12 +487,10 @@ export class TurnkeyClient { throw new Error("No session returned from OTP login"); } - const sessionToReplace = await this.storageManager.getSession(sessionKey); - if (sessionToReplace) { - await this.apiKeyStamper?.deleteKeyPair(sessionToReplace.token); - } - // // Store the session in the storage manager - await this.storageManager.storeSession(loginRes.session, sessionKey); + await this.storeSession({ + sessionToken: loginRes.session, + sessionKey, + }); return loginRes.session; } catch (error) { @@ -534,10 +515,16 @@ export class TurnkeyClient { otpType: OtpType; createSubOrgParams?: CreateSubOrgParams; sessionType?: SessionType; - sessionExpirationSeconds?: string | undefined; sessionKey?: string | undefined; }): Promise => { - const { verificationToken, createSubOrgParams, contact, otpType } = params; + const { + verificationToken, + contact, + otpType, + createSubOrgParams, + sessionType = SessionType.READ_WRITE, + sessionKey = SessionKey.DefaultSessionkey, + } = params; const signUpBody = { userName: @@ -576,6 +563,8 @@ export class TurnkeyClient { await this.loginWithOtp({ verificationToken, publicKey: generatedKeyPair!, + sessionKey, + sessionType, }); } catch (error) { throw new Error(`Failed to sign up with OTP: ${error}`); @@ -593,12 +582,13 @@ export class TurnkeyClient { } }; - handleOauthLogin = async (params: { + handleOauthLoginOrSignup = async (params: { oidcToken: string; publicKey: string; createSubOrgParams?: CreateSubOrgParams | undefined; }): Promise => { const { oidcToken, publicKey, createSubOrgParams } = params; + console.log("Handling Google OAuth login or signup..."); const headers: Record = { "Content-Type": "application/json", @@ -697,12 +687,10 @@ export class TurnkeyClient { throw new Error("No session returned from oauth login"); } - const sessionToReplace = await this.storageManager.getSession(sessionKey); - if (sessionToReplace) { - await this.apiKeyStamper?.deleteKeyPair(sessionToReplace.token); - } - // // Store the session in the storage manager - await this.storageManager.storeSession(loginRes.session, sessionKey); + await this.storeSession({ + sessionToken: loginRes.session, + sessionKey, + }); return loginRes.session; } catch (error) { @@ -727,7 +715,6 @@ export class TurnkeyClient { providerName: string; createSubOrgParams?: CreateSubOrgParams; sessionType?: SessionType; - sessionExpirationSeconds?: string | undefined; sessionKey?: string | undefined; }): Promise => { const { oidcToken, publicKey, providerName, createSubOrgParams } = params; @@ -1181,6 +1168,111 @@ export class TurnkeyClient { } }; + storeSession = async (params: { + sessionToken: string; + sessionKey?: string | undefined; + }): Promise => { + const { sessionToken, sessionKey = SessionKey.DefaultSessionkey } = params; + if (!sessionToken) { + throw new Error("Session token must be provided to create a session"); + } + + try { + // TODO (Amir): This should be done in a helper or something. It's very strange that we have to delete the key pair here + const sessionToReplace = await this.storageManager.getSession(sessionKey); + if (sessionToReplace) { + console.log(sessionToReplace.token); + await this.apiKeyStamper?.deleteKeyPair(sessionToReplace.token); + } + + await this.storageManager.storeSession(sessionToken, sessionKey); + } catch (error) { + throw new Error(`Failed to create session: ${error}`); + } + }; + + clearSession = async (params: { + sessionKey?: string | undefined; + }): Promise => { + const { sessionKey = SessionKey.DefaultSessionkey } = params; + try { + const session = await this.storageManager.getSession(sessionKey); + if (session) { + await this.apiKeyStamper?.deleteKeyPair(session.token); + await this.storageManager.clearSession(sessionKey); + } else { + throw new Error(`No session found with key: ${sessionKey}`); + } + } catch (error) { + throw new Error(`Failed to delete session: ${error}`); + } + }; + + clearAllSessions = async (): Promise => { + const sessionKeys = await this.storageManager.listSessionKeys(); + if (sessionKeys.length === 0) { + throw new Error("No sessions found to clear."); + } + for (const sessionKey of sessionKeys) { + this.clearSession({ sessionKey }); + } + }; + + refreshSession = async (params: { + sessionType?: SessionType; + expirationSeconds?: string | undefined; + publicKey?: string; + sessionKey?: string | undefined; + invalidateExisitng?: boolean; + }): Promise => { + const { + sessionKey = await this.storageManager.getActiveSessionKey(), + expirationSeconds = DEFAULT_SESSION_EXPIRATION_IN_SECONDS, + publicKey, + sessionType = SessionType.READ_WRITE, + invalidateExisitng = false, + } = params; + + try { + switch (sessionType) { + case SessionType.READ_ONLY: { + // IMPLEMENT + } + case SessionType.READ_WRITE: { + let keyPair = publicKey; + + if (!publicKey) { + keyPair = await this.apiKeyStamper?.createKeyPair(); + } + + if (!keyPair) { + throw new Error("Failed to create new key pair."); + } + + const res = await this.httpClient.stampLogin({ + publicKey: keyPair!, + expirationSeconds, + invalidateExisting: invalidateExisitng, + }); + + await this.storeSession({ + sessionToken: res.session, + sessionKey, + }); + + return res; + } + default: { + throw new Error( + "Invalid session type passed. Use SessionType.READ_WRITE or SessionType.READ_ONLY.", + ); + } + } + } catch (error) { + throw new Error(`Failed to refresh session: ${error}`); + } + }; + setActiveSession = async (params: { sessionKey: string }): Promise => { const { sessionKey } = params; await this.storageManager.setActiveSessionKey(sessionKey); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b9a32e7db..d6026fb58 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2129,6 +2129,9 @@ importers: '@headlessui/react': specifier: ^2.2.4 version: 2.2.4(react-dom@18.3.1)(react@18.3.1) + '@noble/hashes': + specifier: ^1.8.0 + version: 1.8.0 '@turnkey/sdk-js': specifier: workspace:* version: link:../sdk-js @@ -3410,8 +3413,22 @@ packages: '@cosmjs/amino@0.33.1': resolution: {integrity: sha512-WfWiBf2EbIWpwKG9AOcsIIkR717SY+JdlXM/SL/bI66BdrhniAF+/ZNis9Vo9HF6lP2UU5XrSmFA4snAvEgdrg==} +<<<<<<< HEAD '@cosmjs/crypto@0.33.1': resolution: {integrity: sha512-U4kGIj/SNBzlb2FGgA0sMR0MapVgJUg8N+oIAiN5+vl4GZ3aefmoL1RDyTrFS/7HrB+M+MtHsxC0tvEu4ic/zA==} +======= + /@cosmjs/crypto@0.33.0: + resolution: {integrity: sha512-kkt06t+cFW2XRGDGUZ0cVf5yoQ2OhZnubwbYbz3QXdyhf1qOXYVPRThfFPsko7dssr+e8Yy4OJKlh5SLA8DXTQ==} + dependencies: + '@cosmjs/encoding': 0.33.0 + '@cosmjs/math': 0.33.0 + '@cosmjs/utils': 0.33.0 + '@noble/hashes': 1.8.0 + bn.js: 5.2.1 + elliptic: 6.6.1 + libsodium-wrappers-sumo: 0.7.11 + dev: false +>>>>>>> 09fd3a9c (added react providers to react-wallet-kit) '@cosmjs/encoding@0.33.1': resolution: {integrity: sha512-nuNxf29fUcQE14+1p//VVQDwd1iau5lhaW/7uMz7V2AH3GJbFJoJVaKvVyZvdFk+Cnu+s3wCqgq4gJkhRCJfKw==} @@ -4575,7 +4592,26 @@ packages: '@mysten/sui.js@0.37.1': resolution: {integrity: sha512-nEOqnjUqb/VJcVk23LgZOX1FmBib/mBCwAWaJhtsCHLwv2jIAfCPY/fpB9lJ62QHrM8UFclpWxsLkqcUkKyPgA==} engines: {node: '>=16'} +<<<<<<< HEAD deprecated: This package has been renamed to @mysten/sui, please update to use the renamed package. +======= + dependencies: + '@mysten/bcs': 0.7.3 + '@noble/curves': 1.4.0 + '@noble/hashes': 1.8.0 + '@open-rpc/client-js': 1.8.1 + '@scure/bip32': 1.4.0 + '@scure/bip39': 1.3.0 + '@suchipi/femver': 1.0.0 + events: 3.3.0 + superstruct: 1.0.4 + tweetnacl: 1.0.3 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + dev: false +>>>>>>> 09fd3a9c (added react providers to react-wallet-kit) '@napi-rs/wasm-runtime@0.2.10': resolution: {integrity: sha512-bCsCyeZEwVErsGmyPNSzwfwFn4OdxBj0mmv6hOFucB/k81Ojdu68RbZdxYsRQUPc9l6SU5F/cG+bXgWs3oUgsQ==} @@ -4752,6 +4788,7 @@ packages: '@noble/hashes@1.4.0': resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==} engines: {node: '>= 16'} + dev: false '@noble/hashes@1.5.0': resolution: {integrity: sha512-1j6kQFb7QRru7eKN3ZDvRcP13rugwdxZqCjbiAVZfIJwgj2A65UmT4TgARXGlXgnRkORLTDTrO19ZErt7+QXgA==} @@ -6407,7 +6444,7 @@ packages: /@safe-global/protocol-kit@3.0.1(typescript@5.4.3): resolution: {integrity: sha512-7S2QCvIDw3NsErF0f8tIfiTBz32btCAkw7IYuQFPc+G7clLrvDNhDaZYSoDsa8F0EoEhn+605VA7XP//iL6AIg==} dependencies: - '@noble/hashes': 1.4.0 + '@noble/hashes': 1.8.0 '@safe-global/safe-deployments': 1.34.0 ethereumjs-util: 7.1.5 ethers: 6.13.5 @@ -7196,7 +7233,34 @@ packages: '@solana/web3.js@1.98.2': resolution: {integrity: sha512-BqVwEG+TaG2yCkBMbD3C4hdpustR4FpuUFRPUmqRZYYlPI9Hg4XMWxHWOWRzHE9Lkc9NDjzXFX7lDXSgzC7R1A==} +<<<<<<< HEAD '@solflare-wallet/metamask-sdk@1.0.3': +======= + /@solana/web3.js@1.95.8(encoding@0.1.13): + resolution: {integrity: sha512-sBHzNh7dHMrmNS5xPD1d0Xa2QffW/RXaxu/OysRXBfwTp+LYqGGmMtCYYwrHPrN5rjAmJCsQRNAwv4FM0t3B6g==} + dependencies: + '@babel/runtime': 7.26.0 + '@noble/curves': 1.6.0 + '@noble/hashes': 1.8.0 + '@solana/buffer-layout': 4.0.1 + agentkeepalive: 4.5.0 + bigint-buffer: 1.1.5 + bn.js: 5.2.1 + borsh: 0.7.0 + bs58: 4.0.1 + buffer: 6.0.3 + fast-stable-stringify: 1.0.0 + jayson: 4.1.1 + node-fetch: 2.7.0(encoding@0.1.13) + rpc-websockets: 9.0.2 + superstruct: 2.0.2 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + + /@solflare-wallet/metamask-sdk@1.0.3(@solana/web3.js@1.95.8): +>>>>>>> 09fd3a9c (added react providers to react-wallet-kit) resolution: {integrity: sha512-os5Px5PTMYKGS5tzOoyjDxtOtj0jZKnbI1Uwt8+Jsw1HHIA+Ib2UACCGNhQ/un2f8sIbTfLD1WuucNMOy8KZpQ==} peerDependencies: '@solana/web3.js': '*' @@ -8703,9 +8767,24 @@ packages: bip32@4.0.0: resolution: {integrity: sha512-aOGy88DDlVUhspIXJN+dVEtclhIsfAUppD43V0j40cPTld3pv/0X/MlrZSZ6jowIaQQzFwP8M6rFU2z2mVYjDQ==} engines: {node: '>=6.0.0'} +<<<<<<< HEAD +======= + dependencies: + '@noble/hashes': 1.8.0 + '@scure/base': 1.1.7 + typeforce: 1.18.0 + wif: 2.0.6 + dev: false +>>>>>>> 09fd3a9c (added react providers to react-wallet-kit) bip39@3.1.0: resolution: {integrity: sha512-c9kiwdk45Do5GL0vJMe7tS95VjCii65mYAH7DfWl3uW8AVzXKQVUm64i3hzVybBDMp9r7j9iNxR85+ul8MdN/A==} +<<<<<<< HEAD +======= + dependencies: + '@noble/hashes': 1.8.0 + dev: false +>>>>>>> 09fd3a9c (added react providers to react-wallet-kit) bip66@2.0.0: resolution: {integrity: sha512-kBG+hSpgvZBrkIm9dt5T1Hd/7xGCPEX2npoxAWZfsK1FvjgaxySEh2WizjyIstWXriKo9K9uJ4u0OnsyLDUPXQ==} @@ -8720,6 +8799,17 @@ packages: bitcoinjs-lib@6.1.7: resolution: {integrity: sha512-tlf/r2DGMbF7ky1MgUqXHzypYHakkEnm0SZP23CJKIqNY/5uNAnMbFhMJdhjrL/7anfb/U8+AlpdjPWjPnAalg==} engines: {node: '>=8.0.0'} +<<<<<<< HEAD +======= + dependencies: + '@noble/hashes': 1.8.0 + bech32: 2.0.0 + bip174: 2.1.1 + bs58check: 3.0.1 + typeforce: 1.18.0 + varuint-bitcoin: 1.1.2 + dev: false +>>>>>>> 09fd3a9c (added react providers to react-wallet-kit) blake-hash@2.0.0: resolution: {integrity: sha512-Igj8YowDu1PRkRsxZA7NVkdFNxH5rKv5cpLxQ0CVXSIA77pVYwCPRQJ2sMew/oneUpfuYRyjG6r8SmmmnbZb1w==} @@ -8820,6 +8910,13 @@ packages: bs58check@4.0.0: resolution: {integrity: sha512-FsGDOnFg9aVI9erdriULkd/JjEWONV/lQE5aYziB5PoBsXRind56lh8doIZIc9X4HoxT5x4bLjMWN1/NB8Zp5g==} +<<<<<<< HEAD +======= + dependencies: + '@noble/hashes': 1.8.0 + bs58: 6.0.0 + dev: false +>>>>>>> 09fd3a9c (added react providers to react-wallet-kit) bser@2.1.1: resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} @@ -9906,7 +10003,7 @@ packages: eslint-import-resolver-webpack: optional: true dependencies: - '@typescript-eslint/parser': 5.62.0(eslint@8.56.0)(typescript@5.1.3) + '@typescript-eslint/parser': 5.62.0(eslint@8.56.0)(typescript@5.4.3) debug: 3.2.7 eslint: 8.56.0 eslint-import-resolver-node: 0.3.9 From c330aba0b6cb163ee44193c00407a537c6442d3b Mon Sep 17 00:00:00 2001 From: Ethan Konkolowicz Date: Fri, 27 Jun 2025 10:07:24 -0400 Subject: [PATCH 031/184] fixed sdk-type type generation to match sdk-server and sdk-browser --- packages/sdk-js/scripts/codegen.js | 4 +- packages/sdk-js/src/__clients__/core.ts | 78 +- .../src/__generated__/sdk-client-base.ts | 504 +++--- packages/sdk-types/scripts/codegen.js | 21 +- packages/sdk-types/src/__generated__/types.ts | 1407 ++++++++++------- 5 files changed, 1123 insertions(+), 891 deletions(-) diff --git a/packages/sdk-js/scripts/codegen.js b/packages/sdk-js/scripts/codegen.js index bb0bf1772..2f61a3799 100644 --- a/packages/sdk-js/scripts/codegen.js +++ b/packages/sdk-js/scripts/codegen.js @@ -446,8 +446,8 @@ const generateSDKClientFromSwagger = async (swaggerSpec, targetPath) => { }`; const methodType = methodTypeFromMethodName(methodName); - const inputType = `${operationNameWithoutNamespace}Request`; - const responseType = `${operationNameWithoutNamespace}Response`; + const inputType = `T${operationNameWithoutNamespace}Body`; + const responseType = `T${operationNameWithoutNamespace}Response`; // For query methods if (methodType === "query") { diff --git a/packages/sdk-js/src/__clients__/core.ts b/packages/sdk-js/src/__clients__/core.ts index 1873016c8..9fd603ad3 100644 --- a/packages/sdk-js/src/__clients__/core.ts +++ b/packages/sdk-js/src/__clients__/core.ts @@ -1,11 +1,12 @@ import { TurnkeySDKClientBase } from "../__generated__/sdk-client-base"; import { - CreateSubOrganizationResponse, - DeleteSubOrganizationResponse, - GetWalletAccountsResponse, + TCreateSubOrganizationResponse, + TDeleteSubOrganizationResponse, + TGetWalletAccountsResponse, + Session, SessionType, - SignTransactionResponse, - StampLoginResponse, + TSignTransactionResponse, + TStampLoginResponse, v1AddressFormat, v1Attestation, v1AuthenticatorParamsV2, @@ -585,10 +586,17 @@ export class TurnkeyClient { handleOauthLoginOrSignup = async (params: { oidcToken: string; publicKey: string; + sessionKey?: string | undefined; + invalidateExisting?: boolean; createSubOrgParams?: CreateSubOrgParams | undefined; }): Promise => { - const { oidcToken, publicKey, createSubOrgParams } = params; - console.log("Handling Google OAuth login or signup..."); + const { + oidcToken, + publicKey, + createSubOrgParams, + sessionKey = SessionKey.DefaultSessionkey, + invalidateExisting = false, + } = params; const headers: Record = { "Content-Type": "application/json", @@ -622,8 +630,8 @@ export class TurnkeyClient { return this.loginWithOauth({ oidcToken, publicKey, - invalidateExisting: true, - sessionKey: SessionKey.DefaultSessionkey, + invalidateExisting, + sessionKey, }); } else { return this.signUpWithOauth({ @@ -695,7 +703,6 @@ export class TurnkeyClient { return loginRes.session; } catch (error) { // Clean up the generated key pair if it wasn't successfully used - console.log("Cleaning up generated key pair if any"); if (publicKey) { try { await this.apiKeyStamper?.deleteKeyPair(publicKey); @@ -806,7 +813,7 @@ export class TurnkeyClient { walletId: string; stamperType?: StamperType; paginationOptions?: v1Pagination; - }): Promise => { + }): Promise => { const { walletId, stamperType, paginationOptions } = params; const session = await this.storageManager.getActiveSession(); if (!session) { @@ -872,7 +879,7 @@ export class TurnkeyClient { unsignedTransaction: string; type: v1TransactionType; stampWith?: StamperType; - }): Promise => { + }): Promise => { const { signWith, unsignedTransaction, type, stampWith } = params; if (!signWith) { @@ -1082,7 +1089,7 @@ export class TurnkeyClient { deleteSubOrganization = async (params: { deleteWithoutExport?: boolean; stamperWith?: StamperType; - }): Promise => { + }): Promise => { const { deleteWithoutExport = false, stamperWith } = params; const session = await this.storageManager.getActiveSession(); if (!session) { @@ -1113,7 +1120,7 @@ export class TurnkeyClient { type: WalletType; } | undefined; - }): Promise => { + }): Promise => { const { oauthProviders, passkey, @@ -1162,7 +1169,7 @@ export class TurnkeyClient { if (!response.subOrganizationId) { throw new Error("Expected a non-null subOrganizationId in response"); } - return response as CreateSubOrganizationResponse; + return response as TCreateSubOrganizationResponse; } catch (error) { throw new Error(`Failed to create sub-organization: ${error}`); } @@ -1188,6 +1195,8 @@ export class TurnkeyClient { await this.storageManager.storeSession(sessionToken, sessionKey); } catch (error) { throw new Error(`Failed to create session: ${error}`); + } finally { + await this.clearUnusedKeyPairs(); } }; @@ -1224,7 +1233,7 @@ export class TurnkeyClient { publicKey?: string; sessionKey?: string | undefined; invalidateExisitng?: boolean; - }): Promise => { + }): Promise => { const { sessionKey = await this.storageManager.getActiveSessionKey(), expirationSeconds = DEFAULT_SESSION_EXPIRATION_IN_SECONDS, @@ -1273,10 +1282,43 @@ export class TurnkeyClient { } }; + getSession = async (params: { + sessionKey?: string | undefined; + }): Promise => { + const { sessionKey = await this.storageManager.getActiveSessionKey() } = + params; + return this.storageManager.getSession(sessionKey); + }; + setActiveSession = async (params: { sessionKey: string }): Promise => { const { sessionKey } = params; await this.storageManager.setActiveSessionKey(sessionKey); }; -} -// TO IMPLEMENT: fetchUser + clearUnusedKeyPairs = async (): Promise => { + const publicKeys = await this.apiKeyStamper?.listKeyPairs(); + if (!publicKeys || publicKeys.length === 0) { + return; + } + const sessionKeys = await this.storageManager?.listSessionKeys(); + + const sessionTokensMap: Record = {}; + for (const sessionKey of sessionKeys) { + const session = await this.storageManager.getSession(sessionKey); + if (session) { + sessionTokensMap[session.token] = sessionKey; + } + } + for (const publicKey of publicKeys) { + if (!sessionTokensMap[publicKey]) { + try { + await this.apiKeyStamper?.deleteKeyPair(publicKey); + } catch (error) { + console.error( + `Failed to delete unused key pair ${publicKey}: ${error}`, + ); + } + } + } + }; +} diff --git a/packages/sdk-js/src/__generated__/sdk-client-base.ts b/packages/sdk-js/src/__generated__/sdk-client-base.ts index 343b8b8a5..d83aff838 100644 --- a/packages/sdk-js/src/__generated__/sdk-client-base.ts +++ b/packages/sdk-js/src/__generated__/sdk-client-base.ts @@ -198,9 +198,9 @@ export class TurnkeySDKClientBase { } getActivity = async ( - input: SdkTypes.GetActivityRequest, + input: SdkTypes.TGetActivityBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -217,7 +217,7 @@ export class TurnkeySDKClientBase { }; stampGetActivity = async ( - input: SdkTypes.GetActivityRequest, + input: SdkTypes.TGetActivityBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -236,9 +236,9 @@ export class TurnkeySDKClientBase { }; getApiKey = async ( - input: SdkTypes.GetApiKeyRequest, + input: SdkTypes.TGetApiKeyBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -255,7 +255,7 @@ export class TurnkeySDKClientBase { }; stampGetApiKey = async ( - input: SdkTypes.GetApiKeyRequest, + input: SdkTypes.TGetApiKeyBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -274,9 +274,9 @@ export class TurnkeySDKClientBase { }; getApiKeys = async ( - input: SdkTypes.GetApiKeysRequest = {}, + input: SdkTypes.TGetApiKeysBody = {}, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -293,7 +293,7 @@ export class TurnkeySDKClientBase { }; stampGetApiKeys = async ( - input: SdkTypes.GetApiKeysRequest, + input: SdkTypes.TGetApiKeysBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -312,9 +312,9 @@ export class TurnkeySDKClientBase { }; getAttestationDocument = async ( - input: SdkTypes.GetAttestationDocumentRequest, + input: SdkTypes.TGetAttestationDocumentBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -331,7 +331,7 @@ export class TurnkeySDKClientBase { }; stampGetAttestationDocument = async ( - input: SdkTypes.GetAttestationDocumentRequest, + input: SdkTypes.TGetAttestationDocumentBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -350,9 +350,9 @@ export class TurnkeySDKClientBase { }; getAuthenticator = async ( - input: SdkTypes.GetAuthenticatorRequest, + input: SdkTypes.TGetAuthenticatorBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -369,7 +369,7 @@ export class TurnkeySDKClientBase { }; stampGetAuthenticator = async ( - input: SdkTypes.GetAuthenticatorRequest, + input: SdkTypes.TGetAuthenticatorBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -389,9 +389,9 @@ export class TurnkeySDKClientBase { }; getAuthenticators = async ( - input: SdkTypes.GetAuthenticatorsRequest, + input: SdkTypes.TGetAuthenticatorsBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -408,7 +408,7 @@ export class TurnkeySDKClientBase { }; stampGetAuthenticators = async ( - input: SdkTypes.GetAuthenticatorsRequest, + input: SdkTypes.TGetAuthenticatorsBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -428,9 +428,9 @@ export class TurnkeySDKClientBase { }; getOauthProviders = async ( - input: SdkTypes.GetOauthProvidersRequest, + input: SdkTypes.TGetOauthProvidersBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -447,7 +447,7 @@ export class TurnkeySDKClientBase { }; stampGetOauthProviders = async ( - input: SdkTypes.GetOauthProvidersRequest, + input: SdkTypes.TGetOauthProvidersBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -467,9 +467,9 @@ export class TurnkeySDKClientBase { }; getOrganization = async ( - input: SdkTypes.GetOrganizationRequest = {}, + input: SdkTypes.TGetOrganizationBody = {}, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -486,7 +486,7 @@ export class TurnkeySDKClientBase { }; stampGetOrganization = async ( - input: SdkTypes.GetOrganizationRequest, + input: SdkTypes.TGetOrganizationBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -506,9 +506,9 @@ export class TurnkeySDKClientBase { }; getOrganizationConfigs = async ( - input: SdkTypes.GetOrganizationConfigsRequest, + input: SdkTypes.TGetOrganizationConfigsBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -525,7 +525,7 @@ export class TurnkeySDKClientBase { }; stampGetOrganizationConfigs = async ( - input: SdkTypes.GetOrganizationConfigsRequest, + input: SdkTypes.TGetOrganizationConfigsBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -545,9 +545,9 @@ export class TurnkeySDKClientBase { }; getPolicy = async ( - input: SdkTypes.GetPolicyRequest, + input: SdkTypes.TGetPolicyBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -564,7 +564,7 @@ export class TurnkeySDKClientBase { }; stampGetPolicy = async ( - input: SdkTypes.GetPolicyRequest, + input: SdkTypes.TGetPolicyBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -583,9 +583,9 @@ export class TurnkeySDKClientBase { }; getPrivateKey = async ( - input: SdkTypes.GetPrivateKeyRequest, + input: SdkTypes.TGetPrivateKeyBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -602,7 +602,7 @@ export class TurnkeySDKClientBase { }; stampGetPrivateKey = async ( - input: SdkTypes.GetPrivateKeyRequest, + input: SdkTypes.TGetPrivateKeyBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -621,9 +621,9 @@ export class TurnkeySDKClientBase { }; getUser = async ( - input: SdkTypes.GetUserRequest, + input: SdkTypes.TGetUserBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -640,7 +640,7 @@ export class TurnkeySDKClientBase { }; stampGetUser = async ( - input: SdkTypes.GetUserRequest, + input: SdkTypes.TGetUserBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -659,9 +659,9 @@ export class TurnkeySDKClientBase { }; getWallet = async ( - input: SdkTypes.GetWalletRequest, + input: SdkTypes.TGetWalletBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -678,7 +678,7 @@ export class TurnkeySDKClientBase { }; stampGetWallet = async ( - input: SdkTypes.GetWalletRequest, + input: SdkTypes.TGetWalletBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -697,9 +697,9 @@ export class TurnkeySDKClientBase { }; getWalletAccount = async ( - input: SdkTypes.GetWalletAccountRequest, + input: SdkTypes.TGetWalletAccountBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -716,7 +716,7 @@ export class TurnkeySDKClientBase { }; stampGetWalletAccount = async ( - input: SdkTypes.GetWalletAccountRequest, + input: SdkTypes.TGetWalletAccountBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -736,9 +736,9 @@ export class TurnkeySDKClientBase { }; getActivities = async ( - input: SdkTypes.GetActivitiesRequest = {}, + input: SdkTypes.TGetActivitiesBody = {}, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -755,7 +755,7 @@ export class TurnkeySDKClientBase { }; stampGetActivities = async ( - input: SdkTypes.GetActivitiesRequest, + input: SdkTypes.TGetActivitiesBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -774,9 +774,9 @@ export class TurnkeySDKClientBase { }; getPolicies = async ( - input: SdkTypes.GetPoliciesRequest = {}, + input: SdkTypes.TGetPoliciesBody = {}, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -793,7 +793,7 @@ export class TurnkeySDKClientBase { }; stampGetPolicies = async ( - input: SdkTypes.GetPoliciesRequest, + input: SdkTypes.TGetPoliciesBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -812,9 +812,9 @@ export class TurnkeySDKClientBase { }; listPrivateKeyTags = async ( - input: SdkTypes.ListPrivateKeyTagsRequest, + input: SdkTypes.TListPrivateKeyTagsBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -831,7 +831,7 @@ export class TurnkeySDKClientBase { }; stampListPrivateKeyTags = async ( - input: SdkTypes.ListPrivateKeyTagsRequest, + input: SdkTypes.TListPrivateKeyTagsBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -851,9 +851,9 @@ export class TurnkeySDKClientBase { }; getPrivateKeys = async ( - input: SdkTypes.GetPrivateKeysRequest = {}, + input: SdkTypes.TGetPrivateKeysBody = {}, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -870,7 +870,7 @@ export class TurnkeySDKClientBase { }; stampGetPrivateKeys = async ( - input: SdkTypes.GetPrivateKeysRequest, + input: SdkTypes.TGetPrivateKeysBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -890,9 +890,9 @@ export class TurnkeySDKClientBase { }; getSubOrgIds = async ( - input: SdkTypes.GetSubOrgIdsRequest = {}, + input: SdkTypes.TGetSubOrgIdsBody = {}, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -909,7 +909,7 @@ export class TurnkeySDKClientBase { }; stampGetSubOrgIds = async ( - input: SdkTypes.GetSubOrgIdsRequest, + input: SdkTypes.TGetSubOrgIdsBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -928,9 +928,9 @@ export class TurnkeySDKClientBase { }; listUserTags = async ( - input: SdkTypes.ListUserTagsRequest = {}, + input: SdkTypes.TListUserTagsBody = {}, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -947,7 +947,7 @@ export class TurnkeySDKClientBase { }; stampListUserTags = async ( - input: SdkTypes.ListUserTagsRequest, + input: SdkTypes.TListUserTagsBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -966,9 +966,9 @@ export class TurnkeySDKClientBase { }; getUsers = async ( - input: SdkTypes.GetUsersRequest = {}, + input: SdkTypes.TGetUsersBody = {}, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -985,7 +985,7 @@ export class TurnkeySDKClientBase { }; stampGetUsers = async ( - input: SdkTypes.GetUsersRequest, + input: SdkTypes.TGetUsersBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -1004,9 +1004,9 @@ export class TurnkeySDKClientBase { }; getVerifiedSubOrgIds = async ( - input: SdkTypes.GetVerifiedSubOrgIdsRequest, + input: SdkTypes.TGetVerifiedSubOrgIdsBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -1023,7 +1023,7 @@ export class TurnkeySDKClientBase { }; stampGetVerifiedSubOrgIds = async ( - input: SdkTypes.GetVerifiedSubOrgIdsRequest, + input: SdkTypes.TGetVerifiedSubOrgIdsBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -1043,9 +1043,9 @@ export class TurnkeySDKClientBase { }; getWalletAccounts = async ( - input: SdkTypes.GetWalletAccountsRequest, + input: SdkTypes.TGetWalletAccountsBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -1062,7 +1062,7 @@ export class TurnkeySDKClientBase { }; stampGetWalletAccounts = async ( - input: SdkTypes.GetWalletAccountsRequest, + input: SdkTypes.TGetWalletAccountsBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -1082,9 +1082,9 @@ export class TurnkeySDKClientBase { }; getWallets = async ( - input: SdkTypes.GetWalletsRequest = {}, + input: SdkTypes.TGetWalletsBody = {}, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -1101,7 +1101,7 @@ export class TurnkeySDKClientBase { }; stampGetWallets = async ( - input: SdkTypes.GetWalletsRequest, + input: SdkTypes.TGetWalletsBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -1120,9 +1120,9 @@ export class TurnkeySDKClientBase { }; getWhoami = async ( - input: SdkTypes.GetWhoamiRequest = {}, + input: SdkTypes.TGetWhoamiBody = {}, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -1139,7 +1139,7 @@ export class TurnkeySDKClientBase { }; stampGetWhoami = async ( - input: SdkTypes.GetWhoamiRequest, + input: SdkTypes.TGetWhoamiBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -1158,9 +1158,9 @@ export class TurnkeySDKClientBase { }; approveActivity = async ( - input: SdkTypes.ApproveActivityRequest, + input: SdkTypes.TApproveActivityBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -1180,7 +1180,7 @@ export class TurnkeySDKClientBase { }; stampApproveActivity = async ( - input: SdkTypes.ApproveActivityRequest, + input: SdkTypes.TApproveActivityBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -1200,9 +1200,9 @@ export class TurnkeySDKClientBase { }; createApiKeys = async ( - input: SdkTypes.CreateApiKeysRequest, + input: SdkTypes.TCreateApiKeysBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -1224,7 +1224,7 @@ export class TurnkeySDKClientBase { }; stampCreateApiKeys = async ( - input: SdkTypes.CreateApiKeysRequest, + input: SdkTypes.TCreateApiKeysBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -1244,9 +1244,9 @@ export class TurnkeySDKClientBase { }; createApiOnlyUsers = async ( - input: SdkTypes.CreateApiOnlyUsersRequest, + input: SdkTypes.TCreateApiOnlyUsersBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -1268,7 +1268,7 @@ export class TurnkeySDKClientBase { }; stampCreateApiOnlyUsers = async ( - input: SdkTypes.CreateApiOnlyUsersRequest, + input: SdkTypes.TCreateApiOnlyUsersBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -1288,9 +1288,9 @@ export class TurnkeySDKClientBase { }; createAuthenticators = async ( - input: SdkTypes.CreateAuthenticatorsRequest, + input: SdkTypes.TCreateAuthenticatorsBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -1312,7 +1312,7 @@ export class TurnkeySDKClientBase { }; stampCreateAuthenticators = async ( - input: SdkTypes.CreateAuthenticatorsRequest, + input: SdkTypes.TCreateAuthenticatorsBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -1332,9 +1332,9 @@ export class TurnkeySDKClientBase { }; createInvitations = async ( - input: SdkTypes.CreateInvitationsRequest, + input: SdkTypes.TCreateInvitationsBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -1356,7 +1356,7 @@ export class TurnkeySDKClientBase { }; stampCreateInvitations = async ( - input: SdkTypes.CreateInvitationsRequest, + input: SdkTypes.TCreateInvitationsBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -1376,9 +1376,9 @@ export class TurnkeySDKClientBase { }; createOauthProviders = async ( - input: SdkTypes.CreateOauthProvidersRequest, + input: SdkTypes.TCreateOauthProvidersBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -1400,7 +1400,7 @@ export class TurnkeySDKClientBase { }; stampCreateOauthProviders = async ( - input: SdkTypes.CreateOauthProvidersRequest, + input: SdkTypes.TCreateOauthProvidersBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -1420,9 +1420,9 @@ export class TurnkeySDKClientBase { }; createPolicies = async ( - input: SdkTypes.CreatePoliciesRequest, + input: SdkTypes.TCreatePoliciesBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -1444,7 +1444,7 @@ export class TurnkeySDKClientBase { }; stampCreatePolicies = async ( - input: SdkTypes.CreatePoliciesRequest, + input: SdkTypes.TCreatePoliciesBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -1464,9 +1464,9 @@ export class TurnkeySDKClientBase { }; createPolicy = async ( - input: SdkTypes.CreatePolicyRequest, + input: SdkTypes.TCreatePolicyBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -1488,7 +1488,7 @@ export class TurnkeySDKClientBase { }; stampCreatePolicy = async ( - input: SdkTypes.CreatePolicyRequest, + input: SdkTypes.TCreatePolicyBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -1507,9 +1507,9 @@ export class TurnkeySDKClientBase { }; createPrivateKeyTag = async ( - input: SdkTypes.CreatePrivateKeyTagRequest, + input: SdkTypes.TCreatePrivateKeyTagBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -1531,7 +1531,7 @@ export class TurnkeySDKClientBase { }; stampCreatePrivateKeyTag = async ( - input: SdkTypes.CreatePrivateKeyTagRequest, + input: SdkTypes.TCreatePrivateKeyTagBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -1551,9 +1551,9 @@ export class TurnkeySDKClientBase { }; createPrivateKeys = async ( - input: SdkTypes.CreatePrivateKeysRequest, + input: SdkTypes.TCreatePrivateKeysBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -1575,7 +1575,7 @@ export class TurnkeySDKClientBase { }; stampCreatePrivateKeys = async ( - input: SdkTypes.CreatePrivateKeysRequest, + input: SdkTypes.TCreatePrivateKeysBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -1595,9 +1595,9 @@ export class TurnkeySDKClientBase { }; createReadOnlySession = async ( - input: SdkTypes.CreateReadOnlySessionRequest, + input: SdkTypes.TCreateReadOnlySessionBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -1619,7 +1619,7 @@ export class TurnkeySDKClientBase { }; stampCreateReadOnlySession = async ( - input: SdkTypes.CreateReadOnlySessionRequest, + input: SdkTypes.TCreateReadOnlySessionBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -1639,9 +1639,9 @@ export class TurnkeySDKClientBase { }; createReadWriteSession = async ( - input: SdkTypes.CreateReadWriteSessionRequest, + input: SdkTypes.TCreateReadWriteSessionBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -1663,7 +1663,7 @@ export class TurnkeySDKClientBase { }; stampCreateReadWriteSession = async ( - input: SdkTypes.CreateReadWriteSessionRequest, + input: SdkTypes.TCreateReadWriteSessionBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -1683,9 +1683,9 @@ export class TurnkeySDKClientBase { }; createSubOrganization = async ( - input: SdkTypes.CreateSubOrganizationRequest, + input: SdkTypes.TCreateSubOrganizationBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -1707,7 +1707,7 @@ export class TurnkeySDKClientBase { }; stampCreateSubOrganization = async ( - input: SdkTypes.CreateSubOrganizationRequest, + input: SdkTypes.TCreateSubOrganizationBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -1727,9 +1727,9 @@ export class TurnkeySDKClientBase { }; createUserTag = async ( - input: SdkTypes.CreateUserTagRequest, + input: SdkTypes.TCreateUserTagBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -1751,7 +1751,7 @@ export class TurnkeySDKClientBase { }; stampCreateUserTag = async ( - input: SdkTypes.CreateUserTagRequest, + input: SdkTypes.TCreateUserTagBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -1771,9 +1771,9 @@ export class TurnkeySDKClientBase { }; createUsers = async ( - input: SdkTypes.CreateUsersRequest, + input: SdkTypes.TCreateUsersBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -1795,7 +1795,7 @@ export class TurnkeySDKClientBase { }; stampCreateUsers = async ( - input: SdkTypes.CreateUsersRequest, + input: SdkTypes.TCreateUsersBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -1814,9 +1814,9 @@ export class TurnkeySDKClientBase { }; createWallet = async ( - input: SdkTypes.CreateWalletRequest, + input: SdkTypes.TCreateWalletBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -1838,7 +1838,7 @@ export class TurnkeySDKClientBase { }; stampCreateWallet = async ( - input: SdkTypes.CreateWalletRequest, + input: SdkTypes.TCreateWalletBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -1857,9 +1857,9 @@ export class TurnkeySDKClientBase { }; createWalletAccounts = async ( - input: SdkTypes.CreateWalletAccountsRequest, + input: SdkTypes.TCreateWalletAccountsBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -1881,7 +1881,7 @@ export class TurnkeySDKClientBase { }; stampCreateWalletAccounts = async ( - input: SdkTypes.CreateWalletAccountsRequest, + input: SdkTypes.TCreateWalletAccountsBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -1901,9 +1901,9 @@ export class TurnkeySDKClientBase { }; deleteApiKeys = async ( - input: SdkTypes.DeleteApiKeysRequest, + input: SdkTypes.TDeleteApiKeysBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -1925,7 +1925,7 @@ export class TurnkeySDKClientBase { }; stampDeleteApiKeys = async ( - input: SdkTypes.DeleteApiKeysRequest, + input: SdkTypes.TDeleteApiKeysBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -1945,9 +1945,9 @@ export class TurnkeySDKClientBase { }; deleteAuthenticators = async ( - input: SdkTypes.DeleteAuthenticatorsRequest, + input: SdkTypes.TDeleteAuthenticatorsBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -1969,7 +1969,7 @@ export class TurnkeySDKClientBase { }; stampDeleteAuthenticators = async ( - input: SdkTypes.DeleteAuthenticatorsRequest, + input: SdkTypes.TDeleteAuthenticatorsBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -1989,9 +1989,9 @@ export class TurnkeySDKClientBase { }; deleteInvitation = async ( - input: SdkTypes.DeleteInvitationRequest, + input: SdkTypes.TDeleteInvitationBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -2013,7 +2013,7 @@ export class TurnkeySDKClientBase { }; stampDeleteInvitation = async ( - input: SdkTypes.DeleteInvitationRequest, + input: SdkTypes.TDeleteInvitationBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -2033,9 +2033,9 @@ export class TurnkeySDKClientBase { }; deleteOauthProviders = async ( - input: SdkTypes.DeleteOauthProvidersRequest, + input: SdkTypes.TDeleteOauthProvidersBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -2057,7 +2057,7 @@ export class TurnkeySDKClientBase { }; stampDeleteOauthProviders = async ( - input: SdkTypes.DeleteOauthProvidersRequest, + input: SdkTypes.TDeleteOauthProvidersBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -2077,9 +2077,9 @@ export class TurnkeySDKClientBase { }; deletePolicy = async ( - input: SdkTypes.DeletePolicyRequest, + input: SdkTypes.TDeletePolicyBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -2101,7 +2101,7 @@ export class TurnkeySDKClientBase { }; stampDeletePolicy = async ( - input: SdkTypes.DeletePolicyRequest, + input: SdkTypes.TDeletePolicyBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -2120,9 +2120,9 @@ export class TurnkeySDKClientBase { }; deletePrivateKeyTags = async ( - input: SdkTypes.DeletePrivateKeyTagsRequest, + input: SdkTypes.TDeletePrivateKeyTagsBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -2144,7 +2144,7 @@ export class TurnkeySDKClientBase { }; stampDeletePrivateKeyTags = async ( - input: SdkTypes.DeletePrivateKeyTagsRequest, + input: SdkTypes.TDeletePrivateKeyTagsBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -2164,9 +2164,9 @@ export class TurnkeySDKClientBase { }; deletePrivateKeys = async ( - input: SdkTypes.DeletePrivateKeysRequest, + input: SdkTypes.TDeletePrivateKeysBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -2188,7 +2188,7 @@ export class TurnkeySDKClientBase { }; stampDeletePrivateKeys = async ( - input: SdkTypes.DeletePrivateKeysRequest, + input: SdkTypes.TDeletePrivateKeysBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -2208,9 +2208,9 @@ export class TurnkeySDKClientBase { }; deleteSubOrganization = async ( - input: SdkTypes.DeleteSubOrganizationRequest, + input: SdkTypes.TDeleteSubOrganizationBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -2232,7 +2232,7 @@ export class TurnkeySDKClientBase { }; stampDeleteSubOrganization = async ( - input: SdkTypes.DeleteSubOrganizationRequest, + input: SdkTypes.TDeleteSubOrganizationBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -2252,9 +2252,9 @@ export class TurnkeySDKClientBase { }; deleteUserTags = async ( - input: SdkTypes.DeleteUserTagsRequest, + input: SdkTypes.TDeleteUserTagsBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -2276,7 +2276,7 @@ export class TurnkeySDKClientBase { }; stampDeleteUserTags = async ( - input: SdkTypes.DeleteUserTagsRequest, + input: SdkTypes.TDeleteUserTagsBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -2296,9 +2296,9 @@ export class TurnkeySDKClientBase { }; deleteUsers = async ( - input: SdkTypes.DeleteUsersRequest, + input: SdkTypes.TDeleteUsersBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -2320,7 +2320,7 @@ export class TurnkeySDKClientBase { }; stampDeleteUsers = async ( - input: SdkTypes.DeleteUsersRequest, + input: SdkTypes.TDeleteUsersBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -2339,9 +2339,9 @@ export class TurnkeySDKClientBase { }; deleteWallets = async ( - input: SdkTypes.DeleteWalletsRequest, + input: SdkTypes.TDeleteWalletsBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -2363,7 +2363,7 @@ export class TurnkeySDKClientBase { }; stampDeleteWallets = async ( - input: SdkTypes.DeleteWalletsRequest, + input: SdkTypes.TDeleteWalletsBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -2382,9 +2382,9 @@ export class TurnkeySDKClientBase { }; emailAuth = async ( - input: SdkTypes.EmailAuthRequest, + input: SdkTypes.TEmailAuthBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -2406,7 +2406,7 @@ export class TurnkeySDKClientBase { }; stampEmailAuth = async ( - input: SdkTypes.EmailAuthRequest, + input: SdkTypes.TEmailAuthBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -2425,9 +2425,9 @@ export class TurnkeySDKClientBase { }; exportPrivateKey = async ( - input: SdkTypes.ExportPrivateKeyRequest, + input: SdkTypes.TExportPrivateKeyBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -2449,7 +2449,7 @@ export class TurnkeySDKClientBase { }; stampExportPrivateKey = async ( - input: SdkTypes.ExportPrivateKeyRequest, + input: SdkTypes.TExportPrivateKeyBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -2469,9 +2469,9 @@ export class TurnkeySDKClientBase { }; exportWallet = async ( - input: SdkTypes.ExportWalletRequest, + input: SdkTypes.TExportWalletBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -2493,7 +2493,7 @@ export class TurnkeySDKClientBase { }; stampExportWallet = async ( - input: SdkTypes.ExportWalletRequest, + input: SdkTypes.TExportWalletBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -2512,9 +2512,9 @@ export class TurnkeySDKClientBase { }; exportWalletAccount = async ( - input: SdkTypes.ExportWalletAccountRequest, + input: SdkTypes.TExportWalletAccountBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -2536,7 +2536,7 @@ export class TurnkeySDKClientBase { }; stampExportWalletAccount = async ( - input: SdkTypes.ExportWalletAccountRequest, + input: SdkTypes.TExportWalletAccountBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -2556,9 +2556,9 @@ export class TurnkeySDKClientBase { }; importPrivateKey = async ( - input: SdkTypes.ImportPrivateKeyRequest, + input: SdkTypes.TImportPrivateKeyBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -2580,7 +2580,7 @@ export class TurnkeySDKClientBase { }; stampImportPrivateKey = async ( - input: SdkTypes.ImportPrivateKeyRequest, + input: SdkTypes.TImportPrivateKeyBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -2600,9 +2600,9 @@ export class TurnkeySDKClientBase { }; importWallet = async ( - input: SdkTypes.ImportWalletRequest, + input: SdkTypes.TImportWalletBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -2624,7 +2624,7 @@ export class TurnkeySDKClientBase { }; stampImportWallet = async ( - input: SdkTypes.ImportWalletRequest, + input: SdkTypes.TImportWalletBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -2643,9 +2643,9 @@ export class TurnkeySDKClientBase { }; initImportPrivateKey = async ( - input: SdkTypes.InitImportPrivateKeyRequest, + input: SdkTypes.TInitImportPrivateKeyBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -2667,7 +2667,7 @@ export class TurnkeySDKClientBase { }; stampInitImportPrivateKey = async ( - input: SdkTypes.InitImportPrivateKeyRequest, + input: SdkTypes.TInitImportPrivateKeyBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -2687,9 +2687,9 @@ export class TurnkeySDKClientBase { }; initImportWallet = async ( - input: SdkTypes.InitImportWalletRequest, + input: SdkTypes.TInitImportWalletBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -2711,7 +2711,7 @@ export class TurnkeySDKClientBase { }; stampInitImportWallet = async ( - input: SdkTypes.InitImportWalletRequest, + input: SdkTypes.TInitImportWalletBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -2731,9 +2731,9 @@ export class TurnkeySDKClientBase { }; initOtp = async ( - input: SdkTypes.InitOtpRequest, + input: SdkTypes.TInitOtpBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -2755,7 +2755,7 @@ export class TurnkeySDKClientBase { }; stampInitOtp = async ( - input: SdkTypes.InitOtpRequest, + input: SdkTypes.TInitOtpBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -2774,9 +2774,9 @@ export class TurnkeySDKClientBase { }; initOtpAuth = async ( - input: SdkTypes.InitOtpAuthRequest, + input: SdkTypes.TInitOtpAuthBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -2798,7 +2798,7 @@ export class TurnkeySDKClientBase { }; stampInitOtpAuth = async ( - input: SdkTypes.InitOtpAuthRequest, + input: SdkTypes.TInitOtpAuthBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -2817,9 +2817,9 @@ export class TurnkeySDKClientBase { }; initUserEmailRecovery = async ( - input: SdkTypes.InitUserEmailRecoveryRequest, + input: SdkTypes.TInitUserEmailRecoveryBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -2841,7 +2841,7 @@ export class TurnkeySDKClientBase { }; stampInitUserEmailRecovery = async ( - input: SdkTypes.InitUserEmailRecoveryRequest, + input: SdkTypes.TInitUserEmailRecoveryBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -2861,9 +2861,9 @@ export class TurnkeySDKClientBase { }; oauth = async ( - input: SdkTypes.OauthRequest, + input: SdkTypes.TOauthBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -2885,7 +2885,7 @@ export class TurnkeySDKClientBase { }; stampOauth = async ( - input: SdkTypes.OauthRequest, + input: SdkTypes.TOauthBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -2904,9 +2904,9 @@ export class TurnkeySDKClientBase { }; oauthLogin = async ( - input: SdkTypes.OauthLoginRequest, + input: SdkTypes.TOauthLoginBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -2928,7 +2928,7 @@ export class TurnkeySDKClientBase { }; stampOauthLogin = async ( - input: SdkTypes.OauthLoginRequest, + input: SdkTypes.TOauthLoginBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -2947,9 +2947,9 @@ export class TurnkeySDKClientBase { }; otpAuth = async ( - input: SdkTypes.OtpAuthRequest, + input: SdkTypes.TOtpAuthBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -2971,7 +2971,7 @@ export class TurnkeySDKClientBase { }; stampOtpAuth = async ( - input: SdkTypes.OtpAuthRequest, + input: SdkTypes.TOtpAuthBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -2990,9 +2990,9 @@ export class TurnkeySDKClientBase { }; otpLogin = async ( - input: SdkTypes.OtpLoginRequest, + input: SdkTypes.TOtpLoginBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -3014,7 +3014,7 @@ export class TurnkeySDKClientBase { }; stampOtpLogin = async ( - input: SdkTypes.OtpLoginRequest, + input: SdkTypes.TOtpLoginBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -3033,9 +3033,9 @@ export class TurnkeySDKClientBase { }; recoverUser = async ( - input: SdkTypes.RecoverUserRequest, + input: SdkTypes.TRecoverUserBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -3057,7 +3057,7 @@ export class TurnkeySDKClientBase { }; stampRecoverUser = async ( - input: SdkTypes.RecoverUserRequest, + input: SdkTypes.TRecoverUserBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -3076,9 +3076,9 @@ export class TurnkeySDKClientBase { }; rejectActivity = async ( - input: SdkTypes.RejectActivityRequest, + input: SdkTypes.TRejectActivityBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -3098,7 +3098,7 @@ export class TurnkeySDKClientBase { }; stampRejectActivity = async ( - input: SdkTypes.RejectActivityRequest, + input: SdkTypes.TRejectActivityBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -3118,9 +3118,9 @@ export class TurnkeySDKClientBase { }; removeOrganizationFeature = async ( - input: SdkTypes.RemoveOrganizationFeatureRequest, + input: SdkTypes.TRemoveOrganizationFeatureBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -3142,7 +3142,7 @@ export class TurnkeySDKClientBase { }; stampRemoveOrganizationFeature = async ( - input: SdkTypes.RemoveOrganizationFeatureRequest, + input: SdkTypes.TRemoveOrganizationFeatureBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -3162,9 +3162,9 @@ export class TurnkeySDKClientBase { }; setOrganizationFeature = async ( - input: SdkTypes.SetOrganizationFeatureRequest, + input: SdkTypes.TSetOrganizationFeatureBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -3186,7 +3186,7 @@ export class TurnkeySDKClientBase { }; stampSetOrganizationFeature = async ( - input: SdkTypes.SetOrganizationFeatureRequest, + input: SdkTypes.TSetOrganizationFeatureBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -3206,9 +3206,9 @@ export class TurnkeySDKClientBase { }; signRawPayload = async ( - input: SdkTypes.SignRawPayloadRequest, + input: SdkTypes.TSignRawPayloadBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -3230,7 +3230,7 @@ export class TurnkeySDKClientBase { }; stampSignRawPayload = async ( - input: SdkTypes.SignRawPayloadRequest, + input: SdkTypes.TSignRawPayloadBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -3250,9 +3250,9 @@ export class TurnkeySDKClientBase { }; signRawPayloads = async ( - input: SdkTypes.SignRawPayloadsRequest, + input: SdkTypes.TSignRawPayloadsBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -3274,7 +3274,7 @@ export class TurnkeySDKClientBase { }; stampSignRawPayloads = async ( - input: SdkTypes.SignRawPayloadsRequest, + input: SdkTypes.TSignRawPayloadsBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -3294,9 +3294,9 @@ export class TurnkeySDKClientBase { }; signTransaction = async ( - input: SdkTypes.SignTransactionRequest, + input: SdkTypes.TSignTransactionBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -3318,7 +3318,7 @@ export class TurnkeySDKClientBase { }; stampSignTransaction = async ( - input: SdkTypes.SignTransactionRequest, + input: SdkTypes.TSignTransactionBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -3338,9 +3338,9 @@ export class TurnkeySDKClientBase { }; stampLogin = async ( - input: SdkTypes.StampLoginRequest, + input: SdkTypes.TStampLoginBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -3362,7 +3362,7 @@ export class TurnkeySDKClientBase { }; stampStampLogin = async ( - input: SdkTypes.StampLoginRequest, + input: SdkTypes.TStampLoginBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -3381,9 +3381,9 @@ export class TurnkeySDKClientBase { }; updatePolicy = async ( - input: SdkTypes.UpdatePolicyRequest, + input: SdkTypes.TUpdatePolicyBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -3405,7 +3405,7 @@ export class TurnkeySDKClientBase { }; stampUpdatePolicy = async ( - input: SdkTypes.UpdatePolicyRequest, + input: SdkTypes.TUpdatePolicyBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -3424,9 +3424,9 @@ export class TurnkeySDKClientBase { }; updatePrivateKeyTag = async ( - input: SdkTypes.UpdatePrivateKeyTagRequest, + input: SdkTypes.TUpdatePrivateKeyTagBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -3448,7 +3448,7 @@ export class TurnkeySDKClientBase { }; stampUpdatePrivateKeyTag = async ( - input: SdkTypes.UpdatePrivateKeyTagRequest, + input: SdkTypes.TUpdatePrivateKeyTagBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -3468,9 +3468,9 @@ export class TurnkeySDKClientBase { }; updateRootQuorum = async ( - input: SdkTypes.UpdateRootQuorumRequest, + input: SdkTypes.TUpdateRootQuorumBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -3492,7 +3492,7 @@ export class TurnkeySDKClientBase { }; stampUpdateRootQuorum = async ( - input: SdkTypes.UpdateRootQuorumRequest, + input: SdkTypes.TUpdateRootQuorumBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -3512,9 +3512,9 @@ export class TurnkeySDKClientBase { }; updateUser = async ( - input: SdkTypes.UpdateUserRequest, + input: SdkTypes.TUpdateUserBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -3536,7 +3536,7 @@ export class TurnkeySDKClientBase { }; stampUpdateUser = async ( - input: SdkTypes.UpdateUserRequest, + input: SdkTypes.TUpdateUserBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -3555,9 +3555,9 @@ export class TurnkeySDKClientBase { }; updateUserTag = async ( - input: SdkTypes.UpdateUserTagRequest, + input: SdkTypes.TUpdateUserTagBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -3579,7 +3579,7 @@ export class TurnkeySDKClientBase { }; stampUpdateUserTag = async ( - input: SdkTypes.UpdateUserTagRequest, + input: SdkTypes.TUpdateUserTagBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -3599,9 +3599,9 @@ export class TurnkeySDKClientBase { }; updateWallet = async ( - input: SdkTypes.UpdateWalletRequest, + input: SdkTypes.TUpdateWalletBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -3623,7 +3623,7 @@ export class TurnkeySDKClientBase { }; stampUpdateWallet = async ( - input: SdkTypes.UpdateWalletRequest, + input: SdkTypes.TUpdateWalletBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -3642,9 +3642,9 @@ export class TurnkeySDKClientBase { }; verifyOtp = async ( - input: SdkTypes.VerifyOtpRequest, + input: SdkTypes.TVerifyOtpBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { const { organizationId, timestampMs, ...rest } = input; let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage @@ -3666,7 +3666,7 @@ export class TurnkeySDKClientBase { }; stampVerifyOtp = async ( - input: SdkTypes.VerifyOtpRequest, + input: SdkTypes.TVerifyOtpBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); @@ -3685,9 +3685,9 @@ export class TurnkeySDKClientBase { }; testRateLimits = async ( - input: SdkTypes.TestRateLimitsRequest, + input: SdkTypes.TTestRateLimitsBody, stampWith?: StamperType, - ): Promise => { + ): Promise => { let session = await this.storageManager?.getActiveSession(); session = parseSession(session!); // TODO (Amir): We may not need this anymore since we want to store the full session object in storage return this.request( @@ -3704,7 +3704,7 @@ export class TurnkeySDKClientBase { }; stampTestRateLimits = async ( - input: SdkTypes.TestRateLimitsRequest, + input: SdkTypes.TTestRateLimitsBody, stampWith?: StamperType, ): Promise => { const activeStamper = this.getStamper(stampWith); diff --git a/packages/sdk-types/scripts/codegen.js b/packages/sdk-types/scripts/codegen.js index 029b042fa..edbf67bd9 100644 --- a/packages/sdk-types/scripts/codegen.js +++ b/packages/sdk-types/scripts/codegen.js @@ -138,6 +138,7 @@ function isValidIdentifier(name) { * @returns {string} */ function methodTypeFromMethodName(methodName) { + methodName = methodName.toLowerCase(); if (["approveActivity", "rejectActivity"].includes(methodName)) { return "activityDecision"; } @@ -146,9 +147,9 @@ function methodTypeFromMethodName(methodName) { } // TODO: filter out unnecessary client methods, whether here or from the source if ( - methodName.startsWith("get") || - methodName.startsWith("list") || - methodName.startsWith("test") + methodName.startsWith("tget") || + methodName.startsWith("tlist") || + methodName.startsWith("ttest") ) { return "query"; } @@ -234,7 +235,7 @@ function generateApiTypes(swagger) { const operationNameWithoutNamespace = operationId.replace( new RegExp(`${namespace}_`), - "", + "T", ); const methodName = operationNameWithoutNamespace.charAt(0).toLowerCase() + @@ -253,9 +254,13 @@ function generateApiTypes(swagger) { const apiTypeName = operationNameWithoutNamespace.replace(/^./, (c) => c.toUpperCase()) + "Response"; - const apiRequestTypeName = + const apiBodyTypeName = operationNameWithoutNamespace.replace(/^./, (c) => c.toUpperCase()) + - "Request"; + "Body"; + + const apiInputTypeName = + operationNameWithoutNamespace.replace(/^./, (c) => c.toUpperCase()) + + "Input"; // --- RESPONSE TYPE GENERATION --- if (methodType === "command") { @@ -366,7 +371,7 @@ function generateApiTypes(swagger) { if (!requestTypeDef) continue; - output += `export type ${apiRequestTypeName} = {\n`; + output += `export type ${apiBodyTypeName} = {\n`; if (methodType === "command" || methodType === "activityDecision") { output += ` timestampMs?: string;\n organizationId?: string;\n`; @@ -415,6 +420,8 @@ function generateApiTypes(swagger) { } } output += "}\n\n"; + + output += `export type ${apiInputTypeName} = { body: ${apiBodyTypeName} };\n\n`; } return output; } diff --git a/packages/sdk-types/src/__generated__/types.ts b/packages/sdk-types/src/__generated__/types.ts index aa9f679ba..ea88ba15a 100644 --- a/packages/sdk-types/src/__generated__/types.ts +++ b/packages/sdk-types/src/__generated__/types.ts @@ -138,9 +138,9 @@ export type v1AcceptInvitationResult = { }; export type v1AccessType = - | "ACCESS_TYPE_WEB" - | "ACCESS_TYPE_API" - | "ACCESS_TYPE_ALL"; + "ACCESS_TYPE_WEB" | + "ACCESS_TYPE_API" | + "ACCESS_TYPE_ALL"; export type v1Activity = { /** Unique identifier for a given Activity object. */ @@ -173,144 +173,144 @@ export type v1ActivityResponse = { }; export type v1ActivityStatus = - | "ACTIVITY_STATUS_CREATED" - | "ACTIVITY_STATUS_PENDING" - | "ACTIVITY_STATUS_COMPLETED" - | "ACTIVITY_STATUS_FAILED" - | "ACTIVITY_STATUS_CONSENSUS_NEEDED" - | "ACTIVITY_STATUS_REJECTED"; + "ACTIVITY_STATUS_CREATED" | + "ACTIVITY_STATUS_PENDING" | + "ACTIVITY_STATUS_COMPLETED" | + "ACTIVITY_STATUS_FAILED" | + "ACTIVITY_STATUS_CONSENSUS_NEEDED" | + "ACTIVITY_STATUS_REJECTED"; export type v1ActivityType = - | "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_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"; export type v1AddressFormat = - | "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_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"; export type v1ApiKey = { /** A User credential that can be used to authenticate to Turnkey. */ @@ -326,9 +326,9 @@ export type v1ApiKey = { }; export type v1ApiKeyCurve = - | "API_KEY_CURVE_P256" - | "API_KEY_CURVE_SECP256K1" - | "API_KEY_CURVE_ED25519"; + "API_KEY_CURVE_P256" | + "API_KEY_CURVE_SECP256K1" | + "API_KEY_CURVE_ED25519"; export type v1ApiKeyParamsV2 = { /** Human-readable name for an API Key. */ @@ -424,11 +424,11 @@ export type v1AuthenticatorParamsV2 = { }; export type v1AuthenticatorTransport = - | "AUTHENTICATOR_TRANSPORT_BLE" - | "AUTHENTICATOR_TRANSPORT_INTERNAL" - | "AUTHENTICATOR_TRANSPORT_NFC" - | "AUTHENTICATOR_TRANSPORT_USB" - | "AUTHENTICATOR_TRANSPORT_HYBRID"; + "AUTHENTICATOR_TRANSPORT_BLE" | + "AUTHENTICATOR_TRANSPORT_INTERNAL" | + "AUTHENTICATOR_TRANSPORT_NFC" | + "AUTHENTICATOR_TRANSPORT_USB" | + "AUTHENTICATOR_TRANSPORT_HYBRID"; export type v1Config = { features?: v1Feature[]; @@ -1021,18 +1021,20 @@ export type v1CredPropsAuthenticationExtensionsClientOutputs = { }; export type v1CredentialType = - | "CREDENTIAL_TYPE_WEBAUTHN_AUTHENTICATOR" - | "CREDENTIAL_TYPE_API_KEY_P256" - | "CREDENTIAL_TYPE_RECOVER_USER_KEY_P256" - | "CREDENTIAL_TYPE_API_KEY_SECP256K1" - | "CREDENTIAL_TYPE_EMAIL_AUTH_KEY_P256" - | "CREDENTIAL_TYPE_API_KEY_ED25519" - | "CREDENTIAL_TYPE_OTP_AUTH_KEY_P256" - | "CREDENTIAL_TYPE_READ_WRITE_SESSION_KEY_P256" - | "CREDENTIAL_TYPE_OAUTH_KEY_P256" - | "CREDENTIAL_TYPE_LOGIN"; - -export type v1Curve = "CURVE_SECP256K1" | "CURVE_ED25519"; + "CREDENTIAL_TYPE_WEBAUTHN_AUTHENTICATOR" | + "CREDENTIAL_TYPE_API_KEY_P256" | + "CREDENTIAL_TYPE_RECOVER_USER_KEY_P256" | + "CREDENTIAL_TYPE_API_KEY_SECP256K1" | + "CREDENTIAL_TYPE_EMAIL_AUTH_KEY_P256" | + "CREDENTIAL_TYPE_API_KEY_ED25519" | + "CREDENTIAL_TYPE_OTP_AUTH_KEY_P256" | + "CREDENTIAL_TYPE_READ_WRITE_SESSION_KEY_P256" | + "CREDENTIAL_TYPE_OAUTH_KEY_P256" | + "CREDENTIAL_TYPE_LOGIN"; + +export type v1Curve = + "CURVE_SECP256K1" | + "CURVE_ED25519"; export type v1DeleteApiKeysIntent = { /** Unique identifier for a given User. */ @@ -1277,7 +1279,9 @@ export type v1DisablePrivateKeyResult = { privateKeyId: string; }; -export type v1Effect = "EFFECT_ALLOW" | "EFFECT_DENY"; +export type v1Effect = + "EFFECT_ALLOW" | + "EFFECT_DENY"; export type v1EmailAuthIntent = { /** Email of the authenticating user. */ @@ -1427,80 +1431,80 @@ export type v1Feature = { }; export type v1FeatureName = - | "FEATURE_NAME_ROOT_USER_EMAIL_RECOVERY" - | "FEATURE_NAME_WEBAUTHN_ORIGINS" - | "FEATURE_NAME_EMAIL_AUTH" - | "FEATURE_NAME_EMAIL_RECOVERY" - | "FEATURE_NAME_WEBHOOK" - | "FEATURE_NAME_SMS_AUTH" - | "FEATURE_NAME_OTP_EMAIL_AUTH"; + "FEATURE_NAME_ROOT_USER_EMAIL_RECOVERY" | + "FEATURE_NAME_WEBAUTHN_ORIGINS" | + "FEATURE_NAME_EMAIL_AUTH" | + "FEATURE_NAME_EMAIL_RECOVERY" | + "FEATURE_NAME_WEBHOOK" | + "FEATURE_NAME_SMS_AUTH" | + "FEATURE_NAME_OTP_EMAIL_AUTH"; export type v1FiatOnRampBlockchainNetwork = - | "FIAT_ON_RAMP_BLOCKCHAIN_NETWORK_BITCOIN" - | "FIAT_ON_RAMP_BLOCKCHAIN_NETWORK_ETHEREUM" - | "FIAT_ON_RAMP_BLOCKCHAIN_NETWORK_SOLANA" - | "FIAT_ON_RAMP_BLOCKCHAIN_NETWORK_BASE"; + "FIAT_ON_RAMP_BLOCKCHAIN_NETWORK_BITCOIN" | + "FIAT_ON_RAMP_BLOCKCHAIN_NETWORK_ETHEREUM" | + "FIAT_ON_RAMP_BLOCKCHAIN_NETWORK_SOLANA" | + "FIAT_ON_RAMP_BLOCKCHAIN_NETWORK_BASE"; export type v1FiatOnRampCryptoCurrency = - | "FIAT_ON_RAMP_CRYPTO_CURRENCY_BTC" - | "FIAT_ON_RAMP_CRYPTO_CURRENCY_ETH" - | "FIAT_ON_RAMP_CRYPTO_CURRENCY_SOL" - | "FIAT_ON_RAMP_CRYPTO_CURRENCY_USDC"; + "FIAT_ON_RAMP_CRYPTO_CURRENCY_BTC" | + "FIAT_ON_RAMP_CRYPTO_CURRENCY_ETH" | + "FIAT_ON_RAMP_CRYPTO_CURRENCY_SOL" | + "FIAT_ON_RAMP_CRYPTO_CURRENCY_USDC"; export type v1FiatOnRampCurrency = - | "FIAT_ON_RAMP_CURRENCY_AUD" - | "FIAT_ON_RAMP_CURRENCY_BGN" - | "FIAT_ON_RAMP_CURRENCY_BRL" - | "FIAT_ON_RAMP_CURRENCY_CAD" - | "FIAT_ON_RAMP_CURRENCY_CHF" - | "FIAT_ON_RAMP_CURRENCY_COP" - | "FIAT_ON_RAMP_CURRENCY_CZK" - | "FIAT_ON_RAMP_CURRENCY_DKK" - | "FIAT_ON_RAMP_CURRENCY_DOP" - | "FIAT_ON_RAMP_CURRENCY_EGP" - | "FIAT_ON_RAMP_CURRENCY_EUR" - | "FIAT_ON_RAMP_CURRENCY_GBP" - | "FIAT_ON_RAMP_CURRENCY_HKD" - | "FIAT_ON_RAMP_CURRENCY_IDR" - | "FIAT_ON_RAMP_CURRENCY_ILS" - | "FIAT_ON_RAMP_CURRENCY_JOD" - | "FIAT_ON_RAMP_CURRENCY_KES" - | "FIAT_ON_RAMP_CURRENCY_KWD" - | "FIAT_ON_RAMP_CURRENCY_LKR" - | "FIAT_ON_RAMP_CURRENCY_MXN" - | "FIAT_ON_RAMP_CURRENCY_NGN" - | "FIAT_ON_RAMP_CURRENCY_NOK" - | "FIAT_ON_RAMP_CURRENCY_NZD" - | "FIAT_ON_RAMP_CURRENCY_OMR" - | "FIAT_ON_RAMP_CURRENCY_PEN" - | "FIAT_ON_RAMP_CURRENCY_PLN" - | "FIAT_ON_RAMP_CURRENCY_RON" - | "FIAT_ON_RAMP_CURRENCY_SEK" - | "FIAT_ON_RAMP_CURRENCY_THB" - | "FIAT_ON_RAMP_CURRENCY_TRY" - | "FIAT_ON_RAMP_CURRENCY_TWD" - | "FIAT_ON_RAMP_CURRENCY_USD" - | "FIAT_ON_RAMP_CURRENCY_VND" - | "FIAT_ON_RAMP_CURRENCY_ZAR"; + "FIAT_ON_RAMP_CURRENCY_AUD" | + "FIAT_ON_RAMP_CURRENCY_BGN" | + "FIAT_ON_RAMP_CURRENCY_BRL" | + "FIAT_ON_RAMP_CURRENCY_CAD" | + "FIAT_ON_RAMP_CURRENCY_CHF" | + "FIAT_ON_RAMP_CURRENCY_COP" | + "FIAT_ON_RAMP_CURRENCY_CZK" | + "FIAT_ON_RAMP_CURRENCY_DKK" | + "FIAT_ON_RAMP_CURRENCY_DOP" | + "FIAT_ON_RAMP_CURRENCY_EGP" | + "FIAT_ON_RAMP_CURRENCY_EUR" | + "FIAT_ON_RAMP_CURRENCY_GBP" | + "FIAT_ON_RAMP_CURRENCY_HKD" | + "FIAT_ON_RAMP_CURRENCY_IDR" | + "FIAT_ON_RAMP_CURRENCY_ILS" | + "FIAT_ON_RAMP_CURRENCY_JOD" | + "FIAT_ON_RAMP_CURRENCY_KES" | + "FIAT_ON_RAMP_CURRENCY_KWD" | + "FIAT_ON_RAMP_CURRENCY_LKR" | + "FIAT_ON_RAMP_CURRENCY_MXN" | + "FIAT_ON_RAMP_CURRENCY_NGN" | + "FIAT_ON_RAMP_CURRENCY_NOK" | + "FIAT_ON_RAMP_CURRENCY_NZD" | + "FIAT_ON_RAMP_CURRENCY_OMR" | + "FIAT_ON_RAMP_CURRENCY_PEN" | + "FIAT_ON_RAMP_CURRENCY_PLN" | + "FIAT_ON_RAMP_CURRENCY_RON" | + "FIAT_ON_RAMP_CURRENCY_SEK" | + "FIAT_ON_RAMP_CURRENCY_THB" | + "FIAT_ON_RAMP_CURRENCY_TRY" | + "FIAT_ON_RAMP_CURRENCY_TWD" | + "FIAT_ON_RAMP_CURRENCY_USD" | + "FIAT_ON_RAMP_CURRENCY_VND" | + "FIAT_ON_RAMP_CURRENCY_ZAR"; export type v1FiatOnRampPaymentMethod = - | "FIAT_ON_RAMP_PAYMENT_METHOD_CREDIT_DEBIT_CARD" - | "FIAT_ON_RAMP_PAYMENT_METHOD_APPLE_PAY" - | "FIAT_ON_RAMP_PAYMENT_METHOD_GBP_BANK_TRANSFER" - | "FIAT_ON_RAMP_PAYMENT_METHOD_GBP_OPEN_BANKING_PAYMENT" - | "FIAT_ON_RAMP_PAYMENT_METHOD_GOOGLE_PAY" - | "FIAT_ON_RAMP_PAYMENT_METHOD_SEPA_BANK_TRANSFER" - | "FIAT_ON_RAMP_PAYMENT_METHOD_PIX_INSTANT_PAYMENT" - | "FIAT_ON_RAMP_PAYMENT_METHOD_PAYPAL" - | "FIAT_ON_RAMP_PAYMENT_METHOD_VENMO" - | "FIAT_ON_RAMP_PAYMENT_METHOD_MOONPAY_BALANCE" - | "FIAT_ON_RAMP_PAYMENT_METHOD_CRYPTO_ACCOUNT" - | "FIAT_ON_RAMP_PAYMENT_METHOD_FIAT_WALLET" - | "FIAT_ON_RAMP_PAYMENT_METHOD_ACH_BANK_ACCOUNT"; + "FIAT_ON_RAMP_PAYMENT_METHOD_CREDIT_DEBIT_CARD" | + "FIAT_ON_RAMP_PAYMENT_METHOD_APPLE_PAY" | + "FIAT_ON_RAMP_PAYMENT_METHOD_GBP_BANK_TRANSFER" | + "FIAT_ON_RAMP_PAYMENT_METHOD_GBP_OPEN_BANKING_PAYMENT" | + "FIAT_ON_RAMP_PAYMENT_METHOD_GOOGLE_PAY" | + "FIAT_ON_RAMP_PAYMENT_METHOD_SEPA_BANK_TRANSFER" | + "FIAT_ON_RAMP_PAYMENT_METHOD_PIX_INSTANT_PAYMENT" | + "FIAT_ON_RAMP_PAYMENT_METHOD_PAYPAL" | + "FIAT_ON_RAMP_PAYMENT_METHOD_VENMO" | + "FIAT_ON_RAMP_PAYMENT_METHOD_MOONPAY_BALANCE" | + "FIAT_ON_RAMP_PAYMENT_METHOD_CRYPTO_ACCOUNT" | + "FIAT_ON_RAMP_PAYMENT_METHOD_FIAT_WALLET" | + "FIAT_ON_RAMP_PAYMENT_METHOD_ACH_BANK_ACCOUNT"; export type v1FiatOnRampProvider = - | "FIAT_ON_RAMP_PROVIDER_COINBASE" - | "FIAT_ON_RAMP_PROVIDER_MOONPAY"; + "FIAT_ON_RAMP_PROVIDER_COINBASE" | + "FIAT_ON_RAMP_PROVIDER_MOONPAY"; export type v1GetActivitiesRequest = { /** Unique identifier for a given Organization. */ @@ -1784,10 +1788,10 @@ export type v1GetWhoamiResponse = { }; export type v1HashFunction = - | "HASH_FUNCTION_NO_OP" - | "HASH_FUNCTION_SHA256" - | "HASH_FUNCTION_KECCAK256" - | "HASH_FUNCTION_NOT_APPLICABLE"; + "HASH_FUNCTION_NO_OP" | + "HASH_FUNCTION_SHA256" | + "HASH_FUNCTION_KECCAK256" | + "HASH_FUNCTION_NOT_APPLICABLE"; export type v1ImportPrivateKeyIntent = { /** The ID of the User importing a Private Key. */ @@ -2173,9 +2177,9 @@ export type v1InvitationParams = { }; export type v1InvitationStatus = - | "INVITATION_STATUS_CREATED" - | "INVITATION_STATUS_ACCEPTED" - | "INVITATION_STATUS_REVOKED"; + "INVITATION_STATUS_CREATED" | + "INVITATION_STATUS_ACCEPTED" | + "INVITATION_STATUS_REVOKED"; export type v1ListPrivateKeyTagsRequest = { /** Unique identifier for a given Organization. */ @@ -2198,15 +2202,15 @@ export type v1ListUserTagsResponse = { }; export type v1MnemonicLanguage = - | "MNEMONIC_LANGUAGE_ENGLISH" - | "MNEMONIC_LANGUAGE_SIMPLIFIED_CHINESE" - | "MNEMONIC_LANGUAGE_TRADITIONAL_CHINESE" - | "MNEMONIC_LANGUAGE_CZECH" - | "MNEMONIC_LANGUAGE_FRENCH" - | "MNEMONIC_LANGUAGE_ITALIAN" - | "MNEMONIC_LANGUAGE_JAPANESE" - | "MNEMONIC_LANGUAGE_KOREAN" - | "MNEMONIC_LANGUAGE_SPANISH"; + "MNEMONIC_LANGUAGE_ENGLISH" | + "MNEMONIC_LANGUAGE_SIMPLIFIED_CHINESE" | + "MNEMONIC_LANGUAGE_TRADITIONAL_CHINESE" | + "MNEMONIC_LANGUAGE_CZECH" | + "MNEMONIC_LANGUAGE_FRENCH" | + "MNEMONIC_LANGUAGE_ITALIAN" | + "MNEMONIC_LANGUAGE_JAPANESE" | + "MNEMONIC_LANGUAGE_KOREAN" | + "MNEMONIC_LANGUAGE_SPANISH"; export type v1NOOPCodegenAnchorResponse = { stamp: v1WebAuthnStamp; @@ -2291,17 +2295,17 @@ export type v1OauthResult = { }; export type v1Operator = - | "OPERATOR_EQUAL" - | "OPERATOR_MORE_THAN" - | "OPERATOR_MORE_THAN_OR_EQUAL" - | "OPERATOR_LESS_THAN" - | "OPERATOR_LESS_THAN_OR_EQUAL" - | "OPERATOR_CONTAINS" - | "OPERATOR_NOT_EQUAL" - | "OPERATOR_IN" - | "OPERATOR_NOT_IN" - | "OPERATOR_CONTAINS_ONE" - | "OPERATOR_CONTAINS_ALL"; + "OPERATOR_EQUAL" | + "OPERATOR_MORE_THAN" | + "OPERATOR_MORE_THAN_OR_EQUAL" | + "OPERATOR_LESS_THAN" | + "OPERATOR_LESS_THAN_OR_EQUAL" | + "OPERATOR_CONTAINS" | + "OPERATOR_NOT_EQUAL" | + "OPERATOR_IN" | + "OPERATOR_NOT_IN" | + "OPERATOR_CONTAINS_ONE" | + "OPERATOR_CONTAINS_ALL"; export type v1OrganizationData = { organizationId?: string; @@ -2383,11 +2387,12 @@ export type v1Pagination = { after?: string; }; -export type v1PathFormat = "PATH_FORMAT_BIP32"; +export type v1PathFormat = + "PATH_FORMAT_BIP32"; export type v1PayloadEncoding = - | "PAYLOAD_ENCODING_HEXADECIMAL" - | "PAYLOAD_ENCODING_TEXT_UTF8"; + "PAYLOAD_ENCODING_HEXADECIMAL" | + "PAYLOAD_ENCODING_TEXT_UTF8"; export type v1Policy = { /** Unique identifier for a given Policy. */ @@ -2798,7 +2803,9 @@ export type v1StampLoginResult = { session: string; }; -export type v1TagType = "TAG_TYPE_USER" | "TAG_TYPE_PRIVATE_KEY"; +export type v1TagType = + "TAG_TYPE_USER" | + "TAG_TYPE_PRIVATE_KEY"; export type v1TestRateLimitsRequest = { /** 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. */ @@ -2811,9 +2818,9 @@ export type v1TestRateLimitsRequest = { export type v1TestRateLimitsResponse = {}; export type v1TransactionType = - | "TRANSACTION_TYPE_ETHEREUM" - | "TRANSACTION_TYPE_SOLANA" - | "TRANSACTION_TYPE_TRON"; + "TRANSACTION_TYPE_ETHEREUM" | + "TRANSACTION_TYPE_SOLANA" | + "TRANSACTION_TYPE_TRON"; export type v1UpdateAllowedOriginsIntent = { /** Additional origins requests are allowed from besides Turnkey origins */ @@ -3235,152 +3242,179 @@ export type v1WebAuthnStamp = { signature: string; }; + // --- API Types from Swagger Paths --- -export type GetActivityResponse = { +export type TGetActivityResponse = { /** An action that can that can be taken within the Turnkey infrastructure. */ activity: v1Activity; -}; +} -export type GetActivityRequest = { +export type TGetActivityBody = { organizationId?: string; /** Unique identifier for a given Activity object. */ activityId: string; -}; +} -export type GetApiKeyResponse = { +export type TGetActivityInput = { body: TGetActivityBody }; + +export type TGetApiKeyResponse = { /** An API key. */ apiKey: v1ApiKey; -}; +} -export type GetApiKeyRequest = { +export type TGetApiKeyBody = { organizationId?: string; /** Unique identifier for a given API key. */ apiKeyId: string; -}; +} + +export type TGetApiKeyInput = { body: TGetApiKeyBody }; -export type GetApiKeysResponse = { +export type TGetApiKeysResponse = { /** A list of API keys. */ apiKeys: v1ApiKey[]; -}; +} -export type GetApiKeysRequest = { +export type TGetApiKeysBody = { organizationId?: string; /** Unique identifier for a given User. */ userId?: string; -}; +} -export type GetAttestationDocumentResponse = { +export type TGetApiKeysInput = { body: TGetApiKeysBody }; + +export type TGetAttestationDocumentResponse = { /** Raw (CBOR-encoded) attestation document */ attestationDocument: string; -}; +} -export type GetAttestationDocumentRequest = { +export type TGetAttestationDocumentBody = { organizationId?: string; /** The enclave type, one of: ump, notarizer, signer, evm-parser */ enclaveType: string; -}; +} + +export type TGetAttestationDocumentInput = { body: TGetAttestationDocumentBody }; -export type GetAuthenticatorResponse = { +export type TGetAuthenticatorResponse = { /** An authenticator. */ authenticator: v1Authenticator; -}; +} -export type GetAuthenticatorRequest = { +export type TGetAuthenticatorBody = { organizationId?: string; /** Unique identifier for a given Authenticator. */ authenticatorId: string; -}; +} -export type GetAuthenticatorsResponse = { +export type TGetAuthenticatorInput = { body: TGetAuthenticatorBody }; + +export type TGetAuthenticatorsResponse = { /** A list of authenticators. */ authenticators: v1Authenticator[]; -}; +} -export type GetAuthenticatorsRequest = { +export type TGetAuthenticatorsBody = { organizationId?: string; /** Unique identifier for a given User. */ userId: string; -}; +} + +export type TGetAuthenticatorsInput = { body: TGetAuthenticatorsBody }; -export type GetOauthProvidersResponse = { +export type TGetOauthProvidersResponse = { /** A list of Oauth Providers */ oauthProviders: v1OauthProvider[]; -}; +} -export type GetOauthProvidersRequest = { +export type TGetOauthProvidersBody = { organizationId?: string; /** Unique identifier for a given User. */ userId?: string; -}; +} + +export type TGetOauthProvidersInput = { body: TGetOauthProvidersBody }; -export type GetOrganizationResponse = { +export type TGetOrganizationResponse = { /** Object representing the full current and deleted / disabled collection of Users, Policies, Private Keys, and Invitations attributable to a particular Organization. */ organizationData: v1OrganizationData; -}; +} -export type GetOrganizationRequest = { +export type TGetOrganizationBody = { organizationId?: string; -}; +} -export type GetOrganizationConfigsResponse = { +export type TGetOrganizationInput = { body: TGetOrganizationBody }; + +export type TGetOrganizationConfigsResponse = { /** Organization configs including quorum settings and organization features */ configs: v1Config; -}; +} -export type GetOrganizationConfigsRequest = { +export type TGetOrganizationConfigsBody = { organizationId?: string; -}; +} + +export type TGetOrganizationConfigsInput = { body: TGetOrganizationConfigsBody }; -export type GetPolicyResponse = { +export type TGetPolicyResponse = { /** Object that codifies rules defining the actions that are permissible within an Organization. */ policy: v1Policy; -}; +} -export type GetPolicyRequest = { +export type TGetPolicyBody = { organizationId?: string; /** Unique identifier for a given Policy. */ policyId: string; -}; +} -export type GetPrivateKeyResponse = { +export type TGetPolicyInput = { body: TGetPolicyBody }; + +export type TGetPrivateKeyResponse = { /** Cryptographic public/private key pair that can be used for cryptocurrency needs or more generalized encryption. */ privateKey: v1PrivateKey; -}; +} -export type GetPrivateKeyRequest = { +export type TGetPrivateKeyBody = { organizationId?: string; /** Unique identifier for a given Private Key. */ privateKeyId: string; -}; +} + +export type TGetPrivateKeyInput = { body: TGetPrivateKeyBody }; -export type GetUserResponse = { +export type TGetUserResponse = { /** Web and/or API user within your Organization. */ user: v1User; -}; +} -export type GetUserRequest = { +export type TGetUserBody = { organizationId?: string; /** Unique identifier for a given User. */ userId: string; -}; +} + +export type TGetUserInput = { body: TGetUserBody }; -export type GetWalletResponse = { +export type TGetWalletResponse = { /** A collection of deterministically generated cryptographic public / private key pairs that share a common seed */ wallet: v1Wallet; -}; +} -export type GetWalletRequest = { +export type TGetWalletBody = { organizationId?: string; /** Unique identifier for a given Wallet. */ walletId: string; -}; +} -export type GetWalletAccountResponse = { +export type TGetWalletInput = { body: TGetWalletBody }; + +export type TGetWalletAccountResponse = { /** The resulting Wallet Account. */ account: v1WalletAccount; -}; +} -export type GetWalletAccountRequest = { +export type TGetWalletAccountBody = { organizationId?: string; /** Unique identifier for a given Wallet. */ walletId: string; @@ -3388,14 +3422,16 @@ export type GetWalletAccountRequest = { address?: string; /** Path corresponding to a Wallet Account. */ path?: string; -}; +} + +export type TGetWalletAccountInput = { body: TGetWalletAccountBody }; -export type GetActivitiesResponse = { +export type TGetActivitiesResponse = { /** A list of Activities. */ activities: v1Activity[]; -}; +} -export type GetActivitiesRequest = { +export type TGetActivitiesBody = { organizationId?: string; /** Array of Activity Statuses filtering which Activities will be listed in the response. */ filterByStatus?: v1ActivityStatus[]; @@ -3403,41 +3439,49 @@ export type GetActivitiesRequest = { paginationOptions?: v1Pagination; /** Array of Activity Types filtering which Activities will be listed in the response. */ filterByType?: v1ActivityType[]; -}; +} -export type GetPoliciesResponse = { +export type TGetActivitiesInput = { body: TGetActivitiesBody }; + +export type TGetPoliciesResponse = { /** A list of Policies. */ policies: v1Policy[]; -}; +} -export type GetPoliciesRequest = { +export type TGetPoliciesBody = { organizationId?: string; -}; +} + +export type TGetPoliciesInput = { body: TGetPoliciesBody }; -export type ListPrivateKeyTagsResponse = { +export type TListPrivateKeyTagsResponse = { /** A list of Private Key Tags */ privateKeyTags: datav1Tag[]; -}; +} -export type ListPrivateKeyTagsRequest = { +export type TListPrivateKeyTagsBody = { organizationId?: string; -}; +} -export type GetPrivateKeysResponse = { +export type TListPrivateKeyTagsInput = { body: TListPrivateKeyTagsBody }; + +export type TGetPrivateKeysResponse = { /** A list of Private Keys. */ privateKeys: v1PrivateKey[]; -}; +} -export type GetPrivateKeysRequest = { +export type TGetPrivateKeysBody = { organizationId?: string; -}; +} -export type GetSubOrgIdsResponse = { +export type TGetPrivateKeysInput = { body: TGetPrivateKeysBody }; + +export type TGetSubOrgIdsResponse = { /** List of unique identifiers for the matching sub-organizations. */ organizationIds: string[]; -}; +} -export type GetSubOrgIdsRequest = { +export type TGetSubOrgIdsBody = { organizationId?: string; /** Specifies the type of filter to apply, i.e 'CREDENTIAL_ID', 'NAME', 'USERNAME', 'EMAIL', 'PHONE_NUMBER', 'OIDC_TOKEN' or 'PUBLIC_KEY' */ filterType?: string; @@ -3445,32 +3489,38 @@ export type GetSubOrgIdsRequest = { filterValue?: string; /** Parameters used for cursor-based pagination. */ paginationOptions?: v1Pagination; -}; +} + +export type TGetSubOrgIdsInput = { body: TGetSubOrgIdsBody }; -export type ListUserTagsResponse = { +export type TListUserTagsResponse = { /** A list of User Tags */ userTags: datav1Tag[]; -}; +} -export type ListUserTagsRequest = { +export type TListUserTagsBody = { organizationId?: string; -}; +} -export type GetUsersResponse = { +export type TListUserTagsInput = { body: TListUserTagsBody }; + +export type TGetUsersResponse = { /** A list of Users. */ users: v1User[]; -}; +} -export type GetUsersRequest = { +export type TGetUsersBody = { organizationId?: string; -}; +} + +export type TGetUsersInput = { body: TGetUsersBody }; -export type GetVerifiedSubOrgIdsResponse = { +export type TGetVerifiedSubOrgIdsResponse = { /** List of unique identifiers for the matching sub-organizations. */ organizationIds: string[]; -}; +} -export type GetVerifiedSubOrgIdsRequest = { +export type TGetVerifiedSubOrgIdsBody = { organizationId?: string; /** Specifies the type of filter to apply, i.e 'EMAIL', 'PHONE_NUMBER' */ filterType?: string; @@ -3478,31 +3528,37 @@ export type GetVerifiedSubOrgIdsRequest = { filterValue?: string; /** Parameters used for cursor-based pagination. */ paginationOptions?: v1Pagination; -}; +} -export type GetWalletAccountsResponse = { +export type TGetVerifiedSubOrgIdsInput = { body: TGetVerifiedSubOrgIdsBody }; + +export type TGetWalletAccountsResponse = { /** A list of Accounts generated from a Wallet that share a common seed. */ accounts: v1WalletAccount[]; -}; +} -export type GetWalletAccountsRequest = { +export type TGetWalletAccountsBody = { organizationId?: string; /** Unique identifier for a given Wallet. */ walletId: string; /** Parameters used for cursor-based pagination. */ paginationOptions?: v1Pagination; -}; +} + +export type TGetWalletAccountsInput = { body: TGetWalletAccountsBody }; -export type GetWalletsResponse = { +export type TGetWalletsResponse = { /** A list of Wallets. */ wallets: v1Wallet[]; -}; +} -export type GetWalletsRequest = { +export type TGetWalletsBody = { organizationId?: string; -}; +} + +export type TGetWalletsInput = { body: TGetWalletsBody }; -export type GetWhoamiResponse = { +export type TGetWhoamiResponse = { /** Unique identifier for a given Organization. */ organizationId: string; /** Human-readable name for an Organization. */ @@ -3511,115 +3567,130 @@ export type GetWhoamiResponse = { userId: string; /** Human-readable name for a User. */ username: string; -}; +} -export type GetWhoamiRequest = { +export type TGetWhoamiBody = { organizationId?: string; -}; +} -export type ApproveActivityResponse = { - /** An action that can that can be taken within the Turnkey infrastructure. */ +export type TGetWhoamiInput = { body: TGetWhoamiBody }; + +export type TApproveActivityResponse = { activity: v1Activity; -}; +} -export type ApproveActivityRequest = { +export type TApproveActivityBody = { timestampMs?: string; organizationId?: string; /** An artifact verifying a User's action. */ fingerprint: string; -}; +} -export type CreateApiKeysResponse = { +export type TApproveActivityInput = { body: TApproveActivityBody }; + +export type TCreateApiKeysResponse = { activity: v1Activity; /** A list of API Key IDs. */ apiKeyIds: string[]; -}; +} -export type CreateApiKeysRequest = { +export type TCreateApiKeysBody = { timestampMs?: string; organizationId?: string; /** A list of API Keys. */ apiKeys: v1ApiKeyParamsV2[]; /** Unique identifier for a given User. */ userId: string; -}; +} + +export type TCreateApiKeysInput = { body: TCreateApiKeysBody }; -export type CreateApiOnlyUsersResponse = { +export type TCreateApiOnlyUsersResponse = { activity: v1Activity; /** A list of API-only User IDs. */ userIds: string[]; -}; +} -export type CreateApiOnlyUsersRequest = { +export type TCreateApiOnlyUsersBody = { timestampMs?: string; organizationId?: string; /** A list of API-only Users to create. */ apiOnlyUsers: v1ApiOnlyUserParams[]; -}; +} -export type CreateAuthenticatorsResponse = { +export type TCreateApiOnlyUsersInput = { body: TCreateApiOnlyUsersBody }; + +export type TCreateAuthenticatorsResponse = { activity: v1Activity; /** A list of Authenticator IDs. */ authenticatorIds: string[]; -}; +} -export type CreateAuthenticatorsRequest = { +export type TCreateAuthenticatorsBody = { timestampMs?: string; organizationId?: string; /** A list of Authenticators. */ authenticators: v1AuthenticatorParamsV2[]; /** Unique identifier for a given User. */ userId: string; -}; +} -export type CreateInvitationsResponse = { +export type TCreateAuthenticatorsInput = { body: TCreateAuthenticatorsBody }; + +export type TCreateInvitationsResponse = { activity: v1Activity; /** A list of Invitation IDs */ invitationIds: string[]; -}; +} -export type CreateInvitationsRequest = { +export type TCreateInvitationsBody = { timestampMs?: string; organizationId?: string; /** A list of Invitations. */ invitations: v1InvitationParams[]; -}; +} + +export type TCreateInvitationsInput = { body: TCreateInvitationsBody }; -export type CreateOauthProvidersResponse = { +export type TCreateOauthProvidersResponse = { activity: v1Activity; /** A list of unique identifiers for Oauth Providers */ providerIds: string[]; -}; +} -export type CreateOauthProvidersRequest = { +export type TCreateOauthProvidersBody = { timestampMs?: string; organizationId?: string; /** The ID of the User to add an Oauth provider to */ userId: string; /** A list of Oauth providers. */ oauthProviders: v1OauthProviderParams[]; -}; +} -export type CreatePoliciesResponse = { +export type TCreateOauthProvidersInput = { body: TCreateOauthProvidersBody }; + +export type TCreatePoliciesResponse = { activity: v1Activity; /** A list of unique identifiers for the created policies. */ policyIds: string[]; -}; +} -export type CreatePoliciesRequest = { +export type TCreatePoliciesBody = { timestampMs?: string; organizationId?: string; /** An array of policy intents to be created. */ policies: v1CreatePolicyIntentV3[]; -}; +} + +export type TCreatePoliciesInput = { body: TCreatePoliciesBody }; -export type CreatePolicyResponse = { +export type TCreatePolicyResponse = { activity: v1Activity; /** Unique identifier for a given Policy. */ policyId: string; -}; +} -export type CreatePolicyRequest = { +export type TCreatePolicyBody = { timestampMs?: string; organizationId?: string; /** Human-readable name for a Policy. */ @@ -3631,39 +3702,45 @@ export type CreatePolicyRequest = { /** The consensus expression that triggers the Effect */ consensus?: string; notes?: string; -}; +} -export type CreatePrivateKeyTagResponse = { +export type TCreatePolicyInput = { body: TCreatePolicyBody }; + +export type TCreatePrivateKeyTagResponse = { activity: v1Activity; /** Unique identifier for a given Private Key Tag. */ privateKeyTagId: string; /** A list of Private Key IDs. */ privateKeyIds: string[]; -}; +} -export type CreatePrivateKeyTagRequest = { +export type TCreatePrivateKeyTagBody = { timestampMs?: string; organizationId?: string; /** Human-readable name for a Private Key Tag. */ privateKeyTagName: string; /** A list of Private Key IDs. */ privateKeyIds: string[]; -}; +} + +export type TCreatePrivateKeyTagInput = { body: TCreatePrivateKeyTagBody }; -export type CreatePrivateKeysResponse = { +export type TCreatePrivateKeysResponse = { activity: v1Activity; /** A list of Private Key IDs and addresses. */ privateKeys: v1PrivateKeyResult[]; -}; +} -export type CreatePrivateKeysRequest = { +export type TCreatePrivateKeysBody = { timestampMs?: string; organizationId?: string; /** A list of Private Keys. */ privateKeys: v1PrivateKeyParams[]; -}; +} + +export type TCreatePrivateKeysInput = { body: TCreatePrivateKeysBody }; -export type CreateReadOnlySessionResponse = { +export type TCreateReadOnlySessionResponse = { activity: v1Activity; /** Unique identifier for a given Organization. If the request is being made by a user and their Sub-Organization ID is unknown, this can be the Parent Organization ID. However, using the Sub-Organization ID is preferred due to performance reasons. */ organizationId: string; @@ -3677,14 +3754,16 @@ export type CreateReadOnlySessionResponse = { session: string; /** UTC timestamp in seconds representing the expiry time for the read only session. */ sessionExpiry: string; -}; +} -export type CreateReadOnlySessionRequest = { +export type TCreateReadOnlySessionBody = { timestampMs?: string; organizationId?: string; -}; +} -export type CreateReadWriteSessionResponse = { +export type TCreateReadOnlySessionInput = { body: TCreateReadOnlySessionBody }; + +export type TCreateReadWriteSessionResponse = { activity: v1Activity; /** Unique identifier for a given Organization. If the request is being made by a user and their Sub-Organization ID is unknown, this can be the Parent Organization ID. However, using the Sub-Organization ID is preferred due to performance reasons. */ organizationId: string; @@ -3698,9 +3777,9 @@ export type CreateReadWriteSessionResponse = { apiKeyId: string; /** HPKE encrypted credential bundle */ credentialBundle: string; -}; +} -export type CreateReadWriteSessionRequest = { +export type TCreateReadWriteSessionBody = { timestampMs?: string; organizationId?: string; /** Client-side public key generated by the user, to which the read write session bundle (credentials) will be encrypted. */ @@ -3713,16 +3792,18 @@ export type CreateReadWriteSessionRequest = { expirationSeconds?: string; /** Invalidate all other previously generated ReadWriteSession API keys */ invalidateExisting?: boolean; -}; +} + +export type TCreateReadWriteSessionInput = { body: TCreateReadWriteSessionBody }; -export type CreateSubOrganizationResponse = { +export type TCreateSubOrganizationResponse = { activity: v1Activity; subOrganizationId: string; wallet?: v1WalletResult; rootUserIds?: string[]; -}; +} -export type CreateSubOrganizationRequest = { +export type TCreateSubOrganizationBody = { timestampMs?: string; organizationId?: string; /** Name for this sub-organization */ @@ -3741,47 +3822,53 @@ export type CreateSubOrganizationRequest = { disableSmsAuth?: boolean; /** Disable OTP email auth for the sub-organization */ disableOtpEmailAuth?: boolean; -}; +} -export type CreateUserTagResponse = { +export type TCreateSubOrganizationInput = { body: TCreateSubOrganizationBody }; + +export type TCreateUserTagResponse = { activity: v1Activity; /** Unique identifier for a given User Tag. */ userTagId: string; /** A list of User IDs. */ userIds: string[]; -}; +} -export type CreateUserTagRequest = { +export type TCreateUserTagBody = { timestampMs?: string; organizationId?: string; /** Human-readable name for a User Tag. */ userTagName: string; /** A list of User IDs. */ userIds: string[]; -}; +} + +export type TCreateUserTagInput = { body: TCreateUserTagBody }; -export type CreateUsersResponse = { +export type TCreateUsersResponse = { activity: v1Activity; /** A list of User IDs. */ userIds: string[]; -}; +} -export type CreateUsersRequest = { +export type TCreateUsersBody = { timestampMs?: string; organizationId?: string; /** A list of Users. */ users: v1UserParamsV3[]; -}; +} -export type CreateWalletResponse = { +export type TCreateUsersInput = { body: TCreateUsersBody }; + +export type TCreateWalletResponse = { activity: v1Activity; /** Unique identifier for a Wallet. */ walletId: string; /** A list of account addresses. */ addresses: string[]; -}; +} -export type CreateWalletRequest = { +export type TCreateWalletBody = { timestampMs?: string; organizationId?: string; /** Human-readable name for a Wallet. */ @@ -3790,189 +3877,215 @@ export type CreateWalletRequest = { accounts: v1WalletAccountParams[]; /** Length of mnemonic to generate the Wallet seed. Defaults to 12. Accepted values: 12, 15, 18, 21, 24. */ mnemonicLength?: number; -}; +} + +export type TCreateWalletInput = { body: TCreateWalletBody }; -export type CreateWalletAccountsResponse = { +export type TCreateWalletAccountsResponse = { activity: v1Activity; /** A list of derived addresses. */ addresses: string[]; -}; +} -export type CreateWalletAccountsRequest = { +export type TCreateWalletAccountsBody = { timestampMs?: string; organizationId?: string; /** Unique identifier for a given Wallet. */ walletId: string; /** A list of wallet Accounts. */ accounts: v1WalletAccountParams[]; -}; +} -export type DeleteApiKeysResponse = { +export type TCreateWalletAccountsInput = { body: TCreateWalletAccountsBody }; + +export type TDeleteApiKeysResponse = { activity: v1Activity; /** A list of API Key IDs. */ apiKeyIds: string[]; -}; +} -export type DeleteApiKeysRequest = { +export type TDeleteApiKeysBody = { timestampMs?: string; organizationId?: string; /** Unique identifier for a given User. */ userId: string; /** A list of API Key IDs. */ apiKeyIds: string[]; -}; +} + +export type TDeleteApiKeysInput = { body: TDeleteApiKeysBody }; -export type DeleteAuthenticatorsResponse = { +export type TDeleteAuthenticatorsResponse = { activity: v1Activity; /** Unique identifier for a given Authenticator. */ authenticatorIds: string[]; -}; +} -export type DeleteAuthenticatorsRequest = { +export type TDeleteAuthenticatorsBody = { timestampMs?: string; organizationId?: string; /** Unique identifier for a given User. */ userId: string; /** A list of Authenticator IDs. */ authenticatorIds: string[]; -}; +} -export type DeleteInvitationResponse = { +export type TDeleteAuthenticatorsInput = { body: TDeleteAuthenticatorsBody }; + +export type TDeleteInvitationResponse = { activity: v1Activity; /** Unique identifier for a given Invitation. */ invitationId: string; -}; +} -export type DeleteInvitationRequest = { +export type TDeleteInvitationBody = { timestampMs?: string; organizationId?: string; /** Unique identifier for a given Invitation object. */ invitationId: string; -}; +} + +export type TDeleteInvitationInput = { body: TDeleteInvitationBody }; -export type DeleteOauthProvidersResponse = { +export type TDeleteOauthProvidersResponse = { activity: v1Activity; /** A list of unique identifiers for Oauth Providers */ providerIds: string[]; -}; +} -export type DeleteOauthProvidersRequest = { +export type TDeleteOauthProvidersBody = { timestampMs?: string; organizationId?: string; /** The ID of the User to remove an Oauth provider from */ userId: string; /** Unique identifier for a given Provider. */ providerIds: string[]; -}; +} + +export type TDeleteOauthProvidersInput = { body: TDeleteOauthProvidersBody }; -export type DeletePolicyResponse = { +export type TDeletePolicyResponse = { activity: v1Activity; /** Unique identifier for a given Policy. */ policyId: string; -}; +} -export type DeletePolicyRequest = { +export type TDeletePolicyBody = { timestampMs?: string; organizationId?: string; /** Unique identifier for a given Policy. */ policyId: string; -}; +} -export type DeletePrivateKeyTagsResponse = { +export type TDeletePolicyInput = { body: TDeletePolicyBody }; + +export type TDeletePrivateKeyTagsResponse = { activity: v1Activity; /** A list of Private Key Tag IDs. */ privateKeyTagIds: string[]; /** A list of Private Key IDs. */ privateKeyIds: string[]; -}; +} -export type DeletePrivateKeyTagsRequest = { +export type TDeletePrivateKeyTagsBody = { timestampMs?: string; organizationId?: string; /** A list of Private Key Tag IDs. */ privateKeyTagIds: string[]; -}; +} + +export type TDeletePrivateKeyTagsInput = { body: TDeletePrivateKeyTagsBody }; -export type DeletePrivateKeysResponse = { +export type TDeletePrivateKeysResponse = { activity: v1Activity; /** A list of private key unique identifiers that were removed */ privateKeyIds: string[]; -}; +} -export type DeletePrivateKeysRequest = { +export type TDeletePrivateKeysBody = { timestampMs?: string; organizationId?: string; /** List of unique identifiers for private keys within an organization */ privateKeyIds: string[]; /** Optional parameter for deleting the private keys, even if any have not been previously exported. If they have been exported, this field is ignored. */ deleteWithoutExport?: boolean; -}; +} -export type DeleteSubOrganizationResponse = { +export type TDeletePrivateKeysInput = { body: TDeletePrivateKeysBody }; + +export type TDeleteSubOrganizationResponse = { activity: v1Activity; /** Unique identifier of the sub organization that was removed */ subOrganizationUuid: string; -}; +} -export type DeleteSubOrganizationRequest = { +export type TDeleteSubOrganizationBody = { timestampMs?: string; organizationId?: string; /** Sub-organization deletion, by default, requires associated wallets and private keys to be exported for security reasons. Set this boolean to true to force sub-organization deletion even if some wallets or private keys within it have not been exported yet. Default: false. */ deleteWithoutExport?: boolean; -}; +} + +export type TDeleteSubOrganizationInput = { body: TDeleteSubOrganizationBody }; -export type DeleteUserTagsResponse = { +export type TDeleteUserTagsResponse = { activity: v1Activity; /** A list of User Tag IDs. */ userTagIds: string[]; /** A list of User IDs. */ userIds: string[]; -}; +} -export type DeleteUserTagsRequest = { +export type TDeleteUserTagsBody = { timestampMs?: string; organizationId?: string; /** A list of User Tag IDs. */ userTagIds: string[]; -}; +} + +export type TDeleteUserTagsInput = { body: TDeleteUserTagsBody }; -export type DeleteUsersResponse = { +export type TDeleteUsersResponse = { activity: v1Activity; /** A list of User IDs. */ userIds: string[]; -}; +} -export type DeleteUsersRequest = { +export type TDeleteUsersBody = { timestampMs?: string; organizationId?: string; /** A list of User IDs. */ userIds: string[]; -}; +} -export type DeleteWalletsResponse = { +export type TDeleteUsersInput = { body: TDeleteUsersBody }; + +export type TDeleteWalletsResponse = { activity: v1Activity; /** A list of wallet unique identifiers that were removed */ walletIds: string[]; -}; +} -export type DeleteWalletsRequest = { +export type TDeleteWalletsBody = { timestampMs?: string; organizationId?: string; /** List of unique identifiers for wallets within an organization */ walletIds: string[]; /** Optional parameter for deleting the wallets, even if any have not been previously exported. If they have been exported, this field is ignored. */ deleteWithoutExport?: boolean; -}; +} + +export type TDeleteWalletsInput = { body: TDeleteWalletsBody }; -export type EmailAuthResponse = { +export type TEmailAuthResponse = { activity: v1Activity; /** Unique identifier for the authenticating User. */ userId: string; /** Unique identifier for the created API key. */ apiKeyId: string; -}; +} -export type EmailAuthRequest = { +export type TEmailAuthBody = { timestampMs?: string; organizationId?: string; /** Email of the authenticating user. */ @@ -3993,34 +4106,38 @@ export type EmailAuthRequest = { sendFromEmailSenderName?: string; /** Optional custom email address to use as reply-to */ replyToEmailAddress?: string; -}; +} -export type ExportPrivateKeyResponse = { +export type TEmailAuthInput = { body: TEmailAuthBody }; + +export type TExportPrivateKeyResponse = { activity: v1Activity; /** Unique identifier for a given Private Key. */ privateKeyId: string; /** Export bundle containing a private key encrypted to the client's target public key. */ exportBundle: string; -}; +} -export type ExportPrivateKeyRequest = { +export type TExportPrivateKeyBody = { timestampMs?: string; organizationId?: string; /** Unique identifier for a given Private Key. */ privateKeyId: string; /** Client-side public key generated by the user, to which the export bundle will be encrypted. */ targetPublicKey: string; -}; +} + +export type TExportPrivateKeyInput = { body: TExportPrivateKeyBody }; -export type ExportWalletResponse = { +export type TExportWalletResponse = { activity: v1Activity; /** Unique identifier for a given Wallet. */ walletId: string; /** Export bundle containing a wallet mnemonic + optional newline passphrase encrypted by the client's target public key. */ exportBundle: string; -}; +} -export type ExportWalletRequest = { +export type TExportWalletBody = { timestampMs?: string; organizationId?: string; /** Unique identifier for a given Wallet. */ @@ -4029,34 +4146,38 @@ export type ExportWalletRequest = { targetPublicKey: string; /** The language of the mnemonic to export. Defaults to English. */ language?: v1MnemonicLanguage; -}; +} -export type ExportWalletAccountResponse = { +export type TExportWalletInput = { body: TExportWalletBody }; + +export type TExportWalletAccountResponse = { activity: v1Activity; /** Address to identify Wallet Account. */ address: string; /** Export bundle containing a private key encrypted by the client's target public key. */ exportBundle: string; -}; +} -export type ExportWalletAccountRequest = { +export type TExportWalletAccountBody = { timestampMs?: string; organizationId?: string; /** Address to identify Wallet Account. */ address: string; /** Client-side public key generated by the user, to which the export bundle will be encrypted. */ targetPublicKey: string; -}; +} -export type ImportPrivateKeyResponse = { +export type TExportWalletAccountInput = { body: TExportWalletAccountBody }; + +export type TImportPrivateKeyResponse = { activity: v1Activity; /** Unique identifier for a Private Key. */ privateKeyId: string; /** A list of addresses. */ addresses: immutableactivityv1Address[]; -}; +} -export type ImportPrivateKeyRequest = { +export type TImportPrivateKeyBody = { timestampMs?: string; organizationId?: string; /** The ID of the User importing a Private Key. */ @@ -4069,17 +4190,19 @@ export type ImportPrivateKeyRequest = { curve: v1Curve; /** Cryptocurrency-specific formats for a derived address (e.g., Ethereum). */ addressFormats: v1AddressFormat[]; -}; +} + +export type TImportPrivateKeyInput = { body: TImportPrivateKeyBody }; -export type ImportWalletResponse = { +export type TImportWalletResponse = { activity: v1Activity; /** Unique identifier for a Wallet. */ walletId: string; /** A list of account addresses. */ addresses: string[]; -}; +} -export type ImportWalletRequest = { +export type TImportWalletBody = { timestampMs?: string; organizationId?: string; /** The ID of the User importing a Wallet. */ @@ -4090,17 +4213,19 @@ export type ImportWalletRequest = { encryptedBundle: string; /** A list of wallet Accounts. */ accounts: v1WalletAccountParams[]; -}; +} -export type InitFiatOnRampResponse = { +export type TImportWalletInput = { body: TImportWalletBody }; + +export type TInitFiatOnRampResponse = { activity: v1Activity; /** Unique URL for a given fiat on-ramp flow. */ onRampUrl: string; /** Unique identifier used to retrieve transaction statuses for a given fiat on-ramp flow. */ onRampTransactionId: string; -}; +} -export type InitFiatOnRampRequest = { +export type TInitFiatOnRampBody = { timestampMs?: string; organizationId?: string; /** Enum to specifiy which on-ramp provider to use */ @@ -4121,41 +4246,47 @@ export type InitFiatOnRampRequest = { countryCode?: string; /** ISO 3166-2 two-digit country subdivision code for Coinbase representing the purchasing user’s subdivision of residence within their country, e.g. NY. Required if country_code=US. */ countrySubdivisionCode?: string; -}; +} + +export type TInitFiatOnRampInput = { body: TInitFiatOnRampBody }; -export type InitImportPrivateKeyResponse = { +export type TInitImportPrivateKeyResponse = { activity: v1Activity; /** Import bundle containing a public key and signature to use for importing client data. */ importBundle: string; -}; +} -export type InitImportPrivateKeyRequest = { +export type TInitImportPrivateKeyBody = { timestampMs?: string; organizationId?: string; /** The ID of the User importing a Private Key. */ userId: string; -}; +} -export type InitImportWalletResponse = { +export type TInitImportPrivateKeyInput = { body: TInitImportPrivateKeyBody }; + +export type TInitImportWalletResponse = { activity: v1Activity; /** Import bundle containing a public key and signature to use for importing client data. */ importBundle: string; -}; +} -export type InitImportWalletRequest = { +export type TInitImportWalletBody = { timestampMs?: string; organizationId?: string; /** The ID of the User importing a Wallet. */ userId: string; -}; +} + +export type TInitImportWalletInput = { body: TInitImportWalletBody }; -export type InitOtpResponse = { +export type TInitOtpResponse = { activity: v1Activity; /** Unique identifier for an OTP authentication */ otpId: string; -}; +} -export type InitOtpRequest = { +export type TInitOtpBody = { timestampMs?: string; organizationId?: string; /** Whether to send OTP via SMS or email. Possible values: OTP_TYPE_SMS, OTP_TYPE_EMAIL */ @@ -4180,15 +4311,17 @@ export type InitOtpRequest = { expirationSeconds?: string; /** Optional custom email address to use as reply-to */ replyToEmailAddress?: string; -}; +} + +export type TInitOtpInput = { body: TInitOtpBody }; -export type InitOtpAuthResponse = { +export type TInitOtpAuthResponse = { activity: v1Activity; /** Unique identifier for an OTP authentication */ otpId: string; -}; +} -export type InitOtpAuthRequest = { +export type TInitOtpAuthBody = { timestampMs?: string; organizationId?: string; /** Enum to specifiy whether to send OTP via SMS or email */ @@ -4211,15 +4344,17 @@ export type InitOtpAuthRequest = { sendFromEmailSenderName?: string; /** Optional custom email address to use as reply-to */ replyToEmailAddress?: string; -}; +} -export type InitUserEmailRecoveryResponse = { +export type TInitOtpAuthInput = { body: TInitOtpAuthBody }; + +export type TInitUserEmailRecoveryResponse = { activity: v1Activity; /** Unique identifier for the user being recovered. */ userId: string; -}; +} -export type InitUserEmailRecoveryRequest = { +export type TInitUserEmailRecoveryBody = { timestampMs?: string; organizationId?: string; /** Email of the user starting recovery */ @@ -4230,9 +4365,11 @@ export type InitUserEmailRecoveryRequest = { expirationSeconds?: string; /** Optional parameters for customizing emails. If not provided, the default email will be used. */ emailCustomization?: v1EmailCustomizationParams; -}; +} + +export type TInitUserEmailRecoveryInput = { body: TInitUserEmailRecoveryBody }; -export type OauthResponse = { +export type TOauthResponse = { activity: v1Activity; /** Unique identifier for the authenticating User. */ userId: string; @@ -4240,9 +4377,9 @@ export type OauthResponse = { apiKeyId: string; /** HPKE encrypted credential bundle */ credentialBundle: string; -}; +} -export type OauthRequest = { +export type TOauthBody = { timestampMs?: string; organizationId?: string; /** Base64 encoded OIDC token */ @@ -4255,15 +4392,17 @@ export type OauthRequest = { expirationSeconds?: string; /** Invalidate all other previously generated Oauth API keys */ invalidateExisting?: boolean; -}; +} -export type OauthLoginResponse = { +export type TOauthInput = { body: TOauthBody }; + +export type TOauthLoginResponse = { activity: v1Activity; /** Signed JWT containing an expiry, public key, session type, user id, and organization id */ session: string; -}; +} -export type OauthLoginRequest = { +export type TOauthLoginBody = { timestampMs?: string; organizationId?: string; /** Base64 encoded OIDC token */ @@ -4274,9 +4413,11 @@ export type OauthLoginRequest = { expirationSeconds?: string; /** Invalidate all other previously generated Login API keys */ invalidateExisting?: boolean; -}; +} + +export type TOauthLoginInput = { body: TOauthLoginBody }; -export type OtpAuthResponse = { +export type TOtpAuthResponse = { activity: v1Activity; /** Unique identifier for the authenticating User. */ userId: string; @@ -4284,9 +4425,9 @@ export type OtpAuthResponse = { apiKeyId?: string; /** HPKE encrypted credential bundle */ credentialBundle?: string; -}; +} -export type OtpAuthRequest = { +export type TOtpAuthBody = { timestampMs?: string; organizationId?: string; /** ID representing the result of an init OTP activity. */ @@ -4301,15 +4442,17 @@ export type OtpAuthRequest = { expirationSeconds?: string; /** Invalidate all other previously generated OTP Auth API keys */ invalidateExisting?: boolean; -}; +} + +export type TOtpAuthInput = { body: TOtpAuthBody }; -export type OtpLoginResponse = { +export type TOtpLoginResponse = { activity: v1Activity; /** Signed JWT containing an expiry, public key, session type, user id, and organization id */ session: string; -}; +} -export type OtpLoginRequest = { +export type TOtpLoginBody = { timestampMs?: string; organizationId?: string; /** Signed JWT containing a unique id, expiry, verification type, contact */ @@ -4320,64 +4463,73 @@ export type OtpLoginRequest = { expirationSeconds?: string; /** Invalidate all other previously generated Login API keys */ invalidateExisting?: boolean; -}; +} -export type RecoverUserResponse = { +export type TOtpLoginInput = { body: TOtpLoginBody }; + +export type TRecoverUserResponse = { activity: v1Activity; /** ID of the authenticator created. */ authenticatorId: string[]; -}; +} -export type RecoverUserRequest = { +export type TRecoverUserBody = { timestampMs?: string; organizationId?: string; /** The new authenticator to register. */ authenticator: v1AuthenticatorParamsV2; /** Unique identifier for the user performing recovery. */ userId: string; -}; +} -export type RejectActivityResponse = { - /** An action that can that can be taken within the Turnkey infrastructure. */ +export type TRecoverUserInput = { body: TRecoverUserBody }; + +export type TRejectActivityResponse = { activity: v1Activity; -}; +} -export type RejectActivityRequest = { +export type TRejectActivityBody = { timestampMs?: string; organizationId?: string; /** An artifact verifying a User's action. */ fingerprint: string; -}; +} + +export type TRejectActivityInput = { body: TRejectActivityBody }; -export type RemoveOrganizationFeatureResponse = { +export type TRemoveOrganizationFeatureResponse = { activity: v1Activity; /** Resulting list of organization features. */ features: v1Feature[]; -}; +} -export type RemoveOrganizationFeatureRequest = { +export type TRemoveOrganizationFeatureBody = { timestampMs?: string; organizationId?: string; /** Name of the feature to remove */ name: v1FeatureName; -}; +} -export type SetOrganizationFeatureResponse = { +export type TRemoveOrganizationFeatureInput = { body: TRemoveOrganizationFeatureBody }; + +export type TSetOrganizationFeatureResponse = { activity: v1Activity; /** Resulting list of organization features. */ features: v1Feature[]; -}; +} -export type SetOrganizationFeatureRequest = { +export type TSetOrganizationFeatureBody = { timestampMs?: string; organizationId?: string; /** Name of the feature to set */ name: v1FeatureName; /** Optional value for the feature. Will override existing values if feature is already set. */ value: string; -}; +} + +export type TSetOrganizationFeatureInput = { body: TSetOrganizationFeatureBody }; -export type SignRawPayloadResponse = { +export type TSignRawPayloadResponse = { activity: v1Activity; /** Component of an ECSDA signature. */ r: string; @@ -4385,9 +4537,9 @@ export type SignRawPayloadResponse = { s: string; /** Component of an ECSDA signature. */ v: string; -}; +} -export type SignRawPayloadRequest = { +export type TSignRawPayloadBody = { timestampMs?: string; organizationId?: string; /** A Wallet account address, Private Key address, or Private Key identifier. */ @@ -4398,14 +4550,16 @@ export type SignRawPayloadRequest = { encoding: v1PayloadEncoding; /** Hash function to apply to payload bytes before signing. This field must be set to HASH_FUNCTION_NOT_APPLICABLE for EdDSA/ed25519 signature requests; configurable payload hashing is not supported by RFC 8032. */ hashFunction: v1HashFunction; -}; +} + +export type TSignRawPayloadInput = { body: TSignRawPayloadBody }; -export type SignRawPayloadsResponse = { +export type TSignRawPayloadsResponse = { activity: v1Activity; signatures?: v1SignRawPayloadResult[]; -}; +} -export type SignRawPayloadsRequest = { +export type TSignRawPayloadsBody = { timestampMs?: string; organizationId?: string; /** A Wallet account address, Private Key address, or Private Key identifier. */ @@ -4416,14 +4570,16 @@ export type SignRawPayloadsRequest = { encoding: v1PayloadEncoding; /** Hash function to apply to payload bytes before signing. This field must be set to HASH_FUNCTION_NOT_APPLICABLE for EdDSA/ed25519 signature requests; configurable payload hashing is not supported by RFC 8032. */ hashFunction: v1HashFunction; -}; +} -export type SignTransactionResponse = { +export type TSignRawPayloadsInput = { body: TSignRawPayloadsBody }; + +export type TSignTransactionResponse = { activity: v1Activity; signedTransaction: string; -}; +} -export type SignTransactionRequest = { +export type TSignTransactionBody = { timestampMs?: string; organizationId?: string; /** A Wallet account address, Private Key address, or Private Key identifier. */ @@ -4431,15 +4587,17 @@ export type SignTransactionRequest = { /** Raw unsigned transaction to be signed */ unsignedTransaction: string; type: v1TransactionType; -}; +} + +export type TSignTransactionInput = { body: TSignTransactionBody }; -export type StampLoginResponse = { +export type TStampLoginResponse = { activity: v1Activity; /** Signed JWT containing an expiry, public key, session type, user id, and organization id */ session: string; -}; +} -export type StampLoginRequest = { +export type TStampLoginBody = { timestampMs?: string; organizationId?: string; /** Client-side public key generated by the user, which will be conditionally added to org data based on the passkey stamp associated with this request */ @@ -4448,15 +4606,17 @@ export type StampLoginRequest = { expirationSeconds?: string; /** Invalidate all other previously generated Login API keys */ invalidateExisting?: boolean; -}; +} -export type UpdatePolicyResponse = { +export type TStampLoginInput = { body: TStampLoginBody }; + +export type TUpdatePolicyResponse = { activity: v1Activity; /** Unique identifier for a given Policy. */ policyId: string; -}; +} -export type UpdatePolicyRequest = { +export type TUpdatePolicyBody = { timestampMs?: string; organizationId?: string; /** Unique identifier for a given Policy. */ @@ -4471,15 +4631,17 @@ export type UpdatePolicyRequest = { policyConsensus?: string; /** Accompanying notes for a Policy (optional). */ policyNotes?: string; -}; +} + +export type TUpdatePolicyInput = { body: TUpdatePolicyBody }; -export type UpdatePrivateKeyTagResponse = { +export type TUpdatePrivateKeyTagResponse = { activity: v1Activity; /** Unique identifier for a given Private Key Tag. */ privateKeyTagId: string; -}; +} -export type UpdatePrivateKeyTagRequest = { +export type TUpdatePrivateKeyTagBody = { timestampMs?: string; organizationId?: string; /** Unique identifier for a given Private Key Tag. */ @@ -4490,28 +4652,32 @@ export type UpdatePrivateKeyTagRequest = { addPrivateKeyIds: string[]; /** A list of Private Key IDs to remove this tag from. */ removePrivateKeyIds: string[]; -}; +} + +export type TUpdatePrivateKeyTagInput = { body: TUpdatePrivateKeyTagBody }; -export type UpdateRootQuorumResponse = { +export type TUpdateRootQuorumResponse = { activity: v1Activity; -}; +} -export type UpdateRootQuorumRequest = { +export type TUpdateRootQuorumBody = { timestampMs?: string; organizationId?: string; /** The threshold of unique approvals to reach quorum. */ threshold: number; /** The unique identifiers of users who comprise the quorum set. */ userIds: string[]; -}; +} -export type UpdateUserResponse = { +export type TUpdateRootQuorumInput = { body: TUpdateRootQuorumBody }; + +export type TUpdateUserResponse = { activity: v1Activity; /** A User ID. */ userId: string; -}; +} -export type UpdateUserRequest = { +export type TUpdateUserBody = { timestampMs?: string; organizationId?: string; /** Unique identifier for a given User. */ @@ -4524,15 +4690,17 @@ export type UpdateUserRequest = { userTagIds?: string[]; /** The user's phone number in E.164 format e.g. +13214567890 */ userPhoneNumber?: string; -}; +} + +export type TUpdateUserInput = { body: TUpdateUserBody }; -export type UpdateUserEmailResponse = { +export type TUpdateUserEmailResponse = { activity: v1Activity; /** Unique identifier of the User whose email was updated. */ userId: string; -}; +} -export type UpdateUserEmailRequest = { +export type TUpdateUserEmailBody = { timestampMs?: string; organizationId?: string; /** Unique identifier for a given User. */ @@ -4541,30 +4709,34 @@ export type UpdateUserEmailRequest = { userEmail: string; /** Signed JWT containing a unique id, expiry, verification type, contact */ verificationToken?: string; -}; +} -export type UpdateUserNameResponse = { +export type TUpdateUserEmailInput = { body: TUpdateUserEmailBody }; + +export type TUpdateUserNameResponse = { activity: v1Activity; /** Unique identifier of the User whose name was updated. */ userId: string; -}; +} -export type UpdateUserNameRequest = { +export type TUpdateUserNameBody = { timestampMs?: string; organizationId?: string; /** Unique identifier for a given User. */ userId: string; /** Human-readable name for a User. */ userName: string; -}; +} + +export type TUpdateUserNameInput = { body: TUpdateUserNameBody }; -export type UpdateUserPhoneNumberResponse = { +export type TUpdateUserPhoneNumberResponse = { activity: v1Activity; /** Unique identifier of the User whose phone number was updated. */ userId: string; -}; +} -export type UpdateUserPhoneNumberRequest = { +export type TUpdateUserPhoneNumberBody = { timestampMs?: string; organizationId?: string; /** Unique identifier for a given User. */ @@ -4573,15 +4745,17 @@ export type UpdateUserPhoneNumberRequest = { userPhoneNumber: string; /** Signed JWT containing a unique id, expiry, verification type, contact */ verificationToken?: string; -}; +} -export type UpdateUserTagResponse = { +export type TUpdateUserPhoneNumberInput = { body: TUpdateUserPhoneNumberBody }; + +export type TUpdateUserTagResponse = { activity: v1Activity; /** Unique identifier for a given User Tag. */ userTagId: string; -}; +} -export type UpdateUserTagRequest = { +export type TUpdateUserTagBody = { timestampMs?: string; organizationId?: string; /** Unique identifier for a given User Tag. */ @@ -4592,30 +4766,34 @@ export type UpdateUserTagRequest = { addUserIds: string[]; /** A list of User IDs to remove this tag from. */ removeUserIds: string[]; -}; +} + +export type TUpdateUserTagInput = { body: TUpdateUserTagBody }; -export type UpdateWalletResponse = { +export type TUpdateWalletResponse = { activity: v1Activity; /** A Wallet ID. */ walletId: string; -}; +} -export type UpdateWalletRequest = { +export type TUpdateWalletBody = { timestampMs?: string; organizationId?: string; /** Unique identifier for a given Wallet. */ walletId: string; /** Human-readable name for a Wallet. */ walletName?: string; -}; +} -export type VerifyOtpResponse = { +export type TUpdateWalletInput = { body: TUpdateWalletBody }; + +export type TVerifyOtpResponse = { activity: v1Activity; /** Signed JWT containing a unique id, expiry, verification type, contact. Verification status of a user is updated when the token is consumed (in OTP_LOGIN requests) */ verificationToken: string; -}; +} -export type VerifyOtpRequest = { +export type TVerifyOtpBody = { timestampMs?: string; organizationId?: string; /** ID representing the result of an init OTP activity. */ @@ -4624,18 +4802,23 @@ export type VerifyOtpRequest = { otpCode: string; /** Expiration window (in seconds) indicating how long the verification token is valid for. If not provided, a default of 1 hour will be used. Maximum value is 86400 seconds (24 hours) */ expirationSeconds?: string; -}; +} -export type NOOPCodegenAnchorResponse = { - stamp: v1WebAuthnStamp; -}; +export type TVerifyOtpInput = { body: TVerifyOtpBody }; + +export type TNOOPCodegenAnchorResponse = { + activity: v1Activity; +} -export type TestRateLimitsResponse = {}; +export type TTestRateLimitsResponse = {}; -export type TestRateLimitsRequest = { +export type TTestRateLimitsBody = { organizationId?: string; /** Whether or not to set a limit on this request. */ isSetLimit: boolean; /** Rate limit to set for org, if is_set_limit is set to true */ limit: number; -}; +} + +export type TTestRateLimitsInput = { body: TTestRateLimitsBody }; + From 7521702c8c311e037bee8c40020e3f5c1e7756eb Mon Sep 17 00:00:00 2001 From: Amir Cheikh Date: Thu, 26 Jun 2025 11:41:34 -0400 Subject: [PATCH 032/184] Polished colors and buttons --- .../src/components/Buttons.tsx | 5 ++-- packages/react-wallet-kit/src/index.css | 15 +++++++++--- .../src/providers/modal/Root.tsx | 23 +++++++++++-------- 3 files changed, 27 insertions(+), 16 deletions(-) diff --git a/packages/react-wallet-kit/src/components/Buttons.tsx b/packages/react-wallet-kit/src/components/Buttons.tsx index 406944564..0480dd0a3 100644 --- a/packages/react-wallet-kit/src/components/Buttons.tsx +++ b/packages/react-wallet-kit/src/components/Buttons.tsx @@ -10,7 +10,7 @@ interface IconButtonProps { } export function BaseButton( - props: React.ButtonHTMLAttributes, + props: React.ButtonHTMLAttributes ) { const { children, className, disabled, ...buttonProps } = props; @@ -26,10 +26,9 @@ export function BaseButton( } export function IconButton(props: IconButtonProps) { const { icon, onClick, disabled, className } = props; - // TODO (Amir): Use standardized colors. Define these and make one for light and dark mode return ( diff --git a/packages/react-wallet-kit/src/index.css b/packages/react-wallet-kit/src/index.css index 2afe08277..13c78fd25 100644 --- a/packages/react-wallet-kit/src/index.css +++ b/packages/react-wallet-kit/src/index.css @@ -5,6 +5,15 @@ @custom-variant dark (&:where(.dark, .dark *)); @theme { - --color-modal-background-light: oklch(1 0 344); - --color-modal-background-dark: oklch(0.2532 0.0056 285.99); -} + --color-primary-light: oklch(0.547 0.2389 266.82); + --color-primary-dark: oklch(0.547 0.2389 266.82); + --color-modal-background-light: oklch(1 0 344); + --color-modal-background-dark: oklch(0.2532 0.0056 285.99); + --color-modal-text-light: oklch(0 0.1 41); + --color-modal-text-dark: rgb(255, 255, 255); + --color-icon-background-light: oklch(0.928 0.006 264.531); + --color-icon-background-dark: oklch(0.3222 0.0053 286.1); + --color-icon-text-light: oklch(0.6066 0 0); + --color-icon-text-dark: oklch(0.7174 0.0029 286.32); + +} \ No newline at end of file diff --git a/packages/react-wallet-kit/src/providers/modal/Root.tsx b/packages/react-wallet-kit/src/providers/modal/Root.tsx index e03d416d0..a037fe932 100644 --- a/packages/react-wallet-kit/src/providers/modal/Root.tsx +++ b/packages/react-wallet-kit/src/providers/modal/Root.tsx @@ -7,7 +7,7 @@ import { } from "@headlessui/react"; import { useModal } from "./Provider"; import { IconButton } from "../../components/Buttons"; -import { faArrowLeft } from "@fortawesome/free-solid-svg-icons"; +import { faArrowLeft, faClose } from "@fortawesome/free-solid-svg-icons"; export function ModalRoot() { const { modalStack, popPage, closeModal } = useModal(); @@ -77,23 +77,26 @@ export function ModalRoot() { width, padding: innerPadding, }} - className="bg-modal-background-light dark:bg-modal-background-dark flex rounded-2xl shadow-xl transition-all" + className="bg-modal-background-light dark:bg-modal-background-dark text-modal-text-light dark:text-modal-text-dark flex rounded-2xl shadow-xl transition-all" >
{hasBack ? ( - + ) : (
)} - + />
Date: Thu, 26 Jun 2025 18:19:33 -0400 Subject: [PATCH 033/184] Auth component started. Google oAuth --- examples/with-sdk-js/src/app/layout.tsx | 12 +- examples/with-sdk-js/src/app/page.tsx | 50 +----- packages/react-wallet-kit/package.json | 4 +- .../src/components/Buttons.tsx | 3 +- .../src/components/auth/OAuth.tsx | 75 +++++++++ .../src/components/auth/index.tsx | 27 ++++ packages/react-wallet-kit/src/index.css | 4 +- .../src/providers/TurnkeyProvider.tsx | 17 +- .../src/providers/client/Provider.tsx | 147 +++++++++--------- .../src/providers/modal/Provider.tsx | 3 +- .../src/providers/modal/Root.tsx | 14 +- pnpm-lock.yaml | 13 ++ 12 files changed, 230 insertions(+), 139 deletions(-) create mode 100644 packages/react-wallet-kit/src/components/auth/OAuth.tsx create mode 100644 packages/react-wallet-kit/src/components/auth/index.tsx diff --git a/examples/with-sdk-js/src/app/layout.tsx b/examples/with-sdk-js/src/app/layout.tsx index 50561f234..f193de4e5 100644 --- a/examples/with-sdk-js/src/app/layout.tsx +++ b/examples/with-sdk-js/src/app/layout.tsx @@ -4,14 +4,6 @@ import { TurnkeyProvider } from "@turnkey/react-wallet-kit"; import "@turnkey/react-wallet-kit/dist/styles.css"; import "./global.css"; -const turnkeyConfig = { - apiBaseUrl: process.env.NEXT_PUBLIC_BASE_URL!, - authProxyUrl: process.env.NEXT_PUBLIC_AUTH_PROXY_URL!, - authProxyId: process.env.NEXT_PUBLIC_AUTH_PROXY_ID!, - defaultOrganizationId: process.env.NEXT_PUBLIC_ORGANIZATION_ID!, - rpId: process.env.NEXT_PUBLIC_RPID!, -}; - interface RootLayoutProps { children: React.ReactNode; } @@ -30,6 +22,10 @@ function RootLayout({ children }: RootLayoutProps) { authProxyUrl: process.env.NEXT_PUBLIC_AUTH_PROXY_URL!, authProxyId: process.env.NEXT_PUBLIC_AUTH_PROXY_ID!, organizationId: process.env.NEXT_PUBLIC_ORGANIZATION_ID!, + auth: { + googleClientId: process.env.NEXT_PUBLIC_GOOGLE_CLIENT_ID, + oAuthRedirectUri: process.env.NEXT_PUBLIC_OAUTH_REDIRECT_URI, + }, passkeyConfig: { rpId: process.env.NEXT_PUBLIC_RPID!, timeout: 60000, // 60 seconds diff --git a/examples/with-sdk-js/src/app/page.tsx b/examples/with-sdk-js/src/app/page.tsx index f3b99a867..90ba88d08 100644 --- a/examples/with-sdk-js/src/app/page.tsx +++ b/examples/with-sdk-js/src/app/page.tsx @@ -18,7 +18,7 @@ export default function AuthPage() { const { pushPage } = useModal(); const [oauthPublicKey, setOauthPublicKey] = useState(""); - const { client, handleGoogleOauth } = useTurnkey(); + const { client, login, handleGoogleOauth } = useTurnkey(); const createPasskey = async () => { await client?.createPasskey({}); @@ -165,53 +165,7 @@ export default function AuthPage() { }; const showModal = () => { - pushPage({ - key: "example-modal", - content: ( -
-

Example Modal

-

This is an example modal content.

- -
- ), - }); + login(); }; return ( diff --git a/packages/react-wallet-kit/package.json b/packages/react-wallet-kit/package.json index b4b8e83e2..295c93f6e 100644 --- a/packages/react-wallet-kit/package.json +++ b/packages/react-wallet-kit/package.json @@ -22,12 +22,14 @@ "license": "MIT", "dependencies": { "@fortawesome/fontawesome-svg-core": "^6.7.2", + "@fortawesome/free-brands-svg-icons": "^6.7.2", "@fortawesome/free-solid-svg-icons": "^6.7.2", "@fortawesome/react-fontawesome": "^0.2.2", "@headlessui/react": "^2.2.4", "@noble/hashes": "^1.8.0", "@turnkey/sdk-js": "workspace:*", - "@turnkey/sdk-types": "workspace:*" + "@turnkey/sdk-types": "workspace:*", + "clsx": "^2.1.1" }, "devDependencies": { "@tailwindcss/postcss": "^4.1.10", diff --git a/packages/react-wallet-kit/src/components/Buttons.tsx b/packages/react-wallet-kit/src/components/Buttons.tsx index 0480dd0a3..5c9f93910 100644 --- a/packages/react-wallet-kit/src/components/Buttons.tsx +++ b/packages/react-wallet-kit/src/components/Buttons.tsx @@ -1,6 +1,7 @@ import type { IconDefinition } from "@fortawesome/fontawesome-svg-core"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { _internal_ComponentButton } from "@headlessui/react"; +import clsx from "clsx"; interface IconButtonProps { icon: IconDefinition; @@ -16,7 +17,7 @@ export function BaseButton( return ( -
- ), + key: "Log in or sign up", + content: , }); - }, []); + }; return ( = ({ client, session, httpClient: client?.httpClient, + login, + handleOauthLoginOrSignup, handleGoogleOauth, }} > diff --git a/packages/react-wallet-kit/src/providers/modal/Provider.tsx b/packages/react-wallet-kit/src/providers/modal/Provider.tsx index 85c2479f0..2016ed440 100644 --- a/packages/react-wallet-kit/src/providers/modal/Provider.tsx +++ b/packages/react-wallet-kit/src/providers/modal/Provider.tsx @@ -1,9 +1,9 @@ import { createContext, useContext, useState, ReactNode } from "react"; -import { ModalRoot } from "./Root"; type ModalPage = { key: string; content: ReactNode; + showTitle?: boolean; }; type ModalContextType = { @@ -36,7 +36,6 @@ export function ModalProvider({ children }: { children: ReactNode }) { value={{ openModal, pushPage, popPage, closeModal, modalStack }} > {children} - ); } diff --git a/packages/react-wallet-kit/src/providers/modal/Root.tsx b/packages/react-wallet-kit/src/providers/modal/Root.tsx index a037fe932..6f699ce6c 100644 --- a/packages/react-wallet-kit/src/providers/modal/Root.tsx +++ b/packages/react-wallet-kit/src/providers/modal/Root.tsx @@ -2,6 +2,7 @@ import { Fragment, useRef, useEffect, useState } from "react"; import { Dialog, DialogPanel, + DialogTitle, Transition, TransitionChild, } from "@headlessui/react"; @@ -80,8 +81,8 @@ export function ModalRoot() { className="bg-modal-background-light dark:bg-modal-background-dark text-modal-text-light dark:text-modal-text-dark flex rounded-2xl shadow-xl transition-all" >
{hasBack ? ( ) : ( -
+
)} + + {current?.showTitle === undefined + ? current?.key + : current.showTitle + ? current?.key + : null} + =6'} + dependencies: + '@fortawesome/fontawesome-common-types': 6.7.2 + dev: false + /@fortawesome/free-solid-svg-icons@6.7.2: resolution: {integrity: sha512-GsBrnOzU8uj0LECDfD5zomZJIjrPhIlWU82AHwa2s40FKH+kcxQaBvBo3Z4TxyZHIyX8XTDxsyA33/Vx9eFuQA==} engines: {node: '>=6'} From aff08ed54c760cbd915405ad42f76986a3ef9172 Mon Sep 17 00:00:00 2001 From: Ethan Konkolowicz Date: Fri, 27 Jun 2025 17:24:58 -0400 Subject: [PATCH 034/184] added all sugared functions from core to react-wallet-kit provider, added more robust session management options --- examples/with-sdk-js/src/app/page.tsx | 167 ++-- packages/react-wallet-kit/package.json | 1 + .../src/components/Buttons.tsx | 2 +- packages/react-wallet-kit/src/index.css | 27 +- .../src/providers/client/Provider.tsx | 523 +++++++++- packages/sdk-js/src/__clients__/core.ts | 254 +++-- packages/sdk-js/src/index.ts | 3 +- packages/sdk-types/src/__generated__/types.ts | 893 +++++++++--------- pnpm-lock.yaml | 37 + 9 files changed, 1246 insertions(+), 661 deletions(-) diff --git a/examples/with-sdk-js/src/app/page.tsx b/examples/with-sdk-js/src/app/page.tsx index 90ba88d08..a3bdccd40 100644 --- a/examples/with-sdk-js/src/app/page.tsx +++ b/examples/with-sdk-js/src/app/page.tsx @@ -5,64 +5,68 @@ import styles from "./index.module.css"; import { StamperType, TurnkeyClient, Wallet } from "@turnkey/sdk-js"; import { useContext, useEffect, useState } from "react"; -import { Session, v1AddressFormat } from "@turnkey/sdk-types"; +import { Session, v1AddressFormat, v1Attestation } from "@turnkey/sdk-types"; import { OtpType } from "@turnkey/sdk-js"; import { useModal, useTurnkey } from "@turnkey/react-wallet-kit"; export default function AuthPage() { - const [session, setSession] = useState(null); const [wallets, setWallets] = useState([]); const [email, setEmail] = useState(""); const [otpCode, setOtpCode] = useState(""); const [otpId, setOtpId] = useState(""); - const { pushPage } = useModal(); - const [oauthPublicKey, setOauthPublicKey] = useState(""); - const { client, login, handleGoogleOauth } = useTurnkey(); - - const createPasskey = async () => { - await client?.createPasskey({}); - }; + const { + httpClient, + session, + allSessions, + login, + handleGoogleOauth, + loginWithPasskey, + createPasskey, + signUpWithPasskey, + fetchUser, + fetchWallets, + initOtp, + completeOtp, + signMessage, + refreshSession, + createWallet, + logout, + setActiveSession, + } = useTurnkey(); + + useEffect(() => { + console.log("All Sessions:", allSessions); + }, [allSessions]); const logInWithPasskey1 = async () => { - await client?.loginWithPasskey({ sessionKey: "session-1" }); + await loginWithPasskey({ sessionKey: "session-1" }); }; const logInWithPasskey2 = async () => { - await client?.loginWithPasskey({ sessionKey: "session-2" }); + await loginWithPasskey({ sessionKey: "session-2" }); }; const indexedDB = async () => { - const resp = await client?.httpClient.getWhoami({}); + const resp = await httpClient?.getWhoami({}); console.log("Response from getWhoami:", resp); }; + const handleCreatePasskey = async () => { + const res = await createPasskey(); + console.log("Created passkey:", res); + }; + const getWallets = async () => { - const res = await client?.fetchWallets({}); + const res = await fetchWallets(); if (res) { setWallets(res); console.log("Wallets:", res); - } else { - console.error("Failed to fetch wallets"); } }; - const initOtp = async () => { - const res = await client?.initOtp({ - otpType: "OTP_TYPE_EMAIL", - contact: email, - }); - - console.log("OTP initialized:", res); - if (!res) { - console.error("Failed to initialize OTP"); - return; - } - setOtpId(res); - }; - - const verifyOtp = async () => { - const res = await client?.verifyOtp({ + const handleVerifyOtp = async () => { + const res = await completeOtp({ otpId, otpCode, contact: email, @@ -70,31 +74,10 @@ export default function AuthPage() { }); console.log("OTP verification response:", res); - - if (!res || !res.verificationToken) { - console.error("Failed to verify OTP"); - return; - } - - if (!res?.subOrganizationId) { - const signupRes = await client?.signUpWithOtp({ - verificationToken: res.verificationToken, - contact: email, - otpType: OtpType.Email, - }); - console.log("OTP verified and user signed up:", signupRes); - return signupRes; - } else { - const loginRes = await client?.loginWithOtp({ - verificationToken: res.verificationToken, - }); - console.log("OTP verified and user logged in:", loginRes); - return loginRes; - } }; const getUser = async () => { - const res = await client?.fetchUser({}); + const res = await fetchUser(); if (res) { console.log("Users:", res); } else { @@ -102,7 +85,7 @@ export default function AuthPage() { } }; - const signMessage = async () => { + const handleSignMessage = async () => { if ( (wallets.length === 0 && !wallets[0]) || !wallets[0].accounts || @@ -113,7 +96,7 @@ export default function AuthPage() { } for (const walletAccount of wallets[0].accounts) { - const res = await client?.signMessage({ + const res = await signMessage({ message: "Hello, Turnkey!", wallet: walletAccount, }); @@ -122,32 +105,21 @@ export default function AuthPage() { } }; - const signUpWithPasskey = async () => { - const res = await client?.signUpWithPasskey({ - passkeyDisplayName: `local-shmocal-passkey_${Date.now()}`, - createSubOrgParams: { - passkeyName: `local-shmocal-passkey_${Date.now()}`, - }, - }); - }; - const handleRefreshSession = async () => { - return await client?.refreshSession({}); + return await refreshSession({}); }; - const createWallet = async (walletName: string) => { + const handleCreateWallet = async (walletName: string) => { // List of all v1AddressFormat values const allAddressFormats: v1AddressFormat[] = [ + "ADDRESS_FORMAT_BITCOIN_MAINNET_P2PKH", + "ADDRESS_FORMAT_BITCOIN_MAINNET_P2WPKH", + "ADDRESS_FORMAT_APTOS", "ADDRESS_FORMAT_ETHEREUM", "ADDRESS_FORMAT_SOLANA", - "ADDRESS_FORMAT_APTOS", - "ADDRESS_FORMAT_BITCOIN_MAINNET_P2PKH", - "ADDRESS_FORMAT_XLM", - "ADDRESS_FORMAT_XRP", - "ADDRESS_FORMAT_TRON", ]; - const res = await client?.createWallet({ + const res = await createWallet({ walletName, accounts: allAddressFormats, }); @@ -155,13 +127,8 @@ export default function AuthPage() { console.log("Created wallet response:", res); }; - const logout = async () => { - client?.logout({}); - // window.location.reload(); - }; - const switchSession = async (sessionKey: string) => { - await client?.setActiveSession({ sessionKey }); + await setActiveSession({ sessionKey }); }; const showModal = () => { @@ -196,7 +163,14 @@ export default function AuthPage() { - {client?.storageManager?.getActiveSession() ? ( + {session ? ( - {client?.storageManager?.getActiveSession() ? ( + {session ? ( ) : null} - {client?.storageManager?.getActiveSession() ? ( + {session ? ( ) : null} - {client?.storageManager?.getActiveSession() ? ( + {session ? ( ) : null} - {client?.storageManager?.getActiveSession() ? ( + {session ? ( ) : null} - {session ? ( + + - ) : null} - {session ? ( - ) : null} {session ? ( + onClick={() => switchSession(SessionKey.DefaultSessionkey)} + style={{ + backgroundColor: "lightblue", + borderRadius: "8px", + padding: "8px 16px", + color: "white", + }} + > + Switch to Default Session + - + - + {session ? (
- -
- {current?.content} -
+
+ {current?.content} +
+
From 08b94615ffe06fa311d13b26621246781c5a773d Mon Sep 17 00:00:00 2001 From: Amir Cheikh Date: Tue, 1 Jul 2025 17:42:13 -0400 Subject: [PATCH 041/184] Auth component functionally complete. Need more mork --- packages/react-wallet-kit/package.json | 4 +- .../src/components/auth/Action.tsx | 63 +++++ .../src/components/auth/Email.tsx | 11 +- .../src/components/auth/OAuth.tsx | 77 +----- .../src/components/auth/OTP.tsx | 35 +-- .../src/components/auth/OrSeparator.tsx | 8 +- .../src/components/auth/Passkey.tsx | 26 ++ .../src/components/auth/Phone.tsx | 56 ++++ .../src/components/auth/index.tsx | 86 +++++- .../src/components/design/Buttons.tsx | 21 +- .../src/components/design/Inputs.tsx | 258 ++++++++++++++++++ packages/react-wallet-kit/src/index.css | 52 +++- .../src/providers/client/Provider.tsx | 12 +- .../src/providers/modal/Root.tsx | 2 +- packages/sdk-js/src/__clients__/core.ts | 6 +- pnpm-lock.yaml | 26 ++ 16 files changed, 616 insertions(+), 127 deletions(-) create mode 100644 packages/react-wallet-kit/src/components/auth/Action.tsx create mode 100644 packages/react-wallet-kit/src/components/auth/Passkey.tsx create mode 100644 packages/react-wallet-kit/src/components/auth/Phone.tsx create mode 100644 packages/react-wallet-kit/src/components/design/Inputs.tsx diff --git a/packages/react-wallet-kit/package.json b/packages/react-wallet-kit/package.json index a894fa0b8..42ef5087b 100644 --- a/packages/react-wallet-kit/package.json +++ b/packages/react-wallet-kit/package.json @@ -30,7 +30,9 @@ "@turnkey/sdk-js": "workspace:*", "@turnkey/sdk-types": "workspace:*", "@turnkey/wallet-stamper": "^1.0.5", - "clsx": "^2.1.1" + "clsx": "^2.1.1", + "libphonenumber-js": "^1.11.14", + "react-international-phone": "^4.3.0" }, "devDependencies": { "@tailwindcss/postcss": "^4.1.10", diff --git a/packages/react-wallet-kit/src/components/auth/Action.tsx b/packages/react-wallet-kit/src/components/auth/Action.tsx new file mode 100644 index 000000000..5c0708f65 --- /dev/null +++ b/packages/react-wallet-kit/src/components/auth/Action.tsx @@ -0,0 +1,63 @@ +import { useRef, useState, useEffect } from "react"; +import { useModal } from "../../providers"; +import { Spinner } from "../design/Spinners"; + +interface ActionPageProps { + title: string; + icon: React.ReactNode; + action?: () => Promise; +} + +export function ActionPage(props: ActionPageProps) { + const { title, icon, action } = props; + const { popPage, closeModal } = useModal(); + const hasRun = useRef(false); + const iconRef = useRef(null); + const [spinnerSize, setSpinnerSize] = useState(40); + + useEffect(() => { + if (iconRef.current) { + const rect = iconRef.current.getBoundingClientRect(); + const size = Math.max(rect.width, rect.height); + setSpinnerSize(size + 50); + } + }, []); + + useEffect(() => { + if (hasRun.current) return; + hasRun.current = true; + const runAction = async () => { + if (action) { + try { + await action(); + } catch (error) { + popPage(); + throw new Error(`${error}`); + } + closeModal(); + } + }; + runAction(); + }, []); + + return ( +
+
+
+
+ {icon} +
+ +
+ {title} +
+
+ ); +} diff --git a/packages/react-wallet-kit/src/components/auth/Email.tsx b/packages/react-wallet-kit/src/components/auth/Email.tsx index 3d8030ffd..7e3a13a55 100644 --- a/packages/react-wallet-kit/src/components/auth/Email.tsx +++ b/packages/react-wallet-kit/src/components/auth/Email.tsx @@ -1,6 +1,6 @@ import { useState } from "react"; import { Input } from "@headlessui/react"; -import { TextButton } from "../design/Buttons"; +import { ActionButton } from "../design/Buttons"; function isValidEmail(email: string): boolean { return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email); @@ -36,9 +36,8 @@ export function EmailInput(props: EmailInputProps) { }; const buttonDisabled = !emailIsValid; - const buttonBgClass = isFocused - ? "bg-primary-light dark:bg-primary-dark hover:bg-primary-light/90 dark:hover:bg-primary-dark/90 text-modal-text-dark" - : "bg-button-light dark:bg-button-dark text-inherit"; + const buttonBgClass = + "bg-primary-light dark:bg-primary-dark hover:bg-primary-light/90 dark:hover:bg-primary-dark/90 text-modal-text-dark"; return (
@@ -55,14 +54,14 @@ export function EmailInput(props: EmailInputProps) { />
- Continue - +
); } diff --git a/packages/react-wallet-kit/src/components/auth/OAuth.tsx b/packages/react-wallet-kit/src/components/auth/OAuth.tsx index e4b0ed7f3..d5fbb1a22 100644 --- a/packages/react-wallet-kit/src/components/auth/OAuth.tsx +++ b/packages/react-wallet-kit/src/components/auth/OAuth.tsx @@ -1,12 +1,10 @@ import { useEffect, useRef, useState } from "react"; -import { BaseButton } from "../design/Buttons"; -import { useModal } from "../../providers"; -import { Spinner } from "../design/Spinners"; +import { ActionButton } from "../design/Buttons"; interface OAuthButtonProps { name: string; icon: React.ReactNode; - onClick?: () => void; + onClick: () => void; className?: string; } @@ -30,11 +28,8 @@ export function OAuthButton(props: OAuthButtonProps) { }, []); return ( -
- + @@ -42,69 +37,7 @@ export function OAuthButton(props: OAuthButtonProps) { {showText && ( {`Continue with ${name}`} )} - -
- ); -} - -interface OAuthLoadingProps { - name: string; - icon: React.ReactNode; - action?: () => Promise; -} - -export function OAuthLoading(props: OAuthLoadingProps) { - const { name, icon, action } = props; - const { popPage, closeModal } = useModal(); - const hasRun = useRef(false); - const iconRef = useRef(null); - const [spinnerSize, setSpinnerSize] = useState(40); - - const displayName = name.charAt(0).toUpperCase() + name.slice(1); - - useEffect(() => { - if (iconRef.current) { - const rect = iconRef.current.getBoundingClientRect(); - const size = Math.max(rect.width, rect.height); - setSpinnerSize(size + 50); - } - }, []); - - useEffect(() => { - if (hasRun.current) return; - hasRun.current = true; - const runAction = async () => { - if (action) { - try { - await action(); - } catch (error) { - popPage(); - throw new Error(`Error during OAuth action: ${error}`); - } - closeModal(); - } - }; - runAction(); - }, []); - - return ( -
-
-
-
- {icon} -
- -
- {`Authenticating with ${displayName}...`} -
+
); } diff --git a/packages/react-wallet-kit/src/components/auth/OTP.tsx b/packages/react-wallet-kit/src/components/auth/OTP.tsx index ae270cc10..49ba99009 100644 --- a/packages/react-wallet-kit/src/components/auth/OTP.tsx +++ b/packages/react-wallet-kit/src/components/auth/OTP.tsx @@ -13,9 +13,16 @@ interface OtpVerificationProps { otpType: OtpType; otpLength?: number; alphanumeric?: boolean; + formattedContact?: string; // Optional formatted contact for display purposes } export function OtpVerification(props: OtpVerificationProps) { - const { contact, otpType, otpLength = 6, alphanumeric = true } = props; + const { + contact, + otpType, + otpLength = 6, + alphanumeric = true, + formattedContact, + } = props; const { initOtp, completeOtp } = useTurnkey(); const { closeModal } = useModal(); const [submitting, setSubmitting] = useState(false); @@ -23,17 +30,11 @@ export function OtpVerification(props: OtpVerificationProps) { const [resent, setResent] = useState(false); const [otpId, setOtpId] = useState(props.otpId); const [error, setError] = useState(null); - const [inputTranslation, setInputTranslation] = useState(0); + const [shaking, setShaking] = useState(false); const shakeInput = () => { - // TODO (Amir): Should maybe use keyframes? - setInputTranslation(5); - setTimeout(() => { - setInputTranslation(-5); - }, 100); - setTimeout(() => { - setInputTranslation(0); - }, 200); + setShaking(true); + setTimeout(() => setShaking(false), 250); }; const handleContinue = async (otpCode: string) => { @@ -91,13 +92,12 @@ export function OtpVerification(props: OtpVerificationProps) {
{`Enter the ${otpLength}-digit code we sent to:`} - {contact} + + {formattedContact ?? contact} +
-
+
{resending ? ( @@ -164,7 +164,7 @@ export function OtpInput(props: OtpInputProps) { const handleKeyDown = ( e: React.KeyboardEvent, - index: number + index: number, ) => { if (e.key === "Backspace" && !values[index] && index > 0) { inputsRef.current[index - 1]?.focus(); @@ -219,6 +219,7 @@ export function OtpInput(props: OtpInputProps) { inputMode={alphanumeric ? "text" : "numeric"} maxLength={1} value={values[i]} + autoComplete="off" onChange={(e) => handleChange(i, e.target.value)} onKeyDown={(e) => handleKeyDown(e, i)} onPaste={handlePaste} diff --git a/packages/react-wallet-kit/src/components/auth/OrSeparator.tsx b/packages/react-wallet-kit/src/components/auth/OrSeparator.tsx index 3c96f597c..221fb0737 100644 --- a/packages/react-wallet-kit/src/components/auth/OrSeparator.tsx +++ b/packages/react-wallet-kit/src/components/auth/OrSeparator.tsx @@ -1,9 +1,11 @@ export function OrSeparator() { return (
-
- OR -
+
+ + OR + +
); } diff --git a/packages/react-wallet-kit/src/components/auth/Passkey.tsx b/packages/react-wallet-kit/src/components/auth/Passkey.tsx new file mode 100644 index 000000000..6c80a5d5f --- /dev/null +++ b/packages/react-wallet-kit/src/components/auth/Passkey.tsx @@ -0,0 +1,26 @@ +import { ActionButton } from "../design/Buttons"; + +interface PasskeyButtonsProps { + onLogin: () => void; + onSignUp: () => void; +} + +export function PasskeyButtons(props: PasskeyButtonsProps) { + const { onLogin, onSignUp } = props; + return ( +
+ + Log in with passkey + + + Sign up with passkey + +
+ ); +} diff --git a/packages/react-wallet-kit/src/components/auth/Phone.tsx b/packages/react-wallet-kit/src/components/auth/Phone.tsx new file mode 100644 index 000000000..adbccf631 --- /dev/null +++ b/packages/react-wallet-kit/src/components/auth/Phone.tsx @@ -0,0 +1,56 @@ +import { useState } from "react"; +import { ActionButton } from "../design/Buttons"; +import { PhoneInputBox } from "../design/Inputs"; + +interface PhoneNumberInputProps { + onContinue?: (phone: string, formattedPhone: string) => void; +} + +export function PhoneNumberInput(props: PhoneNumberInputProps) { + const { onContinue } = props; + const [phone, setPhone] = useState(""); + const [formattedPhone, setformattedPhone] = useState(""); + const [isValid, setIsValid] = useState(false); + const [loading, setLoading] = useState(false); + const [isFocused, setIsFocused] = useState(false); + + const handleContinue = async () => { + if (isValid && onContinue) { + setLoading(true); + try { + await Promise.resolve(onContinue(phone, formattedPhone)); + } finally { + setLoading(false); + } + } + }; + + const buttonDisabled = !isValid; + const buttonBgClass = + "bg-primary-light dark:bg-primary-dark hover:bg-primary-light/90 dark:hover:bg-primary-dark/90 text-modal-text-dark"; + + return ( +
+ { + setPhone(phone); + setformattedPhone(formattedPhone); + setIsValid(valid); + }} + onFocus={() => setIsFocused(true)} + onBlur={() => setIsFocused(false)} + onEnter={handleContinue} + /> + + + Continue + +
+ ); +} diff --git a/packages/react-wallet-kit/src/components/auth/index.tsx b/packages/react-wallet-kit/src/components/auth/index.tsx index 8c2efbc00..4c440bb66 100644 --- a/packages/react-wallet-kit/src/components/auth/index.tsx +++ b/packages/react-wallet-kit/src/components/auth/index.tsx @@ -1,21 +1,26 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { OAuthButton, OAuthLoading } from "./OAuth"; +import { OAuthButton } from "./OAuth"; import { faGoogle } from "@fortawesome/free-brands-svg-icons"; import { useModal, useTurnkey } from "../../providers"; import { EmailInput } from "./Email"; import { OrSeparator } from "./OrSeparator"; import { OtpVerification } from "./OTP"; import { OtpType } from "@turnkey/sdk-js"; +import { PhoneNumberInput } from "./Phone"; +import { ActionPage } from "./Action"; +import { PasskeyButtons } from "./Passkey"; +import { faFingerprint } from "@fortawesome/free-solid-svg-icons"; export function AuthComponent() { - const { handleGoogleOauth, initOtp } = useTurnkey(); + const { handleGoogleOauth, initOtp, loginWithPasskey, signUpWithPasskey } = + useTurnkey(); const { pushPage } = useModal(); const handleEmailSubmit = async (email: string) => { try { const otpId = await initOtp({ otpType: OtpType.Email, contact: email }); pushPage({ - key: "Verify Email", + key: "Verify OTP", content: ( { + try { + const otpId = await initOtp({ + otpType: OtpType.Sms, + contact: phone, + }); + pushPage({ + key: "Verify OTP", + content: ( + + ), + showTitle: false, + }); + } catch (error) { + throw new Error(`Error initializing OTP: ${error}`); + } + }; + + const handlePasskeyLogin = () => { + pushPage({ + key: "Passkey Login", + content: ( + { + await loginWithPasskey({}); + }} + icon={} + /> + ), + showTitle: false, + }); + }; + + const handlePasskeySignUp = () => { + pushPage({ + key: "Passkey Sign Up", + content: ( + { + const websiteName = window.location.hostname; + const timestamp = Date.now(); + const passkeyDisplayName = `${websiteName}-${timestamp}`; + + await signUpWithPasskey({ + passkeyDisplayName, + }); + }} + icon={} + /> + ), + showTitle: false, + }); + }; + return ( -
+
handleGoogleOauth({ additionalState: { openModal: "true" }, // Tell the provider to reopen the auth modal and show the loading state @@ -57,6 +124,13 @@ export function AuthComponent() {
+ + + +
); } diff --git a/packages/react-wallet-kit/src/components/design/Buttons.tsx b/packages/react-wallet-kit/src/components/design/Buttons.tsx index 48d1b56ff..0b8d630c5 100644 --- a/packages/react-wallet-kit/src/components/design/Buttons.tsx +++ b/packages/react-wallet-kit/src/components/design/Buttons.tsx @@ -12,13 +12,13 @@ interface IconButtonProps { } export function BaseButton( - props: React.ButtonHTMLAttributes + props: React.ButtonHTMLAttributes, ) { const { children, className, disabled, ...buttonProps } = props; return (
) : ( - {children} + children )} ); diff --git a/packages/react-wallet-kit/src/components/design/Inputs.tsx b/packages/react-wallet-kit/src/components/design/Inputs.tsx new file mode 100644 index 000000000..5f87ab421 --- /dev/null +++ b/packages/react-wallet-kit/src/components/design/Inputs.tsx @@ -0,0 +1,258 @@ +import { + usePhoneInput, + parseCountry, + defaultCountries, + FlagImage as OriginalFlagImage, +} from "react-international-phone"; +import { + Input, + ListboxButton, + ListboxOption, + ListboxOptions, +} from "@headlessui/react"; +import { Listbox } from "@headlessui/react"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { faChevronDown } from "@fortawesome/free-solid-svg-icons"; +import parsePhoneNumberFromString from "libphonenumber-js"; + +const FlagImage = OriginalFlagImage as React.ElementType; + +// Supported country dial codes +const supported_country_codes = [ + "+1", + "+33", + "+420", + "+358", + "+49", + "+30", + "+36", + "+354", + "+353", + "+39", + "+371", + "+370", + "+352", + "+356", + "+373", + "+382", + "+31", + "+47", + "+48", + "+351", + "+40", + "+381", + "+386", + "+34", + "+46", + "+41", + "+355", + "+376", + "+244", + "+54", + "+374", + "+61", + "+43", + "+994", + "+1242", + "+973", + "+880", + "+1246", + "+32", + "+501", + "+229", + "+591", + "+387", + "+267", + "+55", + "+1284", + "+673", + "+237", + "+238", + "+1345", + "+235", + "+56", + "+57", + "+506", + "+385", + "+599", + "+357", + "+243", + "+45", + "+253", + "+1767", + "+593", + "+503", + "+240", + "+372", + "+298", + "+679", + "+689", + "+220", + "+995", + "+233", + "+350", + "+1473", + "+502", + "+590", + "+224", + "+592", + "+509", + "+504", + "+852", + "+91", + "+62", + "+972", + "+225", + "+1876", + "+81", + "+383", + "+965", + "+996", + "+856", + "+961", + "+266", + "+231", + "+261", + "+60", + "+960", + "+223", + "+230", + "+52", + "+373", + "+976", + "+212", + "+258", + "+264", + "+977", + "+64", + "+505", + "+227", + "+234", + "+92", + "+507", + "+51", + "+63", + "+1787", + "+1939", + "+974", + "+262", + "+1758", + "+1784", + "+685", + "+966", + "+221", + "+248", + "+232", + "+65", + "+27", + "+82", + "+597", + "+268", + "+992", + "+255", + "+66", + "+228", + "+1868", + "+216", + "+598", + "+998", + "+58", +]; + +const countries = defaultCountries.filter((country) => { + const { dialCode } = parseCountry(country); + return supported_country_codes.includes(`+${dialCode}`); +}); + +export interface PhoneInputBoxProps { + value: string; + onChange: (phone: string, formattedPhone: string, isValid: boolean) => void; + onFocus?: () => void; + onBlur?: () => void; + onEnter?: () => void; +} + +const isValidPhone = (phone: string) => { + const phoneNumber = parsePhoneNumberFromString(phone); + return phoneNumber?.isValid() ?? false; +}; + +export function PhoneInputBox(props: PhoneInputBoxProps) { + const { value, onChange, onFocus, onBlur, onEnter } = props; + const { inputValue, handlePhoneValueChange, inputRef, country, setCountry } = + usePhoneInput({ + value, + defaultCountry: "us", + disableDialCodeAndPrefix: true, + countries, + onChange: (data) => { + onChange( + data.phone, + `+${data.country.dialCode} ${data.inputValue}`, + isValidPhone(data.phone), + ); + }, + }); + + return ( +
+ +
+ + + + + +{country.dialCode} + + + + + + + {countries.map((c) => { + const { iso2, name, dialCode } = parseCountry(c); + return ( + + `cursor-pointer select-none py-2 px-3 flex items-center gap-2 ${ + active ? "bg-gray-100 dark:bg-modal-background-dark" : "" + }` + } + > + + {name} + + +{dialCode} + + + ); + })} + +
+
+ + { + if (e.key === "Enter") onEnter?.(); + }} + placeholder="Phone number" + className="w-full py-3 bg-transparent border-none text-inherit focus:outline-none focus:ring-0 focus:border-none" + /> +
+ ); +} diff --git a/packages/react-wallet-kit/src/index.css b/packages/react-wallet-kit/src/index.css index 21f8c11d2..f94567d1c 100644 --- a/packages/react-wallet-kit/src/index.css +++ b/packages/react-wallet-kit/src/index.css @@ -8,7 +8,7 @@ --color-primary-light: oklch(0.547 0.2389 266.82); --color-primary-dark: oklch(0.547 0.2389 266.82); --color-button-light: rgb(255, 255, 255); - --color-button-dark: oklch(0 0.1 41); + --color-button-dark: oklch(0.15 0 0); --color-modal-background-light: oklch(0.9758 0.0057 264.53); --color-modal-background-dark: oklch(0.2532 0.0056 285.99); --color-modal-text-light: oklch(0 0.1 41); @@ -17,6 +17,20 @@ --color-icon-background-dark: oklch(0.3222 0.0053 286.1); --color-icon-text-light: oklch(0.6066 0 0); --color-icon-text-dark: oklch(0.7174 0.0029 286.32); + + --animate-shake: shake 250ms ease-in-out; + @keyframes shake { + 0%, + 100% { + transform: translateX(0); + } + 25% { + transform: translateX(-5px); + } + 75% { + transform: translateX(5px); + } + } } @layer base { @@ -34,3 +48,39 @@ caret-color: var(--color-modal-text-dark); } } + +@layer components { + /* A nice scrollbar that conforms to light/dark mode */ + .tk-scrollbar { + /* For Firefox */ + scrollbar-width: thin; + scrollbar-color: var(--color-icon-text-light) + var(--color-icon-background-light); /* thumb and track (light mode) */ + } + /* For WebKit browsers */ + .tk-scrollbar::-webkit-scrollbar { + width: 8px; + height: 8px; + } + .tk-scrollbar::-webkit-scrollbar-track { + background: var(--color-icon-background-light); + } + .tk-scrollbar::-webkit-scrollbar-thumb { + background-color: var(--color-icon-text-light); + border-radius: 10px; + border: 2px solid var(--color-icon-background-light); + } + + /* Dark mode styles */ + .dark .tk-scrollbar { + scrollbar-color: var(--color-icon-text-dark) + var(--color-icon-background-dark); /* thumb and track (dark mode) */ + } + .dark .tk-scrollbar::-webkit-scrollbar-track { + background: var(--color-icon-background-dark); + } + .dark .tk-scrollbar::-webkit-scrollbar-thumb { + background-color: var(--color-icon-text-dark); + border: 2px solid var(--color-icon-background-dark); + } +} diff --git a/packages/react-wallet-kit/src/providers/client/Provider.tsx b/packages/react-wallet-kit/src/providers/client/Provider.tsx index 857875317..8f3214120 100644 --- a/packages/react-wallet-kit/src/providers/client/Provider.tsx +++ b/packages/react-wallet-kit/src/providers/client/Provider.tsx @@ -48,10 +48,10 @@ import { import { useModal } from "../modal/Provider"; import { TurnkeyCallbacks, TurnkeyProviderConfig } from "../TurnkeyProvider"; import { AuthComponent } from "../../components/auth"; -import { OAuthLoading } from "../../components/auth/OAuth"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faGoogle } from "@fortawesome/free-brands-svg-icons"; import { WalletType } from "@turnkey/wallet-stamper"; +import { ActionPage } from "../../components/auth/Action"; interface ClientProviderProps { children: ReactNode; @@ -135,12 +135,15 @@ export const ClientProvider: React.FC = ({ if (idToken && flow === "redirect") { if (openModal === "true") { + const providerName = provider + ? provider?.charAt(0).toUpperCase() + provider?.slice(1) + : "Provider"; // This state is set when the OAuth flow comes from the AuthComponent. We handle it differently because the callback is ran inside the loading component. pushPage({ - key: "Log in or sign up", + key: "Google OAuth", content: ( - { await completeOauth({ oidcToken: idToken, @@ -153,6 +156,7 @@ export const ClientProvider: React.FC = ({ icon={} /> ), + showTitle: false, }); } else if (callbacks?.onOauthRedirect) { callbacks.onOauthRedirect({ idToken, publicKey }); diff --git a/packages/react-wallet-kit/src/providers/modal/Root.tsx b/packages/react-wallet-kit/src/providers/modal/Root.tsx index 03022033a..cd696328f 100644 --- a/packages/react-wallet-kit/src/providers/modal/Root.tsx +++ b/packages/react-wallet-kit/src/providers/modal/Root.tsx @@ -136,7 +136,7 @@ export function ModalRoot() { />
>>>>>> 15d426e9 (Auth component functionally complete. Need more mork) resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} react-is@18.3.1: From 48cf92bead622e81195c44b428586b6faee2826f Mon Sep 17 00:00:00 2001 From: Ethan Konkolowicz Date: Wed, 2 Jul 2025 14:28:09 -0400 Subject: [PATCH 042/184] better errors and error handling --- examples/with-sdk-js/src/app/layout.tsx | 5 + .../src/providers/TurnkeyProvider.tsx | 3 +- .../src/providers/client/Provider.tsx | 766 ++++++++++++---- packages/react-wallet-kit/src/utils.ts | 23 +- packages/sdk-js/src/__clients__/core.ts | 841 ++++++++++++------ packages/sdk-types/src/index.ts | 53 +- 6 files changed, 1243 insertions(+), 448 deletions(-) diff --git a/examples/with-sdk-js/src/app/layout.tsx b/examples/with-sdk-js/src/app/layout.tsx index 80e139d1d..fb7c60439 100644 --- a/examples/with-sdk-js/src/app/layout.tsx +++ b/examples/with-sdk-js/src/app/layout.tsx @@ -35,6 +35,11 @@ function RootLayout({ children }: RootLayoutProps) { }, autoRefreshSession: true, }} + callbacks={{ + onError: (error) => { + console.log("Turnkey error:", error.code); + }, + }} > {children} diff --git a/packages/react-wallet-kit/src/providers/TurnkeyProvider.tsx b/packages/react-wallet-kit/src/providers/TurnkeyProvider.tsx index 1312af473..0f735d7d3 100644 --- a/packages/react-wallet-kit/src/providers/TurnkeyProvider.tsx +++ b/packages/react-wallet-kit/src/providers/TurnkeyProvider.tsx @@ -2,7 +2,7 @@ import { TurnkeySDKClientConfig } from "@turnkey/sdk-js"; import { ClientProvider } from "./client/Provider"; import { ModalProvider } from "./modal/Provider"; import { ModalRoot } from "./modal/Root"; -import { Session } from "@turnkey/sdk-types"; +import { Session, TurnkeyError, TurnkeyNetworkError } from "@turnkey/sdk-types"; export interface TurnkeyProviderConfig extends TurnkeySDKClientConfig { auth?: { @@ -18,6 +18,7 @@ export interface TurnkeyCallbacks { beforeSessionExpiry?: (params: { sessionKey: string }) => void; onSessionExpired?: (params: { sessionKey: string }) => void; onAuthenticationSuccess?: (params: { session: Session | undefined }) => void; + onError?: (error: TurnkeyError | TurnkeyNetworkError) => void; } export function TurnkeyProvider({ diff --git a/packages/react-wallet-kit/src/providers/client/Provider.tsx b/packages/react-wallet-kit/src/providers/client/Provider.tsx index 8f3214120..617a4c283 100644 --- a/packages/react-wallet-kit/src/providers/client/Provider.tsx +++ b/packages/react-wallet-kit/src/providers/client/Provider.tsx @@ -7,6 +7,7 @@ import { popupHeight, popupWidth, SESSION_WARNING_THRESHOLD_MS, + withTurnkeyErrorHandling, } from "../../utils"; import { CreateSubOrgParams, @@ -35,6 +36,9 @@ import { TGetWalletAccountsResponse, TSignTransactionResponse, TStampLoginResponse, + TurnkeyError, + TurnkeyErrorCodes, + TurnkeyNetworkError, v1AddressFormat, v1Attestation, v1AuthenticatorParamsV2, @@ -201,59 +205,95 @@ export const ClientProvider: React.FC = ({ }, [client]); const initializeClient = async () => { - const turnkeyClient = new TurnkeyClient({ - apiBaseUrl: config.apiBaseUrl, - authProxyUrl: config.authProxyUrl, - authProxyId: config.authProxyId, - organizationId: config.organizationId, - passkeyConfig: { - rpId: config.passkeyConfig?.rpId, - timeout: config.passkeyConfig?.timeout || 60000, // 60 seconds - userVerification: config.passkeyConfig?.userVerification || "preferred", - allowCredentials: config.passkeyConfig?.allowCredentials || [], - }, - }); - - setAutoRefreshSession(config?.autoRefreshSession ?? false); - - await turnkeyClient.init(); - setClient(turnkeyClient); + try { + const turnkeyClient = new TurnkeyClient({ + apiBaseUrl: config.apiBaseUrl, + authProxyUrl: config.authProxyUrl, + authProxyId: config.authProxyId, + organizationId: config.organizationId, + passkeyConfig: { + rpId: config.passkeyConfig?.rpId, + timeout: config.passkeyConfig?.timeout || 60000, // 60 seconds + userVerification: + config.passkeyConfig?.userVerification || "preferred", + allowCredentials: config.passkeyConfig?.allowCredentials || [], + }, + }); + + setAutoRefreshSession(config?.autoRefreshSession ?? false); + + await turnkeyClient.init(); + setClient(turnkeyClient); + } catch (error) { + if ( + error instanceof TurnkeyError || + error instanceof TurnkeyNetworkError + ) { + callbacks?.onError?.(error); + } else { + callbacks?.onError?.( + new TurnkeyError( + `Failed to initialize Turnkey client`, + TurnkeyErrorCodes.INITIALIZE_CLIENT_ERROR, + error, + ), + ); + } + } }; const initializeSessions = async () => { setAuthState(AuthState.Loading); - const allSessions = await getAllSessions(); - if (!allSessions) { - setAuthState(AuthState.Unauthenticated); - return; - } + try { + const allSessions = await getAllSessions(); + if (!allSessions) { + setAuthState(AuthState.Unauthenticated); + return; + } - await Promise.all( - Object.keys(allSessions).map(async (sessionKey) => { - const session = allSessions?.[sessionKey]; - if (!isValidSession(session)) { - await clearSession({ sessionKey }); - return; - } + await Promise.all( + Object.keys(allSessions).map(async (sessionKey) => { + const session = allSessions?.[sessionKey]; + if (!isValidSession(session)) { + await clearSession({ sessionKey }); + return; + } - scheduleSessionExpiration({ - sessionKey, - expiry: session!.expiry, - }); - }), - ); + scheduleSessionExpiration({ + sessionKey, + expiry: session!.expiry, + }); + }), + ); - setAllSessions(allSessions); - const activeSessionKey = await client?.getActiveSessionKey(); - if (activeSessionKey) { - setSession(allSessions?.[activeSessionKey]); - await refreshUser(); - await refreshWallets(); + setAllSessions(allSessions); + const activeSessionKey = await client?.getActiveSessionKey(); + if (activeSessionKey) { + setSession(allSessions?.[activeSessionKey]); + await refreshUser(); + await refreshWallets(); - setAuthState(AuthState.Authenticated); - return; + setAuthState(AuthState.Authenticated); + return; + } + setAuthState(AuthState.Unauthenticated); + } catch (error) { + if ( + error instanceof TurnkeyError || + error instanceof TurnkeyNetworkError + ) { + callbacks?.onError?.(error); + } else { + callbacks?.onError?.( + new TurnkeyError( + `Failed to initialize sessions`, + TurnkeyErrorCodes.INITIALIZE_SESSION_ERROR, + error, + ), + ); + } + setAuthState(AuthState.Unauthenticated); } - setAuthState(AuthState.Unauthenticated); }; async function scheduleSessionExpiration(params: { @@ -262,99 +302,160 @@ export const ClientProvider: React.FC = ({ }) { const { sessionKey, expiry } = params; - // Clear any existing timeout for this session key - if (expiryTimeoutsRef.current[sessionKey]) { - clearTimeout(expiryTimeoutsRef.current[sessionKey]); - } + try { + // Clear any existing timeout for this session key + if (expiryTimeoutsRef.current[sessionKey]) { + clearTimeout(expiryTimeoutsRef.current[sessionKey]); + } - if (expiryTimeoutsRef.current[`${sessionKey}-warning`]) { - clearTimeout(expiryTimeoutsRef.current[`${sessionKey}-warning`]); - } + if (expiryTimeoutsRef.current[`${sessionKey}-warning`]) { + clearTimeout(expiryTimeoutsRef.current[`${sessionKey}-warning`]); + } - const timeUntilExpiry = expiry * 1000 - Date.now(); + const timeUntilExpiry = expiry * 1000 - Date.now(); - const beforeExpiry = async () => { - console.log("Session is about to expire, refreshing session..."); - const activeSession = await getSession(); - if (!activeSession && expiryTimeoutsRef.current[sessionKey]) { - expiryTimeoutsRef.current[`${sessionKey}-warning`] = setTimeout( - beforeExpiry, - 10000, - ); - return; - } + const beforeExpiry = async () => { + console.log("Session is about to expire, refreshing session..."); + const activeSession = await getSession(); + if (!activeSession && expiryTimeoutsRef.current[sessionKey]) { + expiryTimeoutsRef.current[`${sessionKey}-warning`] = setTimeout( + beforeExpiry, + 10000, + ); + return; + } - const session = await getSession({ sessionKey }); - if (!session) return; + const session = await getSession({ sessionKey }); + if (!session) return; - callbacks?.beforeSessionExpiry?.({ sessionKey }); - if (autoRefreshSession) { - await refreshSession({ - sessionType: session.sessionType, - sessionKey, - }); - } - delete expiryTimeoutsRef.current[`${sessionKey}-warning`]; - }; + callbacks?.beforeSessionExpiry?.({ sessionKey }); + if (autoRefreshSession) { + await refreshSession({ + sessionType: session.sessionType, + sessionKey, + }); + } + delete expiryTimeoutsRef.current[`${sessionKey}-warning`]; + }; - const expireSession = async () => { - const expiredSession = await getSession({ sessionKey }); - if (!expiredSession) return; + const expireSession = async () => { + const expiredSession = await getSession({ sessionKey }); + if (!expiredSession) return; - callbacks?.onSessionExpired?.({ sessionKey }); + callbacks?.onSessionExpired?.({ sessionKey }); - await clearSession({ sessionKey }); + await clearSession({ sessionKey }); - delete expiryTimeoutsRef.current[sessionKey]; - delete expiryTimeoutsRef.current[`${sessionKey}-warning`]; - }; + delete expiryTimeoutsRef.current[sessionKey]; + delete expiryTimeoutsRef.current[`${sessionKey}-warning`]; + }; - if (timeUntilExpiry <= SESSION_WARNING_THRESHOLD_MS) { - beforeExpiry(); - } else { - expiryTimeoutsRef.current[`${sessionKey}-warning`] = setTimeout( - beforeExpiry, - timeUntilExpiry - SESSION_WARNING_THRESHOLD_MS, + if (timeUntilExpiry <= SESSION_WARNING_THRESHOLD_MS) { + beforeExpiry(); + } else { + expiryTimeoutsRef.current[`${sessionKey}-warning`] = setTimeout( + beforeExpiry, + timeUntilExpiry - SESSION_WARNING_THRESHOLD_MS, + ); + } + + expiryTimeoutsRef.current[sessionKey] = setTimeout( + expireSession, + timeUntilExpiry, ); + } catch (error) { + if ( + error instanceof TurnkeyError || + error instanceof TurnkeyNetworkError + ) { + callbacks?.onError?.(error); + } else { + callbacks?.onError?.( + new TurnkeyError( + `Failed to schedule session expiration for ${sessionKey}`, + TurnkeyErrorCodes.SCHEDULE_SESSION_EXPIRY_ERROR, + error, + ), + ); + } } - - expiryTimeoutsRef.current[sessionKey] = setTimeout( - expireSession, - timeUntilExpiry, - ); } function clearSessionTimeouts() { - Object.values(expiryTimeoutsRef.current).forEach((timeout) => { - clearTimeout(timeout); - }); - expiryTimeoutsRef.current = {}; + try { + Object.values(expiryTimeoutsRef.current).forEach((timeout) => { + clearTimeout(timeout); + }); + expiryTimeoutsRef.current = {}; + } catch (error) { + if ( + error instanceof TurnkeyError || + error instanceof TurnkeyNetworkError + ) { + callbacks?.onError?.(error); + } else { + callbacks?.onError?.( + new TurnkeyError( + `Failed to clear session timeouts`, + TurnkeyErrorCodes.CLEAR_SESSION_TIMEOUTS_ERROR, + error, + ), + ); + } + } } const handlePostAuth = async () => { - const sessionKey = await client!.getActiveSessionKey(); - const session = await client!.getSession({ - ...(sessionKey && { sessionKey }), - }); + try { + const sessionKey = await client!.getActiveSessionKey(); + const session = await client!.getSession({ + ...(sessionKey && { sessionKey }), + }); - if (session && sessionKey) - await scheduleSessionExpiration({ sessionKey, expiry: session.expiry }); + if (session && sessionKey) + await scheduleSessionExpiration({ sessionKey, expiry: session.expiry }); - const allSessions = await client!.getAllSessions(); + const allSessions = await client!.getAllSessions(); - await refreshWallets(); - await refreshUser(); + await refreshWallets(); + await refreshUser(); - setSession(session); - setAllSessions(allSessions); + setSession(session); + setAllSessions(allSessions); + } catch (error) { + if ( + error instanceof TurnkeyError || + error instanceof TurnkeyNetworkError + ) { + callbacks?.onError?.(error); + } else { + callbacks?.onError?.( + new TurnkeyError( + `Failed to handle post-authentication`, + TurnkeyErrorCodes.HANDLE_POST_AUTH_ERROR, + error, + ), + ); + } + } }; const handlePostLogout = () => { - clearSessionTimeouts(); - setSession(undefined); - setAllSessions(undefined); - setUser(undefined); - setWallets([]); + try { + clearSessionTimeouts(); + setSession(undefined); + setAllSessions(undefined); + setUser(undefined); + setWallets([]); + } catch (error) { + callbacks?.onError?.( + new TurnkeyError( + `Failed to initialize sessions`, + TurnkeyErrorCodes.HANDLE_POST_LOGOUT_ERROR, + error, + ), + ); + } }; async function createPasskey(params?: { @@ -362,17 +463,32 @@ export const ClientProvider: React.FC = ({ displayName?: string; }): Promise<{ attestation: v1Attestation; encodedChallenge: string }> { if (!client) { - throw new Error("Client is not initialized."); + throw new TurnkeyError( + "Client is not initialized.", + TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED, + ); } - return client.createPasskey(params); + // return client.createPasskey(params); + return await withTurnkeyErrorHandling( + () => client.createPasskey(params), + callbacks, + "Failed to create passkey", + ); } async function logout(params?: { sessionKey?: string }): Promise { if (!client) { - throw new Error("Client is not initialized."); + throw new TurnkeyError( + "Client is not initialized.", + TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED, + ); } setAuthState(AuthState.Loading); - await client.logout(params); + await withTurnkeyErrorHandling( + () => client.logout(params), + callbacks, + "Failed to logout", + ); handlePostLogout(); setAuthState(AuthState.Unauthenticated); return; @@ -384,10 +500,17 @@ export const ClientProvider: React.FC = ({ sessionKey?: string; }): Promise { if (!client) { - throw new Error("Client is not initialized."); + throw new TurnkeyError( + "Client is not initialized.", + TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED, + ); } setAuthState(AuthState.Loading); - const res = await client.loginWithPasskey(params); + const res = await withTurnkeyErrorHandling( + () => client.loginWithPasskey(params), + callbacks, + "Failed to login with passkey", + ); if (res) { await handlePostAuth(); setAuthState(AuthState.Authenticated); @@ -404,10 +527,17 @@ export const ClientProvider: React.FC = ({ passkeyDisplayName?: string; }): Promise { if (!client) { - throw new Error("Client is not initialized."); + throw new TurnkeyError( + "Client is not initialized.", + TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED, + ); } setAuthState(AuthState.Loading); - const res = await client.signUpWithPasskey(params); + const res = await withTurnkeyErrorHandling( + () => client.signUpWithPasskey(params), + callbacks, + "Failed to sign up with passkey", + ); if (res) { await handlePostAuth(); setAuthState(AuthState.Authenticated); @@ -422,9 +552,16 @@ export const ClientProvider: React.FC = ({ contact: string; }): Promise { if (!client) { - throw new Error("Client is not initialized."); + throw new TurnkeyError( + "Client is not initialized.", + TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED, + ); } - return client.initOtp(params); + return withTurnkeyErrorHandling( + () => client.initOtp(params), + callbacks, + "Failed to initialize OTP", + ); } async function verifyOtp(params: { @@ -434,9 +571,16 @@ export const ClientProvider: React.FC = ({ otpType: OtpType; }): Promise<{ subOrganizationId: string; verificationToken: string }> { if (!client) { - throw new Error("Client is not initialized."); + throw new TurnkeyError( + "Client is not initialized.", + TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED, + ); } - return client.verifyOtp(params); + return withTurnkeyErrorHandling( + () => client.verifyOtp(params), + callbacks, + "Failed to verify OTP", + ); } async function loginWithOtp(params: { @@ -447,10 +591,17 @@ export const ClientProvider: React.FC = ({ sessionKey?: string; }): Promise { if (!client) { - throw new Error("Client is not initialized."); + throw new TurnkeyError( + "Client is not initialized.", + TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED, + ); } setAuthState(AuthState.Loading); - const res = await client.loginWithOtp(params); + const res = await withTurnkeyErrorHandling( + () => client.loginWithOtp(params), + callbacks, + "Failed to login with OTP", + ); if (res) { await handlePostAuth(); setAuthState(AuthState.Authenticated); @@ -469,10 +620,17 @@ export const ClientProvider: React.FC = ({ sessionKey?: string; }): Promise { if (!client) { - throw new Error("Client is not initialized."); + throw new TurnkeyError( + "Client is not initialized.", + TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED, + ); } setAuthState(AuthState.Loading); - const res = await client.signUpWithOtp(params); + const res = await withTurnkeyErrorHandling( + () => client.signUpWithOtp(params), + callbacks, + "Failed to sign up with OTP", + ); if (res) { await handlePostAuth(); setAuthState(AuthState.Authenticated); @@ -493,10 +651,17 @@ export const ClientProvider: React.FC = ({ createSubOrgParams?: CreateSubOrgParams; }): Promise { if (!client) { - throw new Error("Client is not initialized."); + throw new TurnkeyError( + "Client is not initialized.", + TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED, + ); } setAuthState(AuthState.Loading); - const res = await client.completeOtp(params); + const res = await withTurnkeyErrorHandling( + () => client.completeOtp(params), + callbacks, + "Failed to complete OTP", + ); if (res) { await handlePostAuth(); setAuthState(AuthState.Authenticated); @@ -514,10 +679,17 @@ export const ClientProvider: React.FC = ({ createSubOrgParams?: CreateSubOrgParams; }): Promise { if (!client) { - throw new Error("Client is not initialized."); + throw new TurnkeyError( + "Client is not initialized.", + TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED, + ); } setAuthState(AuthState.Loading); - const res = await client.completeOauth(params); + const res = await withTurnkeyErrorHandling( + () => client.completeOauth(params), + callbacks, + "Failed to complete OAuth", + ); if (res) { await handlePostAuth(); setAuthState(AuthState.Authenticated); @@ -534,10 +706,17 @@ export const ClientProvider: React.FC = ({ sessionKey?: string; }): Promise { if (!client) { - throw new Error("Client is not initialized."); + throw new TurnkeyError( + "Client is not initialized.", + TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED, + ); } setAuthState(AuthState.Loading); - const res = await client.loginWithOauth(params); + const res = await withTurnkeyErrorHandling( + () => client.loginWithOauth(params), + callbacks, + "Failed to login with OAuth", + ); if (res) { await handlePostAuth(); setAuthState(AuthState.Authenticated); @@ -556,10 +735,17 @@ export const ClientProvider: React.FC = ({ sessionKey?: string; }): Promise { if (!client) { - throw new Error("Client is not initialized."); + throw new TurnkeyError( + "Client is not initialized.", + TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED, + ); } setAuthState(AuthState.Loading); - const res = await client.signUpWithOauth(params); + const res = await withTurnkeyErrorHandling( + () => client.signUpWithOauth(params), + callbacks, + "Failed to sign up with OAuth", + ); if (res) { await handlePostAuth(); setAuthState(AuthState.Authenticated); @@ -574,9 +760,16 @@ export const ClientProvider: React.FC = ({ saveInClient?: boolean; }): Promise { if (!client) { - throw new Error("Client is not initialized."); + throw new TurnkeyError( + "Client is not initialized.", + TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED, + ); } - return client.fetchWallets(params); + return withTurnkeyErrorHandling( + () => client.fetchWallets(params), + callbacks, + "Failed to fetch wallets", + ); } async function fetchWalletAccounts(params: { @@ -585,25 +778,33 @@ export const ClientProvider: React.FC = ({ paginationOptions?: v1Pagination; }): Promise { if (!client) { - throw new Error("Client is not initialized."); + throw new TurnkeyError( + "Client is not initialized.", + TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED, + ); } - return client.fetchWalletAccounts(params); + return withTurnkeyErrorHandling( + () => client.fetchWalletAccounts(params), + callbacks, + "Failed to fetch wallet accounts", + ); } - const login = async () => { - pushPage({ - key: "Log in or sign up", - content: , - }); - }; - async function signMessage(params: { message: string; wallet?: v1WalletAccount; stampWith?: StamperType; }): Promise { - if (!client) throw new Error("Client is not initialized."); - return client.signMessage(params); + if (!client) + throw new TurnkeyError( + "Client is not initialized.", + TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED, + ); + return withTurnkeyErrorHandling( + () => client.signMessage(params), + callbacks, + "Failed to sign message", + ); } async function signTransaction(params: { @@ -612,16 +813,32 @@ export const ClientProvider: React.FC = ({ type: v1TransactionType; stampWith?: StamperType; }): Promise { - if (!client) throw new Error("Client is not initialized."); - return client.signTransaction(params); + if (!client) + throw new TurnkeyError( + "Client is not initialized.", + TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED, + ); + return withTurnkeyErrorHandling( + () => client.signTransaction(params), + callbacks, + "Failed to sign transaction", + ); } async function fetchUser(params?: { organizationId?: string; userId?: string; }): Promise { - if (!client) throw new Error("Client is not initialized."); - return client.fetchUser(params); + if (!client) + throw new TurnkeyError( + "Client is not initialized.", + TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED, + ); + return withTurnkeyErrorHandling( + () => client.fetchUser(params), + callbacks, + "Failed to fetch user", + ); } async function createWallet(params: { @@ -631,8 +848,16 @@ export const ClientProvider: React.FC = ({ mnemonicLength?: number; stampWith?: StamperType; }): Promise { - if (!client) throw new Error("Client is not initialized."); - const res = await client.createWallet(params); + if (!client) + throw new TurnkeyError( + "Client is not initialized.", + TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED, + ); + const res = await withTurnkeyErrorHandling( + () => client.createWallet(params), + callbacks, + "Failed to create wallet", + ); if (res) await refreshWallets(); return res; } @@ -643,8 +868,16 @@ export const ClientProvider: React.FC = ({ organizationId?: string; stampWith?: StamperType; }): Promise { - if (!client) throw new Error("Client is not initialized."); - const res = await client.createWalletAccounts(params); + if (!client) + throw new TurnkeyError( + "Client is not initialized.", + TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED, + ); + const res = await withTurnkeyErrorHandling( + () => client.createWalletAccounts(params), + callbacks, + "Failed to create wallet accounts", + ); if (res) await refreshWallets(); return res; } @@ -655,8 +888,16 @@ export const ClientProvider: React.FC = ({ organizationId?: string; stamperType?: StamperType; }): Promise { - if (!client) throw new Error("Client is not initialized."); - const res = await client.exportWallet(params); + if (!client) + throw new TurnkeyError( + "Client is not initialized.", + TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED, + ); + const res = await withTurnkeyErrorHandling( + () => client.exportWallet(params), + callbacks, + "Failed to export wallet", + ); if (res) await refreshWallets(); return res; } @@ -667,8 +908,16 @@ export const ClientProvider: React.FC = ({ accounts?: WalletAccount[]; userId?: string; }): Promise { - if (!client) throw new Error("Client is not initialized."); - const res = await client.importWallet(params); + if (!client) + throw new TurnkeyError( + "Client is not initialized.", + TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED, + ); + const res = await withTurnkeyErrorHandling( + () => client.importWallet(params), + callbacks, + "Failed to import wallet", + ); if (res) await refreshWallets(); return res; } @@ -677,8 +926,16 @@ export const ClientProvider: React.FC = ({ deleteWithoutExport?: boolean; stamperWith?: StamperType; }): Promise { - if (!client) throw new Error("Client is not initialized."); - return client.deleteSubOrganization(params); + if (!client) + throw new TurnkeyError( + "Client is not initialized.", + TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED, + ); + return withTurnkeyErrorHandling( + () => client.deleteSubOrganization(params), + callbacks, + "Failed to delete sub-organization", + ); } async function createSubOrganization(params?: { @@ -694,16 +951,32 @@ export const ClientProvider: React.FC = ({ type: WalletType; }; }): Promise { - if (!client) throw new Error("Client is not initialized."); - return client.createSubOrganization(params); + if (!client) + throw new TurnkeyError( + "Client is not initialized.", + TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED, + ); + return withTurnkeyErrorHandling( + () => client.createSubOrganization(params), + callbacks, + "Failed to create sub-organization", + ); } async function storeSession(params: { sessionToken: string; sessionKey?: string; }): Promise { - if (!client) throw new Error("Client is not initialized."); - await client.storeSession(params); + if (!client) + throw new TurnkeyError( + "Client is not initialized.", + TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED, + ); + await withTurnkeyErrorHandling( + () => client.storeSession(params), + callbacks, + "Failed to store session", + ); const sessionKey = await client.getActiveSessionKey(); const session = await client.getSession({ ...(sessionKey && { sessionKey }), @@ -719,8 +992,16 @@ export const ClientProvider: React.FC = ({ } async function clearSession(params?: { sessionKey?: string }): Promise { - if (!client) throw new Error("Client is not initialized."); - await client.clearSession(params); + if (!client) + throw new TurnkeyError( + "Client is not initialized.", + TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED, + ); + await withTurnkeyErrorHandling( + () => client.clearSession(params), + callbacks, + "Failed to clear session", + ); const session = await client.getSession(); const allSessions = await client.getAllSessions(); setSession(session); @@ -729,10 +1010,18 @@ export const ClientProvider: React.FC = ({ } async function clearAllSessions(): Promise { - if (!client) throw new Error("Client is not initialized."); + if (!client) + throw new TurnkeyError( + "Client is not initialized.", + TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED, + ); setSession(undefined); setAllSessions(undefined); - return await client.clearAllSessions(); + return await withTurnkeyErrorHandling( + () => client.clearAllSessions(), + callbacks, + "Failed to clear all sessions", + ); } async function refreshSession(params?: { @@ -742,7 +1031,11 @@ export const ClientProvider: React.FC = ({ sessionKey?: string; invalidateExisitng?: boolean; }): Promise { - if (!client) throw new Error("Client is not initialized."); + if (!client) + throw new TurnkeyError( + "Client is not initialized.", + TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED, + ); const activeSessionKey = await client.getActiveSessionKey(); if (!activeSessionKey) { @@ -751,7 +1044,11 @@ export const ClientProvider: React.FC = ({ let sessionKey = params?.sessionKey ?? activeSessionKey; - await client.refreshSession({ ...params, sessionKey }); + await withTurnkeyErrorHandling( + () => client.refreshSession({ ...params, sessionKey }), + callbacks, + "Failed to refresh session", + ); const session = await client.getSession({ sessionKey }); if (session && sessionKey) { @@ -767,64 +1064,140 @@ export const ClientProvider: React.FC = ({ async function getSession(params?: { sessionKey?: string; }): Promise { - if (!client) throw new Error("Client is not initialized."); - return client.getSession(params); + if (!client) + throw new TurnkeyError( + "Client is not initialized.", + TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED, + ); + return withTurnkeyErrorHandling( + () => client.getSession(params), + callbacks, + "Failed to get session", + ); } async function getAllSessions(): Promise< Record | undefined > { - if (!client) throw new Error("Client is not initialized."); - return client.getAllSessions(); + if (!client) + throw new TurnkeyError( + "Client is not initialized.", + TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED, + ); + return withTurnkeyErrorHandling( + () => client.getAllSessions(), + callbacks, + "Failed to get all sessions", + ); } async function setActiveSession(params: { sessionKey: string; }): Promise { - if (!client) throw new Error("Client is not initialized."); - const session = await client.getSession({ sessionKey: params.sessionKey }); + if (!client) + throw new TurnkeyError( + "Client is not initialized.", + TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED, + ); + const session = await withTurnkeyErrorHandling( + () => client.getSession({ sessionKey: params.sessionKey }), + callbacks, + "Failed to get session", + ); if (!session) { - throw new Error("Session not found."); + throw new TurnkeyError("Session not found.", TurnkeyErrorCodes.NOT_FOUND); } - await client.setActiveSession(params); + await withTurnkeyErrorHandling( + () => client.setActiveSession(params), + callbacks, + "Failed to set active session", + ); setSession(session); return; } async function getActiveSessionKey(): Promise { - if (!client) throw new Error("Client is not initialized."); - return client.getActiveSessionKey(); + if (!client) + throw new TurnkeyError( + "Client is not initialized.", + TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED, + ); + return withTurnkeyErrorHandling( + () => client.getActiveSessionKey(), + callbacks, + "Failed to get active session key", + ); } async function clearUnusedKeyPairs(): Promise { - if (!client) throw new Error("Client is not initialized."); - return client.clearUnusedKeyPairs(); + if (!client) + throw new TurnkeyError( + "Client is not initialized.", + TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED, + ); + return withTurnkeyErrorHandling( + () => client.clearUnusedKeyPairs(), + callbacks, + "Failed to clear unused key pairs", + ); } async function createApiKeyPair(params?: { externalKeyPair?: CryptoKeyPair | { publicKey: string; privateKey: string }; storeOverride?: boolean; }): Promise { - if (!client) throw new Error("Client is not initialized."); - return client.createApiKeyPair(params); + if (!client) + throw new TurnkeyError( + "Client is not initialized.", + TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED, + ); + return withTurnkeyErrorHandling( + () => client.createApiKeyPair(params), + callbacks, + "Failed to create API key pair", + ); } async function getProxyAuthConfig(): Promise { - if (!client) throw new Error("Client is not initialized."); - return client.getProxyAuthConfig(); + if (!client) + throw new TurnkeyError( + "Client is not initialized.", + TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED, + ); + return withTurnkeyErrorHandling( + () => client.getProxyAuthConfig(), + callbacks, + "Failed to get proxy auth config", + ); } async function refreshUser(): Promise { - if (!client) throw new Error("Client is not initialized."); - const user = await client.fetchUser(); + if (!client) + throw new TurnkeyError( + "Client is not initialized.", + TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED, + ); + const user = await withTurnkeyErrorHandling( + () => client.fetchUser(), + callbacks, + "Failed to refresh user", + ); if (user) { setUser(user); } } async function refreshWallets(): Promise { - if (!client) throw new Error("Client is not initialized."); - const wallets = await fetchWallets(); + if (!client) + throw new TurnkeyError( + "Client is not initialized.", + TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED, + ); + const wallets = await withTurnkeyErrorHandling( + () => fetchWallets(), + callbacks, + "Failed to refresh wallets", + ); if (wallets) { setWallets(wallets); } @@ -965,6 +1338,13 @@ export const ClientProvider: React.FC = ({ } } + const login = async () => { + pushPage({ + key: "Log in or sign up", + content: , + }); + }; + return ( { return session?.expiry !== undefined && session.expiry * 1000 > Date.now(); }; + +export async function withTurnkeyErrorHandling( + fn: () => Promise, + callbacks?: { onError?: (error: TurnkeyError) => void }, + fallbackMessage = "An unknown error occurred", + fallbackCode = TurnkeyErrorCodes.UNKNOWN, +): Promise { + try { + console.log("Executing withTurnkeyErrorHandling"); + return await fn(); + } catch (error) { + console.log("Error in withTurnkeyErrorHandling:", error); + if (error instanceof TurnkeyError) { + callbacks?.onError?.(error); + throw error; + } + const tkError = new TurnkeyError(fallbackMessage, fallbackCode, error); + callbacks?.onError?.(tkError); + throw tkError; + } +} diff --git a/packages/sdk-js/src/__clients__/core.ts b/packages/sdk-js/src/__clients__/core.ts index 19869e3e3..b8605f21b 100644 --- a/packages/sdk-js/src/__clients__/core.ts +++ b/packages/sdk-js/src/__clients__/core.ts @@ -20,6 +20,9 @@ import { v1VerifyOtpResult, v1WalletAccount, v1ProxyAuthConfig, + TurnkeyError, + TurnkeyErrorCodes, + TurnkeyNetworkError, } from "@turnkey/sdk-types"; import { DEFAULT_SESSION_EXPIRATION_IN_SECONDS, @@ -142,7 +145,10 @@ export class TurnkeyClient { }, }); if (!res) { - throw new Error("Failed to create React Native passkey"); + throw new TurnkeyError( + "Failed to create React Native passkey", + TurnkeyErrorCodes.INTERNAL_ERROR, + ); } passkey = { encodedChallenge: res?.encodedChallenge, @@ -154,36 +160,63 @@ export class TurnkeyClient { displayName, }); if (!res) { - throw new Error("Failed to create React Native passkey"); + throw new TurnkeyError( + "Failed to create React Native passkey", + TurnkeyErrorCodes.INTERNAL_ERROR, + ); } passkey = { encodedChallenge: res?.challenge, attestation: res?.attestation, }; } else { - throw new Error("Unsupported platform for passkey creation"); + throw new TurnkeyError( + "Unsupported platform for passkey creation", + TurnkeyErrorCodes.INVALID_REQUEST, + ); } return passkey; - } catch (error) { - throw new Error(`Failed to create passkey: ${error}`); + } catch (error: any) { + if (error?.message?.includes("timed out or was not allowed")) + throw new TurnkeyError( + "Passkey creation was cancelled by the user.", + TurnkeyErrorCodes.SELECT_PASSKEY_CANCELLED, + error, + ); + throw new TurnkeyError( + `Failed to create passkey`, + TurnkeyErrorCodes.CREATE_PASSKEY_ERROR, + error, + ); } }; logout = async (params?: { sessionKey?: string }): Promise => { - if (params?.sessionKey) { - const session = await this.storageManager.getSession(params.sessionKey); - this.storageManager.clearSession(params.sessionKey); - this.apiKeyStamper?.deleteKeyPair(session?.token!); - } else { - const sessionKey = await this.storageManager.getActiveSessionKey(); - const session = await this.storageManager.getActiveSession(); - if (sessionKey) { - this.storageManager.clearSession(sessionKey); + try { + if (params?.sessionKey) { + const session = await this.storageManager.getSession(params.sessionKey); + this.storageManager.clearSession(params.sessionKey); this.apiKeyStamper?.deleteKeyPair(session?.token!); } else { - throw new Error("No active session found to log out from."); + const sessionKey = await this.storageManager.getActiveSessionKey(); + const session = await this.storageManager.getActiveSession(); + if (sessionKey) { + this.storageManager.clearSession(sessionKey); + this.apiKeyStamper?.deleteKeyPair(session?.token!); + } else { + throw new TurnkeyError( + "No active session found to log out from.", + TurnkeyErrorCodes.NO_SESSION_FOUND, + ); + } } + } catch (error) { + throw new TurnkeyError( + `Failed to log out`, + TurnkeyErrorCodes.LOGOUT_ERROR, + error, + ); } }; @@ -215,8 +248,9 @@ export class TurnkeyClient { return readOnlySessionResult.session; } else if (sessionType === SessionType.READ_WRITE) { if (!publicKey) { - throw new Error( - "You must provide a publicKey to create a passkey read write session.", + throw new TurnkeyError( + "A publickey could not be found or generated.", + TurnkeyErrorCodes.INTERNAL_ERROR, ); } const sessionResponse = await this.httpClient.stampLogin( @@ -236,18 +270,33 @@ export class TurnkeyClient { return sessionResponse.session; } else { - throw new Error(`Invalid session type passed: ${sessionType}`); + throw new TurnkeyError( + `Invalid session type passed: ${sessionType}`, + TurnkeyErrorCodes.INVALID_REQUEST, + ); } - } catch (error) { - throw new Error(`Unable to log in with the provided passkey: ${error}`); + } catch (error: any) { + if (error?.message?.includes("timed out or was not allowed")) + throw new TurnkeyError( + "Passkey login was cancelled by the user.", + TurnkeyErrorCodes.SELECT_PASSKEY_CANCELLED, + error, + ); + throw new TurnkeyError( + `Unable to log in with the provided passkey`, + TurnkeyErrorCodes.PASSKEY_LOGIN_AUTH_ERROR, + error, + ); } finally { // Clean up the generated key pair if it wasn't successfully used if (generatedKeyPair) { try { await this.apiKeyStamper?.deleteKeyPair(generatedKeyPair); } catch (cleanupError) { - throw new Error( - `Failed to clean up generated key pair: ${cleanupError}`, + throw new TurnkeyError( + `Failed to clean up generated key pair`, + TurnkeyErrorCodes.KEY_PAIR_CLEANUP_ERROR, + cleanupError, ); } } @@ -278,8 +327,9 @@ export class TurnkeyClient { }); if (!passkey) { - throw new Error( + throw new TurnkeyError( "Failed to create passkey: encoded challenge or attestation is missing", + TurnkeyErrorCodes.INTERNAL_ERROR, ); } @@ -334,7 +384,12 @@ export class TurnkeyClient { if (!res.ok) { const errorText = await res.text(); - throw new Error(`Sign up failed: ${res.status} ${errorText}`); + throw new TurnkeyNetworkError( + `Sign up failed`, + res.status, + TurnkeyErrorCodes.PASSKEY_SIGNUP_AUTH_ERROR, + errorText, + ); } const newGeneratedKeyPair = await this.apiKeyStamper?.createKeyPair(); @@ -355,18 +410,29 @@ export class TurnkeyClient { generatedKeyPair = null; // Key pair was successfully used, set to null to prevent cleanup return sessionResponse.session; - } catch (error) { - throw new Error(`Failed to sign up with passkey: ${error}`); + } catch (error: unknown) { + if ( + error instanceof TurnkeyError && + error.code === TurnkeyErrorCodes.SELECT_PASSKEY_CANCELLED + ) { + throw error; // Re-throw the specific cancellation error + } + throw new TurnkeyError( + `Failed to sign up with passkey`, + TurnkeyErrorCodes.PASSKEY_SIGNUP_AUTH_ERROR, + error, + ); } finally { // Clean up the generated key pair if it wasn't successfully used - console.log("Cleaning up generated key pair if any"); this.apiKeyStamper?.clearOverridePublicKey(); if (generatedKeyPair) { try { await this.apiKeyStamper?.deleteKeyPair(generatedKeyPair); } catch (cleanupError) { - throw new Error( - `Failed to clean up generated key pair: ${cleanupError}`, + throw new TurnkeyError( + `Failed to clean up generated key pair`, + TurnkeyErrorCodes.KEY_PAIR_CLEANUP_ERROR, + cleanupError, ); } } @@ -391,14 +457,22 @@ export class TurnkeyClient { }); if (!otpRes.ok) { - const error = await otpRes.text(); - throw new Error(`OTP initialization failed: ${otpRes.status} ${error}`); + throw new TurnkeyNetworkError( + `OTP initialization failed`, + otpRes.status, + TurnkeyErrorCodes.INIT_OTP_ERROR, + await otpRes.text(), + ); } const initOtpRes: v1InitOtpResult = await otpRes.json(); return initOtpRes.otpId; } catch (error) { - throw new Error(`Failed to initialize OTP: ${error}`); + throw new TurnkeyError( + `Failed to initialize OTP`, + TurnkeyErrorCodes.INIT_OTP_ERROR, + error, + ); } }; @@ -427,8 +501,12 @@ export class TurnkeyClient { }); if (!accountRes.ok && accountRes.status !== 404) { - const error = await accountRes.text(); - throw new Error(`Account fetch failed: ${accountRes.status} ${error}`); + throw new TurnkeyNetworkError( + `Account fetch failed`, + accountRes.status, + TurnkeyErrorCodes.ACCOUNT_FETCH_ERROR, + await accountRes.text(), + ); } const verifyRes = await fetch( @@ -444,9 +522,21 @@ export class TurnkeyClient { ); if (!verifyRes.ok) { const error = await verifyRes.text(); - throw new Error( - `OTP verification failed: ${verifyRes.status} ${error}`, - ); + if (error.includes("invalid OTP")) { + throw new TurnkeyNetworkError( + "Invalid OTP code provided", + verifyRes.status, + TurnkeyErrorCodes.INVALID_OTP_CODE, + error, + ); + } else { + throw new TurnkeyNetworkError( + `OTP verification failed`, + verifyRes.status, + TurnkeyErrorCodes.VERIFY_OTP_ERROR, + error, + ); + } } const verifyOtpRes: v1VerifyOtpResult = await verifyRes.json(); @@ -462,7 +552,11 @@ export class TurnkeyClient { verificationToken: verifyOtpRes.verificationToken, }; } catch (error) { - throw new Error(`Failed to verify OTP: ${error}`); + throw new TurnkeyError( + `Failed to verify OTP`, + TurnkeyErrorCodes.VERIFY_OTP_ERROR, + error, + ); } }; @@ -500,13 +594,20 @@ export class TurnkeyClient { }); if (!res.ok) { - const errorText = await res.text(); - throw new Error(`OTP login failed: ${res.status} ${errorText}`); + throw new TurnkeyNetworkError( + `Auth proxy OTP login failed`, + res.status, + TurnkeyErrorCodes.OTP_LOGIN_ERROR, + await res.text(), + ); } const loginRes: v1OtpLoginResult = await res.json(); if (!loginRes.session) { - throw new Error("No session returned from OTP login"); + throw new TurnkeyError( + "No session returned from OTP login", + TurnkeyErrorCodes.OTP_LOGIN_ERROR, + ); } await this.storeSession({ @@ -517,17 +618,22 @@ export class TurnkeyClient { return loginRes.session; } catch (error) { // Clean up the generated key pair if it wasn't successfully used - console.log("Cleaning up generated key pair if any"); if (publicKey) { try { await this.apiKeyStamper?.deleteKeyPair(publicKey); } catch (cleanupError) { - throw new Error( - `Failed to clean up generated key pair: ${cleanupError}`, + throw new TurnkeyError( + `Failed to clean up generated key pair`, + TurnkeyErrorCodes.KEY_PAIR_CLEANUP_ERROR, + cleanupError, ); } } - throw new Error(`Failed to log in with OTP: ${error}`); + throw new TurnkeyError( + `Failed to log in with OTP`, + TurnkeyErrorCodes.OTP_LOGIN_ERROR, + error, + ); } }; @@ -580,8 +686,12 @@ export class TurnkeyClient { }); if (!res.ok) { - const errorText = await res.text(); - throw new Error(`Sign up failed: ${res.status} ${errorText}`); + throw new TurnkeyNetworkError( + `Auth proxy OTP sign up failed`, + res.status, + TurnkeyErrorCodes.OTP_SIGNUP_ERROR, + await res.text(), + ); } return await this.loginWithOtp({ @@ -592,7 +702,11 @@ export class TurnkeyClient { ...(sessionKey && { sessionKey }), }); } catch (error) { - throw new Error(`Failed to sign up with OTP: ${error}`); + throw new TurnkeyError( + `Failed to sign up with OTP`, + TurnkeyErrorCodes.OTP_SIGNUP_ERROR, + error, + ); } }; @@ -619,37 +733,48 @@ export class TurnkeyClient { createSubOrgParams, } = params; - const { subOrganizationId, verificationToken } = await this.verifyOtp({ - otpId: otpId, - otpCode: otpCode, - contact: contact, - otpType: otpType, - }); - - if (!verificationToken) { - throw new Error("No verification token returned from OTP verification"); - } - - if (!subOrganizationId) { - return await this.signUpWithOtp({ - verificationToken, + try { + const { subOrganizationId, verificationToken } = await this.verifyOtp({ + otpId: otpId, + otpCode: otpCode, contact: contact, otpType: otpType, - ...(createSubOrgParams && { - createSubOrgParams, - }), - ...(invalidateExisting && { invalidateExisting }), - ...(sessionType && { sessionType }), - ...(sessionKey && { sessionKey }), - }); - } else { - return await this.loginWithOtp({ - verificationToken, - ...(publicKey && { publicKey }), - ...(invalidateExisting && { invalidateExisting }), - ...(sessionType && { sessionType }), - ...(sessionKey && { sessionKey }), }); + + if (!verificationToken) { + throw new TurnkeyError( + "No verification token returned from OTP verification", + TurnkeyErrorCodes.VERIFY_OTP_ERROR, + ); + } + + if (!subOrganizationId) { + return await this.signUpWithOtp({ + verificationToken, + contact: contact, + otpType: otpType, + ...(createSubOrgParams && { + createSubOrgParams, + }), + ...(invalidateExisting && { invalidateExisting }), + ...(sessionType && { sessionType }), + ...(sessionKey && { sessionKey }), + }); + } else { + return await this.loginWithOtp({ + verificationToken, + ...(publicKey && { publicKey }), + ...(invalidateExisting && { invalidateExisting }), + ...(sessionType && { sessionType }), + ...(sessionKey && { sessionKey }), + }); + } + } catch (error) { + throw new TurnkeyError( + `Failed to complete OTP process`, + TurnkeyErrorCodes.OTP_COMPLETION_ERROR, + error, + ); } }; @@ -714,7 +839,11 @@ export class TurnkeyClient { }); } } catch (error) { - throw new Error(`Failed to handle Google OAuth login: ${error}`); + throw new TurnkeyError( + `Failed to handle Google OAuth login`, + TurnkeyErrorCodes.OAUTH_LOGIN_ERROR, + error, + ); } }; @@ -739,8 +868,9 @@ export class TurnkeyClient { } if (!publicKey) { - throw new Error( + throw new TurnkeyError( "Public key must be provided to log in with OAuth. Please create a key pair first.", + TurnkeyErrorCodes.MISSING_PARAMS, ); } @@ -757,12 +887,20 @@ export class TurnkeyClient { if (!res.ok) { const errorText = await res.text(); - throw new Error(`oauth login failed: ${res.status} ${errorText}`); + throw new TurnkeyNetworkError( + `Auth proxy OAuth login failed`, + res.status, + TurnkeyErrorCodes.OAUTH_LOGIN_ERROR, + errorText, + ); } const loginRes: v1OauthLoginResult = await res.json(); if (!loginRes.session) { - throw new Error("No session returned from oauth login"); + throw new TurnkeyError( + "No session returned from oauth login", + TurnkeyErrorCodes.OAUTH_LOGIN_ERROR, + ); } await this.storeSession({ @@ -777,12 +915,18 @@ export class TurnkeyClient { try { await this.apiKeyStamper?.deleteKeyPair(publicKey); } catch (cleanupError) { - throw new Error( - `Failed to clean up generated key pair: ${cleanupError}`, + throw new TurnkeyError( + `Failed to clean up generated key pair`, + TurnkeyErrorCodes.KEY_PAIR_CLEANUP_ERROR, + cleanupError, ); } } - throw new Error(`Failed to log in with oauth: ${error}`); + throw new TurnkeyError( + `Failed to log in with oauth`, + TurnkeyErrorCodes.OAUTH_LOGIN_ERROR, + error, + ); } }; @@ -796,45 +940,57 @@ export class TurnkeyClient { }): Promise => { const { oidcToken, publicKey, providerName, createSubOrgParams } = params; - const signUpBody = { - userName: - createSubOrgParams?.userName || - createSubOrgParams?.userEmail || - `user-${Date.now()}`, - userTag: createSubOrgParams?.userTag, - subOrgName: createSubOrgParams?.subOrgName || `sub-org-${Date.now()}`, - oauthProviders: [ - { - providerName: providerName, - oidcToken, - }, - ...(createSubOrgParams?.oauthProviders || []), - ], - }; + try { + const signUpBody = { + userName: + createSubOrgParams?.userName || + createSubOrgParams?.userEmail || + `user-${Date.now()}`, + userTag: createSubOrgParams?.userTag, + subOrgName: createSubOrgParams?.subOrgName || `sub-org-${Date.now()}`, + oauthProviders: [ + { + providerName: providerName, + oidcToken, + }, + ...(createSubOrgParams?.oauthProviders || []), + ], + }; - // Set up headers, including X-Proxy-ID if needed - const headers: Record = { - "Content-Type": "application/json", - }; - if (this.config.authProxyId) { - headers["X-Proxy-ID"] = this.config.authProxyId; - } + // Set up headers, including X-Proxy-ID if needed + const headers: Record = { + "Content-Type": "application/json", + }; + if (this.config.authProxyId) { + headers["X-Proxy-ID"] = this.config.authProxyId; + } - const res = await fetch(`${this.config.authProxyUrl}/v1/signup`, { - method: "POST", - headers, - body: JSON.stringify(signUpBody), - }); + const res = await fetch(`${this.config.authProxyUrl}/v1/signup`, { + method: "POST", + headers, + body: JSON.stringify(signUpBody), + }); - if (!res.ok) { - const errorText = await res.text(); - throw new Error(`Sign up failed: ${res.status} ${errorText}`); - } + if (!res.ok) { + throw new TurnkeyNetworkError( + `Auth proxy OAuth signup failed`, + res.status, + TurnkeyErrorCodes.OAUTH_SIGNUP_ERROR, + await res.text(), + ); + } - return await this.loginWithOauth({ - oidcToken, - publicKey: publicKey!, - }); + return await this.loginWithOauth({ + oidcToken, + publicKey: publicKey!, + }); + } catch (error) { + throw new TurnkeyError( + `Failed to sign up with OAuth`, + TurnkeyErrorCodes.OAUTH_SIGNUP_ERROR, + error, + ); + } }; fetchWallets = async (params?: { @@ -844,7 +1000,10 @@ export class TurnkeyClient { const { stamperType, saveInClient = true } = params || {}; const session = await this.storageManager.getActiveSession(); if (!session) { - throw new Error("No active session found. Please log in first."); + throw new TurnkeyError( + "No active session found. Please log in first.", + TurnkeyErrorCodes.NO_SESSION_FOUND, + ); } try { const res = await this.httpClient.getWallets( @@ -853,7 +1012,10 @@ export class TurnkeyClient { ); if (!res || !res.wallets) { - throw new Error("No wallets found in the response"); + throw new TurnkeyError( + "No wallets found in the response", + TurnkeyErrorCodes.BAD_RESPONSE, + ); } const wallets: Wallet[] = res.wallets; @@ -875,7 +1037,11 @@ export class TurnkeyClient { } return wallets; } catch (error) { - throw new Error(`Failed to fetch wallets: ${error}`); + throw new TurnkeyError( + `Failed to fetch wallets`, + TurnkeyErrorCodes.FETCH_WALLETS_ERROR, + error, + ); } }; @@ -887,15 +1053,14 @@ export class TurnkeyClient { const { walletId, stamperType, paginationOptions } = params; const session = await this.storageManager.getActiveSession(); if (!session) { - throw new Error("No active session found. Please log in first."); - } - - if (!walletId) { - throw new Error("Wallet ID must be provided to fetch accounts"); + throw new TurnkeyError( + "No active session found. Please log in first.", + TurnkeyErrorCodes.NO_SESSION_FOUND, + ); } try { - return await this.httpClient.getWalletAccounts( + const walletAccountRes = await this.httpClient.getWalletAccounts( { walletId, organizationId: session.organizationId, @@ -903,8 +1068,21 @@ export class TurnkeyClient { }, stamperType, ); + + if (!walletAccountRes || !walletAccountRes.accounts) { + throw new TurnkeyError( + "No wallet accounts found in the response", + TurnkeyErrorCodes.BAD_RESPONSE, + ); + } + + return walletAccountRes as TGetWalletAccountsResponse; } catch (error) { - throw new Error(`Failed to fetch wallet accounts: ${error}`); + throw new TurnkeyError( + `Failed to fetch wallet accounts`, + TurnkeyErrorCodes.FETCH_WALLET_ACCOUNTS_ERROR, + error, + ); } }; @@ -915,33 +1093,50 @@ export class TurnkeyClient { }): Promise => { const { message, wallet, stampWith } = params; if (!wallet) { - throw new Error("A wallet account must be provided for signing"); + throw new TurnkeyError( + "A wallet account must be provided for signing", + TurnkeyErrorCodes.MISSING_PARAMS, + ); } if (!wallet.address || !wallet.addressFormat) { - throw new Error("Wallet must have an address and addressFormat"); + throw new TurnkeyError( + "Wallet must have an address and addressFormat", + TurnkeyErrorCodes.INVALID_REQUEST, + ); } - // Get the proper encoding and hash function for the address format - const { hashFunction, payloadEncoding, encodedMessage } = - getMessageHashAndEncodingType(wallet.addressFormat, message); - - const response = await this.httpClient.signRawPayload( - { - signWith: wallet.address, - payload: encodedMessage, - encoding: payloadEncoding, - hashFunction, - }, - stampWith, - ); - - if (response.activity.failure) { - throw new Error("Failed to sign message, no signed payload returned"); - } + try { + // Get the proper encoding and hash function for the address format + const { hashFunction, payloadEncoding, encodedMessage } = + getMessageHashAndEncodingType(wallet.addressFormat, message); - return response.activity.result - .signRawPayloadResult as v1SignRawPayloadResult; + const response = await this.httpClient.signRawPayload( + { + signWith: wallet.address, + payload: encodedMessage, + encoding: payloadEncoding, + hashFunction, + }, + stampWith, + ); + + if (response.activity.failure) { + throw new TurnkeyError( + "Failed to sign message, no signed payload returned", + TurnkeyErrorCodes.SIGN_MESSAGE_ERROR, + ); + } + + return response.activity.result + .signRawPayloadResult as v1SignRawPayloadResult; + } catch (error) { + throw new TurnkeyError( + `Failed to sign message: ${error}`, + TurnkeyErrorCodes.SIGN_MESSAGE_ERROR, + error, + ); + } }; signTransaction = async (params: { @@ -952,14 +1147,6 @@ export class TurnkeyClient { }): Promise => { const { signWith, unsignedTransaction, type, stampWith } = params; - if (!signWith) { - throw new Error("A wallet account must be provided for signing"); - } - - if (!unsignedTransaction) { - throw new Error("An unsigned transaction must be provided for signing"); - } - try { return await this.httpClient.signTransaction( { @@ -970,7 +1157,11 @@ export class TurnkeyClient { stampWith, ); } catch (error) { - throw new Error(`Failed to sign transaction: ${error}`); + throw new TurnkeyError( + `Failed to sign transaction`, + TurnkeyErrorCodes.SIGN_TRANSACTION_ERROR, + error, + ); } }; @@ -980,12 +1171,18 @@ export class TurnkeyClient { }): Promise => { const session = await this.storageManager.getActiveSession(); if (!session) { - throw new Error("No active session found. Please log in first."); + throw new TurnkeyError( + "No active session found. Please log in first.", + TurnkeyErrorCodes.NO_SESSION_FOUND, + ); } const userId = params?.userId || session.userId; if (!userId) { - throw new Error("User ID must be provided to fetch user"); + throw new TurnkeyError( + "User ID must be provided to fetch user", + TurnkeyErrorCodes.INVALID_REQUEST, + ); } const organizationId = params?.organizationId || session.organizationId; @@ -997,12 +1194,19 @@ export class TurnkeyClient { ); if (!userResponse || !userResponse.user) { - throw new Error("No user found in the response"); + throw new TurnkeyError( + "No user found in the response", + TurnkeyErrorCodes.BAD_RESPONSE, + ); } return userResponse.user as User; } catch (error) { - throw new Error(`Failed to fetch user: ${error}`); + throw new TurnkeyError( + `Failed to fetch user`, + TurnkeyErrorCodes.FETCH_USER_ERROR, + error, + ); } }; @@ -1017,7 +1221,10 @@ export class TurnkeyClient { params; const session = await this.storageManager.getActiveSession(); if (!session) { - throw new Error("No active session found. Please log in first."); + throw new TurnkeyError( + "No active session found. Please log in first.", + TurnkeyErrorCodes.NO_SESSION_FOUND, + ); } let walletAccounts: WalletAccount[] = []; @@ -1042,11 +1249,18 @@ export class TurnkeyClient { ); if (!res || !res.walletId) { - throw new Error("No wallet ID found in the create wallet response"); + throw new TurnkeyError( + "No wallet found in the create wallet response", + TurnkeyErrorCodes.BAD_RESPONSE, + ); } return res.walletId; } catch (error) { - throw new Error(`Failed to create wallet: ${error}`); + throw new TurnkeyError( + `Failed to create wallet`, + TurnkeyErrorCodes.CREATE_WALLET_ERROR, + error, + ); } }; @@ -1059,11 +1273,10 @@ export class TurnkeyClient { const { accounts, walletId, organizationId, stampWith } = params; const session = await this.storageManager.getActiveSession(); if (!session) { - throw new Error("No active session found. Please log in first."); - } - - if (!walletId) { - throw new Error("Wallet ID must be provided to create an account"); + throw new TurnkeyError( + "No active session found. Please log in first.", + TurnkeyErrorCodes.NO_SESSION_FOUND, + ); } try { @@ -1077,13 +1290,18 @@ export class TurnkeyClient { ); if (!res || !res.addresses) { - throw new Error( + throw new TurnkeyError( "No account found in the create wallet account response", + TurnkeyErrorCodes.BAD_RESPONSE, ); } return res.addresses; } catch (error) { - throw new Error(`Failed to create wallet account: ${error}`); + throw new TurnkeyError( + `Failed to create wallet account`, + TurnkeyErrorCodes.CREATE_WALLET_ACCOUNT_ERROR, + error, + ); } }; @@ -1096,11 +1314,10 @@ export class TurnkeyClient { const { walletId, targetPublicKey, stamperType, organizationId } = params; const session = await this.storageManager.getActiveSession(); if (!session) { - throw new Error("No active session found. Please log in first."); - } - - if (!walletId) { - throw new Error("Wallet ID must be provided to export wallet"); + throw new TurnkeyError( + "No active session found. Please log in first.", + TurnkeyErrorCodes.NO_SESSION_FOUND, + ); } try { @@ -1114,11 +1331,18 @@ export class TurnkeyClient { ); if (!res.exportBundle) { - throw new Error("No export bundle found in the response"); + throw new TurnkeyError( + "No export bundle found in the response", + TurnkeyErrorCodes.BAD_RESPONSE, + ); } return res.exportBundle as ExportBundle; } catch (error) { - throw new Error(`Failed to export wallet: ${error}`); + throw new TurnkeyError( + `Failed to export wallet`, + TurnkeyErrorCodes.EXPORT_WALLET_ERROR, + error, + ); } }; @@ -1132,7 +1356,10 @@ export class TurnkeyClient { const session = await this.storageManager.getActiveSession(); if (!session) { - throw new Error("No active session found. Please log in first."); + throw new TurnkeyError( + "No active session found. Please log in first.", + TurnkeyErrorCodes.NO_SESSION_FOUND, + ); } try { @@ -1148,11 +1375,18 @@ export class TurnkeyClient { }); if (!res || !res.walletId) { - throw new Error("No wallet ID found in the import response"); + throw new TurnkeyError( + "No wallet ID found in the import response", + TurnkeyErrorCodes.BAD_RESPONSE, + ); } return res.walletId; } catch (error) { - throw new Error(`Failed to import wallet: ${error}`); + throw new TurnkeyError( + `Failed to import wallet`, + TurnkeyErrorCodes.IMPORT_WALLET_ERROR, + error, + ); } }; @@ -1163,7 +1397,10 @@ export class TurnkeyClient { const { deleteWithoutExport = false, stamperWith } = params || {}; const session = await this.storageManager.getActiveSession(); if (!session) { - throw new Error("No active session found. Please log in first."); + throw new TurnkeyError( + "No active session found. Please log in first.", + TurnkeyErrorCodes.NO_SESSION_FOUND, + ); } try { @@ -1172,7 +1409,11 @@ export class TurnkeyClient { stamperWith, ); } catch (error) { - throw new Error(`Failed to delete sub-organization: ${error}`); + throw new TurnkeyError( + `Failed to delete sub-organization`, + TurnkeyErrorCodes.DELETE_SUB_ORGANIZATION_ERROR, + error, + ); } }; @@ -1235,11 +1476,18 @@ export class TurnkeyClient { }); if (!response.subOrganizationId) { - throw new Error("Expected a non-null subOrganizationId in response"); + throw new TurnkeyError( + "Expected a non-null subOrganizationId in response", + TurnkeyErrorCodes.BAD_RESPONSE, + ); } return response as TCreateSubOrganizationResponse; } catch (error) { - throw new Error(`Failed to create sub-organization: ${error}`); + throw new TurnkeyError( + `Failed to create sub-organization`, + TurnkeyErrorCodes.CREATE_SUB_ORGANIZATION_ERROR, + error, + ); } }; @@ -1248,10 +1496,6 @@ export class TurnkeyClient { sessionKey?: string; }): Promise => { const { sessionToken, sessionKey = SessionKey.DefaultSessionkey } = params; - if (!sessionToken) { - throw new Error("Session token must be provided to create a session"); - } - try { // TODO (Amir): This should be done in a helper or something. It's very strange that we have to delete the key pair here const sessionToReplace = await this.storageManager.getSession(sessionKey); @@ -1262,7 +1506,11 @@ export class TurnkeyClient { await this.storageManager.storeSession(sessionToken, sessionKey); } catch (error) { - throw new Error(`Failed to create session: ${error}`); + throw new TurnkeyError( + `Failed to store session`, + TurnkeyErrorCodes.STORE_SESSION_ERROR, + error, + ); } finally { await this.clearUnusedKeyPairs(); } @@ -1276,20 +1524,38 @@ export class TurnkeyClient { await this.apiKeyStamper?.deleteKeyPair(session.token); await this.storageManager.clearSession(sessionKey); } else { - throw new Error(`No session found with key: ${sessionKey}`); + throw new TurnkeyError( + `No session found with key: ${sessionKey}`, + TurnkeyErrorCodes.NOT_FOUND, + ); } } catch (error) { - throw new Error(`Failed to delete session: ${error}`); + throw new TurnkeyError( + `Failed to delete session`, + TurnkeyErrorCodes.CLEAR_SESSION_ERROR, + error, + ); } }; clearAllSessions = async (): Promise => { - const sessionKeys = await this.storageManager.listSessionKeys(); - if (sessionKeys.length === 0) { - throw new Error("No sessions found to clear."); - } - for (const sessionKey of sessionKeys) { - this.clearSession({ sessionKey }); + try { + const sessionKeys = await this.storageManager.listSessionKeys(); + if (sessionKeys.length === 0) { + throw new TurnkeyError( + "No sessions found to clear.", + TurnkeyErrorCodes.NO_SESSION_FOUND, + ); + } + for (const sessionKey of sessionKeys) { + this.clearSession({ sessionKey }); + } + } catch (error) { + throw new TurnkeyError( + `Failed to clear all sessions`, + TurnkeyErrorCodes.CLEAR_ALL_SESSIONS_ERROR, + error, + ); } }; @@ -1308,13 +1574,19 @@ export class TurnkeyClient { invalidateExisitng = false, } = params || {}; if (!sessionKey) { - throw new Error("No session key provided to refresh session"); + throw new TurnkeyError( + "No session key provided or active session to refresh session", + TurnkeyErrorCodes.NO_SESSION_FOUND, + ); } const session = await this.getSession({ sessionKey: sessionKey, }); if (!session) { - throw new Error(`No active session found: ${sessionKey}`); + throw new TurnkeyError( + `No active session found: ${sessionKey}`, + TurnkeyErrorCodes.NO_SESSION_FOUND, + ); } try { @@ -1330,7 +1602,10 @@ export class TurnkeyClient { } if (!keyPair) { - throw new Error("Failed to create new key pair."); + throw new TurnkeyError( + "Failed to create new key pair.", + TurnkeyErrorCodes.INTERNAL_ERROR, + ); } const res = await this.httpClient.stampLogin({ @@ -1347,75 +1622,120 @@ export class TurnkeyClient { return res; } default: { - throw new Error( + throw new TurnkeyError( "Invalid session type passed. Use SessionType.READ_WRITE or SessionType.READ_ONLY.", + TurnkeyErrorCodes.INVALID_REQUEST, ); } } } catch (error) { - throw new Error(`Failed to refresh session: ${error}`); + throw new TurnkeyError( + `Failed to refresh session`, + TurnkeyErrorCodes.REFRESH_SESSION_ERROR, + error, + ); } }; getSession = async (params?: { sessionKey?: string; }): Promise => { - const { sessionKey = await this.storageManager.getActiveSessionKey() } = - params || {}; - return this.storageManager.getSession(sessionKey); + try { + const { sessionKey = await this.storageManager.getActiveSessionKey() } = + params || {}; + return this.storageManager.getSession(sessionKey); + } catch (error) { + throw new TurnkeyError( + `Failed to get session with key`, + TurnkeyErrorCodes.GET_SESSION_ERROR, + error, + ); + } }; getAllSessions = async (): Promise | undefined> => { - const sessionKeys = await this.storageManager.listSessionKeys(); - if (!sessionKeys || sessionKeys.length === 0) { - return undefined; - } - const sessions: Record = {}; - for (const sessionKey of sessionKeys) { - const session = await this.storageManager.getSession(sessionKey); - if (session) { - sessions[sessionKey] = session; + try { + const sessionKeys = await this.storageManager.listSessionKeys(); + if (!sessionKeys || sessionKeys.length === 0) { + return undefined; } + const sessions: Record = {}; + for (const sessionKey of sessionKeys) { + const session = await this.storageManager.getSession(sessionKey); + if (session) { + sessions[sessionKey] = session; + } + } + return sessions; + } catch (error) { + throw new TurnkeyError( + `Failed to get all sessions`, + TurnkeyErrorCodes.GET_ALL_SESSIONS_ERROR, + error, + ); } - return sessions; }; setActiveSession = async (params: { sessionKey: string }): Promise => { const { sessionKey } = params; - await this.storageManager.setActiveSessionKey(sessionKey); + try { + await this.storageManager.setActiveSessionKey(sessionKey); + } catch (error) { + throw new TurnkeyError( + `Failed to set active session`, + TurnkeyErrorCodes.SET_ACTIVE_SESSION_ERROR, + error, + ); + } }; getActiveSessionKey = async (): Promise => { - return await this.storageManager.getActiveSessionKey(); + try { + return await this.storageManager.getActiveSessionKey(); + } catch (error) { + throw new TurnkeyError( + `Failed to get active session key`, + TurnkeyErrorCodes.GET_ACTIVE_SESSION_KEY_ERROR, + error, + ); + } }; clearUnusedKeyPairs = async (): Promise => { - const publicKeys = await this.apiKeyStamper?.listKeyPairs(); - if (!publicKeys || publicKeys.length === 0) { - return; - } - const sessionKeys = await this.storageManager?.listSessionKeys(); + try { + const publicKeys = await this.apiKeyStamper?.listKeyPairs(); + if (!publicKeys || publicKeys.length === 0) { + return; + } + const sessionKeys = await this.storageManager?.listSessionKeys(); - const sessionTokensMap: Record = {}; - for (const sessionKey of sessionKeys) { - const session = await this.storageManager.getSession(sessionKey); - if (session) { - sessionTokensMap[session.token] = sessionKey; + const sessionTokensMap: Record = {}; + for (const sessionKey of sessionKeys) { + const session = await this.storageManager.getSession(sessionKey); + if (session) { + sessionTokensMap[session.token] = sessionKey; + } } - } - console.log(sessionTokensMap, publicKeys); - for (const publicKey of publicKeys) { - if (!sessionTokensMap[publicKey]) { - try { - console.log(`Deleting unused key pair: ${publicKey}`); - await this.apiKeyStamper?.deleteKeyPair(publicKey); - } catch (error) { - console.error( - `Failed to delete unused key pair ${publicKey}: ${error}`, - ); + for (const publicKey of publicKeys) { + if (!sessionTokensMap[publicKey]) { + try { + await this.apiKeyStamper?.deleteKeyPair(publicKey); + } catch (error) { + throw new TurnkeyError( + `Failed to delete unused key pair ${publicKey}`, + TurnkeyErrorCodes.INTERNAL_ERROR, + error, + ); + } } } + } catch (error) { + throw new TurnkeyError( + `Failed to clear unused key pairs`, + TurnkeyErrorCodes.CLEAR_UNUSED_KEY_PAIRS_ERROR, + error, + ); } }; @@ -1424,20 +1744,31 @@ export class TurnkeyClient { storeOverride?: boolean; }): Promise => { if (!this.apiKeyStamper) { - throw new Error("API Key Stamper is not initialized."); + throw new TurnkeyError( + "API Key Stamper is not initialized.", + TurnkeyErrorCodes.INTERNAL_ERROR, + ); } const externalKeyPair = params?.externalKeyPair; const storeOverride = params?.storeOverride ?? false; - const publicKey = await this.apiKeyStamper.createKeyPair( - externalKeyPair ? externalKeyPair : undefined, - ); + try { + const publicKey = await this.apiKeyStamper.createKeyPair( + externalKeyPair ? externalKeyPair : undefined, + ); - if (storeOverride && publicKey) { - await this.apiKeyStamper.setPublicKeyOverride(publicKey); - } + if (storeOverride && publicKey) { + await this.apiKeyStamper.setPublicKeyOverride(publicKey); + } - return publicKey; + return publicKey; + } catch (error) { + throw new TurnkeyError( + `Failed to create API key pair`, + TurnkeyErrorCodes.CREATE_API_KEY_PAIR_ERROR, + error, + ); + } }; getProxyAuthConfig = async (): Promise => { @@ -1457,13 +1788,21 @@ export class TurnkeyClient { ); if (!res.ok) { - const errorText = await res.text(); - throw new Error(`Failed to fetch auth proxy config: ${errorText}`); + throw new TurnkeyNetworkError( + `Failed to fetch auth proxy config`, + res.status, + TurnkeyErrorCodes.GET_PROXY_AUTH_CONFIG_ERROR, + await res.text(), + ); } return (await res.json()) as v1ProxyAuthConfig; } catch (error) { - throw new Error(`Failed to get auth proxy config: ${error}`); + throw new TurnkeyError( + `Failed to get auth proxy config`, + TurnkeyErrorCodes.GET_PROXY_AUTH_CONFIG_ERROR, + error, + ); } }; } diff --git a/packages/sdk-types/src/index.ts b/packages/sdk-types/src/index.ts index ae51b315f..258439382 100644 --- a/packages/sdk-types/src/index.ts +++ b/packages/sdk-types/src/index.ts @@ -25,9 +25,59 @@ export type SessionResponse = { export enum TurnkeyErrorCodes { UNKNOWN = "UNKNOWN", NETWORK_ERROR = "NETWORK_ERROR", - AUTH_ERROR = "AUTH_ERROR", + KEY_PAIR_CLEANUP_ERROR = "KEY_PAIR_CLEANUP_ERROR", + LOGOUT_ERROR = "LOGOUT_ERROR", + CREATE_PASSKEY_ERROR = "CREATE_PASSKEY_ERROR", + SELECT_PASSKEY_CANCELLED = "SELECT_PASSKEY_CANCELLED", + PASSKEY_SIGNUP_AUTH_ERROR = "PASSKEY_SIGNUP_AUTH_ERROR", + PASSKEY_LOGIN_AUTH_ERROR = "PASSKEY_LOGIN_AUTH_ERROR", + INIT_OTP_ERROR = "INIT_OTP_ERROR", + VERIFY_OTP_ERROR = "VERIFY_OTP_ERROR", + OTP_LOGIN_ERROR = "OTP_LOGIN_ERROR", + OTP_SIGNUP_ERROR = "OTP_SIGNUP_ERROR", + OTP_COMPLETION_ERROR = "OTP_COMPLETION_ERROR", + OAUTH_LOGIN_ERROR = "OAUTH_LOGIN_ERROR", + OAUTH_SIGNUP_ERROR = "OAUTH_SIGNUP_ERROR", + ACCOUNT_FETCH_ERROR = "ACCOUNT_FETCH_ERROR", + INVALID_OTP_CODE = "INVALID_OTP_CODE", + FETCH_WALLETS_ERROR = "FETCH_WALLETS_ERROR", + FETCH_WALLET_ACCOUNTS_ERROR = "FETCH_WALLET_ACCOUNTS_ERROR", + SIGN_MESSAGE_ERROR = "SIGN_MESSAGE_ERROR", + SIGN_TRANSACTION_ERROR = "SIGN_TRANSACTION_ERROR", + FETCH_USER_ERROR = "FETCH_USERS_ERROR", + CREATE_WALLET_ERROR = "CREATE_WALLET_ERROR", + CREATE_WALLET_ACCOUNT_ERROR = "CREATE_WALLET_ACCOUNT_ERROR", + EXPORT_WALLET_ERROR = "EXPORT_WALLET_ERROR", + IMPORT_WALLET_ERROR = "IMPORT_WALLET_ERROR", + DELETE_SUB_ORGANIZATION_ERROR = "DELETE_SUB_ORGANIZATION_ERROR", + CREATE_SUB_ORGANIZATION_ERROR = "CREATE_SUB_ORGANIZATION_ERROR", + STORE_SESSION_ERROR = "STORE_SESSION_ERROR", + CLEAR_SESSION_ERROR = "CLEAR_SESSION_ERROR", + CLEAR_ALL_SESSIONS_ERROR = "CLEAR_ALL_SESSIONS_ERROR", + REFRESH_SESSION_ERROR = "REFRESH_SESSION_ERROR", + GET_SESSION_ERROR = "GET_SESSION_ERROR", + GET_ALL_SESSIONS_ERROR = "GET_ALL_SESSIONS_ERROR", + SET_ACTIVE_SESSION_ERROR = "SET_ACTIVE_SESSION_ERROR", + GET_ACTIVE_SESSION_KEY_ERROR = "GET_ACTIVE_SESSION_KEY_ERROR", + CLEAR_UNUSED_KEY_PAIRS_ERROR = "CLEAR_UNUSED_KEY_PAIRS_ERROR", + CREATE_API_KEY_PAIR_ERROR = "CREATE_API_KEY_PAIR_ERROR", + GET_PROXY_AUTH_CONFIG_ERROR = "GET_PROXY_AUTH_CONFIG_ERROR", + + CLIENT_NOT_INITIALIZED = "CLIENT_NOT_INITIALIZED", + INITIALIZE_CLIENT_ERROR = "INITIALIZE_CLIENT_ERROR", + INITIALIZE_SESSION_ERROR = "INITIALIZE_SESSION_ERROR", + SCHEDULE_SESSION_EXPIRY_ERROR = "SCHEDULE_SESSION_EXPIRY_ERROR", + HANDLE_POST_AUTH_ERROR = "HANDLE_POST_AUTH_ERROR", + HANDLE_POST_LOGOUT_ERROR = "HANDLE_POST_LOGOUT_ERROR", + CLEAR_SESSION_TIMEOUTS_ERROR = "CLEAR_SESSION_TIMEOUTS_ERROR", + + BAD_RESPONSE = "BAD_RESPONSE", + MISSING_PARAMS = "MISSING_PARAMS", + INVALID_REQUEST = "INVALID_REQUEST", VALIDATION_ERROR = "VALIDATION_ERROR", SESSION_EXPIRED = "SESSION_EXPIRED", + NO_SESSION_FOUND = "NO_SESSION_FOUND", + NO_WALLETS_FOUND = "NO_WALLETS_FOUND", NOT_FOUND = "NOT_FOUND", INTERNAL_ERROR = "INTERNAL_ERROR", UNAUTHORIZED = "UNAUTHORIZED", @@ -37,7 +87,6 @@ export enum TurnkeyErrorCodes { TIMEOUT = "TIMEOUT", SERVICE_UNAVAILABLE = "SERVICE_UNAVAILABLE", GATEWAY_TIMEOUT = "GATEWAY_TIMEOUT", - INVALID_INPUT = "INVALID_INPUT", } export class TurnkeyError extends Error { From 74c05cb36487a894cb9c3d3c98b75c87a03fcf1b Mon Sep 17 00:00:00 2001 From: Ethan Konkolowicz Date: Wed, 2 Jul 2025 15:15:38 -0400 Subject: [PATCH 043/184] updated auth proxy type generation --- .../public/v1/public_api.client.ts | 59 +++ .../public/v1/public_api.fetcher.ts | 74 ++++ .../public/v1/public_api.swagger.json | 174 +++++++++ .../coordinator/public/v1/public_api.types.ts | 114 ++++++ .../src/__generated__/sdk-client-base.ts | 31 ++ .../src/__generated__/sdk_api_types.ts | 13 + .../src/__inputs__/public_api.swagger.json | 174 +++++++++ .../src/__inputs__/public_api.types.ts | 114 ++++++ .../src/__generated__/sdk-client-base.ts | 26 ++ .../src/__generated__/sdk_api_types.ts | 13 + .../src/__inputs__/public_api.swagger.json | 174 +++++++++ .../src/__inputs__/public_api.types.ts | 114 ++++++ packages/sdk-types/scripts/codegen.js | 28 +- packages/sdk-types/src/__generated__/types.ts | 207 +++++++++++ .../src/__inputs__/auth_proxy.swagger.json | 350 ++++++++++++++++++ .../src/__inputs__/public_api.swagger.json | 344 +++++++++++++++++ .../src/__inputs__/public_api.types.ts | 175 +++++++++ 17 files changed, 2181 insertions(+), 3 deletions(-) create mode 100644 packages/sdk-types/src/__inputs__/auth_proxy.swagger.json diff --git a/packages/http/src/__generated__/services/coordinator/public/v1/public_api.client.ts b/packages/http/src/__generated__/services/coordinator/public/v1/public_api.client.ts index 45df76785..a5f524495 100644 --- a/packages/http/src/__generated__/services/coordinator/public/v1/public_api.client.ts +++ b/packages/http/src/__generated__/services/coordinator/public/v1/public_api.client.ts @@ -60,6 +60,10 @@ import type { TGetProxyAuthConfigResponse, >>>>>>> 9473ed72 (re-synced sdk, added user, wallets, and proxyAuthConfig to the context) } from "./public_api.fetcher"; +import type { + TGetSmartContractInterfaceBody, + TGetSmartContractInterfaceResponse, +} from "./public_api.fetcher"; import type { TGetUserBody, TGetUserResponse } from "./public_api.fetcher"; import type { TGetWalletBody, TGetWalletResponse } from "./public_api.fetcher"; import type { @@ -830,9 +834,44 @@ export class TurnkeyClient { }; /** +<<<<<<< HEAD <<<<<<< HEAD * Get details about a user. ======= +======= + * Get details about a Smart Contract Interface + * + * Sign the provided `TGetSmartContractInterfaceBody` with the client's `stamp` function, and submit the request (POST /public/v1/query/get_smart_contract_interface). + * + * See also {@link stampGetSmartContractInterface}. + */ + getSmartContractInterface = async ( + input: TGetSmartContractInterfaceBody, + ): Promise => { + return this.request("/public/v1/query/get_smart_contract_interface", input); + }; + + /** + * Produce a `SignedRequest` from `TGetSmartContractInterfaceBody` by using the client's `stamp` function. + * + * See also {@link GetSmartContractInterface}. + */ + stampGetSmartContractInterface = async ( + input: TGetSmartContractInterfaceBody, + ): Promise => { + const fullUrl = + this.config.baseUrl + "/public/v1/query/get_smart_contract_interface"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + }; + + /** +>>>>>>> 57ef158e (updated auth proxy type generation) * Get details about a User >>>>>>> 9473ed72 (re-synced sdk, added user, wallets, and proxyAuthConfig to the context) * @@ -1044,7 +1083,11 @@ export class TurnkeyClient { }; /** +<<<<<<< HEAD * List all smart contract interfaces within an organization. +======= + * List all Smart Contract Interfaces within an Organization +>>>>>>> 57ef158e (updated auth proxy type generation) * * Sign the provided `TGetSmartContractInterfacesBody` with the client's `stamp` function, and submit the request (POST /public/v1/query/list_smart_contract_interfaces). * @@ -1666,7 +1709,11 @@ export class TurnkeyClient { }; /** +<<<<<<< HEAD * Create an ABI/IDL in JSON. +======= + * Create an ABI/IDL in JSON +>>>>>>> 57ef158e (updated auth proxy type generation) * * Sign the provided `TCreateSmartContractInterfaceBody` with the client's `stamp` function, and submit the request (POST /public/v1/submit/create_smart_contract_interface). * @@ -1701,7 +1748,11 @@ export class TurnkeyClient { }; /** +<<<<<<< HEAD * Create a new sub-organization. +======= + * Create a new Sub-Organization +>>>>>>> 57ef158e (updated auth proxy type generation) * * Sign the provided `TCreateSubOrganizationBody` with the client's `stamp` function, and submit the request (POST /public/v1/submit/create_sub_organization). * @@ -2079,7 +2130,11 @@ export class TurnkeyClient { }; /** +<<<<<<< HEAD * Delete a smart contract interface. +======= + * Delete a Smart Contract Interface +>>>>>>> 57ef158e (updated auth proxy type generation) * * Sign the provided `TDeleteSmartContractInterfaceBody` with the client's `stamp` function, and submit the request (POST /public/v1/submit/delete_smart_contract_interface). * @@ -2114,7 +2169,11 @@ export class TurnkeyClient { }; /** +<<<<<<< HEAD * Delete a sub-organization. +======= + * Deletes a sub organization +>>>>>>> 57ef158e (updated auth proxy type generation) * * Sign the provided `TDeleteSubOrganizationBody` with the client's `stamp` function, and submit the request (POST /public/v1/submit/delete_sub_organization). * diff --git a/packages/http/src/__generated__/services/coordinator/public/v1/public_api.fetcher.ts b/packages/http/src/__generated__/services/coordinator/public/v1/public_api.fetcher.ts index f08714919..8665f95ed 100644 --- a/packages/http/src/__generated__/services/coordinator/public/v1/public_api.fetcher.ts +++ b/packages/http/src/__generated__/services/coordinator/public/v1/public_api.fetcher.ts @@ -702,6 +702,62 @@ export const signGetProxyAuthConfig = ( options, }); +/** + * `POST /public/v1/query/get_smart_contract_interface` + */ +export type TGetSmartContractInterfaceResponse = + operations["PublicApiService_GetSmartContractInterface"]["responses"]["200"]["schema"]; + +/** + * `POST /public/v1/query/get_smart_contract_interface` + */ +export type TGetSmartContractInterfaceInput = { + body: TGetSmartContractInterfaceBody; +}; + +/** + * `POST /public/v1/query/get_smart_contract_interface` + */ +export type TGetSmartContractInterfaceBody = + operations["PublicApiService_GetSmartContractInterface"]["parameters"]["body"]["body"]; + +/** + * Get Smart Contract Interface + * + * Get details about a Smart Contract Interface + * + * `POST /public/v1/query/get_smart_contract_interface` + */ +export const getSmartContractInterface = ( + input: TGetSmartContractInterfaceInput, +) => + request< + TGetSmartContractInterfaceResponse, + TGetSmartContractInterfaceBody, + never, + never, + never + >({ + uri: "/public/v1/query/get_smart_contract_interface", + method: "POST", + body: input.body, + }); + +/** + * Request a WebAuthn assertion and return a signed `GetSmartContractInterface` request, ready to be POSTed to Turnkey. + * + * See {@link GetSmartContractInterface} + */ +export const signGetSmartContractInterface = ( + input: TGetSmartContractInterfaceInput, + options?: TurnkeyCredentialRequestOptions, +) => + signedRequest({ + uri: "/public/v1/query/get_smart_contract_interface", + body: input.body, + options, + }); + /** * `POST /public/v1/query/get_user` */ @@ -1056,9 +1112,15 @@ export type TGetSmartContractInterfacesBody = operations["PublicApiService_GetSmartContractInterfaces"]["parameters"]["body"]["body"]; /** +<<<<<<< HEAD * List smart contract interfaces * * List all smart contract interfaces within an organization. +======= + * List Smart Contract Interfaces + * + * List all Smart Contract Interfaces within an Organization +>>>>>>> 57ef158e (updated auth proxy type generation) * * `POST /public/v1/query/list_smart_contract_interfaces` */ @@ -2048,9 +2110,15 @@ export type TCreateSmartContractInterfaceBody = operations["PublicApiService_CreateSmartContractInterface"]["parameters"]["body"]["body"]; /** +<<<<<<< HEAD * Create smart contract interface * * Create an ABI/IDL in JSON. +======= + * Create Smart Contract Interface + * + * Create an ABI/IDL in JSON +>>>>>>> 57ef158e (updated auth proxy type generation) * * `POST /public/v1/submit/create_smart_contract_interface` */ @@ -2698,9 +2766,15 @@ export type TDeleteSmartContractInterfaceBody = operations["PublicApiService_DeleteSmartContractInterface"]["parameters"]["body"]["body"]; /** +<<<<<<< HEAD * Delete smart contract interface * * Delete a smart contract interface. +======= + * Create Smart Contract Interface + * + * Delete a Smart Contract Interface +>>>>>>> 57ef158e (updated auth proxy type generation) * * `POST /public/v1/submit/delete_smart_contract_interface` */ diff --git a/packages/http/src/__generated__/services/coordinator/public/v1/public_api.swagger.json b/packages/http/src/__generated__/services/coordinator/public/v1/public_api.swagger.json index 78a42e477..ba535a0d7 100644 --- a/packages/http/src/__generated__/services/coordinator/public/v1/public_api.swagger.json +++ b/packages/http/src/__generated__/services/coordinator/public/v1/public_api.swagger.json @@ -504,6 +504,38 @@ >>>>>>> 9473ed72 (re-synced sdk, added user, wallets, and proxyAuthConfig to the context) } }, + "/public/v1/query/get_smart_contract_interface": { + "post": { + "summary": "Get Smart Contract Interface", + "description": "Get details about a Smart Contract Interface", + "operationId": "PublicApiService_GetSmartContractInterface", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetSmartContractInterfaceResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1GetSmartContractInterfaceRequest" + } + } + ], + "tags": ["Policies"] + } + }, "/public/v1/query/get_user": { "post": { "summary": "Get user", @@ -730,8 +762,13 @@ }, "/public/v1/query/list_smart_contract_interfaces": { "post": { +<<<<<<< HEAD "summary": "List smart contract interfaces", "description": "List all smart contract interfaces within an organization.", +======= + "summary": "List Smart Contract Interfaces", + "description": "List all Smart Contract Interfaces within an Organization", +>>>>>>> 57ef158e (updated auth proxy type generation) "operationId": "PublicApiService_GetSmartContractInterfaces", "responses": { "200": { @@ -1370,8 +1407,13 @@ }, "/public/v1/submit/create_smart_contract_interface": { "post": { +<<<<<<< HEAD "summary": "Create smart contract interface", "description": "Create an ABI/IDL in JSON.", +======= + "summary": "Create Smart Contract Interface", + "description": "Create an ABI/IDL in JSON", +>>>>>>> 57ef158e (updated auth proxy type generation) "operationId": "PublicApiService_CreateSmartContractInterface", "responses": { "200": { @@ -1786,8 +1828,13 @@ }, "/public/v1/submit/delete_smart_contract_interface": { "post": { +<<<<<<< HEAD "summary": "Delete smart contract interface", "description": "Delete a smart contract interface.", +======= + "summary": "Create Smart Contract Interface", + "description": "Delete a Smart Contract Interface", +>>>>>>> 57ef158e (updated auth proxy type generation) "operationId": "PublicApiService_DeleteSmartContractInterface", "responses": { "200": { @@ -3771,6 +3818,7 @@ "ACTIVITY_TYPE_UPDATE_USER_EMAIL", "ACTIVITY_TYPE_UPDATE_USER_PHONE_NUMBER", "ACTIVITY_TYPE_INIT_FIAT_ON_RAMP", +<<<<<<< HEAD <<<<<<< HEAD "ACTIVITY_TYPE_CREATE_SMART_CONTRACT_INTERFACE", <<<<<<< HEAD @@ -3781,6 +3829,10 @@ ======= "ACTIVITY_TYPE_DELETE_SMART_CONTRACT_INTERFACE" ======= +======= + "ACTIVITY_TYPE_CREATE_SMART_CONTRACT_INTERFACE", + "ACTIVITY_TYPE_DELETE_SMART_CONTRACT_INTERFACE", +>>>>>>> 57ef158e (updated auth proxy type generation) "ACTIVITY_TYPE_ENABLE_USER_INITIATED_AUTH", "ACTIVITY_TYPE_DISABLE_USER_INITIATED_AUTH", "ACTIVITY_TYPE_UPDATE_PROXY_AUTH_CONFIG" @@ -4983,12 +5035,16 @@ "description": "Notes for a Smart Contract Interface." } }, +<<<<<<< HEAD "required": [ "smartContractAddress", "smartContractInterface", "type", "label" ] +======= + "required": ["smartContractAddress", "smartContractInterface", "type"] +>>>>>>> 57ef158e (updated auth proxy type generation) }, "v1CreateSmartContractInterfaceRequest": { "type": "object", @@ -7227,6 +7283,54 @@ "required": ["proxyAuthConfig"] >>>>>>> 9473ed72 (re-synced sdk, added user, wallets, and proxyAuthConfig to the context) }, + "v1GetSmartContractInterfaceRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "smartContractInterfaceId": { + "type": "string", + "description": "Unique identifier for a given Smart Contract Interface." + } + }, + "required": ["organizationId", "smartContractInterfaceId"] + }, + "v1GetSmartContractInterfaceResponse": { + "type": "object", + "properties": { + "smartContractInterface": { + "$ref": "#/definitions/v1SmartContractInterface", + "description": "Object to be used in conjunction with Policies to guard transaction signing." + } + }, + "required": ["smartContractInterface"] + }, + "v1GetSmartContractInterfacesRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + } + }, + "required": ["organizationId"] + }, + "v1GetSmartContractInterfacesResponse": { + "type": "object", + "properties": { + "smartContractInterfaces": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1SmartContractInterface" + }, + "description": "A list of Smart Contract Interfaces." + } + }, + "required": ["smartContractInterfaces"] + }, "v1GetSubOrgIdsRequest": { "type": "object", "properties": { @@ -8349,11 +8453,15 @@ "$ref": "#/definitions/v1InitFiatOnRampIntent" }, <<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 57ef158e (updated auth proxy type generation) "createSmartContractInterfaceIntent": { "$ref": "#/definitions/v1CreateSmartContractInterfaceIntent" }, "deleteSmartContractInterfaceIntent": { "$ref": "#/definitions/v1DeleteSmartContractInterfaceIntent" +<<<<<<< HEAD <<<<<<< HEAD }, "enableAuthProxyIntent": { @@ -8366,6 +8474,11 @@ "$ref": "#/definitions/v1UpdateAuthProxyConfigIntent" ======= ======= +>>>>>>> 2cffcb69 (updated auth proxy type generation) +======= +======= + }, +>>>>>>> 57ef158e (updated auth proxy type generation) "enableUserInitiatedAuthIntent": { "$ref": "#/definitions/v1EnableUserInitiatedAuthIntent" }, @@ -9602,11 +9715,15 @@ "$ref": "#/definitions/v1InitFiatOnRampResult" }, <<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 57ef158e (updated auth proxy type generation) "createSmartContractInterfaceResult": { "$ref": "#/definitions/v1CreateSmartContractInterfaceResult" }, "deleteSmartContractInterfaceResult": { "$ref": "#/definitions/v1DeleteSmartContractInterfaceResult" +<<<<<<< HEAD <<<<<<< HEAD }, "enableAuthProxyResult": { @@ -9619,6 +9736,11 @@ "$ref": "#/definitions/v1UpdateAuthProxyConfigResult" ======= ======= +>>>>>>> 2cffcb69 (updated auth proxy type generation) +======= +======= + }, +>>>>>>> 57ef158e (updated auth proxy type generation) "enableUserInitiatedAuthResult": { "$ref": "#/definitions/v1EnableUserInitiatedAuthResult" }, @@ -10079,6 +10201,7 @@ } } }, +<<<<<<< HEAD "v1SmartContractInterfaceReference": { "type": "object", "properties": { @@ -10092,6 +10215,57 @@ "type": "string" } } +======= + "v1SmartContractInterface": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "The Organization the Smart Contract Interface belongs to." + }, + "smartContractInterfaceId": { + "type": "string", + "description": "Unique identifier for a given Smart Contract Interface (ABI or IDL)." + }, + "contractAddress": { + "type": "string", + "description": "The address corresponding to the Smart Contract or Program." + }, + "interface": { + "type": "string", + "description": "The JSON corresponding to the Smart Contract Interface." + }, + "type": { + "type": "string", + "description": "The type corresponding to the Smart Contract Interface (either ETHEREUM or SOLANA)." + }, + "label": { + "type": "string", + "description": "The label corresponding to the Smart Contract Interface (either ETHEREUM or SOLANA)." + }, + "notes": { + "type": "string", + "description": "The notes corresponding to the Smart Contract Interface (either ETHEREUM or SOLANA)." + }, + "createdAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + }, + "updatedAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + } + }, + "required": [ + "organizationId", + "smartContractInterfaceId", + "contractAddress", + "interface", + "type", + "label", + "notes", + "createdAt", + "updatedAt" + ] +>>>>>>> 57ef158e (updated auth proxy type generation) }, "v1SmartContractInterfaceType": { "type": "string", diff --git a/packages/http/src/__generated__/services/coordinator/public/v1/public_api.types.ts b/packages/http/src/__generated__/services/coordinator/public/v1/public_api.types.ts index 94024568a..809b5ec9b 100644 --- a/packages/http/src/__generated__/services/coordinator/public/v1/public_api.types.ts +++ b/packages/http/src/__generated__/services/coordinator/public/v1/public_api.types.ts @@ -62,6 +62,10 @@ export type paths = { post: operations["PublicApiService_GetProxyAuthConfig"]; >>>>>>> 9473ed72 (re-synced sdk, added user, wallets, and proxyAuthConfig to the context) }; + "/public/v1/query/get_smart_contract_interface": { + /** Get details about a Smart Contract Interface */ + post: operations["PublicApiService_GetSmartContractInterface"]; + }; "/public/v1/query/get_user": { /** Get details about a user. */ post: operations["PublicApiService_GetUser"]; @@ -91,7 +95,11 @@ export type paths = { post: operations["PublicApiService_GetPrivateKeys"]; }; "/public/v1/query/list_smart_contract_interfaces": { +<<<<<<< HEAD /** List all smart contract interfaces within an organization. */ +======= + /** List all Smart Contract Interfaces within an Organization */ +>>>>>>> 57ef158e (updated auth proxy type generation) post: operations["PublicApiService_GetSmartContractInterfaces"]; }; "/public/v1/query/list_suborgs": { @@ -171,7 +179,11 @@ export type paths = { post: operations["PublicApiService_CreateReadWriteSession"]; }; "/public/v1/submit/create_smart_contract_interface": { +<<<<<<< HEAD /** Create an ABI/IDL in JSON. */ +======= + /** Create an ABI/IDL in JSON */ +>>>>>>> 57ef158e (updated auth proxy type generation) post: operations["PublicApiService_CreateSmartContractInterface"]; }; "/public/v1/submit/create_sub_organization": { @@ -223,7 +235,11 @@ export type paths = { post: operations["PublicApiService_DeletePrivateKeys"]; }; "/public/v1/submit/delete_smart_contract_interface": { +<<<<<<< HEAD /** Delete a smart contract interface. */ +======= + /** Delete a Smart Contract Interface */ +>>>>>>> 57ef158e (updated auth proxy type generation) post: operations["PublicApiService_DeleteSmartContractInterface"]; }; "/public/v1/submit/delete_sub_organization": { @@ -687,6 +703,7 @@ export type definitions = { | "ACTIVITY_TYPE_UPDATE_USER_EMAIL" | "ACTIVITY_TYPE_UPDATE_USER_PHONE_NUMBER" | "ACTIVITY_TYPE_INIT_FIAT_ON_RAMP" +<<<<<<< HEAD <<<<<<< HEAD | "ACTIVITY_TYPE_CREATE_SMART_CONTRACT_INTERFACE" <<<<<<< HEAD @@ -697,6 +714,10 @@ export type definitions = { ======= | "ACTIVITY_TYPE_DELETE_SMART_CONTRACT_INTERFACE"; ======= +======= + | "ACTIVITY_TYPE_CREATE_SMART_CONTRACT_INTERFACE" + | "ACTIVITY_TYPE_DELETE_SMART_CONTRACT_INTERFACE" +>>>>>>> 57ef158e (updated auth proxy type generation) | "ACTIVITY_TYPE_ENABLE_USER_INITIATED_AUTH" | "ACTIVITY_TYPE_DISABLE_USER_INITIATED_AUTH" | "ACTIVITY_TYPE_UPDATE_PROXY_AUTH_CONFIG"; @@ -1182,7 +1203,11 @@ export type definitions = { smartContractInterface: string; type: definitions["v1SmartContractInterfaceType"]; /** @description Human-readable name for a Smart Contract Interface. */ +<<<<<<< HEAD label: string; +======= + label?: string; +>>>>>>> 57ef158e (updated auth proxy type generation) /** @description Notes for a Smart Contract Interface. */ notes?: string; }; @@ -2106,6 +2131,24 @@ export type definitions = { /** @description Proxy authentication configuration (e.g., allowed origins). */ proxyAuthConfig: definitions["v1ProxyAuthConfig"]; }; + v1GetSmartContractInterfaceRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + /** @description Unique identifier for a given Smart Contract Interface. */ + smartContractInterfaceId: string; + }; + v1GetSmartContractInterfaceResponse: { + /** @description Object to be used in conjunction with Policies to guard transaction signing. */ + smartContractInterface: definitions["v1SmartContractInterface"]; + }; + v1GetSmartContractInterfacesRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + }; + v1GetSmartContractInterfacesResponse: { + /** @description A list of Smart Contract Interfaces. */ + smartContractInterfaces: definitions["v1SmartContractInterface"][]; + }; v1GetSubOrgIdsRequest: { /** @description Unique identifier for the parent Organization. This is used to find sub-organizations within it. */ >>>>>>> 9473ed72 (re-synced sdk, added user, wallets, and proxyAuthConfig to the context) @@ -2576,6 +2619,7 @@ export type definitions = { updateUserEmailIntent?: definitions["v1UpdateUserEmailIntent"]; updateUserPhoneNumberIntent?: definitions["v1UpdateUserPhoneNumberIntent"]; initFiatOnRampIntent?: definitions["v1InitFiatOnRampIntent"]; +<<<<<<< HEAD <<<<<<< HEAD createSmartContractInterfaceIntent?: definitions["v1CreateSmartContractInterfaceIntent"]; deleteSmartContractInterfaceIntent?: definitions["v1DeleteSmartContractInterfaceIntent"]; @@ -2585,6 +2629,10 @@ export type definitions = { updateAuthProxyConfigIntent?: definitions["v1UpdateAuthProxyConfigIntent"]; ======= ======= +======= + createSmartContractInterfaceIntent?: definitions["v1CreateSmartContractInterfaceIntent"]; + deleteSmartContractInterfaceIntent?: definitions["v1DeleteSmartContractInterfaceIntent"]; +>>>>>>> 57ef158e (updated auth proxy type generation) enableUserInitiatedAuthIntent?: definitions["v1EnableUserInitiatedAuthIntent"]; disableUserInitiatedAuthIntent?: definitions["v1DisableUserInitiatedAuthIntent"]; updateProxyAuthConfigIntent?: definitions["v1UpdateProxyAuthConfigIntent"]; @@ -3054,6 +3102,7 @@ export type definitions = { updateUserEmailResult?: definitions["v1UpdateUserEmailResult"]; updateUserPhoneNumberResult?: definitions["v1UpdateUserPhoneNumberResult"]; initFiatOnRampResult?: definitions["v1InitFiatOnRampResult"]; +<<<<<<< HEAD <<<<<<< HEAD createSmartContractInterfaceResult?: definitions["v1CreateSmartContractInterfaceResult"]; deleteSmartContractInterfaceResult?: definitions["v1DeleteSmartContractInterfaceResult"]; @@ -3063,6 +3112,10 @@ export type definitions = { updateAuthProxyConfigResult?: definitions["v1UpdateAuthProxyConfigResult"]; ======= ======= +======= + createSmartContractInterfaceResult?: definitions["v1CreateSmartContractInterfaceResult"]; + deleteSmartContractInterfaceResult?: definitions["v1DeleteSmartContractInterfaceResult"]; +>>>>>>> 57ef158e (updated auth proxy type generation) enableUserInitiatedAuthResult?: definitions["v1EnableUserInitiatedAuthResult"]; disableUserInitiatedAuthResult?: definitions["v1DisableUserInitiatedAuthResult"]; updateProxyAuthConfigResult?: definitions["v1UpdateProxyAuthConfigResult"]; @@ -3236,10 +3289,30 @@ export type definitions = { appidExclude?: boolean; credProps?: definitions["v1CredPropsAuthenticationExtensionsClientOutputs"]; }; +<<<<<<< HEAD v1SmartContractInterfaceReference: { smartContractInterfaceId?: string; smartContractAddress?: string; digest?: string; +======= + v1SmartContractInterface: { + /** @description The Organization the Smart Contract Interface belongs to. */ + organizationId: string; + /** @description Unique identifier for a given Smart Contract Interface (ABI or IDL). */ + smartContractInterfaceId: string; + /** @description The address corresponding to the Smart Contract or Program. */ + contractAddress: string; + /** @description The JSON corresponding to the Smart Contract Interface. */ + interface: string; + /** @description The type corresponding to the Smart Contract Interface (either ETHEREUM or SOLANA). */ + type: string; + /** @description The label corresponding to the Smart Contract Interface (either ETHEREUM or SOLANA). */ + label: string; + /** @description The notes corresponding to the Smart Contract Interface (either ETHEREUM or SOLANA). */ + notes: string; + createdAt: definitions["externaldatav1Timestamp"]; + updatedAt: definitions["externaldatav1Timestamp"]; +>>>>>>> 57ef158e (updated auth proxy type generation) }; /** @enum {string} */ v1SmartContractInterfaceType: @@ -4056,9 +4129,30 @@ export type operations = { }; }; }; +<<<<<<< HEAD <<<<<<< HEAD /** Get details about a user. */ ======= +======= + /** Get details about a Smart Contract Interface */ + PublicApiService_GetSmartContractInterface: { + parameters: { + body: { + body: definitions["v1GetSmartContractInterfaceRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1GetSmartContractInterfaceResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; +>>>>>>> 57ef158e (updated auth proxy type generation) /** Get details about a User */ >>>>>>> 9473ed72 (re-synced sdk, added user, wallets, and proxyAuthConfig to the context) PublicApiService_GetUser: { @@ -4186,7 +4280,11 @@ export type operations = { }; }; }; +<<<<<<< HEAD /** List all smart contract interfaces within an organization. */ +======= + /** List all Smart Contract Interfaces within an Organization */ +>>>>>>> 57ef158e (updated auth proxy type generation) PublicApiService_GetSmartContractInterfaces: { parameters: { body: { @@ -4546,7 +4644,11 @@ export type operations = { }; }; }; +<<<<<<< HEAD /** Create an ABI/IDL in JSON. */ +======= + /** Create an ABI/IDL in JSON */ +>>>>>>> 57ef158e (updated auth proxy type generation) PublicApiService_CreateSmartContractInterface: { parameters: { body: { @@ -4564,7 +4666,11 @@ export type operations = { }; }; }; +<<<<<<< HEAD /** Create a new sub-organization. */ +======= + /** Create a new Sub-Organization */ +>>>>>>> 57ef158e (updated auth proxy type generation) PublicApiService_CreateSubOrganization: { parameters: { body: { @@ -4780,7 +4886,11 @@ export type operations = { }; }; }; +<<<<<<< HEAD /** Delete a smart contract interface. */ +======= + /** Delete a Smart Contract Interface */ +>>>>>>> 57ef158e (updated auth proxy type generation) PublicApiService_DeleteSmartContractInterface: { parameters: { body: { @@ -4798,7 +4908,11 @@ export type operations = { }; }; }; +<<<<<<< HEAD /** Delete a sub-organization. */ +======= + /** Deletes a sub organization */ +>>>>>>> 57ef158e (updated auth proxy type generation) PublicApiService_DeleteSubOrganization: { parameters: { body: { diff --git a/packages/sdk-browser/src/__generated__/sdk-client-base.ts b/packages/sdk-browser/src/__generated__/sdk-client-base.ts index d9d6a3af4..bd3b54b13 100644 --- a/packages/sdk-browser/src/__generated__/sdk-client-base.ts +++ b/packages/sdk-browser/src/__generated__/sdk-client-base.ts @@ -567,6 +567,37 @@ export class TurnkeySDKClientBase { }; }; + getSmartContractInterface = async ( + input: SdkApiTypes.TGetSmartContractInterfaceBody, + ): Promise => { + let session = await getStorageValue(StorageKeys.Session); + session = parseSession(session!); + return this.request("/public/v1/query/get_smart_contract_interface", { + ...input, + organizationId: + input.organizationId ?? + session?.organizationId ?? + this.config.organizationId, + }); + }; + + stampGetSmartContractInterface = async ( + input: SdkApiTypes.TGetSmartContractInterfaceBody, + ): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = + this.config.apiBaseUrl + "/public/v1/query/get_smart_contract_interface"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + }; + getUser = async ( input: SdkApiTypes.TGetUserBody, ): Promise => { diff --git a/packages/sdk-browser/src/__generated__/sdk_api_types.ts b/packages/sdk-browser/src/__generated__/sdk_api_types.ts index 4bc822c62..e14ccd36d 100644 --- a/packages/sdk-browser/src/__generated__/sdk_api_types.ts +++ b/packages/sdk-browser/src/__generated__/sdk_api_types.ts @@ -166,6 +166,19 @@ export type TGetProxyAuthConfigBody = Omit< > & queryOverrideParams; +export type TGetSmartContractInterfaceResponse = + operations["PublicApiService_GetSmartContractInterface"]["responses"]["200"]["schema"]; + +export type TGetSmartContractInterfaceInput = { + body: TGetSmartContractInterfaceBody; +}; + +export type TGetSmartContractInterfaceBody = Omit< + operations["PublicApiService_GetSmartContractInterface"]["parameters"]["body"]["body"], + "organizationId" +> & + queryOverrideParams; + export type TGetUserResponse = operations["PublicApiService_GetUser"]["responses"]["200"]["schema"]; diff --git a/packages/sdk-browser/src/__inputs__/public_api.swagger.json b/packages/sdk-browser/src/__inputs__/public_api.swagger.json index 78a42e477..ba535a0d7 100644 --- a/packages/sdk-browser/src/__inputs__/public_api.swagger.json +++ b/packages/sdk-browser/src/__inputs__/public_api.swagger.json @@ -504,6 +504,38 @@ >>>>>>> 9473ed72 (re-synced sdk, added user, wallets, and proxyAuthConfig to the context) } }, + "/public/v1/query/get_smart_contract_interface": { + "post": { + "summary": "Get Smart Contract Interface", + "description": "Get details about a Smart Contract Interface", + "operationId": "PublicApiService_GetSmartContractInterface", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetSmartContractInterfaceResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1GetSmartContractInterfaceRequest" + } + } + ], + "tags": ["Policies"] + } + }, "/public/v1/query/get_user": { "post": { "summary": "Get user", @@ -730,8 +762,13 @@ }, "/public/v1/query/list_smart_contract_interfaces": { "post": { +<<<<<<< HEAD "summary": "List smart contract interfaces", "description": "List all smart contract interfaces within an organization.", +======= + "summary": "List Smart Contract Interfaces", + "description": "List all Smart Contract Interfaces within an Organization", +>>>>>>> 57ef158e (updated auth proxy type generation) "operationId": "PublicApiService_GetSmartContractInterfaces", "responses": { "200": { @@ -1370,8 +1407,13 @@ }, "/public/v1/submit/create_smart_contract_interface": { "post": { +<<<<<<< HEAD "summary": "Create smart contract interface", "description": "Create an ABI/IDL in JSON.", +======= + "summary": "Create Smart Contract Interface", + "description": "Create an ABI/IDL in JSON", +>>>>>>> 57ef158e (updated auth proxy type generation) "operationId": "PublicApiService_CreateSmartContractInterface", "responses": { "200": { @@ -1786,8 +1828,13 @@ }, "/public/v1/submit/delete_smart_contract_interface": { "post": { +<<<<<<< HEAD "summary": "Delete smart contract interface", "description": "Delete a smart contract interface.", +======= + "summary": "Create Smart Contract Interface", + "description": "Delete a Smart Contract Interface", +>>>>>>> 57ef158e (updated auth proxy type generation) "operationId": "PublicApiService_DeleteSmartContractInterface", "responses": { "200": { @@ -3771,6 +3818,7 @@ "ACTIVITY_TYPE_UPDATE_USER_EMAIL", "ACTIVITY_TYPE_UPDATE_USER_PHONE_NUMBER", "ACTIVITY_TYPE_INIT_FIAT_ON_RAMP", +<<<<<<< HEAD <<<<<<< HEAD "ACTIVITY_TYPE_CREATE_SMART_CONTRACT_INTERFACE", <<<<<<< HEAD @@ -3781,6 +3829,10 @@ ======= "ACTIVITY_TYPE_DELETE_SMART_CONTRACT_INTERFACE" ======= +======= + "ACTIVITY_TYPE_CREATE_SMART_CONTRACT_INTERFACE", + "ACTIVITY_TYPE_DELETE_SMART_CONTRACT_INTERFACE", +>>>>>>> 57ef158e (updated auth proxy type generation) "ACTIVITY_TYPE_ENABLE_USER_INITIATED_AUTH", "ACTIVITY_TYPE_DISABLE_USER_INITIATED_AUTH", "ACTIVITY_TYPE_UPDATE_PROXY_AUTH_CONFIG" @@ -4983,12 +5035,16 @@ "description": "Notes for a Smart Contract Interface." } }, +<<<<<<< HEAD "required": [ "smartContractAddress", "smartContractInterface", "type", "label" ] +======= + "required": ["smartContractAddress", "smartContractInterface", "type"] +>>>>>>> 57ef158e (updated auth proxy type generation) }, "v1CreateSmartContractInterfaceRequest": { "type": "object", @@ -7227,6 +7283,54 @@ "required": ["proxyAuthConfig"] >>>>>>> 9473ed72 (re-synced sdk, added user, wallets, and proxyAuthConfig to the context) }, + "v1GetSmartContractInterfaceRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "smartContractInterfaceId": { + "type": "string", + "description": "Unique identifier for a given Smart Contract Interface." + } + }, + "required": ["organizationId", "smartContractInterfaceId"] + }, + "v1GetSmartContractInterfaceResponse": { + "type": "object", + "properties": { + "smartContractInterface": { + "$ref": "#/definitions/v1SmartContractInterface", + "description": "Object to be used in conjunction with Policies to guard transaction signing." + } + }, + "required": ["smartContractInterface"] + }, + "v1GetSmartContractInterfacesRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + } + }, + "required": ["organizationId"] + }, + "v1GetSmartContractInterfacesResponse": { + "type": "object", + "properties": { + "smartContractInterfaces": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1SmartContractInterface" + }, + "description": "A list of Smart Contract Interfaces." + } + }, + "required": ["smartContractInterfaces"] + }, "v1GetSubOrgIdsRequest": { "type": "object", "properties": { @@ -8349,11 +8453,15 @@ "$ref": "#/definitions/v1InitFiatOnRampIntent" }, <<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 57ef158e (updated auth proxy type generation) "createSmartContractInterfaceIntent": { "$ref": "#/definitions/v1CreateSmartContractInterfaceIntent" }, "deleteSmartContractInterfaceIntent": { "$ref": "#/definitions/v1DeleteSmartContractInterfaceIntent" +<<<<<<< HEAD <<<<<<< HEAD }, "enableAuthProxyIntent": { @@ -8366,6 +8474,11 @@ "$ref": "#/definitions/v1UpdateAuthProxyConfigIntent" ======= ======= +>>>>>>> 2cffcb69 (updated auth proxy type generation) +======= +======= + }, +>>>>>>> 57ef158e (updated auth proxy type generation) "enableUserInitiatedAuthIntent": { "$ref": "#/definitions/v1EnableUserInitiatedAuthIntent" }, @@ -9602,11 +9715,15 @@ "$ref": "#/definitions/v1InitFiatOnRampResult" }, <<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 57ef158e (updated auth proxy type generation) "createSmartContractInterfaceResult": { "$ref": "#/definitions/v1CreateSmartContractInterfaceResult" }, "deleteSmartContractInterfaceResult": { "$ref": "#/definitions/v1DeleteSmartContractInterfaceResult" +<<<<<<< HEAD <<<<<<< HEAD }, "enableAuthProxyResult": { @@ -9619,6 +9736,11 @@ "$ref": "#/definitions/v1UpdateAuthProxyConfigResult" ======= ======= +>>>>>>> 2cffcb69 (updated auth proxy type generation) +======= +======= + }, +>>>>>>> 57ef158e (updated auth proxy type generation) "enableUserInitiatedAuthResult": { "$ref": "#/definitions/v1EnableUserInitiatedAuthResult" }, @@ -10079,6 +10201,7 @@ } } }, +<<<<<<< HEAD "v1SmartContractInterfaceReference": { "type": "object", "properties": { @@ -10092,6 +10215,57 @@ "type": "string" } } +======= + "v1SmartContractInterface": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "The Organization the Smart Contract Interface belongs to." + }, + "smartContractInterfaceId": { + "type": "string", + "description": "Unique identifier for a given Smart Contract Interface (ABI or IDL)." + }, + "contractAddress": { + "type": "string", + "description": "The address corresponding to the Smart Contract or Program." + }, + "interface": { + "type": "string", + "description": "The JSON corresponding to the Smart Contract Interface." + }, + "type": { + "type": "string", + "description": "The type corresponding to the Smart Contract Interface (either ETHEREUM or SOLANA)." + }, + "label": { + "type": "string", + "description": "The label corresponding to the Smart Contract Interface (either ETHEREUM or SOLANA)." + }, + "notes": { + "type": "string", + "description": "The notes corresponding to the Smart Contract Interface (either ETHEREUM or SOLANA)." + }, + "createdAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + }, + "updatedAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + } + }, + "required": [ + "organizationId", + "smartContractInterfaceId", + "contractAddress", + "interface", + "type", + "label", + "notes", + "createdAt", + "updatedAt" + ] +>>>>>>> 57ef158e (updated auth proxy type generation) }, "v1SmartContractInterfaceType": { "type": "string", diff --git a/packages/sdk-browser/src/__inputs__/public_api.types.ts b/packages/sdk-browser/src/__inputs__/public_api.types.ts index 94024568a..809b5ec9b 100644 --- a/packages/sdk-browser/src/__inputs__/public_api.types.ts +++ b/packages/sdk-browser/src/__inputs__/public_api.types.ts @@ -62,6 +62,10 @@ export type paths = { post: operations["PublicApiService_GetProxyAuthConfig"]; >>>>>>> 9473ed72 (re-synced sdk, added user, wallets, and proxyAuthConfig to the context) }; + "/public/v1/query/get_smart_contract_interface": { + /** Get details about a Smart Contract Interface */ + post: operations["PublicApiService_GetSmartContractInterface"]; + }; "/public/v1/query/get_user": { /** Get details about a user. */ post: operations["PublicApiService_GetUser"]; @@ -91,7 +95,11 @@ export type paths = { post: operations["PublicApiService_GetPrivateKeys"]; }; "/public/v1/query/list_smart_contract_interfaces": { +<<<<<<< HEAD /** List all smart contract interfaces within an organization. */ +======= + /** List all Smart Contract Interfaces within an Organization */ +>>>>>>> 57ef158e (updated auth proxy type generation) post: operations["PublicApiService_GetSmartContractInterfaces"]; }; "/public/v1/query/list_suborgs": { @@ -171,7 +179,11 @@ export type paths = { post: operations["PublicApiService_CreateReadWriteSession"]; }; "/public/v1/submit/create_smart_contract_interface": { +<<<<<<< HEAD /** Create an ABI/IDL in JSON. */ +======= + /** Create an ABI/IDL in JSON */ +>>>>>>> 57ef158e (updated auth proxy type generation) post: operations["PublicApiService_CreateSmartContractInterface"]; }; "/public/v1/submit/create_sub_organization": { @@ -223,7 +235,11 @@ export type paths = { post: operations["PublicApiService_DeletePrivateKeys"]; }; "/public/v1/submit/delete_smart_contract_interface": { +<<<<<<< HEAD /** Delete a smart contract interface. */ +======= + /** Delete a Smart Contract Interface */ +>>>>>>> 57ef158e (updated auth proxy type generation) post: operations["PublicApiService_DeleteSmartContractInterface"]; }; "/public/v1/submit/delete_sub_organization": { @@ -687,6 +703,7 @@ export type definitions = { | "ACTIVITY_TYPE_UPDATE_USER_EMAIL" | "ACTIVITY_TYPE_UPDATE_USER_PHONE_NUMBER" | "ACTIVITY_TYPE_INIT_FIAT_ON_RAMP" +<<<<<<< HEAD <<<<<<< HEAD | "ACTIVITY_TYPE_CREATE_SMART_CONTRACT_INTERFACE" <<<<<<< HEAD @@ -697,6 +714,10 @@ export type definitions = { ======= | "ACTIVITY_TYPE_DELETE_SMART_CONTRACT_INTERFACE"; ======= +======= + | "ACTIVITY_TYPE_CREATE_SMART_CONTRACT_INTERFACE" + | "ACTIVITY_TYPE_DELETE_SMART_CONTRACT_INTERFACE" +>>>>>>> 57ef158e (updated auth proxy type generation) | "ACTIVITY_TYPE_ENABLE_USER_INITIATED_AUTH" | "ACTIVITY_TYPE_DISABLE_USER_INITIATED_AUTH" | "ACTIVITY_TYPE_UPDATE_PROXY_AUTH_CONFIG"; @@ -1182,7 +1203,11 @@ export type definitions = { smartContractInterface: string; type: definitions["v1SmartContractInterfaceType"]; /** @description Human-readable name for a Smart Contract Interface. */ +<<<<<<< HEAD label: string; +======= + label?: string; +>>>>>>> 57ef158e (updated auth proxy type generation) /** @description Notes for a Smart Contract Interface. */ notes?: string; }; @@ -2106,6 +2131,24 @@ export type definitions = { /** @description Proxy authentication configuration (e.g., allowed origins). */ proxyAuthConfig: definitions["v1ProxyAuthConfig"]; }; + v1GetSmartContractInterfaceRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + /** @description Unique identifier for a given Smart Contract Interface. */ + smartContractInterfaceId: string; + }; + v1GetSmartContractInterfaceResponse: { + /** @description Object to be used in conjunction with Policies to guard transaction signing. */ + smartContractInterface: definitions["v1SmartContractInterface"]; + }; + v1GetSmartContractInterfacesRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + }; + v1GetSmartContractInterfacesResponse: { + /** @description A list of Smart Contract Interfaces. */ + smartContractInterfaces: definitions["v1SmartContractInterface"][]; + }; v1GetSubOrgIdsRequest: { /** @description Unique identifier for the parent Organization. This is used to find sub-organizations within it. */ >>>>>>> 9473ed72 (re-synced sdk, added user, wallets, and proxyAuthConfig to the context) @@ -2576,6 +2619,7 @@ export type definitions = { updateUserEmailIntent?: definitions["v1UpdateUserEmailIntent"]; updateUserPhoneNumberIntent?: definitions["v1UpdateUserPhoneNumberIntent"]; initFiatOnRampIntent?: definitions["v1InitFiatOnRampIntent"]; +<<<<<<< HEAD <<<<<<< HEAD createSmartContractInterfaceIntent?: definitions["v1CreateSmartContractInterfaceIntent"]; deleteSmartContractInterfaceIntent?: definitions["v1DeleteSmartContractInterfaceIntent"]; @@ -2585,6 +2629,10 @@ export type definitions = { updateAuthProxyConfigIntent?: definitions["v1UpdateAuthProxyConfigIntent"]; ======= ======= +======= + createSmartContractInterfaceIntent?: definitions["v1CreateSmartContractInterfaceIntent"]; + deleteSmartContractInterfaceIntent?: definitions["v1DeleteSmartContractInterfaceIntent"]; +>>>>>>> 57ef158e (updated auth proxy type generation) enableUserInitiatedAuthIntent?: definitions["v1EnableUserInitiatedAuthIntent"]; disableUserInitiatedAuthIntent?: definitions["v1DisableUserInitiatedAuthIntent"]; updateProxyAuthConfigIntent?: definitions["v1UpdateProxyAuthConfigIntent"]; @@ -3054,6 +3102,7 @@ export type definitions = { updateUserEmailResult?: definitions["v1UpdateUserEmailResult"]; updateUserPhoneNumberResult?: definitions["v1UpdateUserPhoneNumberResult"]; initFiatOnRampResult?: definitions["v1InitFiatOnRampResult"]; +<<<<<<< HEAD <<<<<<< HEAD createSmartContractInterfaceResult?: definitions["v1CreateSmartContractInterfaceResult"]; deleteSmartContractInterfaceResult?: definitions["v1DeleteSmartContractInterfaceResult"]; @@ -3063,6 +3112,10 @@ export type definitions = { updateAuthProxyConfigResult?: definitions["v1UpdateAuthProxyConfigResult"]; ======= ======= +======= + createSmartContractInterfaceResult?: definitions["v1CreateSmartContractInterfaceResult"]; + deleteSmartContractInterfaceResult?: definitions["v1DeleteSmartContractInterfaceResult"]; +>>>>>>> 57ef158e (updated auth proxy type generation) enableUserInitiatedAuthResult?: definitions["v1EnableUserInitiatedAuthResult"]; disableUserInitiatedAuthResult?: definitions["v1DisableUserInitiatedAuthResult"]; updateProxyAuthConfigResult?: definitions["v1UpdateProxyAuthConfigResult"]; @@ -3236,10 +3289,30 @@ export type definitions = { appidExclude?: boolean; credProps?: definitions["v1CredPropsAuthenticationExtensionsClientOutputs"]; }; +<<<<<<< HEAD v1SmartContractInterfaceReference: { smartContractInterfaceId?: string; smartContractAddress?: string; digest?: string; +======= + v1SmartContractInterface: { + /** @description The Organization the Smart Contract Interface belongs to. */ + organizationId: string; + /** @description Unique identifier for a given Smart Contract Interface (ABI or IDL). */ + smartContractInterfaceId: string; + /** @description The address corresponding to the Smart Contract or Program. */ + contractAddress: string; + /** @description The JSON corresponding to the Smart Contract Interface. */ + interface: string; + /** @description The type corresponding to the Smart Contract Interface (either ETHEREUM or SOLANA). */ + type: string; + /** @description The label corresponding to the Smart Contract Interface (either ETHEREUM or SOLANA). */ + label: string; + /** @description The notes corresponding to the Smart Contract Interface (either ETHEREUM or SOLANA). */ + notes: string; + createdAt: definitions["externaldatav1Timestamp"]; + updatedAt: definitions["externaldatav1Timestamp"]; +>>>>>>> 57ef158e (updated auth proxy type generation) }; /** @enum {string} */ v1SmartContractInterfaceType: @@ -4056,9 +4129,30 @@ export type operations = { }; }; }; +<<<<<<< HEAD <<<<<<< HEAD /** Get details about a user. */ ======= +======= + /** Get details about a Smart Contract Interface */ + PublicApiService_GetSmartContractInterface: { + parameters: { + body: { + body: definitions["v1GetSmartContractInterfaceRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1GetSmartContractInterfaceResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; +>>>>>>> 57ef158e (updated auth proxy type generation) /** Get details about a User */ >>>>>>> 9473ed72 (re-synced sdk, added user, wallets, and proxyAuthConfig to the context) PublicApiService_GetUser: { @@ -4186,7 +4280,11 @@ export type operations = { }; }; }; +<<<<<<< HEAD /** List all smart contract interfaces within an organization. */ +======= + /** List all Smart Contract Interfaces within an Organization */ +>>>>>>> 57ef158e (updated auth proxy type generation) PublicApiService_GetSmartContractInterfaces: { parameters: { body: { @@ -4546,7 +4644,11 @@ export type operations = { }; }; }; +<<<<<<< HEAD /** Create an ABI/IDL in JSON. */ +======= + /** Create an ABI/IDL in JSON */ +>>>>>>> 57ef158e (updated auth proxy type generation) PublicApiService_CreateSmartContractInterface: { parameters: { body: { @@ -4564,7 +4666,11 @@ export type operations = { }; }; }; +<<<<<<< HEAD /** Create a new sub-organization. */ +======= + /** Create a new Sub-Organization */ +>>>>>>> 57ef158e (updated auth proxy type generation) PublicApiService_CreateSubOrganization: { parameters: { body: { @@ -4780,7 +4886,11 @@ export type operations = { }; }; }; +<<<<<<< HEAD /** Delete a smart contract interface. */ +======= + /** Delete a Smart Contract Interface */ +>>>>>>> 57ef158e (updated auth proxy type generation) PublicApiService_DeleteSmartContractInterface: { parameters: { body: { @@ -4798,7 +4908,11 @@ export type operations = { }; }; }; +<<<<<<< HEAD /** Delete a sub-organization. */ +======= + /** Deletes a sub organization */ +>>>>>>> 57ef158e (updated auth proxy type generation) PublicApiService_DeleteSubOrganization: { parameters: { body: { diff --git a/packages/sdk-server/src/__generated__/sdk-client-base.ts b/packages/sdk-server/src/__generated__/sdk-client-base.ts index 1f2e72e71..41e9ac083 100644 --- a/packages/sdk-server/src/__generated__/sdk-client-base.ts +++ b/packages/sdk-server/src/__generated__/sdk-client-base.ts @@ -487,6 +487,32 @@ export class TurnkeySDKClientBase { }; }; + getSmartContractInterface = async ( + input: SdkApiTypes.TGetSmartContractInterfaceBody, + ): Promise => { + return this.request("/public/v1/query/get_smart_contract_interface", { + ...input, + organizationId: input.organizationId ?? this.config.organizationId, + }); + }; + + stampGetSmartContractInterface = async ( + input: SdkApiTypes.TGetSmartContractInterfaceBody, + ): Promise => { + if (!this.stamper) { + return undefined; + } + const fullUrl = + this.config.apiBaseUrl + "/public/v1/query/get_smart_contract_interface"; + const body = JSON.stringify(input); + const stamp = await this.stamper.stamp(body); + return { + body: body, + stamp: stamp, + url: fullUrl, + }; + }; + getUser = async ( input: SdkApiTypes.TGetUserBody, ): Promise => { diff --git a/packages/sdk-server/src/__generated__/sdk_api_types.ts b/packages/sdk-server/src/__generated__/sdk_api_types.ts index 4bc822c62..e14ccd36d 100644 --- a/packages/sdk-server/src/__generated__/sdk_api_types.ts +++ b/packages/sdk-server/src/__generated__/sdk_api_types.ts @@ -166,6 +166,19 @@ export type TGetProxyAuthConfigBody = Omit< > & queryOverrideParams; +export type TGetSmartContractInterfaceResponse = + operations["PublicApiService_GetSmartContractInterface"]["responses"]["200"]["schema"]; + +export type TGetSmartContractInterfaceInput = { + body: TGetSmartContractInterfaceBody; +}; + +export type TGetSmartContractInterfaceBody = Omit< + operations["PublicApiService_GetSmartContractInterface"]["parameters"]["body"]["body"], + "organizationId" +> & + queryOverrideParams; + export type TGetUserResponse = operations["PublicApiService_GetUser"]["responses"]["200"]["schema"]; diff --git a/packages/sdk-server/src/__inputs__/public_api.swagger.json b/packages/sdk-server/src/__inputs__/public_api.swagger.json index 78a42e477..ba535a0d7 100644 --- a/packages/sdk-server/src/__inputs__/public_api.swagger.json +++ b/packages/sdk-server/src/__inputs__/public_api.swagger.json @@ -504,6 +504,38 @@ >>>>>>> 9473ed72 (re-synced sdk, added user, wallets, and proxyAuthConfig to the context) } }, + "/public/v1/query/get_smart_contract_interface": { + "post": { + "summary": "Get Smart Contract Interface", + "description": "Get details about a Smart Contract Interface", + "operationId": "PublicApiService_GetSmartContractInterface", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetSmartContractInterfaceResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1GetSmartContractInterfaceRequest" + } + } + ], + "tags": ["Policies"] + } + }, "/public/v1/query/get_user": { "post": { "summary": "Get user", @@ -730,8 +762,13 @@ }, "/public/v1/query/list_smart_contract_interfaces": { "post": { +<<<<<<< HEAD "summary": "List smart contract interfaces", "description": "List all smart contract interfaces within an organization.", +======= + "summary": "List Smart Contract Interfaces", + "description": "List all Smart Contract Interfaces within an Organization", +>>>>>>> 57ef158e (updated auth proxy type generation) "operationId": "PublicApiService_GetSmartContractInterfaces", "responses": { "200": { @@ -1370,8 +1407,13 @@ }, "/public/v1/submit/create_smart_contract_interface": { "post": { +<<<<<<< HEAD "summary": "Create smart contract interface", "description": "Create an ABI/IDL in JSON.", +======= + "summary": "Create Smart Contract Interface", + "description": "Create an ABI/IDL in JSON", +>>>>>>> 57ef158e (updated auth proxy type generation) "operationId": "PublicApiService_CreateSmartContractInterface", "responses": { "200": { @@ -1786,8 +1828,13 @@ }, "/public/v1/submit/delete_smart_contract_interface": { "post": { +<<<<<<< HEAD "summary": "Delete smart contract interface", "description": "Delete a smart contract interface.", +======= + "summary": "Create Smart Contract Interface", + "description": "Delete a Smart Contract Interface", +>>>>>>> 57ef158e (updated auth proxy type generation) "operationId": "PublicApiService_DeleteSmartContractInterface", "responses": { "200": { @@ -3771,6 +3818,7 @@ "ACTIVITY_TYPE_UPDATE_USER_EMAIL", "ACTIVITY_TYPE_UPDATE_USER_PHONE_NUMBER", "ACTIVITY_TYPE_INIT_FIAT_ON_RAMP", +<<<<<<< HEAD <<<<<<< HEAD "ACTIVITY_TYPE_CREATE_SMART_CONTRACT_INTERFACE", <<<<<<< HEAD @@ -3781,6 +3829,10 @@ ======= "ACTIVITY_TYPE_DELETE_SMART_CONTRACT_INTERFACE" ======= +======= + "ACTIVITY_TYPE_CREATE_SMART_CONTRACT_INTERFACE", + "ACTIVITY_TYPE_DELETE_SMART_CONTRACT_INTERFACE", +>>>>>>> 57ef158e (updated auth proxy type generation) "ACTIVITY_TYPE_ENABLE_USER_INITIATED_AUTH", "ACTIVITY_TYPE_DISABLE_USER_INITIATED_AUTH", "ACTIVITY_TYPE_UPDATE_PROXY_AUTH_CONFIG" @@ -4983,12 +5035,16 @@ "description": "Notes for a Smart Contract Interface." } }, +<<<<<<< HEAD "required": [ "smartContractAddress", "smartContractInterface", "type", "label" ] +======= + "required": ["smartContractAddress", "smartContractInterface", "type"] +>>>>>>> 57ef158e (updated auth proxy type generation) }, "v1CreateSmartContractInterfaceRequest": { "type": "object", @@ -7227,6 +7283,54 @@ "required": ["proxyAuthConfig"] >>>>>>> 9473ed72 (re-synced sdk, added user, wallets, and proxyAuthConfig to the context) }, + "v1GetSmartContractInterfaceRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "smartContractInterfaceId": { + "type": "string", + "description": "Unique identifier for a given Smart Contract Interface." + } + }, + "required": ["organizationId", "smartContractInterfaceId"] + }, + "v1GetSmartContractInterfaceResponse": { + "type": "object", + "properties": { + "smartContractInterface": { + "$ref": "#/definitions/v1SmartContractInterface", + "description": "Object to be used in conjunction with Policies to guard transaction signing." + } + }, + "required": ["smartContractInterface"] + }, + "v1GetSmartContractInterfacesRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + } + }, + "required": ["organizationId"] + }, + "v1GetSmartContractInterfacesResponse": { + "type": "object", + "properties": { + "smartContractInterfaces": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1SmartContractInterface" + }, + "description": "A list of Smart Contract Interfaces." + } + }, + "required": ["smartContractInterfaces"] + }, "v1GetSubOrgIdsRequest": { "type": "object", "properties": { @@ -8349,11 +8453,15 @@ "$ref": "#/definitions/v1InitFiatOnRampIntent" }, <<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 57ef158e (updated auth proxy type generation) "createSmartContractInterfaceIntent": { "$ref": "#/definitions/v1CreateSmartContractInterfaceIntent" }, "deleteSmartContractInterfaceIntent": { "$ref": "#/definitions/v1DeleteSmartContractInterfaceIntent" +<<<<<<< HEAD <<<<<<< HEAD }, "enableAuthProxyIntent": { @@ -8366,6 +8474,11 @@ "$ref": "#/definitions/v1UpdateAuthProxyConfigIntent" ======= ======= +>>>>>>> 2cffcb69 (updated auth proxy type generation) +======= +======= + }, +>>>>>>> 57ef158e (updated auth proxy type generation) "enableUserInitiatedAuthIntent": { "$ref": "#/definitions/v1EnableUserInitiatedAuthIntent" }, @@ -9602,11 +9715,15 @@ "$ref": "#/definitions/v1InitFiatOnRampResult" }, <<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> 57ef158e (updated auth proxy type generation) "createSmartContractInterfaceResult": { "$ref": "#/definitions/v1CreateSmartContractInterfaceResult" }, "deleteSmartContractInterfaceResult": { "$ref": "#/definitions/v1DeleteSmartContractInterfaceResult" +<<<<<<< HEAD <<<<<<< HEAD }, "enableAuthProxyResult": { @@ -9619,6 +9736,11 @@ "$ref": "#/definitions/v1UpdateAuthProxyConfigResult" ======= ======= +>>>>>>> 2cffcb69 (updated auth proxy type generation) +======= +======= + }, +>>>>>>> 57ef158e (updated auth proxy type generation) "enableUserInitiatedAuthResult": { "$ref": "#/definitions/v1EnableUserInitiatedAuthResult" }, @@ -10079,6 +10201,7 @@ } } }, +<<<<<<< HEAD "v1SmartContractInterfaceReference": { "type": "object", "properties": { @@ -10092,6 +10215,57 @@ "type": "string" } } +======= + "v1SmartContractInterface": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "The Organization the Smart Contract Interface belongs to." + }, + "smartContractInterfaceId": { + "type": "string", + "description": "Unique identifier for a given Smart Contract Interface (ABI or IDL)." + }, + "contractAddress": { + "type": "string", + "description": "The address corresponding to the Smart Contract or Program." + }, + "interface": { + "type": "string", + "description": "The JSON corresponding to the Smart Contract Interface." + }, + "type": { + "type": "string", + "description": "The type corresponding to the Smart Contract Interface (either ETHEREUM or SOLANA)." + }, + "label": { + "type": "string", + "description": "The label corresponding to the Smart Contract Interface (either ETHEREUM or SOLANA)." + }, + "notes": { + "type": "string", + "description": "The notes corresponding to the Smart Contract Interface (either ETHEREUM or SOLANA)." + }, + "createdAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + }, + "updatedAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + } + }, + "required": [ + "organizationId", + "smartContractInterfaceId", + "contractAddress", + "interface", + "type", + "label", + "notes", + "createdAt", + "updatedAt" + ] +>>>>>>> 57ef158e (updated auth proxy type generation) }, "v1SmartContractInterfaceType": { "type": "string", diff --git a/packages/sdk-server/src/__inputs__/public_api.types.ts b/packages/sdk-server/src/__inputs__/public_api.types.ts index 94024568a..809b5ec9b 100644 --- a/packages/sdk-server/src/__inputs__/public_api.types.ts +++ b/packages/sdk-server/src/__inputs__/public_api.types.ts @@ -62,6 +62,10 @@ export type paths = { post: operations["PublicApiService_GetProxyAuthConfig"]; >>>>>>> 9473ed72 (re-synced sdk, added user, wallets, and proxyAuthConfig to the context) }; + "/public/v1/query/get_smart_contract_interface": { + /** Get details about a Smart Contract Interface */ + post: operations["PublicApiService_GetSmartContractInterface"]; + }; "/public/v1/query/get_user": { /** Get details about a user. */ post: operations["PublicApiService_GetUser"]; @@ -91,7 +95,11 @@ export type paths = { post: operations["PublicApiService_GetPrivateKeys"]; }; "/public/v1/query/list_smart_contract_interfaces": { +<<<<<<< HEAD /** List all smart contract interfaces within an organization. */ +======= + /** List all Smart Contract Interfaces within an Organization */ +>>>>>>> 57ef158e (updated auth proxy type generation) post: operations["PublicApiService_GetSmartContractInterfaces"]; }; "/public/v1/query/list_suborgs": { @@ -171,7 +179,11 @@ export type paths = { post: operations["PublicApiService_CreateReadWriteSession"]; }; "/public/v1/submit/create_smart_contract_interface": { +<<<<<<< HEAD /** Create an ABI/IDL in JSON. */ +======= + /** Create an ABI/IDL in JSON */ +>>>>>>> 57ef158e (updated auth proxy type generation) post: operations["PublicApiService_CreateSmartContractInterface"]; }; "/public/v1/submit/create_sub_organization": { @@ -223,7 +235,11 @@ export type paths = { post: operations["PublicApiService_DeletePrivateKeys"]; }; "/public/v1/submit/delete_smart_contract_interface": { +<<<<<<< HEAD /** Delete a smart contract interface. */ +======= + /** Delete a Smart Contract Interface */ +>>>>>>> 57ef158e (updated auth proxy type generation) post: operations["PublicApiService_DeleteSmartContractInterface"]; }; "/public/v1/submit/delete_sub_organization": { @@ -687,6 +703,7 @@ export type definitions = { | "ACTIVITY_TYPE_UPDATE_USER_EMAIL" | "ACTIVITY_TYPE_UPDATE_USER_PHONE_NUMBER" | "ACTIVITY_TYPE_INIT_FIAT_ON_RAMP" +<<<<<<< HEAD <<<<<<< HEAD | "ACTIVITY_TYPE_CREATE_SMART_CONTRACT_INTERFACE" <<<<<<< HEAD @@ -697,6 +714,10 @@ export type definitions = { ======= | "ACTIVITY_TYPE_DELETE_SMART_CONTRACT_INTERFACE"; ======= +======= + | "ACTIVITY_TYPE_CREATE_SMART_CONTRACT_INTERFACE" + | "ACTIVITY_TYPE_DELETE_SMART_CONTRACT_INTERFACE" +>>>>>>> 57ef158e (updated auth proxy type generation) | "ACTIVITY_TYPE_ENABLE_USER_INITIATED_AUTH" | "ACTIVITY_TYPE_DISABLE_USER_INITIATED_AUTH" | "ACTIVITY_TYPE_UPDATE_PROXY_AUTH_CONFIG"; @@ -1182,7 +1203,11 @@ export type definitions = { smartContractInterface: string; type: definitions["v1SmartContractInterfaceType"]; /** @description Human-readable name for a Smart Contract Interface. */ +<<<<<<< HEAD label: string; +======= + label?: string; +>>>>>>> 57ef158e (updated auth proxy type generation) /** @description Notes for a Smart Contract Interface. */ notes?: string; }; @@ -2106,6 +2131,24 @@ export type definitions = { /** @description Proxy authentication configuration (e.g., allowed origins). */ proxyAuthConfig: definitions["v1ProxyAuthConfig"]; }; + v1GetSmartContractInterfaceRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + /** @description Unique identifier for a given Smart Contract Interface. */ + smartContractInterfaceId: string; + }; + v1GetSmartContractInterfaceResponse: { + /** @description Object to be used in conjunction with Policies to guard transaction signing. */ + smartContractInterface: definitions["v1SmartContractInterface"]; + }; + v1GetSmartContractInterfacesRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + }; + v1GetSmartContractInterfacesResponse: { + /** @description A list of Smart Contract Interfaces. */ + smartContractInterfaces: definitions["v1SmartContractInterface"][]; + }; v1GetSubOrgIdsRequest: { /** @description Unique identifier for the parent Organization. This is used to find sub-organizations within it. */ >>>>>>> 9473ed72 (re-synced sdk, added user, wallets, and proxyAuthConfig to the context) @@ -2576,6 +2619,7 @@ export type definitions = { updateUserEmailIntent?: definitions["v1UpdateUserEmailIntent"]; updateUserPhoneNumberIntent?: definitions["v1UpdateUserPhoneNumberIntent"]; initFiatOnRampIntent?: definitions["v1InitFiatOnRampIntent"]; +<<<<<<< HEAD <<<<<<< HEAD createSmartContractInterfaceIntent?: definitions["v1CreateSmartContractInterfaceIntent"]; deleteSmartContractInterfaceIntent?: definitions["v1DeleteSmartContractInterfaceIntent"]; @@ -2585,6 +2629,10 @@ export type definitions = { updateAuthProxyConfigIntent?: definitions["v1UpdateAuthProxyConfigIntent"]; ======= ======= +======= + createSmartContractInterfaceIntent?: definitions["v1CreateSmartContractInterfaceIntent"]; + deleteSmartContractInterfaceIntent?: definitions["v1DeleteSmartContractInterfaceIntent"]; +>>>>>>> 57ef158e (updated auth proxy type generation) enableUserInitiatedAuthIntent?: definitions["v1EnableUserInitiatedAuthIntent"]; disableUserInitiatedAuthIntent?: definitions["v1DisableUserInitiatedAuthIntent"]; updateProxyAuthConfigIntent?: definitions["v1UpdateProxyAuthConfigIntent"]; @@ -3054,6 +3102,7 @@ export type definitions = { updateUserEmailResult?: definitions["v1UpdateUserEmailResult"]; updateUserPhoneNumberResult?: definitions["v1UpdateUserPhoneNumberResult"]; initFiatOnRampResult?: definitions["v1InitFiatOnRampResult"]; +<<<<<<< HEAD <<<<<<< HEAD createSmartContractInterfaceResult?: definitions["v1CreateSmartContractInterfaceResult"]; deleteSmartContractInterfaceResult?: definitions["v1DeleteSmartContractInterfaceResult"]; @@ -3063,6 +3112,10 @@ export type definitions = { updateAuthProxyConfigResult?: definitions["v1UpdateAuthProxyConfigResult"]; ======= ======= +======= + createSmartContractInterfaceResult?: definitions["v1CreateSmartContractInterfaceResult"]; + deleteSmartContractInterfaceResult?: definitions["v1DeleteSmartContractInterfaceResult"]; +>>>>>>> 57ef158e (updated auth proxy type generation) enableUserInitiatedAuthResult?: definitions["v1EnableUserInitiatedAuthResult"]; disableUserInitiatedAuthResult?: definitions["v1DisableUserInitiatedAuthResult"]; updateProxyAuthConfigResult?: definitions["v1UpdateProxyAuthConfigResult"]; @@ -3236,10 +3289,30 @@ export type definitions = { appidExclude?: boolean; credProps?: definitions["v1CredPropsAuthenticationExtensionsClientOutputs"]; }; +<<<<<<< HEAD v1SmartContractInterfaceReference: { smartContractInterfaceId?: string; smartContractAddress?: string; digest?: string; +======= + v1SmartContractInterface: { + /** @description The Organization the Smart Contract Interface belongs to. */ + organizationId: string; + /** @description Unique identifier for a given Smart Contract Interface (ABI or IDL). */ + smartContractInterfaceId: string; + /** @description The address corresponding to the Smart Contract or Program. */ + contractAddress: string; + /** @description The JSON corresponding to the Smart Contract Interface. */ + interface: string; + /** @description The type corresponding to the Smart Contract Interface (either ETHEREUM or SOLANA). */ + type: string; + /** @description The label corresponding to the Smart Contract Interface (either ETHEREUM or SOLANA). */ + label: string; + /** @description The notes corresponding to the Smart Contract Interface (either ETHEREUM or SOLANA). */ + notes: string; + createdAt: definitions["externaldatav1Timestamp"]; + updatedAt: definitions["externaldatav1Timestamp"]; +>>>>>>> 57ef158e (updated auth proxy type generation) }; /** @enum {string} */ v1SmartContractInterfaceType: @@ -4056,9 +4129,30 @@ export type operations = { }; }; }; +<<<<<<< HEAD <<<<<<< HEAD /** Get details about a user. */ ======= +======= + /** Get details about a Smart Contract Interface */ + PublicApiService_GetSmartContractInterface: { + parameters: { + body: { + body: definitions["v1GetSmartContractInterfaceRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1GetSmartContractInterfaceResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; +>>>>>>> 57ef158e (updated auth proxy type generation) /** Get details about a User */ >>>>>>> 9473ed72 (re-synced sdk, added user, wallets, and proxyAuthConfig to the context) PublicApiService_GetUser: { @@ -4186,7 +4280,11 @@ export type operations = { }; }; }; +<<<<<<< HEAD /** List all smart contract interfaces within an organization. */ +======= + /** List all Smart Contract Interfaces within an Organization */ +>>>>>>> 57ef158e (updated auth proxy type generation) PublicApiService_GetSmartContractInterfaces: { parameters: { body: { @@ -4546,7 +4644,11 @@ export type operations = { }; }; }; +<<<<<<< HEAD /** Create an ABI/IDL in JSON. */ +======= + /** Create an ABI/IDL in JSON */ +>>>>>>> 57ef158e (updated auth proxy type generation) PublicApiService_CreateSmartContractInterface: { parameters: { body: { @@ -4564,7 +4666,11 @@ export type operations = { }; }; }; +<<<<<<< HEAD /** Create a new sub-organization. */ +======= + /** Create a new Sub-Organization */ +>>>>>>> 57ef158e (updated auth proxy type generation) PublicApiService_CreateSubOrganization: { parameters: { body: { @@ -4780,7 +4886,11 @@ export type operations = { }; }; }; +<<<<<<< HEAD /** Delete a smart contract interface. */ +======= + /** Delete a Smart Contract Interface */ +>>>>>>> 57ef158e (updated auth proxy type generation) PublicApiService_DeleteSmartContractInterface: { parameters: { body: { @@ -4798,7 +4908,11 @@ export type operations = { }; }; }; +<<<<<<< HEAD /** Delete a sub-organization. */ +======= + /** Deletes a sub organization */ +>>>>>>> 57ef158e (updated auth proxy type generation) PublicApiService_DeleteSubOrganization: { parameters: { body: { diff --git a/packages/sdk-types/scripts/codegen.js b/packages/sdk-types/scripts/codegen.js index edbf67bd9..a147254f0 100644 --- a/packages/sdk-types/scripts/codegen.js +++ b/packages/sdk-types/scripts/codegen.js @@ -10,6 +10,10 @@ const typesPath = path.resolve( __dirname, "../src/__inputs__/public_api.types.ts", ); +const authProxySwaggerPath = path.resolve( + __dirname, + "../src/__inputs__/auth_proxy.swagger.json", +); const outputPath = path.resolve(__dirname, "../src/__generated__/types.ts"); const COMMENT_HEADER = "/* @generated by codegen. DO NOT EDIT BY HAND */"; @@ -427,7 +431,25 @@ function generateApiTypes(swagger) { } function main() { - const swagger = JSON.parse(fs.readFileSync(swaggerPath, "utf8")); + const swaggerMain = JSON.parse(fs.readFileSync(swaggerPath, "utf8")); + const swaggerAuthProxy = JSON.parse( + fs.readFileSync(authProxySwaggerPath, "utf8"), + ); + + // Merge definitions and paths + const mergedSwagger = { + ...swaggerMain, + definitions: { + ...swaggerMain.definitions, + ...swaggerAuthProxy.definitions, + }, + paths: { + ...swaggerMain.paths, + ...swaggerAuthProxy.paths, + }, + // Optionally merge other top-level keys if needed + }; + const typesSrc = fs.readFileSync(typesPath, "utf8"); const typeDefRegex = /export type (\w+) = ([^;]+);/g; @@ -447,7 +469,7 @@ function main() { // --- Base Types --- output += `// --- Base Types from Swagger Definitions ---\n`; - for (const [defName, def] of Object.entries(swagger.definitions)) { + for (const [defName, def] of Object.entries(mergedSwagger.definitions)) { if ( (def.type === "object" && def.properties) || (def.type === "string" && def.enum) @@ -461,7 +483,7 @@ function main() { // -- Api Types -- output += "\n// --- API Types from Swagger Paths ---\n"; - output += generateApiTypes(swagger); + output += generateApiTypes(mergedSwagger); fs.writeFileSync(outputPath, output); } diff --git a/packages/sdk-types/src/__generated__/types.ts b/packages/sdk-types/src/__generated__/types.ts index 3cdaac209..57fc7a0d7 100644 --- a/packages/sdk-types/src/__generated__/types.ts +++ b/packages/sdk-types/src/__generated__/types.ts @@ -273,6 +273,8 @@ export type v1ActivityType = | "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_USER_INITIATED_AUTH" | "ACTIVITY_TYPE_DISABLE_USER_INITIATED_AUTH" | "ACTIVITY_TYPE_UPDATE_PROXY_AUTH_CONFIG"; @@ -785,6 +787,32 @@ export type v1CreateReadWriteSessionResultV2 = { credentialBundle: string; }; +export type v1CreateSmartContractInterfaceIntent = { + /** Corresponding contract address or program ID */ + smartContractAddress: string; + /** ABI/IDL as a JSON string */ + smartContractInterface: string; + type: v1SmartContractInterfaceType; + /** Human-readable name for a Smart Contract Interface. */ + label?: string; + /** Notes for a Smart Contract Interface. */ + notes?: string; +}; + +export type v1CreateSmartContractInterfaceRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: v1CreateSmartContractInterfaceIntent; +}; + +export type v1CreateSmartContractInterfaceResult = { + /** The ID of the created Smart Contract Interface. */ + smartContractInterfaceId: string; +}; + export type v1CreateSubOrganizationIntent = { /** Name for this sub-organization */ name: string; @@ -1192,6 +1220,25 @@ export type v1DeletePrivateKeysResult = { privateKeyIds: string[]; }; +export type v1DeleteSmartContractInterfaceIntent = { + /** The ID of a Smart Contract Interface intended for deletion. */ + smartContractInterfaceId: string; +}; + +export type v1DeleteSmartContractInterfaceRequest = { + type: string; + /** Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** Unique identifier for a given Organization. */ + organizationId: string; + parameters: v1DeleteSmartContractInterfaceIntent; +}; + +export type v1DeleteSmartContractInterfaceResult = { + /** The ID of the deleted Smart Contract Interface. */ + smartContractInterfaceId: string; +}; + export type v1DeleteSubOrganizationIntent = { /** Sub-organization deletion, by default, requires associated wallets and private keys to be exported for security reasons. Set this boolean to true to force sub-organization deletion even if some wallets or private keys within it have not been exported yet. Default: false. */ deleteWithoutExport?: boolean; @@ -1721,6 +1768,28 @@ export type v1GetProxyAuthConfigResponse = { proxyAuthConfig: v1ProxyAuthConfig; }; +export type v1GetSmartContractInterfaceRequest = { + /** Unique identifier for a given Organization. */ + organizationId: string; + /** Unique identifier for a given Smart Contract Interface. */ + smartContractInterfaceId: string; +}; + +export type v1GetSmartContractInterfaceResponse = { + /** Object to be used in conjunction with Policies to guard transaction signing. */ + smartContractInterface: v1SmartContractInterface; +}; + +export type v1GetSmartContractInterfacesRequest = { + /** Unique identifier for a given Organization. */ + organizationId: string; +}; + +export type v1GetSmartContractInterfacesResponse = { + /** A list of Smart Contract Interfaces. */ + smartContractInterfaces: v1SmartContractInterface[]; +}; + export type v1GetSubOrgIdsRequest = { /** Unique identifier for the parent Organization. This is used to find sub-organizations within it. */ organizationId: string; @@ -2198,6 +2267,8 @@ export type v1Intent = { updateUserEmailIntent?: v1UpdateUserEmailIntent; updateUserPhoneNumberIntent?: v1UpdateUserPhoneNumberIntent; initFiatOnRampIntent?: v1InitFiatOnRampIntent; + createSmartContractInterfaceIntent?: v1CreateSmartContractInterfaceIntent; + deleteSmartContractInterfaceIntent?: v1DeleteSmartContractInterfaceIntent; enableUserInitiatedAuthIntent?: v1EnableUserInitiatedAuthIntent; disableUserInitiatedAuthIntent?: v1DisableUserInitiatedAuthIntent; updateProxyAuthConfigIntent?: v1UpdateProxyAuthConfigIntent; @@ -2676,6 +2747,8 @@ export type v1Result = { updateUserEmailResult?: v1UpdateUserEmailResult; updateUserPhoneNumberResult?: v1UpdateUserPhoneNumberResult; initFiatOnRampResult?: v1InitFiatOnRampResult; + createSmartContractInterfaceResult?: v1CreateSmartContractInterfaceResult; + deleteSmartContractInterfaceResult?: v1DeleteSmartContractInterfaceResult; enableUserInitiatedAuthResult?: v1EnableUserInitiatedAuthResult; disableUserInitiatedAuthResult?: v1DisableUserInitiatedAuthResult; updateProxyAuthConfigResult?: v1UpdateProxyAuthConfigResult; @@ -2865,6 +2938,29 @@ export type v1SimpleClientExtensionResults = { credProps?: v1CredPropsAuthenticationExtensionsClientOutputs; }; +export type v1SmartContractInterface = { + /** The Organization the Smart Contract Interface belongs to. */ + organizationId: string; + /** Unique identifier for a given Smart Contract Interface (ABI or IDL). */ + smartContractInterfaceId: string; + /** The address corresponding to the Smart Contract or Program. */ + contractAddress: string; + /** The JSON corresponding to the Smart Contract Interface. */ + interface: string; + /** The type corresponding to the Smart Contract Interface (either ETHEREUM or SOLANA). */ + type: string; + /** The label corresponding to the Smart Contract Interface (either ETHEREUM or SOLANA). */ + label: string; + /** The notes corresponding to the Smart Contract Interface (either ETHEREUM or SOLANA). */ + notes: string; + createdAt: externaldatav1Timestamp; + updatedAt: externaldatav1Timestamp; +}; + +export type v1SmartContractInterfaceType = + | "SMART_CONTRACT_INTERFACE_TYPE_ETHEREUM" + | "SMART_CONTRACT_INTERFACE_TYPE_SOLANA"; + export type v1SmsCustomizationParams = { /** Template containing references to .OtpCode i.e Your OTP is {{.OtpCode}} */ template?: string; @@ -3379,6 +3475,48 @@ export type v1WebAuthnStamp = { signature: string; }; +export type v1GetAccountResponse = { + organizationId: string; +}; + +export type v1GetWalletKitConfigResponse = { + facebookEnabled: boolean; + googleEnabled: boolean; + appleEnabled: boolean; + emailEnabled: boolean; + smsEnabled: boolean; + passkeyEnabled: boolean; + walletEnabled: boolean; + openOAuthInPage: boolean; + passkeySessionExpirationSeconds: string; + walletSessionExpirationSeconds: string; + organizationId: string; +}; + +export type v1InitOtpResponse = { + /** Unique identifier for an OTP authentication */ + otpId: string; +}; + +export type v1OAuthLoginResponse = { + /** Signed JWT containing an expiry, public key, session type, user id, and organization id */ + session: string; +}; + +export type v1OtpLoginResponse = { + /** Signed JWT containing an expiry, public key, session type, user id, and organization id */ + session: string; +}; + +export type v1SignupResponse = { + organizationId: string; +}; + +export type v1VerifyOtpResponse = { + /** Signed JWT containing a unique id, expiry, verification type, contact. Verification status of a user is updated when the token is consumed (in OTP_LOGIN requests) */ + verificationToken: string; +}; + // --- API Types from Swagger Paths --- export type TGetActivityResponse = { /** An action that can that can be taken within the Turnkey infrastructure. */ @@ -3534,6 +3672,21 @@ export type TGetProxyAuthConfigBody = { export type TGetProxyAuthConfigInput = { body: TGetProxyAuthConfigBody }; +export type TGetSmartContractInterfaceResponse = { + /** Object to be used in conjunction with Policies to guard transaction signing. */ + smartContractInterface: v1SmartContractInterface; +}; + +export type TGetSmartContractInterfaceBody = { + organizationId?: string; + /** Unique identifier for a given Smart Contract Interface. */ + smartContractInterfaceId: string; +}; + +export type TGetSmartContractInterfaceInput = { + body: TGetSmartContractInterfaceBody; +}; + export type TGetUserResponse = { /** Web and/or API user within your Organization. */ user: v1User; @@ -3627,6 +3780,19 @@ export type TGetPrivateKeysBody = { export type TGetPrivateKeysInput = { body: TGetPrivateKeysBody }; +export type TGetSmartContractInterfacesResponse = { + /** A list of Smart Contract Interfaces. */ + smartContractInterfaces: v1SmartContractInterface[]; +}; + +export type TGetSmartContractInterfacesBody = { + organizationId?: string; +}; + +export type TGetSmartContractInterfacesInput = { + body: TGetSmartContractInterfacesBody; +}; + export type TGetSubOrgIdsResponse = { /** List of unique identifiers for the matching sub-organizations. */ organizationIds: string[]; @@ -3949,6 +4115,30 @@ export type TCreateReadWriteSessionInput = { body: TCreateReadWriteSessionBody; }; +export type TCreateSmartContractInterfaceResponse = { + activity: v1Activity; + /** The ID of the created Smart Contract Interface. */ + smartContractInterfaceId: string; +}; + +export type TCreateSmartContractInterfaceBody = { + timestampMs?: string; + organizationId?: string; + /** Corresponding contract address or program ID */ + smartContractAddress: string; + /** ABI/IDL as a JSON string */ + smartContractInterface: string; + type: v1SmartContractInterfaceType; + /** Human-readable name for a Smart Contract Interface. */ + label?: string; + /** Notes for a Smart Contract Interface. */ + notes?: string; +}; + +export type TCreateSmartContractInterfaceInput = { + body: TCreateSmartContractInterfaceBody; +}; + export type TCreateSubOrganizationResponse = { activity: v1Activity; subOrganizationId: string; @@ -4168,6 +4358,23 @@ export type TDeletePrivateKeysBody = { export type TDeletePrivateKeysInput = { body: TDeletePrivateKeysBody }; +export type TDeleteSmartContractInterfaceResponse = { + activity: v1Activity; + /** The ID of the deleted Smart Contract Interface. */ + smartContractInterfaceId: string; +}; + +export type TDeleteSmartContractInterfaceBody = { + timestampMs?: string; + organizationId?: string; + /** The ID of a Smart Contract Interface intended for deletion. */ + smartContractInterfaceId: string; +}; + +export type TDeleteSmartContractInterfaceInput = { + body: TDeleteSmartContractInterfaceBody; +}; + export type TDeleteSubOrganizationResponse = { activity: v1Activity; /** Unique identifier of the sub organization that was removed */ diff --git a/packages/sdk-types/src/__inputs__/auth_proxy.swagger.json b/packages/sdk-types/src/__inputs__/auth_proxy.swagger.json new file mode 100644 index 000000000..ad69dd2fb --- /dev/null +++ b/packages/sdk-types/src/__inputs__/auth_proxy.swagger.json @@ -0,0 +1,350 @@ +{ + "swagger": "2.0", + "info": { + "title": "services/auth_proxy/v1/proxy_api.proto", + "version": "version not set" + }, + "tags": [ + { + "name": "AuthProxyService" + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "paths": {}, + "definitions": { + "protobufAny": { + "type": "object", + "properties": { + "@type": { + "type": "string" + } + }, + "additionalProperties": {} + }, + "rpcStatus": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/protobufAny" + } + } + } + }, + "v1AddressFormat": { + "type": "string", + "enum": [ + "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" + ] + }, + "v1ApiKeyCurve": { + "type": "string", + "enum": [ + "API_KEY_CURVE_P256", + "API_KEY_CURVE_SECP256K1", + "API_KEY_CURVE_ED25519" + ] + }, + "v1ApiKeyParamsV2": { + "type": "object", + "properties": { + "apiKeyName": { + "type": "string", + "description": "Human-readable name for an API Key." + }, + "publicKey": { + "type": "string", + "description": "The public component of a cryptographic key pair used to sign messages and transactions." + }, + "curveType": { + "$ref": "#/definitions/v1ApiKeyCurve", + "description": "The curve type to be used for processing API key signatures." + }, + "expirationSeconds": { + "type": "string", + "description": "Optional window (in seconds) indicating how long the API Key should last." + } + }, + "required": ["apiKeyName", "publicKey", "curveType"] + }, + "v1Attestation": { + "type": "object", + "properties": { + "credentialId": { + "type": "string", + "description": "The cbor encoded then base64 url encoded id of the credential." + }, + "clientDataJson": { + "type": "string", + "description": "A base64 url encoded payload containing metadata about the signing context and the challenge." + }, + "attestationObject": { + "type": "string", + "description": "A base64 url encoded payload containing authenticator data and any attestation the webauthn provider chooses." + }, + "transports": { + "type": "array", + "items": { + "$ref": "#/definitions/v1AuthenticatorTransport" + }, + "description": "The type of authenticator transports." + } + }, + "required": [ + "credentialId", + "clientDataJson", + "attestationObject", + "transports" + ] + }, + "v1AuthenticatorParamsV2": { + "type": "object", + "properties": { + "authenticatorName": { + "type": "string", + "description": "Human-readable name for an Authenticator." + }, + "challenge": { + "type": "string", + "description": "Challenge presented for authentication purposes." + }, + "attestation": { + "$ref": "#/definitions/v1Attestation", + "description": "The attestation that proves custody of the authenticator and provides metadata about it." + } + }, + "required": ["authenticatorName", "challenge", "attestation"] + }, + "v1AuthenticatorTransport": { + "type": "string", + "enum": [ + "AUTHENTICATOR_TRANSPORT_BLE", + "AUTHENTICATOR_TRANSPORT_INTERNAL", + "AUTHENTICATOR_TRANSPORT_NFC", + "AUTHENTICATOR_TRANSPORT_USB", + "AUTHENTICATOR_TRANSPORT_HYBRID" + ] + }, + "v1Curve": { + "type": "string", + "enum": ["CURVE_SECP256K1", "CURVE_ED25519"] + }, + "v1GetAccountResponse": { + "type": "object", + "properties": { + "organizationId": { + "type": "string" + } + }, + "required": ["organizationId"] + }, + "v1GetWalletKitConfigResponse": { + "type": "object", + "properties": { + "facebookEnabled": { + "type": "boolean" + }, + "googleEnabled": { + "type": "boolean" + }, + "appleEnabled": { + "type": "boolean" + }, + "emailEnabled": { + "type": "boolean" + }, + "smsEnabled": { + "type": "boolean" + }, + "passkeyEnabled": { + "type": "boolean" + }, + "walletEnabled": { + "type": "boolean" + }, + "openOAuthInPage": { + "type": "boolean" + }, + "passkeySessionExpirationSeconds": { + "type": "string" + }, + "walletSessionExpirationSeconds": { + "type": "string" + }, + "organizationId": { + "type": "string" + } + }, + "required": [ + "facebookEnabled", + "googleEnabled", + "appleEnabled", + "emailEnabled", + "smsEnabled", + "passkeyEnabled", + "walletEnabled", + "openOAuthInPage", + "passkeySessionExpirationSeconds", + "walletSessionExpirationSeconds", + "organizationId" + ] + }, + "v1InitOtpResponse": { + "type": "object", + "properties": { + "otpId": { + "type": "string", + "description": "Unique identifier for an OTP authentication" + } + }, + "required": ["otpId"] + }, + "v1OAuthLoginResponse": { + "type": "object", + "properties": { + "session": { + "type": "string", + "description": "Signed JWT containing an expiry, public key, session type, user id, and organization id" + } + }, + "required": ["session"] + }, + "v1OauthProviderParams": { + "type": "object", + "properties": { + "providerName": { + "type": "string", + "description": "Human-readable name to identify a Provider." + }, + "oidcToken": { + "type": "string", + "description": "Base64 encoded OIDC token" + } + }, + "required": ["providerName", "oidcToken"] + }, + "v1OtpLoginResponse": { + "type": "object", + "properties": { + "session": { + "type": "string", + "description": "Signed JWT containing an expiry, public key, session type, user id, and organization id" + } + }, + "required": ["session"] + }, + "v1PathFormat": { + "type": "string", + "enum": ["PATH_FORMAT_BIP32"] + }, + "v1SignupResponse": { + "type": "object", + "properties": { + "organizationId": { + "type": "string" + } + }, + "required": ["organizationId"] + }, + "v1VerifyOtpResponse": { + "type": "object", + "properties": { + "verificationToken": { + "type": "string", + "description": "Signed JWT containing a unique id, expiry, verification type, contact. Verification status of a user is updated when the token is consumed (in OTP_LOGIN requests)" + } + }, + "required": ["verificationToken"] + }, + "v1WalletAccountParams": { + "type": "object", + "properties": { + "curve": { + "$ref": "#/definitions/v1Curve", + "description": "Cryptographic curve used to generate a wallet Account." + }, + "pathFormat": { + "$ref": "#/definitions/v1PathFormat", + "description": "Path format used to generate a wallet Account." + }, + "path": { + "type": "string", + "description": "Path used to generate a wallet Account." + }, + "addressFormat": { + "$ref": "#/definitions/v1AddressFormat", + "description": "Address format used to generate a wallet Acccount." + } + }, + "required": ["curve", "pathFormat", "path", "addressFormat"] + }, + "v1WalletParams": { + "type": "object", + "properties": { + "walletName": { + "type": "string", + "description": "Human-readable name for a Wallet." + }, + "accounts": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1WalletAccountParams" + }, + "description": "A list of wallet Accounts. This field, if not needed, should be an empty array in your request body." + }, + "mnemonicLength": { + "type": "integer", + "format": "int32", + "description": "Length of mnemonic to generate the Wallet seed. Defaults to 12. Accepted values: 12, 15, 18, 21, 24." + } + }, + "required": ["walletName", "accounts"] + } + } +} diff --git a/packages/sdk-types/src/__inputs__/public_api.swagger.json b/packages/sdk-types/src/__inputs__/public_api.swagger.json index 473c24e61..da171bdff 100644 --- a/packages/sdk-types/src/__inputs__/public_api.swagger.json +++ b/packages/sdk-types/src/__inputs__/public_api.swagger.json @@ -452,6 +452,38 @@ "tags": ["Organizations"] } }, + "/public/v1/query/get_smart_contract_interface": { + "post": { + "summary": "Get Smart Contract Interface", + "description": "Get details about a Smart Contract Interface", + "operationId": "PublicApiService_GetSmartContractInterface", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetSmartContractInterfaceResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1GetSmartContractInterfaceRequest" + } + } + ], + "tags": ["Policies"] + } + }, "/public/v1/query/get_user": { "post": { "summary": "Get User", @@ -676,6 +708,38 @@ "tags": ["Private Keys"] } }, + "/public/v1/query/list_smart_contract_interfaces": { + "post": { + "summary": "List Smart Contract Interfaces", + "description": "List all Smart Contract Interfaces within an Organization", + "operationId": "PublicApiService_GetSmartContractInterfaces", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1GetSmartContractInterfacesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1GetSmartContractInterfacesRequest" + } + } + ], + "tags": ["Policies"] + } + }, "/public/v1/query/list_suborgs": { "post": { "summary": "Get Suborgs", @@ -1284,6 +1348,38 @@ "tags": ["Sessions"] } }, + "/public/v1/submit/create_smart_contract_interface": { + "post": { + "summary": "Create Smart Contract Interface", + "description": "Create an ABI/IDL in JSON", + "operationId": "PublicApiService_CreateSmartContractInterface", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1CreateSmartContractInterfaceRequest" + } + } + ], + "tags": ["Policies"] + } + }, "/public/v1/submit/create_sub_organization": { "post": { "summary": "Create Sub-Organization", @@ -1668,6 +1764,38 @@ "tags": ["Private Keys"] } }, + "/public/v1/submit/delete_smart_contract_interface": { + "post": { + "summary": "Create Smart Contract Interface", + "description": "Delete a Smart Contract Interface", + "operationId": "PublicApiService_DeleteSmartContractInterface", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ActivityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1DeleteSmartContractInterfaceRequest" + } + } + ], + "tags": ["Policies"] + } + }, "/public/v1/submit/delete_sub_organization": { "post": { "summary": "Delete Sub Organization", @@ -3522,6 +3650,8 @@ "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_USER_INITIATED_AUTH", "ACTIVITY_TYPE_DISABLE_USER_INITIATED_AUTH", "ACTIVITY_TYPE_UPDATE_PROXY_AUTH_CONFIG" @@ -4699,6 +4829,62 @@ "credentialBundle" ] }, + "v1CreateSmartContractInterfaceIntent": { + "type": "object", + "properties": { + "smartContractAddress": { + "type": "string", + "description": "Corresponding contract address or program ID" + }, + "smartContractInterface": { + "type": "string", + "description": "ABI/IDL as a JSON string" + }, + "type": { + "$ref": "#/definitions/v1SmartContractInterfaceType" + }, + "label": { + "type": "string", + "description": "Human-readable name for a Smart Contract Interface." + }, + "notes": { + "type": "string", + "description": "Notes for a Smart Contract Interface." + } + }, + "required": ["smartContractAddress", "smartContractInterface", "type"] + }, + "v1CreateSmartContractInterfaceRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_CREATE_SMART_CONTRACT_INTERFACE"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1CreateSmartContractInterfaceIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1CreateSmartContractInterfaceResult": { + "type": "object", + "properties": { + "smartContractInterfaceId": { + "type": "string", + "description": "The ID of the created Smart Contract Interface." + } + }, + "required": ["smartContractInterfaceId"] + }, "v1CreateSubOrganizationIntent": { "type": "object", "properties": { @@ -5687,6 +5873,47 @@ }, "required": ["privateKeyIds"] }, + "v1DeleteSmartContractInterfaceIntent": { + "type": "object", + "properties": { + "smartContractInterfaceId": { + "type": "string", + "description": "The ID of a Smart Contract Interface intended for deletion." + } + }, + "required": ["smartContractInterfaceId"] + }, + "v1DeleteSmartContractInterfaceRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ACTIVITY_TYPE_DELETE_SMART_CONTRACT_INTERFACE"] + }, + "timestampMs": { + "type": "string", + "description": "Timestamp (in milliseconds) of the request, used to verify liveness of user requests." + }, + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "parameters": { + "$ref": "#/definitions/v1DeleteSmartContractInterfaceIntent" + } + }, + "required": ["type", "timestampMs", "organizationId", "parameters"] + }, + "v1DeleteSmartContractInterfaceResult": { + "type": "object", + "properties": { + "smartContractInterfaceId": { + "type": "string", + "description": "The ID of the deleted Smart Contract Interface." + } + }, + "required": ["smartContractInterfaceId"] + }, "v1DeleteSubOrganizationIntent": { "type": "object", "properties": { @@ -6768,6 +6995,54 @@ }, "required": ["proxyAuthConfig"] }, + "v1GetSmartContractInterfaceRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + }, + "smartContractInterfaceId": { + "type": "string", + "description": "Unique identifier for a given Smart Contract Interface." + } + }, + "required": ["organizationId", "smartContractInterfaceId"] + }, + "v1GetSmartContractInterfaceResponse": { + "type": "object", + "properties": { + "smartContractInterface": { + "$ref": "#/definitions/v1SmartContractInterface", + "description": "Object to be used in conjunction with Policies to guard transaction signing." + } + }, + "required": ["smartContractInterface"] + }, + "v1GetSmartContractInterfacesRequest": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Unique identifier for a given Organization." + } + }, + "required": ["organizationId"] + }, + "v1GetSmartContractInterfacesResponse": { + "type": "object", + "properties": { + "smartContractInterfaces": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1SmartContractInterface" + }, + "description": "A list of Smart Contract Interfaces." + } + }, + "required": ["smartContractInterfaces"] + }, "v1GetSubOrgIdsRequest": { "type": "object", "properties": { @@ -7881,6 +8156,12 @@ "initFiatOnRampIntent": { "$ref": "#/definitions/v1InitFiatOnRampIntent" }, + "createSmartContractInterfaceIntent": { + "$ref": "#/definitions/v1CreateSmartContractInterfaceIntent" + }, + "deleteSmartContractInterfaceIntent": { + "$ref": "#/definitions/v1DeleteSmartContractInterfaceIntent" + }, "enableUserInitiatedAuthIntent": { "$ref": "#/definitions/v1EnableUserInitiatedAuthIntent" }, @@ -9096,6 +9377,12 @@ "initFiatOnRampResult": { "$ref": "#/definitions/v1InitFiatOnRampResult" }, + "createSmartContractInterfaceResult": { + "$ref": "#/definitions/v1CreateSmartContractInterfaceResult" + }, + "deleteSmartContractInterfaceResult": { + "$ref": "#/definitions/v1DeleteSmartContractInterfaceResult" + }, "enableUserInitiatedAuthResult": { "$ref": "#/definitions/v1EnableUserInitiatedAuthResult" }, @@ -9554,6 +9841,63 @@ } } }, + "v1SmartContractInterface": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "The Organization the Smart Contract Interface belongs to." + }, + "smartContractInterfaceId": { + "type": "string", + "description": "Unique identifier for a given Smart Contract Interface (ABI or IDL)." + }, + "contractAddress": { + "type": "string", + "description": "The address corresponding to the Smart Contract or Program." + }, + "interface": { + "type": "string", + "description": "The JSON corresponding to the Smart Contract Interface." + }, + "type": { + "type": "string", + "description": "The type corresponding to the Smart Contract Interface (either ETHEREUM or SOLANA)." + }, + "label": { + "type": "string", + "description": "The label corresponding to the Smart Contract Interface (either ETHEREUM or SOLANA)." + }, + "notes": { + "type": "string", + "description": "The notes corresponding to the Smart Contract Interface (either ETHEREUM or SOLANA)." + }, + "createdAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + }, + "updatedAt": { + "$ref": "#/definitions/externaldatav1Timestamp" + } + }, + "required": [ + "organizationId", + "smartContractInterfaceId", + "contractAddress", + "interface", + "type", + "label", + "notes", + "createdAt", + "updatedAt" + ] + }, + "v1SmartContractInterfaceType": { + "type": "string", + "enum": [ + "SMART_CONTRACT_INTERFACE_TYPE_ETHEREUM", + "SMART_CONTRACT_INTERFACE_TYPE_SOLANA" + ] + }, "v1SmsCustomizationParams": { "type": "object", "properties": { diff --git a/packages/sdk-types/src/__inputs__/public_api.types.ts b/packages/sdk-types/src/__inputs__/public_api.types.ts index bdcd866ec..846944f0e 100644 --- a/packages/sdk-types/src/__inputs__/public_api.types.ts +++ b/packages/sdk-types/src/__inputs__/public_api.types.ts @@ -52,6 +52,10 @@ export type paths = { /** Get the proxy-auth configuration (allowed origins, etc.) for an Organization */ post: operations["PublicApiService_GetProxyAuthConfig"]; }; + "/public/v1/query/get_smart_contract_interface": { + /** Get details about a Smart Contract Interface */ + post: operations["PublicApiService_GetSmartContractInterface"]; + }; "/public/v1/query/get_user": { /** Get details about a User */ post: operations["PublicApiService_GetUser"]; @@ -80,6 +84,10 @@ export type paths = { /** List all Private Keys within an Organization */ post: operations["PublicApiService_GetPrivateKeys"]; }; + "/public/v1/query/list_smart_contract_interfaces": { + /** List all Smart Contract Interfaces within an Organization */ + post: operations["PublicApiService_GetSmartContractInterfaces"]; + }; "/public/v1/query/list_suborgs": { /** Get all suborg IDs associated given a parent org ID and an optional filter. */ post: operations["PublicApiService_GetSubOrgIds"]; @@ -156,6 +164,10 @@ export type paths = { /** Create a read write session for a user */ post: operations["PublicApiService_CreateReadWriteSession"]; }; + "/public/v1/submit/create_smart_contract_interface": { + /** Create an ABI/IDL in JSON */ + post: operations["PublicApiService_CreateSmartContractInterface"]; + }; "/public/v1/submit/create_sub_organization": { /** Create a new Sub-Organization */ post: operations["PublicApiService_CreateSubOrganization"]; @@ -204,6 +216,10 @@ export type paths = { /** Deletes private keys for an organization */ post: operations["PublicApiService_DeletePrivateKeys"]; }; + "/public/v1/submit/delete_smart_contract_interface": { + /** Delete a Smart Contract Interface */ + post: operations["PublicApiService_DeleteSmartContractInterface"]; + }; "/public/v1/submit/delete_sub_organization": { /** Deletes a sub organization */ post: operations["PublicApiService_DeleteSubOrganization"]; @@ -630,6 +646,8 @@ export type definitions = { | "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_USER_INITIATED_AUTH" | "ACTIVITY_TYPE_DISABLE_USER_INITIATED_AUTH" | "ACTIVITY_TYPE_UPDATE_PROXY_AUTH_CONFIG"; @@ -1106,6 +1124,30 @@ export type definitions = { /** @description HPKE encrypted credential bundle */ credentialBundle: string; }; + v1CreateSmartContractInterfaceIntent: { + /** @description Corresponding contract address or program ID */ + smartContractAddress: string; + /** @description ABI/IDL as a JSON string */ + smartContractInterface: string; + type: definitions["v1SmartContractInterfaceType"]; + /** @description Human-readable name for a Smart Contract Interface. */ + label?: string; + /** @description Notes for a Smart Contract Interface. */ + notes?: string; + }; + v1CreateSmartContractInterfaceRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_CREATE_SMART_CONTRACT_INTERFACE"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1CreateSmartContractInterfaceIntent"]; + }; + v1CreateSmartContractInterfaceResult: { + /** @description The ID of the created Smart Contract Interface. */ + smartContractInterfaceId: string; + }; v1CreateSubOrganizationIntent: { /** @description Name for this sub-organization */ name: string; @@ -1494,6 +1536,23 @@ export type definitions = { /** @description A list of private key unique identifiers that were removed */ privateKeyIds: string[]; }; + v1DeleteSmartContractInterfaceIntent: { + /** @description The ID of a Smart Contract Interface intended for deletion. */ + smartContractInterfaceId: string; + }; + v1DeleteSmartContractInterfaceRequest: { + /** @enum {string} */ + type: "ACTIVITY_TYPE_DELETE_SMART_CONTRACT_INTERFACE"; + /** @description Timestamp (in milliseconds) of the request, used to verify liveness of user requests. */ + timestampMs: string; + /** @description Unique identifier for a given Organization. */ + organizationId: string; + parameters: definitions["v1DeleteSmartContractInterfaceIntent"]; + }; + v1DeleteSmartContractInterfaceResult: { + /** @description The ID of the deleted Smart Contract Interface. */ + smartContractInterfaceId: string; + }; v1DeleteSubOrganizationIntent: { /** @description Sub-organization deletion, by default, requires associated wallets and private keys to be exported for security reasons. Set this boolean to true to force sub-organization deletion even if some wallets or private keys within it have not been exported yet. Default: false. */ deleteWithoutExport?: boolean; @@ -1973,6 +2032,24 @@ export type definitions = { /** @description Proxy authentication configuration (e.g., allowed origins). */ proxyAuthConfig: definitions["v1ProxyAuthConfig"]; }; + v1GetSmartContractInterfaceRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + /** @description Unique identifier for a given Smart Contract Interface. */ + smartContractInterfaceId: string; + }; + v1GetSmartContractInterfaceResponse: { + /** @description Object to be used in conjunction with Policies to guard transaction signing. */ + smartContractInterface: definitions["v1SmartContractInterface"]; + }; + v1GetSmartContractInterfacesRequest: { + /** @description Unique identifier for a given Organization. */ + organizationId: string; + }; + v1GetSmartContractInterfacesResponse: { + /** @description A list of Smart Contract Interfaces. */ + smartContractInterfaces: definitions["v1SmartContractInterface"][]; + }; v1GetSubOrgIdsRequest: { /** @description Unique identifier for the parent Organization. This is used to find sub-organizations within it. */ organizationId: string; @@ -2420,6 +2497,8 @@ export type definitions = { updateUserEmailIntent?: definitions["v1UpdateUserEmailIntent"]; updateUserPhoneNumberIntent?: definitions["v1UpdateUserPhoneNumberIntent"]; initFiatOnRampIntent?: definitions["v1InitFiatOnRampIntent"]; + createSmartContractInterfaceIntent?: definitions["v1CreateSmartContractInterfaceIntent"]; + deleteSmartContractInterfaceIntent?: definitions["v1DeleteSmartContractInterfaceIntent"]; enableUserInitiatedAuthIntent?: definitions["v1EnableUserInitiatedAuthIntent"]; disableUserInitiatedAuthIntent?: definitions["v1DisableUserInitiatedAuthIntent"]; updateProxyAuthConfigIntent?: definitions["v1UpdateProxyAuthConfigIntent"]; @@ -2878,6 +2957,8 @@ export type definitions = { updateUserEmailResult?: definitions["v1UpdateUserEmailResult"]; updateUserPhoneNumberResult?: definitions["v1UpdateUserPhoneNumberResult"]; initFiatOnRampResult?: definitions["v1InitFiatOnRampResult"]; + createSmartContractInterfaceResult?: definitions["v1CreateSmartContractInterfaceResult"]; + deleteSmartContractInterfaceResult?: definitions["v1DeleteSmartContractInterfaceResult"]; enableUserInitiatedAuthResult?: definitions["v1EnableUserInitiatedAuthResult"]; disableUserInitiatedAuthResult?: definitions["v1DisableUserInitiatedAuthResult"]; updateProxyAuthConfigResult?: definitions["v1UpdateProxyAuthConfigResult"]; @@ -3049,6 +3130,28 @@ export type definitions = { appidExclude?: boolean; credProps?: definitions["v1CredPropsAuthenticationExtensionsClientOutputs"]; }; + v1SmartContractInterface: { + /** @description The Organization the Smart Contract Interface belongs to. */ + organizationId: string; + /** @description Unique identifier for a given Smart Contract Interface (ABI or IDL). */ + smartContractInterfaceId: string; + /** @description The address corresponding to the Smart Contract or Program. */ + contractAddress: string; + /** @description The JSON corresponding to the Smart Contract Interface. */ + interface: string; + /** @description The type corresponding to the Smart Contract Interface (either ETHEREUM or SOLANA). */ + type: string; + /** @description The label corresponding to the Smart Contract Interface (either ETHEREUM or SOLANA). */ + label: string; + /** @description The notes corresponding to the Smart Contract Interface (either ETHEREUM or SOLANA). */ + notes: string; + createdAt: definitions["externaldatav1Timestamp"]; + updatedAt: definitions["externaldatav1Timestamp"]; + }; + /** @enum {string} */ + v1SmartContractInterfaceType: + | "SMART_CONTRACT_INTERFACE_TYPE_ETHEREUM" + | "SMART_CONTRACT_INTERFACE_TYPE_SOLANA"; v1SmsCustomizationParams: { /** @description Template containing references to .OtpCode i.e Your OTP is {{.OtpCode}} */ template?: string; @@ -3775,6 +3878,24 @@ export type operations = { }; }; }; + /** Get details about a Smart Contract Interface */ + PublicApiService_GetSmartContractInterface: { + parameters: { + body: { + body: definitions["v1GetSmartContractInterfaceRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1GetSmartContractInterfaceResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; /** Get details about a User */ PublicApiService_GetUser: { parameters: { @@ -3901,6 +4022,24 @@ export type operations = { }; }; }; + /** List all Smart Contract Interfaces within an Organization */ + PublicApiService_GetSmartContractInterfaces: { + parameters: { + body: { + body: definitions["v1GetSmartContractInterfacesRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1GetSmartContractInterfacesResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; /** Get all suborg IDs associated given a parent org ID and an optional filter. */ PublicApiService_GetSubOrgIds: { parameters: { @@ -4243,6 +4382,24 @@ export type operations = { }; }; }; + /** Create an ABI/IDL in JSON */ + PublicApiService_CreateSmartContractInterface: { + parameters: { + body: { + body: definitions["v1CreateSmartContractInterfaceRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; /** Create a new Sub-Organization */ PublicApiService_CreateSubOrganization: { parameters: { @@ -4459,6 +4616,24 @@ export type operations = { }; }; }; + /** Delete a Smart Contract Interface */ + PublicApiService_DeleteSmartContractInterface: { + parameters: { + body: { + body: definitions["v1DeleteSmartContractInterfaceRequest"]; + }; + }; + responses: { + /** A successful response. */ + 200: { + schema: definitions["v1ActivityResponse"]; + }; + /** An unexpected error response. */ + default: { + schema: definitions["rpcStatus"]; + }; + }; + }; /** Deletes a sub organization */ PublicApiService_DeleteSubOrganization: { parameters: { From c19b9a44eddaab5feeb21f377caf31042eac833f Mon Sep 17 00:00:00 2001 From: Ethan Konkolowicz Date: Wed, 2 Jul 2025 15:15:38 -0400 Subject: [PATCH 044/184] updated auth proxy type generation --- packages/sdk-types/src/__generated__/types.ts | 44 ------------------- 1 file changed, 44 deletions(-) diff --git a/packages/sdk-types/src/__generated__/types.ts b/packages/sdk-types/src/__generated__/types.ts index 57fc7a0d7..e1413b659 100644 --- a/packages/sdk-types/src/__generated__/types.ts +++ b/packages/sdk-types/src/__generated__/types.ts @@ -273,8 +273,6 @@ export type v1ActivityType = | "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_USER_INITIATED_AUTH" | "ACTIVITY_TYPE_DISABLE_USER_INITIATED_AUTH" | "ACTIVITY_TYPE_UPDATE_PROXY_AUTH_CONFIG"; @@ -3475,48 +3473,6 @@ export type v1WebAuthnStamp = { signature: string; }; -export type v1GetAccountResponse = { - organizationId: string; -}; - -export type v1GetWalletKitConfigResponse = { - facebookEnabled: boolean; - googleEnabled: boolean; - appleEnabled: boolean; - emailEnabled: boolean; - smsEnabled: boolean; - passkeyEnabled: boolean; - walletEnabled: boolean; - openOAuthInPage: boolean; - passkeySessionExpirationSeconds: string; - walletSessionExpirationSeconds: string; - organizationId: string; -}; - -export type v1InitOtpResponse = { - /** Unique identifier for an OTP authentication */ - otpId: string; -}; - -export type v1OAuthLoginResponse = { - /** Signed JWT containing an expiry, public key, session type, user id, and organization id */ - session: string; -}; - -export type v1OtpLoginResponse = { - /** Signed JWT containing an expiry, public key, session type, user id, and organization id */ - session: string; -}; - -export type v1SignupResponse = { - organizationId: string; -}; - -export type v1VerifyOtpResponse = { - /** Signed JWT containing a unique id, expiry, verification type, contact. Verification status of a user is updated when the token is consumed (in OTP_LOGIN requests) */ - verificationToken: string; -}; - // --- API Types from Swagger Paths --- export type TGetActivityResponse = { /** An action that can that can be taken within the Turnkey infrastructure. */ From 9bedb44bf39b3df7abef8c22efcab5f1cdeac648 Mon Sep 17 00:00:00 2001 From: Amir Cheikh Date: Wed, 2 Jul 2025 15:16:54 -0400 Subject: [PATCH 045/184] Better buttons, started customization --- examples/with-sdk-js/src/app/layout.tsx | 9 +- examples/with-sdk-js/src/app/page.tsx | 1 - .../src/components/auth/Email.tsx | 62 +++++++++---- .../src/components/auth/Phone.tsx | 81 +++++++++++----- .../src/components/auth/index.tsx | 88 +++++++++++------- .../src/components/design/Buttons.tsx | 33 +++++-- .../src/components/design/Spinners.tsx | 3 +- packages/react-wallet-kit/src/index.css | 10 +- .../src/providers/TurnkeyProvider.tsx | 27 +++++- .../src/providers/client/Provider.tsx | 93 ++++++++++++++----- packages/sdk-js/src/__clients__/core.ts | 5 +- packages/sdk-types/src/__generated__/types.ts | 44 +++++++++ packages/sdk-types/src/index.ts | 5 +- 13 files changed, 340 insertions(+), 121 deletions(-) diff --git a/examples/with-sdk-js/src/app/layout.tsx b/examples/with-sdk-js/src/app/layout.tsx index fb7c60439..5761f2120 100644 --- a/examples/with-sdk-js/src/app/layout.tsx +++ b/examples/with-sdk-js/src/app/layout.tsx @@ -23,9 +23,11 @@ function RootLayout({ children }: RootLayoutProps) { authProxyId: process.env.NEXT_PUBLIC_AUTH_PROXY_ID!, organizationId: process.env.NEXT_PUBLIC_ORGANIZATION_ID!, auth: { - googleClientId: process.env.NEXT_PUBLIC_GOOGLE_CLIENT_ID, - oAuthRedirectUri: process.env.NEXT_PUBLIC_OAUTH_REDIRECT_URI, - openOAuthInPage: true, + oAuthConfig: { + googleClientId: process.env.NEXT_PUBLIC_GOOGLE_CLIENT_ID, + oAuthRedirectUri: process.env.NEXT_PUBLIC_OAUTH_REDIRECT_URI, + }, + autoRefreshSession: true, }, passkeyConfig: { rpId: process.env.NEXT_PUBLIC_RPID!, @@ -33,7 +35,6 @@ function RootLayout({ children }: RootLayoutProps) { userVerification: "preferred", allowCredentials: [], }, - autoRefreshSession: true, }} callbacks={{ onError: (error) => { diff --git a/examples/with-sdk-js/src/app/page.tsx b/examples/with-sdk-js/src/app/page.tsx index e691670ec..117b80482 100644 --- a/examples/with-sdk-js/src/app/page.tsx +++ b/examples/with-sdk-js/src/app/page.tsx @@ -22,7 +22,6 @@ export default function AuthPage() { authState, wallets, user, - proxyAuthConfig, login, handleGoogleOauth, loginWithPasskey, diff --git a/packages/react-wallet-kit/src/components/auth/Email.tsx b/packages/react-wallet-kit/src/components/auth/Email.tsx index 7e3a13a55..baf58a2e9 100644 --- a/packages/react-wallet-kit/src/components/auth/Email.tsx +++ b/packages/react-wallet-kit/src/components/auth/Email.tsx @@ -1,6 +1,8 @@ import { useState } from "react"; import { Input } from "@headlessui/react"; -import { ActionButton } from "../design/Buttons"; +import { ActionButton, IconButton } from "../design/Buttons"; +import { faArrowRight } from "@fortawesome/free-solid-svg-icons"; +import clsx from "clsx"; function isValidEmail(email: string): boolean { return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email); @@ -9,12 +11,12 @@ function isValidEmail(email: string): boolean { interface EmailInputProps { onContinue?: (email: string) => void; } + export function EmailInput(props: EmailInputProps) { const { onContinue } = props; const [loading, setLoading] = useState(false); - const [email, setEmail] = useState(""); - const [isFocused, setIsFocused] = useState(false); + const [useIconButton] = useState(true); // TODO (Amir): Pull from config const emailIsValid = isValidEmail(email); @@ -36,32 +38,58 @@ export function EmailInput(props: EmailInputProps) { }; const buttonDisabled = !emailIsValid; - const buttonBgClass = - "bg-primary-light dark:bg-primary-dark hover:bg-primary-light/90 dark:hover:bg-primary-dark/90 text-modal-text-dark"; + + const buttonClass = clsx( + "transition-all duration-300", + (emailIsValid || !useIconButton) && + "bg-primary-light dark:bg-primary-dark hover:bg-primary-light/90 dark:hover:bg-primary-dark/90 text-primary-text-light dark:text-primary-text-dark", + ); return ( -
-
+
+
setEmail(e.target.value)} - onFocus={() => setIsFocused(true)} - onBlur={() => setIsFocused(false)} onKeyDown={handleKeyDown} className="w-full py-3 px-4 rounded-md text-inherit bg-button-light dark:bg-button-dark border border-modal-background-dark/20 dark:border-modal-background-light/20 focus:outline-primary-light focus:dark:outline-primary-dark focus:outline-[1px] focus:outline-offset-0 box-border" /> + + {useIconButton && ( + + )}
- - Continue - + {!useIconButton && ( + + Continue + + )}
); } diff --git a/packages/react-wallet-kit/src/components/auth/Phone.tsx b/packages/react-wallet-kit/src/components/auth/Phone.tsx index adbccf631..87da5ee53 100644 --- a/packages/react-wallet-kit/src/components/auth/Phone.tsx +++ b/packages/react-wallet-kit/src/components/auth/Phone.tsx @@ -1,6 +1,8 @@ import { useState } from "react"; -import { ActionButton } from "../design/Buttons"; +import { ActionButton, IconButton } from "../design/Buttons"; import { PhoneInputBox } from "../design/Inputs"; +import { faArrowRight } from "@fortawesome/free-solid-svg-icons"; +import clsx from "clsx"; interface PhoneNumberInputProps { onContinue?: (phone: string, formattedPhone: string) => void; @@ -9,10 +11,11 @@ interface PhoneNumberInputProps { export function PhoneNumberInput(props: PhoneNumberInputProps) { const { onContinue } = props; const [phone, setPhone] = useState(""); - const [formattedPhone, setformattedPhone] = useState(""); + const [formattedPhone, setFormattedPhone] = useState(""); const [isValid, setIsValid] = useState(false); const [loading, setLoading] = useState(false); - const [isFocused, setIsFocused] = useState(false); + + const [useIconButton] = useState(true); // TODO (Amir): Pull from config const handleContinue = async () => { if (isValid && onContinue) { @@ -26,31 +29,59 @@ export function PhoneNumberInput(props: PhoneNumberInputProps) { }; const buttonDisabled = !isValid; - const buttonBgClass = - "bg-primary-light dark:bg-primary-dark hover:bg-primary-light/90 dark:hover:bg-primary-dark/90 text-modal-text-dark"; + + const buttonClass = clsx( + "transition-all duration-300", + (isValid || !useIconButton) && + "bg-primary-light dark:bg-primary-dark hover:bg-primary-light/90 dark:hover:bg-primary-dark/90 text-primary-text-light dark:text-primary-text-dark", + ); return ( -
- { - setPhone(phone); - setformattedPhone(formattedPhone); - setIsValid(valid); - }} - onFocus={() => setIsFocused(true)} - onBlur={() => setIsFocused(false)} - onEnter={handleContinue} - /> - - +
- Continue - + { + setPhone(raw); + setFormattedPhone(formatted); + setIsValid(valid); + }} + onEnter={handleContinue} + /> + + {useIconButton && ( + + )} +
+ + {!useIconButton && ( + + Continue + + )}
); } diff --git a/packages/react-wallet-kit/src/components/auth/index.tsx b/packages/react-wallet-kit/src/components/auth/index.tsx index 4c440bb66..13c622f89 100644 --- a/packages/react-wallet-kit/src/components/auth/index.tsx +++ b/packages/react-wallet-kit/src/components/auth/index.tsx @@ -10,10 +10,17 @@ import { PhoneNumberInput } from "./Phone"; import { ActionPage } from "./Action"; import { PasskeyButtons } from "./Passkey"; import { faFingerprint } from "@fortawesome/free-solid-svg-icons"; +import { Spinner } from "../design/Spinners"; +import { useEffect } from "react"; export function AuthComponent() { - const { handleGoogleOauth, initOtp, loginWithPasskey, signUpWithPasskey } = - useTurnkey(); + const { + config, + handleGoogleOauth, + initOtp, + loginWithPasskey, + signUpWithPasskey, + } = useTurnkey(); const { pushPage } = useModal(); const handleEmailSubmit = async (email: string) => { @@ -97,40 +104,53 @@ export function AuthComponent() { }); }; + const handleGoogle = async () => { + pushPage({ + key: "Google OAuth", + content: ( + + handleGoogleOauth({ + additionalState: { openModal: "true" }, // Tell the provider to reopen the auth modal and show the loading state + }) + } + icon={} + /> + ), + showTitle: false, + }); + }; + useEffect(() => { + console.log(config); + }, [config]); return (
-
- } - onClick={async () => { - pushPage({ - key: "Google OAuth", - content: ( - - handleGoogleOauth({ - additionalState: { openModal: "true" }, // Tell the provider to reopen the auth modal and show the loading state - }) - } - icon={} - /> - ), - showTitle: false, - }); - }} - /> -
- - - - - - + {config ? ( + <> +
+ } + onClick={handleGoogle} + /> +
+ + + + {config.auth?.methods?.smsOtpAuthEnabled && ( + + )} + + + + + ) : ( + + )}
); } diff --git a/packages/react-wallet-kit/src/components/design/Buttons.tsx b/packages/react-wallet-kit/src/components/design/Buttons.tsx index 0b8d630c5..d9886658b 100644 --- a/packages/react-wallet-kit/src/components/design/Buttons.tsx +++ b/packages/react-wallet-kit/src/components/design/Buttons.tsx @@ -8,7 +8,9 @@ interface IconButtonProps { icon: IconDefinition; onClick?: () => void; disabled?: boolean; + loading?: boolean; className?: string; + spinnerClassName?: string; } export function BaseButton( @@ -27,14 +29,25 @@ export function BaseButton( ); } export function IconButton(props: IconButtonProps) { - const { icon, onClick, disabled, className } = props; + const { icon, onClick, disabled, loading, className, spinnerClassName } = + props; return ( - + {loading ? ( +
+ +
+ ) : ( + + )}
); } @@ -45,21 +58,25 @@ interface ActionButtonProps { disabled?: boolean; loading?: boolean; className?: string; + spinnerClassName?: string; } export function ActionButton(props: ActionButtonProps) { - const { children, onClick, disabled, loading, className } = props; + const { children, onClick, disabled, loading, className, spinnerClassName } = + props; return ( {loading ? (
- +
) : ( children diff --git a/packages/react-wallet-kit/src/components/design/Spinners.tsx b/packages/react-wallet-kit/src/components/design/Spinners.tsx index 28e23afc6..dada61296 100644 --- a/packages/react-wallet-kit/src/components/design/Spinners.tsx +++ b/packages/react-wallet-kit/src/components/design/Spinners.tsx @@ -12,6 +12,7 @@ export function Spinner(props: SpinnerProps) { - + ); diff --git a/packages/react-wallet-kit/src/index.css b/packages/react-wallet-kit/src/index.css index f94567d1c..1bea17bd2 100644 --- a/packages/react-wallet-kit/src/index.css +++ b/packages/react-wallet-kit/src/index.css @@ -7,12 +7,18 @@ @theme { --color-primary-light: oklch(0.547 0.2389 266.82); --color-primary-dark: oklch(0.547 0.2389 266.82); + /* This is the color of the text that goes on top of primary color buttons */ + --color-primary-text-light: rgb(255, 255, 255); + --color-primary-text-dark: rgb(255, 255, 255); + --color-button-light: rgb(255, 255, 255); - --color-button-dark: oklch(0.15 0 0); + --color-button-dark: oklch(0.2532 0.0056 285.99); + --color-modal-background-light: oklch(0.9758 0.0057 264.53); - --color-modal-background-dark: oklch(0.2532 0.0056 285.99); + --color-modal-background-dark: oklch(0.15 0 0); --color-modal-text-light: oklch(0 0.1 41); --color-modal-text-dark: rgb(255, 255, 255); + --color-icon-background-light: oklch(0.928 0.006 264.531); --color-icon-background-dark: oklch(0.3222 0.0053 286.1); --color-icon-text-light: oklch(0.6066 0 0); diff --git a/packages/react-wallet-kit/src/providers/TurnkeyProvider.tsx b/packages/react-wallet-kit/src/providers/TurnkeyProvider.tsx index 0f735d7d3..82848e46c 100644 --- a/packages/react-wallet-kit/src/providers/TurnkeyProvider.tsx +++ b/packages/react-wallet-kit/src/providers/TurnkeyProvider.tsx @@ -6,11 +6,30 @@ import { Session, TurnkeyError, TurnkeyNetworkError } from "@turnkey/sdk-types"; export interface TurnkeyProviderConfig extends TurnkeySDKClientConfig { auth?: { - googleClientId?: string; - oAuthRedirectUri?: string; - openOAuthInPage?: boolean; + methods?: { + emailOtpAuthEnabled?: boolean; + smsOtpAuthEnabled?: boolean; + passkeyAuthEnabled?: boolean; + walletAuthEnabled?: boolean; + googleOAuthEnabled?: boolean; + appleOAuthEnabled?: boolean; + facebookOAuthEnabled?: boolean; + }; + oAuthConfig?: { + oAuthRedirectUri?: string; + googleClientId?: string; + appleClientId?: string; + facebookClientId?: string; + openOAuthInPage?: boolean; + }; + autoRefreshSession?: boolean; + }; + ui?: { + // Good mornig! + }; + language?: { + // Ohayō! }; - autoRefreshSession?: boolean; } export interface TurnkeyCallbacks { diff --git a/packages/react-wallet-kit/src/providers/client/Provider.tsx b/packages/react-wallet-kit/src/providers/client/Provider.tsx index 617a4c283..dc3efeade 100644 --- a/packages/react-wallet-kit/src/providers/client/Provider.tsx +++ b/packages/react-wallet-kit/src/providers/client/Provider.tsx @@ -42,8 +42,8 @@ import { v1AddressFormat, v1Attestation, v1AuthenticatorParamsV2, + v1GetWalletKitConfigResponse, v1Pagination, - v1ProxyAuthConfig, v1SignRawPayloadResult, v1TransactionType, v1User, @@ -68,7 +68,7 @@ export interface ClientContextType extends TurnkeyClientMethods { session: Session | undefined; allSessions?: Record | undefined; authState: AuthState; - proxyAuthConfig?: v1ProxyAuthConfig | undefined; + config?: TurnkeyProviderConfig | undefined; user: v1User | undefined; wallets: Wallet[]; login: () => Promise; @@ -98,8 +98,8 @@ export const ClientProvider: React.FC = ({ const [client, setClient] = useState(undefined); const [session, setSession] = useState(undefined); const [autoRefreshSession, setAutoRefreshSession] = useState(false); - const [proxyAuthConfig, setProxyAuthConfig] = useState< - v1ProxyAuthConfig | undefined + const [masterConfig, setMasterConfig] = useState< + TurnkeyProviderConfig | undefined >(undefined); const [wallets, setWallets] = useState([]); const [user, setUser] = useState(undefined); @@ -193,17 +193,54 @@ export const ClientProvider: React.FC = ({ if (!client) return; const fetchProxyAuthConfig = async () => { const proxyAuthConfig = await client.getProxyAuthConfig(); - if (proxyAuthConfig) { - setProxyAuthConfig(proxyAuthConfig); - } else { - console.warn("No proxy auth config found."); - } + const masterConfig = buildConfig(proxyAuthConfig); + setMasterConfig(masterConfig); + return; }; fetchProxyAuthConfig(); }, [client]); + const buildConfig = (proxyAuthConfig: v1GetWalletKitConfigResponse) => { + return { + ...config, + auth: { + ...config.auth, + methods: { + ...config.auth?.methods, + emailOtpAuthEnabled: + config.auth?.methods?.emailOtpAuthEnabled ?? + proxyAuthConfig.emailEnabled, + smsOtpAuthEnabled: + config.auth?.methods?.smsOtpAuthEnabled ?? + proxyAuthConfig.smsEnabled, + passkeyAuthEnabled: + config.auth?.methods?.passkeyAuthEnabled ?? + proxyAuthConfig.passkeyEnabled, + walletAuthEnabled: + config.auth?.methods?.walletAuthEnabled ?? + proxyAuthConfig.walletEnabled, + googleOAuthEnabled: + config.auth?.methods?.googleOAuthEnabled ?? + proxyAuthConfig.googleEnabled, + appleOAuthEnabled: + config.auth?.methods?.appleOAuthEnabled ?? + proxyAuthConfig.appleEnabled, + facebookOAuthEnabled: + config.auth?.methods?.facebookOAuthEnabled ?? + proxyAuthConfig.facebookEnabled, + }, + oAuthConfig: { + ...config.auth?.oAuthConfig, + openOAuthInPage: + config.auth?.oAuthConfig?.openOAuthInPage ?? + proxyAuthConfig.openOAuthInPage, + }, + }, + } as TurnkeyProviderConfig; + }; + const initializeClient = async () => { try { const turnkeyClient = new TurnkeyClient({ @@ -220,7 +257,7 @@ export const ClientProvider: React.FC = ({ }, }); - setAutoRefreshSession(config?.autoRefreshSession ?? false); + setAutoRefreshSession(config?.auth?.autoRefreshSession ?? false); await turnkeyClient.init(); setClient(turnkeyClient); @@ -1026,7 +1063,7 @@ export const ClientProvider: React.FC = ({ async function refreshSession(params?: { sessionType?: SessionType; - expirationSeconds?: string; + expirationSeconds?: string; // TODO: Need to pull from proxyAuthConfig publicKey?: string; sessionKey?: string; invalidateExisitng?: boolean; @@ -1158,7 +1195,7 @@ export const ClientProvider: React.FC = ({ ); } - async function getProxyAuthConfig(): Promise { + async function getProxyAuthConfig(): Promise { if (!client) throw new TurnkeyError( "Client is not initialized.", @@ -1209,21 +1246,34 @@ export const ClientProvider: React.FC = ({ additionalState?: Record; }): Promise { const { - clientId = config.auth?.googleClientId, - openInPage = config.auth?.openOAuthInPage, + clientId = masterConfig?.auth?.oAuthConfig?.googleClientId, + openInPage = masterConfig?.auth?.oAuthConfig?.openOAuthInPage ?? false, additionalState: additionalParameters, } = params; - try { + if (!masterConfig) { + throw new TurnkeyError( + "Config is not ready yet!", + TurnkeyErrorCodes.INVALID_CONFIGURATION, + ); + } if (!clientId) { - throw new Error("Google Client ID is not configured."); + throw new TurnkeyError( + "Google Client ID is not configured.", + TurnkeyErrorCodes.INVALID_CONFIGURATION, + ); } - if (!config.auth?.oAuthRedirectUri) { - throw new Error("OAuth redirect URI is not configured."); + if (!masterConfig.auth?.oAuthConfig?.oAuthRedirectUri) { + throw new TurnkeyError( + "OAuth Redirect URI is not configured.", + TurnkeyErrorCodes.INVALID_CONFIGURATION, + ); } + console.log(typeof openInPage); const flow = openInPage ? "redirect" : "popup"; - const redirectURI = config.auth?.oAuthRedirectUri.replace(/\/$/, ""); + const redirectURI = + masterConfig.auth?.oAuthConfig.oAuthRedirectUri.replace(/\/$/, ""); // Create key pair and generate nonce const publicKey = await createApiKeyPair(); @@ -1255,8 +1305,9 @@ export const ClientProvider: React.FC = ({ } } googleAuthUrl.searchParams.set("state", state); - + console.log("openingopage", openInPage); if (openInPage) { + console.log("WHHYYY"); // Redirect current page to Google Auth window.location.href = googleAuthUrl.toString(); return new Promise((_, reject) => { @@ -1353,7 +1404,7 @@ export const ClientProvider: React.FC = ({ authState, user, wallets, - proxyAuthConfig, + config: masterConfig, httpClient: client?.httpClient, login, createPasskey, diff --git a/packages/sdk-js/src/__clients__/core.ts b/packages/sdk-js/src/__clients__/core.ts index b8605f21b..eafded257 100644 --- a/packages/sdk-js/src/__clients__/core.ts +++ b/packages/sdk-js/src/__clients__/core.ts @@ -23,6 +23,7 @@ import { TurnkeyError, TurnkeyErrorCodes, TurnkeyNetworkError, + v1GetWalletKitConfigResponse, } from "@turnkey/sdk-types"; import { DEFAULT_SESSION_EXPIRATION_IN_SECONDS, @@ -1771,7 +1772,7 @@ export class TurnkeyClient { } }; - getProxyAuthConfig = async (): Promise => { + getProxyAuthConfig = async (): Promise => { const headers: Record = { "Content-Type": "application/json", }; @@ -1796,7 +1797,7 @@ export class TurnkeyClient { ); } - return (await res.json()) as v1ProxyAuthConfig; + return (await res.json()) as v1GetWalletKitConfigResponse; } catch (error) { throw new TurnkeyError( `Failed to get auth proxy config`, diff --git a/packages/sdk-types/src/__generated__/types.ts b/packages/sdk-types/src/__generated__/types.ts index e1413b659..57fc7a0d7 100644 --- a/packages/sdk-types/src/__generated__/types.ts +++ b/packages/sdk-types/src/__generated__/types.ts @@ -273,6 +273,8 @@ export type v1ActivityType = | "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_USER_INITIATED_AUTH" | "ACTIVITY_TYPE_DISABLE_USER_INITIATED_AUTH" | "ACTIVITY_TYPE_UPDATE_PROXY_AUTH_CONFIG"; @@ -3473,6 +3475,48 @@ export type v1WebAuthnStamp = { signature: string; }; +export type v1GetAccountResponse = { + organizationId: string; +}; + +export type v1GetWalletKitConfigResponse = { + facebookEnabled: boolean; + googleEnabled: boolean; + appleEnabled: boolean; + emailEnabled: boolean; + smsEnabled: boolean; + passkeyEnabled: boolean; + walletEnabled: boolean; + openOAuthInPage: boolean; + passkeySessionExpirationSeconds: string; + walletSessionExpirationSeconds: string; + organizationId: string; +}; + +export type v1InitOtpResponse = { + /** Unique identifier for an OTP authentication */ + otpId: string; +}; + +export type v1OAuthLoginResponse = { + /** Signed JWT containing an expiry, public key, session type, user id, and organization id */ + session: string; +}; + +export type v1OtpLoginResponse = { + /** Signed JWT containing an expiry, public key, session type, user id, and organization id */ + session: string; +}; + +export type v1SignupResponse = { + organizationId: string; +}; + +export type v1VerifyOtpResponse = { + /** Signed JWT containing a unique id, expiry, verification type, contact. Verification status of a user is updated when the token is consumed (in OTP_LOGIN requests) */ + verificationToken: string; +}; + // --- API Types from Swagger Paths --- export type TGetActivityResponse = { /** An action that can that can be taken within the Turnkey infrastructure. */ diff --git a/packages/sdk-types/src/index.ts b/packages/sdk-types/src/index.ts index 258439382..34009dd95 100644 --- a/packages/sdk-types/src/index.ts +++ b/packages/sdk-types/src/index.ts @@ -73,6 +73,7 @@ export enum TurnkeyErrorCodes { BAD_RESPONSE = "BAD_RESPONSE", MISSING_PARAMS = "MISSING_PARAMS", + INVALID_CONFIGURATION = "INVALID_CONFIGURATION", INVALID_REQUEST = "INVALID_REQUEST", VALIDATION_ERROR = "VALIDATION_ERROR", SESSION_EXPIRED = "SESSION_EXPIRED", @@ -92,7 +93,7 @@ export enum TurnkeyErrorCodes { export class TurnkeyError extends Error { constructor( message: string, - public code?: string, + public code?: TurnkeyErrorCodes, public cause?: unknown, ) { super(message); @@ -104,7 +105,7 @@ export class TurnkeyNetworkError extends TurnkeyError { constructor( message: string, public statusCode?: number, - code?: string, + code?: TurnkeyErrorCodes, cause?: unknown, ) { super(message, code, cause); From ba9ba89967fc5e0ef9d6f6529d5fcd7edeab0cd4 Mon Sep 17 00:00:00 2001 From: Ethan Konkolowicz Date: Wed, 2 Jul 2025 17:38:44 -0400 Subject: [PATCH 046/184] added session token to session object, added updateUser method --- .../src/providers/TurnkeyProvider.tsx | 4 ++ .../src/providers/client/Provider.tsx | 39 ++++++++++- packages/react-wallet-kit/src/utils.ts | 2 - packages/sdk-js/src/__clients__/core.ts | 64 +++++++++++++++++-- packages/sdk-js/src/__stampers__/api/base.ts | 2 +- packages/sdk-js/src/utils.ts | 3 +- packages/sdk-types/src/index.ts | 2 + 7 files changed, 102 insertions(+), 14 deletions(-) diff --git a/packages/react-wallet-kit/src/providers/TurnkeyProvider.tsx b/packages/react-wallet-kit/src/providers/TurnkeyProvider.tsx index 82848e46c..4475aa819 100644 --- a/packages/react-wallet-kit/src/providers/TurnkeyProvider.tsx +++ b/packages/react-wallet-kit/src/providers/TurnkeyProvider.tsx @@ -22,6 +22,10 @@ export interface TurnkeyProviderConfig extends TurnkeySDKClientConfig { facebookClientId?: string; openOAuthInPage?: boolean; }; + sessionExpirationSeconds?: { + passkey?: string; + wallet?: string; + }; autoRefreshSession?: boolean; }; ui?: { diff --git a/packages/react-wallet-kit/src/providers/client/Provider.tsx b/packages/react-wallet-kit/src/providers/client/Provider.tsx index dc3efeade..04665ca53 100644 --- a/packages/react-wallet-kit/src/providers/client/Provider.tsx +++ b/packages/react-wallet-kit/src/providers/client/Provider.tsx @@ -11,6 +11,7 @@ import { } from "../../utils"; import { CreateSubOrgParams, + DEFAULT_SESSION_EXPIRATION_IN_SECONDS, ExportBundle, OtpType, Provider, @@ -237,6 +238,10 @@ export const ClientProvider: React.FC = ({ config.auth?.oAuthConfig?.openOAuthInPage ?? proxyAuthConfig.openOAuthInPage, }, + sessionExpirationSeconds: { + passkey: proxyAuthConfig?.passkeySessionExpirationSeconds, + wallet: proxyAuthConfig?.walletSessionExpirationSeconds, + } }, } as TurnkeyProviderConfig; }; @@ -543,8 +548,10 @@ export const ClientProvider: React.FC = ({ ); } setAuthState(AuthState.Loading); + + const expirationSeconds = masterConfig?.auth?.sessionExpirationSeconds?.passkey ?? DEFAULT_SESSION_EXPIRATION_IN_SECONDS; const res = await withTurnkeyErrorHandling( - () => client.loginWithPasskey(params), + () => client.loginWithPasskey({...params, expirationSeconds }), callbacks, "Failed to login with passkey", ); @@ -570,8 +577,10 @@ export const ClientProvider: React.FC = ({ ); } setAuthState(AuthState.Loading); + + const expirationSeconds = masterConfig?.auth?.sessionExpirationSeconds?.passkey ?? DEFAULT_SESSION_EXPIRATION_IN_SECONDS; const res = await withTurnkeyErrorHandling( - () => client.signUpWithPasskey(params), + () => client.signUpWithPasskey({ ...params, expirationSeconds }), callbacks, "Failed to sign up with passkey", ); @@ -878,6 +887,29 @@ export const ClientProvider: React.FC = ({ ); } + async function updateUser(params: { + userId?: string; + organizationId?: string; + name?: string; + email?: string; + phoneNumber?: string; + }): Promise { + if (!client) + throw new TurnkeyError( + "Client is not initialized.", + TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED, + ); + const res = await withTurnkeyErrorHandling( + () => client.updateUser(params), + callbacks, + "Failed to update user", + ); + if (res) { + setUser(res); + } + return res; + } + async function createWallet(params: { walletName: string; accounts?: WalletAccount[] | v1AddressFormat[]; @@ -1076,7 +1108,7 @@ export const ClientProvider: React.FC = ({ const activeSessionKey = await client.getActiveSessionKey(); if (!activeSessionKey) { - throw new Error("No active session found."); + throw new TurnkeyError("No active session found.", TurnkeyErrorCodes.NO_SESSION_FOUND); } let sessionKey = params?.sessionKey ?? activeSessionKey; @@ -1424,6 +1456,7 @@ export const ClientProvider: React.FC = ({ signMessage, signTransaction, fetchUser, + updateUser, createWallet, createWalletAccounts, exportWallet, diff --git a/packages/react-wallet-kit/src/utils.ts b/packages/react-wallet-kit/src/utils.ts index b52a337c0..ef743be7d 100644 --- a/packages/react-wallet-kit/src/utils.ts +++ b/packages/react-wallet-kit/src/utils.ts @@ -76,10 +76,8 @@ export async function withTurnkeyErrorHandling( fallbackCode = TurnkeyErrorCodes.UNKNOWN, ): Promise { try { - console.log("Executing withTurnkeyErrorHandling"); return await fn(); } catch (error) { - console.log("Error in withTurnkeyErrorHandling:", error); if (error instanceof TurnkeyError) { callbacks?.onError?.(error); throw error; diff --git a/packages/sdk-js/src/__clients__/core.ts b/packages/sdk-js/src/__clients__/core.ts index eafded257..03f681001 100644 --- a/packages/sdk-js/src/__clients__/core.ts +++ b/packages/sdk-js/src/__clients__/core.ts @@ -19,7 +19,6 @@ import { v1User, v1VerifyOtpResult, v1WalletAccount, - v1ProxyAuthConfig, TurnkeyError, TurnkeyErrorCodes, TurnkeyNetworkError, @@ -198,13 +197,13 @@ export class TurnkeyClient { if (params?.sessionKey) { const session = await this.storageManager.getSession(params.sessionKey); this.storageManager.clearSession(params.sessionKey); - this.apiKeyStamper?.deleteKeyPair(session?.token!); + this.apiKeyStamper?.deleteKeyPair(session?.publicKey!); } else { const sessionKey = await this.storageManager.getActiveSessionKey(); const session = await this.storageManager.getActiveSession(); if (sessionKey) { this.storageManager.clearSession(sessionKey); - this.apiKeyStamper?.deleteKeyPair(session?.token!); + this.apiKeyStamper?.deleteKeyPair(session?.publicKey!); } else { throw new TurnkeyError( "No active session found to log out from.", @@ -225,6 +224,7 @@ export class TurnkeyClient { sessionType?: SessionType; publicKey?: string; sessionKey?: string; + expirationSeconds?: string; }): Promise => { let generatedKeyPair = null; try { @@ -233,6 +233,8 @@ export class TurnkeyClient { params?.publicKey || (await this.apiKeyStamper?.createKeyPair()); const sessionKey = params?.sessionKey || SessionKey.DefaultSessionkey; + const expirationSeconds = params?.expirationSeconds || DEFAULT_SESSION_EXPIRATION_IN_SECONDS; + // Create a read-only session if (sessionType === SessionType.READ_ONLY) { const readOnlySessionResult = @@ -258,6 +260,7 @@ export class TurnkeyClient { { publicKey, organizationId: this.config.organizationId, + expirationSeconds }, StamperType.Passkey, ); @@ -309,12 +312,14 @@ export class TurnkeyClient { sessionType?: SessionType; sessionKey?: string; passkeyDisplayName?: string; + expirationSeconds?: string; }): Promise => { const { createSubOrgParams, passkeyDisplayName, sessionType = SessionType.READ_WRITE, sessionKey = SessionKey.DefaultSessionkey, + expirationSeconds = DEFAULT_SESSION_EXPIRATION_IN_SECONDS, } = params || {}; let generatedKeyPair = null; @@ -399,6 +404,7 @@ export class TurnkeyClient { const sessionResponse = await this.httpClient.stampLogin({ publicKey: newGeneratedKeyPair!, organizationId: this.config.organizationId, + expirationSeconds, }); await this.apiKeyStamper?.deleteKeyPair(generatedKeyPair!); @@ -1211,6 +1217,51 @@ export class TurnkeyClient { } }; + updateUser = async (params: { + userId?: string; + userName?: string; + userEmail?: string; + userTagIds?: string[]; + userPhoneNumber?: string; + }): Promise => { + const session = await this.storageManager.getActiveSession(); + if (!session) { + throw new TurnkeyError( + "No active session found. Please log in first.", + TurnkeyErrorCodes.NO_SESSION_FOUND, + ); + } + + const { userId = session.userId, ...updateFields } = params; + const organizationId = session.organizationId; + + try { + const updatedUser = await this.httpClient.updateUser( + { + organizationId: organizationId || session.organizationId, + userId, + ...updateFields, + }, + ); + + if (!updatedUser || !updatedUser.userId) { + throw new TurnkeyError( + "No updated user found in the response", + TurnkeyErrorCodes.BAD_RESPONSE, + ); + } + + const user = await this.fetchUser(); + return user; + } catch (error) { + throw new TurnkeyError( + `Failed to update user`, + TurnkeyErrorCodes.UPDATE_USER_ERROR, + error, + ); + } + }; + createWallet = async (params: { walletName: string; accounts?: WalletAccount[] | v1AddressFormat[]; @@ -1501,8 +1552,7 @@ export class TurnkeyClient { // TODO (Amir): This should be done in a helper or something. It's very strange that we have to delete the key pair here const sessionToReplace = await this.storageManager.getSession(sessionKey); if (sessionToReplace) { - console.log(sessionToReplace.token); - await this.apiKeyStamper?.deleteKeyPair(sessionToReplace.token); + await this.apiKeyStamper?.deleteKeyPair(sessionToReplace.publicKey); } await this.storageManager.storeSession(sessionToken, sessionKey); @@ -1522,7 +1572,7 @@ export class TurnkeyClient { try { const session = await this.storageManager.getSession(sessionKey); if (session) { - await this.apiKeyStamper?.deleteKeyPair(session.token); + await this.apiKeyStamper?.deleteKeyPair(session.publicKey); await this.storageManager.clearSession(sessionKey); } else { throw new TurnkeyError( @@ -1714,7 +1764,7 @@ export class TurnkeyClient { for (const sessionKey of sessionKeys) { const session = await this.storageManager.getSession(sessionKey); if (session) { - sessionTokensMap[session.token] = sessionKey; + sessionTokensMap[session.publicKey] = sessionKey; } } diff --git a/packages/sdk-js/src/__stampers__/api/base.ts b/packages/sdk-js/src/__stampers__/api/base.ts index a2f5e4ed6..1967947a6 100644 --- a/packages/sdk-js/src/__stampers__/api/base.ts +++ b/packages/sdk-js/src/__stampers__/api/base.ts @@ -77,7 +77,7 @@ export class CrossPlatformApiKeyStamper implements TStamper { if (!session) { throw new Error("No active session or token available."); } - publicKeyHex = session.token; + publicKeyHex = session.publicKey; } return this.stamper.stamp(payload, publicKeyHex); diff --git a/packages/sdk-js/src/utils.ts b/packages/sdk-js/src/utils.ts index 440012957..8e1883158 100644 --- a/packages/sdk-js/src/utils.ts +++ b/packages/sdk-js/src/utils.ts @@ -295,7 +295,8 @@ export function parseSession(token: string | Session): Session { userId, organizationId, expiry: exp, - token: publicKey, // TODO (Amir): Should token be the JWT then add another field for publicKey? + publicKey, + token, }; } diff --git a/packages/sdk-types/src/index.ts b/packages/sdk-types/src/index.ts index 34009dd95..d81ae737f 100644 --- a/packages/sdk-types/src/index.ts +++ b/packages/sdk-types/src/index.ts @@ -9,6 +9,7 @@ export type Session = { organizationId: string; expiry: number; token: string; + publicKey: string; }; export type SessionResponse = { @@ -70,6 +71,7 @@ export enum TurnkeyErrorCodes { HANDLE_POST_AUTH_ERROR = "HANDLE_POST_AUTH_ERROR", HANDLE_POST_LOGOUT_ERROR = "HANDLE_POST_LOGOUT_ERROR", CLEAR_SESSION_TIMEOUTS_ERROR = "CLEAR_SESSION_TIMEOUTS_ERROR", + UPDATE_USER_ERROR = "UPDATE_USER_ERROR", BAD_RESPONSE = "BAD_RESPONSE", MISSING_PARAMS = "MISSING_PARAMS", From a104c599a95ad43dff0a20c762183e1689c37737 Mon Sep 17 00:00:00 2001 From: Amir Cheikh Date: Wed, 2 Jul 2025 16:57:08 -0400 Subject: [PATCH 047/184] Auth component ordering --- examples/with-sdk-js/src/app/layout.tsx | 2 + .../src/components/auth/index.tsx | 90 +++++++++++++------ .../src/providers/TurnkeyProvider.tsx | 2 + .../src/providers/client/Provider.tsx | 35 +++++--- packages/sdk-js/src/__clients__/core.ts | 17 ++-- 5 files changed, 98 insertions(+), 48 deletions(-) diff --git a/examples/with-sdk-js/src/app/layout.tsx b/examples/with-sdk-js/src/app/layout.tsx index 5761f2120..53d0ca603 100644 --- a/examples/with-sdk-js/src/app/layout.tsx +++ b/examples/with-sdk-js/src/app/layout.tsx @@ -28,6 +28,8 @@ function RootLayout({ children }: RootLayoutProps) { oAuthRedirectUri: process.env.NEXT_PUBLIC_OAUTH_REDIRECT_URI, }, autoRefreshSession: true, + methodOrder: ["socials", "email", "sms", "passkey"], + oauthOrder: ["google"], }, passkeyConfig: { rpId: process.env.NEXT_PUBLIC_RPID!, diff --git a/packages/react-wallet-kit/src/components/auth/index.tsx b/packages/react-wallet-kit/src/components/auth/index.tsx index 13c622f89..29b3d123e 100644 --- a/packages/react-wallet-kit/src/components/auth/index.tsx +++ b/packages/react-wallet-kit/src/components/auth/index.tsx @@ -11,7 +11,6 @@ import { ActionPage } from "./Action"; import { PasskeyButtons } from "./Passkey"; import { faFingerprint } from "@fortawesome/free-solid-svg-icons"; import { Spinner } from "../design/Spinners"; -import { useEffect } from "react"; export function AuthComponent() { const { @@ -23,6 +22,10 @@ export function AuthComponent() { } = useTurnkey(); const { pushPage } = useModal(); + if (!config) return ; + + const { methods = {}, methodOrder = [], oauthOrder = [] } = config.auth || {}; // TODO (Amir): This should have default values! + const handleEmailSubmit = async (email: string) => { try { const otpId = await initOtp({ otpType: OtpType.Email, contact: email }); @@ -121,36 +124,65 @@ export function AuthComponent() { showTitle: false, }); }; - useEffect(() => { - console.log(config); - }, [config]); + + const oauthButtonMap: Record = { + google: methods.googleOAuthEnabled ? ( + } + onClick={handleGoogle} + /> + ) : null, + // apple: ... + // facebook: ... + }; + + const oauthButtons = oauthOrder + .map((provider) => oauthButtonMap[provider]) + .filter(Boolean); + + const oauthBlock = + oauthButtons.length > 0 ? ( +
+ {oauthButtons} +
+ ) : null; + + // -- Individual Auth Method Components -- + const methodComponents: Record = { + socials: oauthBlock, + email: methods.emailOtpAuthEnabled ? ( + + ) : null, + sms: methods.smsOtpAuthEnabled ? ( + + ) : null, + passkey: methods.passkeyAuthEnabled ? ( + + ) : null, + }; + + // -- Final Rendering Order -- + const rendered = methodOrder + .map((key) => methodComponents[key]) + .filter(Boolean); + return (
- {config ? ( - <> -
- } - onClick={handleGoogle} - /> -
- - - - {config.auth?.methods?.smsOtpAuthEnabled && ( - - )} - - - - - ) : ( - - )} +
+ {rendered.map((component, index) => ( +
+ {index > 0 && } + {component} +
+ ))}
); } diff --git a/packages/react-wallet-kit/src/providers/TurnkeyProvider.tsx b/packages/react-wallet-kit/src/providers/TurnkeyProvider.tsx index 4475aa819..9d6d89744 100644 --- a/packages/react-wallet-kit/src/providers/TurnkeyProvider.tsx +++ b/packages/react-wallet-kit/src/providers/TurnkeyProvider.tsx @@ -15,6 +15,8 @@ export interface TurnkeyProviderConfig extends TurnkeySDKClientConfig { appleOAuthEnabled?: boolean; facebookOAuthEnabled?: boolean; }; + methodOrder?: Array<"socials" | "email" | "sms" | "passkey" | "wallet">; + oauthOrder?: Array<"google" | "apple" | "facebook">; oAuthConfig?: { oAuthRedirectUri?: string; googleClientId?: string; diff --git a/packages/react-wallet-kit/src/providers/client/Provider.tsx b/packages/react-wallet-kit/src/providers/client/Provider.tsx index 04665ca53..2e4c432c0 100644 --- a/packages/react-wallet-kit/src/providers/client/Provider.tsx +++ b/packages/react-wallet-kit/src/providers/client/Provider.tsx @@ -108,6 +108,8 @@ export const ClientProvider: React.FC = ({ AuthState.Unauthenticated, ); const expiryTimeoutsRef = useRef>({}); + const proxyAuthConfigRef = useRef(null); + const [allSessions, setAllSessions] = useState< Record | undefined >(undefined); @@ -191,18 +193,24 @@ export const ClientProvider: React.FC = ({ }, [client]); useEffect(() => { - if (!client) return; + if (!client || proxyAuthConfigRef.current) return; + + // Only fetch the proxy auth config once. Use that to build the master config. const fetchProxyAuthConfig = async () => { const proxyAuthConfig = await client.getProxyAuthConfig(); - const masterConfig = buildConfig(proxyAuthConfig); - setMasterConfig(masterConfig); - - return; + proxyAuthConfigRef.current = proxyAuthConfig; + setMasterConfig(buildConfig(proxyAuthConfig)); }; fetchProxyAuthConfig(); }, [client]); + useEffect(() => { + // If the proxyAuthConfigRef is already set, we don't need to fetch it again. Rebuild the master config with the updated config and stored proxyAuthConfig + if (!proxyAuthConfigRef.current) return; + setMasterConfig(buildConfig(proxyAuthConfigRef.current)); + }, [config]); + const buildConfig = (proxyAuthConfig: v1GetWalletKitConfigResponse) => { return { ...config, @@ -241,7 +249,7 @@ export const ClientProvider: React.FC = ({ sessionExpirationSeconds: { passkey: proxyAuthConfig?.passkeySessionExpirationSeconds, wallet: proxyAuthConfig?.walletSessionExpirationSeconds, - } + }, }, } as TurnkeyProviderConfig; }; @@ -549,9 +557,11 @@ export const ClientProvider: React.FC = ({ } setAuthState(AuthState.Loading); - const expirationSeconds = masterConfig?.auth?.sessionExpirationSeconds?.passkey ?? DEFAULT_SESSION_EXPIRATION_IN_SECONDS; + const expirationSeconds = + masterConfig?.auth?.sessionExpirationSeconds?.passkey ?? + DEFAULT_SESSION_EXPIRATION_IN_SECONDS; const res = await withTurnkeyErrorHandling( - () => client.loginWithPasskey({...params, expirationSeconds }), + () => client.loginWithPasskey({ ...params, expirationSeconds }), callbacks, "Failed to login with passkey", ); @@ -578,7 +588,9 @@ export const ClientProvider: React.FC = ({ } setAuthState(AuthState.Loading); - const expirationSeconds = masterConfig?.auth?.sessionExpirationSeconds?.passkey ?? DEFAULT_SESSION_EXPIRATION_IN_SECONDS; + const expirationSeconds = + masterConfig?.auth?.sessionExpirationSeconds?.passkey ?? + DEFAULT_SESSION_EXPIRATION_IN_SECONDS; const res = await withTurnkeyErrorHandling( () => client.signUpWithPasskey({ ...params, expirationSeconds }), callbacks, @@ -1108,7 +1120,10 @@ export const ClientProvider: React.FC = ({ const activeSessionKey = await client.getActiveSessionKey(); if (!activeSessionKey) { - throw new TurnkeyError("No active session found.", TurnkeyErrorCodes.NO_SESSION_FOUND); + throw new TurnkeyError( + "No active session found.", + TurnkeyErrorCodes.NO_SESSION_FOUND, + ); } let sessionKey = params?.sessionKey ?? activeSessionKey; diff --git a/packages/sdk-js/src/__clients__/core.ts b/packages/sdk-js/src/__clients__/core.ts index 03f681001..7eb33e403 100644 --- a/packages/sdk-js/src/__clients__/core.ts +++ b/packages/sdk-js/src/__clients__/core.ts @@ -233,7 +233,8 @@ export class TurnkeyClient { params?.publicKey || (await this.apiKeyStamper?.createKeyPair()); const sessionKey = params?.sessionKey || SessionKey.DefaultSessionkey; - const expirationSeconds = params?.expirationSeconds || DEFAULT_SESSION_EXPIRATION_IN_SECONDS; + const expirationSeconds = + params?.expirationSeconds || DEFAULT_SESSION_EXPIRATION_IN_SECONDS; // Create a read-only session if (sessionType === SessionType.READ_ONLY) { @@ -260,7 +261,7 @@ export class TurnkeyClient { { publicKey, organizationId: this.config.organizationId, - expirationSeconds + expirationSeconds, }, StamperType.Passkey, ); @@ -1236,13 +1237,11 @@ export class TurnkeyClient { const organizationId = session.organizationId; try { - const updatedUser = await this.httpClient.updateUser( - { - organizationId: organizationId || session.organizationId, - userId, - ...updateFields, - }, - ); + const updatedUser = await this.httpClient.updateUser({ + organizationId: organizationId || session.organizationId, + userId, + ...updateFields, + }); if (!updatedUser || !updatedUser.userId) { throw new TurnkeyError( From 85beff479fc1773d22b3cf3984bc4b80ffe76c80 Mon Sep 17 00:00:00 2001 From: Amir Cheikh Date: Mon, 7 Jul 2025 12:44:35 -0400 Subject: [PATCH 048/184] more customization. Apple and facebbok oauth --- examples/with-sdk-js/src/app/layout.tsx | 10 +- .../src/components/auth/OAuth.tsx | 2 +- .../src/components/auth/index.tsx | 71 ++- .../src/providers/TurnkeyProvider.tsx | 11 +- .../src/providers/client/Provider.tsx | 601 +++++++++++++++--- .../src/providers/modal/Provider.tsx | 2 +- .../src/providers/modal/Root.tsx | 10 +- .../src/providers/theme/Overrides.tsx | 48 ++ packages/react-wallet-kit/src/utils.ts | 218 ++++++- packages/sdk-js/src/__clients__/core.ts | 4 +- 10 files changed, 880 insertions(+), 97 deletions(-) create mode 100644 packages/react-wallet-kit/src/providers/theme/Overrides.tsx diff --git a/examples/with-sdk-js/src/app/layout.tsx b/examples/with-sdk-js/src/app/layout.tsx index 53d0ca603..d32dfcea2 100644 --- a/examples/with-sdk-js/src/app/layout.tsx +++ b/examples/with-sdk-js/src/app/layout.tsx @@ -25,11 +25,17 @@ function RootLayout({ children }: RootLayoutProps) { auth: { oAuthConfig: { googleClientId: process.env.NEXT_PUBLIC_GOOGLE_CLIENT_ID, + appleClientId: process.env.NEXT_PUBLIC_APPLE_CLIENT_ID, + facebookClientId: process.env.NEXT_PUBLIC_FACEBOOK_CLIENT_ID, oAuthRedirectUri: process.env.NEXT_PUBLIC_OAUTH_REDIRECT_URI, }, + methods: { + smsOtpAuthEnabled: true, + }, autoRefreshSession: true, - methodOrder: ["socials", "email", "sms", "passkey"], - oauthOrder: ["google"], + }, + ui: { + darkMode: false, }, passkeyConfig: { rpId: process.env.NEXT_PUBLIC_RPID!, diff --git a/packages/react-wallet-kit/src/components/auth/OAuth.tsx b/packages/react-wallet-kit/src/components/auth/OAuth.tsx index d5fbb1a22..f1ba83e18 100644 --- a/packages/react-wallet-kit/src/components/auth/OAuth.tsx +++ b/packages/react-wallet-kit/src/components/auth/OAuth.tsx @@ -17,7 +17,7 @@ export function OAuthButton(props: OAuthButtonProps) { const observer = new ResizeObserver(([entry]) => { if (!entry) return; const width = entry.contentRect.width; - setShowText(width > 200); + setShowText(width > 300); }); if (containerRef.current) { diff --git a/packages/react-wallet-kit/src/components/auth/index.tsx b/packages/react-wallet-kit/src/components/auth/index.tsx index 29b3d123e..3a6b14cc4 100644 --- a/packages/react-wallet-kit/src/components/auth/index.tsx +++ b/packages/react-wallet-kit/src/components/auth/index.tsx @@ -1,6 +1,10 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { OAuthButton } from "./OAuth"; -import { faGoogle } from "@fortawesome/free-brands-svg-icons"; +import { + faApple, + faFacebook, + faGoogle, +} from "@fortawesome/free-brands-svg-icons"; import { useModal, useTurnkey } from "../../providers"; import { EmailInput } from "./Email"; import { OrSeparator } from "./OrSeparator"; @@ -16,15 +20,22 @@ export function AuthComponent() { const { config, handleGoogleOauth, + handleAppleOauth, + handleFacebookOauth, initOtp, loginWithPasskey, signUpWithPasskey, } = useTurnkey(); const { pushPage } = useModal(); - if (!config) return ; + if (!config) + return ( +
+ +
+ ); - const { methods = {}, methodOrder = [], oauthOrder = [] } = config.auth || {}; // TODO (Amir): This should have default values! + const { methods = {}, methodOrder = [], oauthOrder = [] } = config.auth || {}; const handleEmailSubmit = async (email: string) => { try { @@ -125,6 +136,42 @@ export function AuthComponent() { }); }; + const handleApple = async () => { + pushPage({ + key: "Apple OAuth", + content: ( + + handleAppleOauth({ + additionalState: { openModal: "true" }, // Tell the provider to reopen the auth modal and show the loading state + }) + } + icon={} + /> + ), + showTitle: false, + }); + }; + + const handleFacebook = async () => { + pushPage({ + key: "Facebook OAuth", + content: ( + + handleFacebookOauth({ + additionalState: { openModal: "true" }, // Tell the provider to reopen the auth modal and show the loading state + }) + } + icon={} + /> + ), + showTitle: false, + }); + }; + const oauthButtonMap: Record = { google: methods.googleOAuthEnabled ? ( ) : null, - // apple: ... - // facebook: ... + apple: methods.appleOAuthEnabled ? ( + } + onClick={handleApple} + /> + ) : null, + facebook: methods.facebookOAuthEnabled ? ( + } + onClick={handleFacebook} + /> + ) : null, }; const oauthButtons = oauthOrder diff --git a/packages/react-wallet-kit/src/providers/TurnkeyProvider.tsx b/packages/react-wallet-kit/src/providers/TurnkeyProvider.tsx index 9d6d89744..09dce2e64 100644 --- a/packages/react-wallet-kit/src/providers/TurnkeyProvider.tsx +++ b/packages/react-wallet-kit/src/providers/TurnkeyProvider.tsx @@ -3,6 +3,7 @@ import { ClientProvider } from "./client/Provider"; import { ModalProvider } from "./modal/Provider"; import { ModalRoot } from "./modal/Root"; import { Session, TurnkeyError, TurnkeyNetworkError } from "@turnkey/sdk-types"; +import { ThemeOverrides, TurnkeyThemeOverrides } from "./theme/Overrides"; export interface TurnkeyProviderConfig extends TurnkeySDKClientConfig { auth?: { @@ -31,7 +32,11 @@ export interface TurnkeyProviderConfig extends TurnkeySDKClientConfig { autoRefreshSession?: boolean; }; ui?: { - // Good mornig! + darkMode?: boolean; + theme?: { + light?: Partial; + dark?: Partial; + }; }; language?: { // Ohayō! @@ -58,6 +63,10 @@ export function TurnkeyProvider({ return ( + {children} diff --git a/packages/react-wallet-kit/src/providers/client/Provider.tsx b/packages/react-wallet-kit/src/providers/client/Provider.tsx index 2e4c432c0..30702ce3c 100644 --- a/packages/react-wallet-kit/src/providers/client/Provider.tsx +++ b/packages/react-wallet-kit/src/providers/client/Provider.tsx @@ -1,9 +1,15 @@ import { sha256 } from "@noble/hashes/sha2"; import { bytesToHex } from "@noble/hashes/utils"; import { + APPLE_AUTH_URL, AuthState, + exchangeCodeForToken, + FACEBOOK_AUTH_URL, + generateChallengePair, GOOGLE_AUTH_URL, + handleFacebookPKCEFlow, isValidSession, + parseOAuthRedirect, popupHeight, popupWidth, SESSION_WARNING_THRESHOLD_MS, @@ -54,7 +60,11 @@ import { useModal } from "../modal/Provider"; import { TurnkeyCallbacks, TurnkeyProviderConfig } from "../TurnkeyProvider"; import { AuthComponent } from "../../components/auth"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { faGoogle } from "@fortawesome/free-brands-svg-icons"; +import { + faApple, + faFacebook, + faGoogle, +} from "@fortawesome/free-brands-svg-icons"; import { WalletType } from "@turnkey/wallet-stamper"; import { ActionPage } from "../../components/auth/Action"; @@ -78,6 +88,16 @@ export interface ClientContextType extends TurnkeyClientMethods { additionalState?: Record; openInPage?: boolean; }) => Promise; + handleAppleOauth: (params: { + clientId?: string; + additionalState?: Record; + openInPage?: boolean; + }) => Promise; + handleFacebookOauth: (params: { + clientId?: string; + additionalState?: Record; + openInPage?: boolean; + }) => Promise; } export const ClientContext = createContext( @@ -121,67 +141,141 @@ export const ClientProvider: React.FC = ({ // Handle redirect-based auth useEffect(() => { - if (window.location.hash) { - if (!client) return; // Client is not ready yet. Don't error just return. - const hashParams = new URLSearchParams(window.location.hash.substring(1)); - const idToken = hashParams.get("id_token"); - const state = hashParams.get("state"); - - const stateParams = new URLSearchParams(state || ""); - const provider = stateParams.get("provider"); - const flow = stateParams.get("flow"); - const openModal = stateParams.get("openModal"); - - const publicKey = stateParams.get("publicKey"); - - if (!publicKey) { - throw new Error( - "Public key is missing in the state parameters. You must encode the public key in the state parameter when initiating the OAuth flow.", + // Check for either hash or search parameters that could indicate an OAuth redirect + if ((window.location.hash || window.location.search) && client) { + // Handle Facebook redirect (uses search params with code) + if ( + window.location.search && + window.location.search.includes("code=") && + window.location.search.includes("state=") + ) { + const searchParams = new URLSearchParams( + window.location.search.substring(1), ); + const code = searchParams.get("code"); + const state = searchParams.get("state"); + + // Parse state parameter + if (state && code) { + const stateParams = new URLSearchParams(state); + const provider = stateParams.get("provider"); + const flow = stateParams.get("flow"); + const publicKey = stateParams.get("publicKey"); + const openModal = stateParams.get("openModal"); + + if (provider === "facebook" && flow === "redirect" && publicKey) { + // We have all the required parameters for a Facebook PKCE flow + const clientId = masterConfig?.auth?.oAuthConfig?.facebookClientId; + const redirectURI = + masterConfig?.auth?.oAuthConfig?.oAuthRedirectUri; + + if (clientId && redirectURI) { + handleFacebookPKCEFlow({ + code, + publicKey, + openModal, + clientId, + redirectURI, + callbacks, + completeOauth, + onPushPage: (oidcToken) => { + pushPage({ + key: `Facebook OAuth`, + content: ( + { + await completeOauth({ + oidcToken, + publicKey, + providerName: "facebook", + }); + }} + icon={} + /> + ), + showTitle: false, + }); + }, + }).catch((error) => { + // Handle errors + if (callbacks?.onError) { + callbacks.onError( + error instanceof TurnkeyError + ? error + : new TurnkeyError( + "Facebook authentication failed", + TurnkeyErrorCodes.OAUTH_SIGNUP_ERROR, + error, + ), + ); + } + }); + } + } + } } + // Handle Google/Apple redirects (uses hash with id_token) + else if (window.location.hash) { + const hash = window.location.hash.substring(1); + + // Parse the hash using our helper functions + const { idToken, provider, flow, publicKey, openModal } = + parseOAuthRedirect(hash); + + if (idToken && flow === "redirect" && publicKey) { + if (openModal === "true") { + const providerName = provider + ? provider.charAt(0).toUpperCase() + provider.slice(1) + : "Provider"; + + // Determine which icon to show based on the provider + let icon; + if (provider === "apple") { + icon = ; + } else { + // Default to Google icon + icon = ; + } - if (idToken && flow === "redirect") { - if (openModal === "true") { - const providerName = provider - ? provider?.charAt(0).toUpperCase() + provider?.slice(1) - : "Provider"; - // This state is set when the OAuth flow comes from the AuthComponent. We handle it differently because the callback is ran inside the loading component. - pushPage({ - key: "Google OAuth", - content: ( - { - await completeOauth({ - oidcToken: idToken, - publicKey, - // TODO (Amir): Shall we pass createSubOrgParams here? - }); + // This state is set when the OAuth flow comes from the AuthComponent + pushPage({ + key: `${providerName} OAuth`, + content: ( + { + await completeOauth({ + oidcToken: idToken, + publicKey, + providerName: provider ?? "oauth-provider", // Keep lowercase provider name + }); + }} + icon={icon} + /> + ), + showTitle: false, + }); + } else if (callbacks?.onOauthRedirect) { + callbacks.onOauthRedirect({ idToken, publicKey }); + } else { + completeOauth({ + oidcToken: idToken, + publicKey, + providerName: provider ?? "oauth-provider", // Keep lowercase provider name + }); + } - // TODO (Amir): Shall we also allow the oAuthcallbacks to run here? - }} - icon={} - /> - ), - showTitle: false, - }); - } else if (callbacks?.onOauthRedirect) { - callbacks.onOauthRedirect({ idToken, publicKey }); - } else { - completeOauth({ - oidcToken: idToken, - publicKey, - // TODO (Amir): Shall we pass createSubOrgParams here?. Edit: Yes totally. We need to find a way to pass it in the page replace flow. - }); + // Clean up the URL after processing + window.history.replaceState( + null, + document.title, + window.location.pathname + window.location.search, + ); } - window.history.replaceState( - null, - document.title, - window.location.pathname + window.location.search, - ); } } - }, [client]); + }, [client, masterConfig, callbacks, pushPage]); useEffect(() => { if (!client) return; @@ -212,34 +306,54 @@ export const ClientProvider: React.FC = ({ }, [config]); const buildConfig = (proxyAuthConfig: v1GetWalletKitConfigResponse) => { + // Juggle the local overrides with the values set in the dashboard (proxyAuthConfig). + const resolvedMethods = { + emailOtpAuthEnabled: + config.auth?.methods?.emailOtpAuthEnabled ?? + proxyAuthConfig.emailEnabled, + smsOtpAuthEnabled: + config.auth?.methods?.smsOtpAuthEnabled ?? proxyAuthConfig.smsEnabled, + passkeyAuthEnabled: + config.auth?.methods?.passkeyAuthEnabled ?? + proxyAuthConfig.passkeyEnabled, + walletAuthEnabled: + config.auth?.methods?.walletAuthEnabled ?? + proxyAuthConfig.walletEnabled, + googleOAuthEnabled: + config.auth?.methods?.googleOAuthEnabled ?? + proxyAuthConfig.googleEnabled, + appleOAuthEnabled: + config.auth?.methods?.appleOAuthEnabled ?? proxyAuthConfig.appleEnabled, + facebookOAuthEnabled: + config.auth?.methods?.facebookOAuthEnabled ?? + proxyAuthConfig.facebookEnabled, + }; + + // Set a default ordering for the oAuth methods + const oauthOrder = + config.auth?.oauthOrder ?? + (["google", "apple", "facebook"] as const).filter( + (provider) => resolvedMethods[`${provider}OAuthEnabled` as const], + ); + + // Set a default ordering for the overall auth methods + const methodOrder = + config.auth?.methodOrder ?? + ([ + oauthOrder.length > 0 ? "socials" : null, + resolvedMethods.emailOtpAuthEnabled ? "email" : null, + resolvedMethods.smsOtpAuthEnabled ? "sms" : null, + resolvedMethods.passkeyAuthEnabled ? "passkey" : null, + resolvedMethods.walletAuthEnabled ? "wallet" : null, + ].filter(Boolean) as Array< + "socials" | "email" | "sms" | "passkey" | "wallet" + >); + return { ...config, auth: { ...config.auth, - methods: { - ...config.auth?.methods, - emailOtpAuthEnabled: - config.auth?.methods?.emailOtpAuthEnabled ?? - proxyAuthConfig.emailEnabled, - smsOtpAuthEnabled: - config.auth?.methods?.smsOtpAuthEnabled ?? - proxyAuthConfig.smsEnabled, - passkeyAuthEnabled: - config.auth?.methods?.passkeyAuthEnabled ?? - proxyAuthConfig.passkeyEnabled, - walletAuthEnabled: - config.auth?.methods?.walletAuthEnabled ?? - proxyAuthConfig.walletEnabled, - googleOAuthEnabled: - config.auth?.methods?.googleOAuthEnabled ?? - proxyAuthConfig.googleEnabled, - appleOAuthEnabled: - config.auth?.methods?.appleOAuthEnabled ?? - proxyAuthConfig.appleEnabled, - facebookOAuthEnabled: - config.auth?.methods?.facebookOAuthEnabled ?? - proxyAuthConfig.facebookEnabled, - }, + methods: resolvedMethods, oAuthConfig: { ...config.auth?.oAuthConfig, openOAuthInPage: @@ -250,6 +364,8 @@ export const ClientProvider: React.FC = ({ passkey: proxyAuthConfig?.passkeySessionExpirationSeconds, wallet: proxyAuthConfig?.walletSessionExpirationSeconds, }, + methodOrder, + oauthOrder, }, } as TurnkeyProviderConfig; }; @@ -732,6 +848,7 @@ export const ClientProvider: React.FC = ({ async function completeOauth(params: { oidcToken: string; publicKey: string; + providerName?: string; sessionKey?: string; invalidateExisting?: boolean; createSubOrgParams?: CreateSubOrgParams; @@ -1317,7 +1434,6 @@ export const ClientProvider: React.FC = ({ ); } - console.log(typeof openInPage); const flow = openInPage ? "redirect" : "popup"; const redirectURI = masterConfig.auth?.oAuthConfig.oAuthRedirectUri.replace(/\/$/, ""); @@ -1352,9 +1468,7 @@ export const ClientProvider: React.FC = ({ } } googleAuthUrl.searchParams.set("state", state); - console.log("openingopage", openInPage); if (openInPage) { - console.log("WHHYYY"); // Redirect current page to Google Auth window.location.href = googleAuthUrl.toString(); return new Promise((_, reject) => { @@ -1413,6 +1527,7 @@ export const ClientProvider: React.FC = ({ completeOauth({ oidcToken: idToken, publicKey, + providerName: "google", }) .then(() => resolve()) .catch(reject); @@ -1436,6 +1551,326 @@ export const ClientProvider: React.FC = ({ } } + async function handleAppleOauth(params: { + clientId?: string; + openInPage?: boolean; + additionalState?: Record; + }): Promise { + const { + clientId = masterConfig?.auth?.oAuthConfig?.appleClientId, + openInPage = masterConfig?.auth?.oAuthConfig?.openOAuthInPage ?? false, + additionalState: additionalParameters, + } = params; + try { + if (!masterConfig) { + throw new TurnkeyError( + "Config is not ready yet!", + TurnkeyErrorCodes.INVALID_CONFIGURATION, + ); + } + if (!clientId) { + throw new TurnkeyError( + "Apple Client ID is not configured.", + TurnkeyErrorCodes.INVALID_CONFIGURATION, + ); + } + if (!masterConfig.auth?.oAuthConfig?.oAuthRedirectUri) { + throw new TurnkeyError( + "OAuth Redirect URI is not configured.", + TurnkeyErrorCodes.INVALID_CONFIGURATION, + ); + } + + const flow = openInPage ? "redirect" : "popup"; + const redirectURI = masterConfig.auth?.oAuthConfig.oAuthRedirectUri; // TODO (Amir): Apple needs the '/' at the end. Maybe we should add it if not there? + + // Create key pair and generate nonce + const publicKey = await createApiKeyPair(); + if (!publicKey) { + throw new Error("Failed to create public key for OAuth."); + } + const nonce = bytesToHex(sha256(publicKey)); + + // Construct Apple Auth URL + const appleAuthUrl = new URL(APPLE_AUTH_URL); + appleAuthUrl.searchParams.set("client_id", clientId); + appleAuthUrl.searchParams.set("redirect_uri", redirectURI); + appleAuthUrl.searchParams.set("response_type", "code id_token"); + appleAuthUrl.searchParams.set("response_mode", "fragment"); + appleAuthUrl.searchParams.set("nonce", nonce); + + // Create state parameter + let state = `provider=apple&flow=${flow}&publicKey=${encodeURIComponent(publicKey)}`; + if (additionalParameters) { + const additionalState = Object.entries(additionalParameters) + .map( + ([key, value]) => + `${encodeURIComponent(key)}=${encodeURIComponent(value)}`, + ) + .join("&"); + if (additionalState) { + state += `&${additionalState}`; + } + } + appleAuthUrl.searchParams.set("state", state); + + if (openInPage) { + // Redirect current page to Apple Auth + window.location.href = appleAuthUrl.toString(); + return new Promise((_, reject) => { + // Set a timeout just in case the redirect doesn't happen + const timeout = setTimeout(() => { + reject(new Error("Authentication timed out.")); + }, 300000); // 5 minutes + + // If the page is unloaded (user navigates away), clear the timeout + window.addEventListener("beforeunload", () => clearTimeout(timeout)); + }); + } else { + // Open popup window + const width = popupWidth; + const height = popupHeight; + const left = window.screenX + (window.innerWidth - width) / 2; + const top = window.screenY + (window.innerHeight - height) / 2; + + const authWindow = window.open( + "about:blank", + "_blank", + `width=${width},height=${height},top=${top},left=${left},scrollbars=yes,resizable=yes`, + ); + + if (!authWindow) { + throw new Error("Failed to open Apple login window."); + } + + authWindow.location.href = appleAuthUrl.toString(); + + // Return a promise that resolves when the OAuth flow completes + return new Promise((resolve, reject) => { + const interval = setInterval(() => { + try { + // Check if window was closed without completing auth + if (authWindow.closed) { + clearInterval(interval); + reject(new Error("Authentication window was closed.")); + return; + } + + const url = authWindow.location.href || ""; + if (url.startsWith(window.location.origin)) { + const hashParams = new URLSearchParams(url.split("#")[1]); + const idToken = hashParams.get("id_token"); + if (idToken) { + authWindow.close(); + clearInterval(interval); + + if (callbacks?.onOauthRedirect) { + callbacks.onOauthRedirect({ idToken, publicKey }); + } else { + completeOauth({ + oidcToken: idToken, + publicKey, + providerName: "apple", + }) + .then(() => resolve()) + .catch(reject); + return; + } + resolve(); + } + } + } catch (error) { + // Ignore cross-origin errors + } + }, 500); + + if (authWindow.closed) { + clearInterval(interval); + } + }); + } + } catch (error) { + throw error; + } + } + + async function handleFacebookOauth(params: { + clientId?: string; + openInPage?: boolean; + additionalState?: Record; + }): Promise { + const { + clientId = masterConfig?.auth?.oAuthConfig?.facebookClientId, + openInPage = masterConfig?.auth?.oAuthConfig?.openOAuthInPage ?? false, + additionalState: additionalParameters, + } = params; + try { + if (!masterConfig) { + throw new TurnkeyError( + "Config is not ready yet!", + TurnkeyErrorCodes.INVALID_CONFIGURATION, + ); + } + if (!clientId) { + throw new TurnkeyError( + "Facebook Client ID is not configured.", + TurnkeyErrorCodes.INVALID_CONFIGURATION, + ); + } + if (!masterConfig.auth?.oAuthConfig?.oAuthRedirectUri) { + throw new TurnkeyError( + "OAuth Redirect URI is not configured.", + TurnkeyErrorCodes.INVALID_CONFIGURATION, + ); + } + + const flow = openInPage ? "redirect" : "popup"; + const redirectURI = masterConfig.auth?.oAuthConfig.oAuthRedirectUri; + + // Create key pair and generate nonce + const publicKey = await createApiKeyPair(); + if (!publicKey) { + throw new Error("Failed to create public key for OAuth."); + } + const nonce = bytesToHex(sha256(publicKey)); + + // Generate PKCE challenge pair + const { verifier, codeChallenge } = await generateChallengePair(); + // Store verifier for later token exchange + sessionStorage.setItem("facebook_verifier", verifier); + + // Construct Facebook Auth URL + const facebookAuthUrl = new URL(FACEBOOK_AUTH_URL); + facebookAuthUrl.searchParams.set("client_id", clientId); + facebookAuthUrl.searchParams.set("redirect_uri", redirectURI); + facebookAuthUrl.searchParams.set("response_type", "code"); + facebookAuthUrl.searchParams.set("code_challenge", codeChallenge); + facebookAuthUrl.searchParams.set("code_challenge_method", "S256"); + facebookAuthUrl.searchParams.set("nonce", nonce); + facebookAuthUrl.searchParams.set("scope", "openid"); + + // Create state parameter + let state = `provider=facebook&flow=${flow}&publicKey=${encodeURIComponent(publicKey)}`; + if (additionalParameters) { + const additionalState = Object.entries(additionalParameters) + .map( + ([key, value]) => + `${encodeURIComponent(key)}=${encodeURIComponent(value)}`, + ) + .join("&"); + if (additionalState) { + state += `&${additionalState}`; + } + } + facebookAuthUrl.searchParams.set("state", state); + + if (openInPage) { + // Redirect current page to Facebook Auth + window.location.href = facebookAuthUrl.toString(); + return new Promise((_, reject) => { + // Set a timeout just in case the redirect doesn't happen + const timeout = setTimeout(() => { + reject(new Error("Authentication timed out.")); + }, 300000); // 5 minutes + + // If the page is unloaded (user navigates away), clear the timeout + window.addEventListener("beforeunload", () => clearTimeout(timeout)); + }); + } else { + // Open popup window + const width = popupWidth; + const height = popupHeight; + const left = window.screenX + (window.innerWidth - width) / 2; + const top = window.screenY + (window.innerHeight - height) / 2; + + const authWindow = window.open( + "about:blank", + "_blank", + `width=${width},height=${height},top=${top},left=${left},scrollbars=yes,resizable=yes`, + ); + + if (!authWindow) { + throw new Error("Failed to open Facebook login window."); + } + + authWindow.location.href = facebookAuthUrl.toString(); + + // Return a promise that resolves when the OAuth flow completes + return new Promise((resolve, reject) => { + const interval = setInterval(() => { + try { + // Check if window was closed without completing auth + if (authWindow.closed) { + clearInterval(interval); + reject(new Error("Authentication window was closed.")); + return; + } + + const url = authWindow.location.href || ""; + if (url.startsWith(window.location.origin)) { + const urlParams = new URLSearchParams(new URL(url).search); + const authCode = urlParams.get("code"); + const stateParam = urlParams.get("state"); + + if ( + authCode && + stateParam && + stateParam.includes("provider=facebook") + ) { + authWindow.close(); + clearInterval(interval); + + // Exchange code for token + const verifier = sessionStorage.getItem("facebook_verifier"); + if (!verifier) { + reject(new Error("Missing PKCE verifier")); + return; + } + + exchangeCodeForToken( + clientId, + redirectURI, + authCode, + verifier, + ) + .then((tokenData) => { + sessionStorage.removeItem("facebook_verifier"); + + if (callbacks?.onOauthRedirect) { + callbacks.onOauthRedirect({ + idToken: tokenData.id_token, + publicKey, + }); + } else { + completeOauth({ + oidcToken: tokenData.id_token, + publicKey, + providerName: "facebook", + }) + .then(() => resolve()) + .catch(reject); + return; + } + resolve(); + }) + .catch(reject); + } + } + } catch (error) { + // Ignore cross-origin errors + } + }, 500); + + if (authWindow.closed) { + clearInterval(interval); + } + }); + } + } catch (error) { + throw error; + } + } + const login = async () => { pushPage({ key: "Log in or sign up", @@ -1489,6 +1924,8 @@ export const ClientProvider: React.FC = ({ getActiveSessionKey, createApiKeyPair, handleGoogleOauth, + handleAppleOauth, + handleFacebookOauth, getProxyAuthConfig, }} > diff --git a/packages/react-wallet-kit/src/providers/modal/Provider.tsx b/packages/react-wallet-kit/src/providers/modal/Provider.tsx index 2016ed440..6c77c68b0 100644 --- a/packages/react-wallet-kit/src/providers/modal/Provider.tsx +++ b/packages/react-wallet-kit/src/providers/modal/Provider.tsx @@ -1,6 +1,6 @@ import { createContext, useContext, useState, ReactNode } from "react"; -type ModalPage = { +export type ModalPage = { key: string; content: ReactNode; showTitle?: boolean; diff --git a/packages/react-wallet-kit/src/providers/modal/Root.tsx b/packages/react-wallet-kit/src/providers/modal/Root.tsx index cd696328f..0614ba94b 100644 --- a/packages/react-wallet-kit/src/providers/modal/Root.tsx +++ b/packages/react-wallet-kit/src/providers/modal/Root.tsx @@ -9,9 +9,11 @@ import { import { useModal } from "./Provider"; import { IconButton } from "../../components/design/Buttons"; import { faArrowLeft, faClose } from "@fortawesome/free-solid-svg-icons"; +import { useTurnkey } from "../client/Provider"; export function ModalRoot() { const { modalStack, popPage, closeModal } = useModal(); + const { config } = useTurnkey(); const current = modalStack[modalStack.length - 1]; const hasBack = modalStack.length > 1; @@ -88,8 +90,10 @@ export function ModalRoot() { {/* Modal Panel */ - /* NOTE (Amir): dark is applied manually here. This should be controlled in a variable. Idk why but, tailwind's default dark mode auto selecting causes so many bugs. If we have UI anywhere else, we need to add this modifer also! */} -
+ /* TODO (Amir): Does adding transition-colors here mess with the children? Probably. If you see some weird slow colour transitions, this is most likely the culprit! */} +
{/* White background container */}
| undefined; + dark?: Partial | undefined; +}) { + const { light, dark } = props; + const generateCSSVars = (theme?: Partial) => { + if (!theme) return ""; + return Object.entries(theme) + .map(([key, value]) => `--color-${kebab(key)}-light: ${value};`) + .join("\n"); + }; + + const generateDarkCSSVars = (theme?: Partial) => { + if (!theme) return ""; + return Object.entries(theme) + .map(([key, value]) => `--color-${kebab(key)}-dark: ${value};`) + .join("\n"); + }; + + return ( + + ); +} + +// Utility to convert camelCase to kebab-case πŸ₯™ +function kebab(str: string): string { + return str.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`); +} diff --git a/packages/react-wallet-kit/src/utils.ts b/packages/react-wallet-kit/src/utils.ts index ef743be7d..e42f24c6b 100644 --- a/packages/react-wallet-kit/src/utils.ts +++ b/packages/react-wallet-kit/src/utils.ts @@ -1,7 +1,8 @@ import { Session, TurnkeyError, TurnkeyErrorCodes } from "@turnkey/sdk-types"; +import { TurnkeyCallbacks } from "./providers"; export const GOOGLE_AUTH_URL = "https://accounts.google.com/o/oauth2/v2/auth"; -export const APPLE_AUTH_URL = "https://appleid.apple.com/auth/authorize"; +export const APPLE_AUTH_URL = "https://account.apple.com/auth/authorize"; export const APPLE_AUTH_SCRIPT_URL = "https://appleid.cdn-apple.com/appleauth/static/jsapi/appleid/1/en_US/appleid.auth.js"; export const FACEBOOK_AUTH_URL = "https://www.facebook.com/v11.0/dialog/oauth"; @@ -87,3 +88,218 @@ export async function withTurnkeyErrorHandling( throw tkError; } } + +// Helper function to parse Apple OAuth redirects +function parseAppleOAuthRedirect(hash: string): { + idToken: string | null | undefined; + provider: string | null; + flow: string | null; + publicKey: string | null; + openModal: string | null; +} { + // Apple's format has unencoded parameters in the state portion + const idTokenMatch = hash.match(/id_token=([^&]+)$/); + const idToken = idTokenMatch ? idTokenMatch[1] : null; + + // Extract state parameters - state is at the beginning + // It typically looks like: state=provider=apple&flow=redirect&publicKey=123...&openModal=true&code=...&id_token=... + const stateEndIndex = hash.indexOf("&code="); + if (stateEndIndex === -1) + return { + idToken, + provider: null, + flow: null, + publicKey: null, + openModal: null, + }; + + const stateContent = hash.substring(6, stateEndIndex); // Remove "state=" prefix + const stateParams = new URLSearchParams(stateContent); + + return { + idToken, + provider: stateParams.get("provider"), + flow: stateParams.get("flow"), + publicKey: stateParams.get("publicKey"), + openModal: stateParams.get("openModal"), + }; +} + +// Helper function to parse Google OAuth redirects +function parseGoogleOAuthRedirect(hash: string): { + idToken: string | null; + provider: string | null; + flow: string | null; + publicKey: string | null; + openModal: string | null; +} { + const hashParams = new URLSearchParams(hash); + const idToken = hashParams.get("id_token"); + const state = hashParams.get("state"); + + let provider = null; + let flow = null; + let publicKey = null; + let openModal = null; + + if (state) { + const stateParams = new URLSearchParams(state); + provider = stateParams.get("provider"); + flow = stateParams.get("flow"); + publicKey = stateParams.get("publicKey"); + openModal = stateParams.get("openModal"); + } + + return { + idToken, + provider, + flow, + publicKey, + openModal, + }; +} + +// Main function to determine provider and parse accordingly +export function parseOAuthRedirect(hash: string): { + idToken: string | null | undefined; + provider: string | null; + flow: string | null; + publicKey: string | null; + openModal: string | null; +} { + // Check if this is an Apple redirect + if (hash.startsWith("state=provider=apple")) { + return parseAppleOAuthRedirect(hash); + } else { + return parseGoogleOAuthRedirect(hash); + } +} + +// Function to generate PKCE challenge pair for Facebook OAuth +export async function generateChallengePair(): Promise<{ + verifier: string; + codeChallenge: string; +}> { + const randomBytes = new Uint8Array(32); + window.crypto.getRandomValues(randomBytes); + const verifier = btoa(String.fromCharCode(...randomBytes)) + .replace(/\+/g, "-") + .replace(/\//g, "_") + .replace(/=+$/, ""); + + const encoder = new TextEncoder(); + const data = encoder.encode(verifier); + const digest = await window.crypto.subtle.digest("SHA-256", data); + + const base64Challenge = btoa(String.fromCharCode(...new Uint8Array(digest))) + .replace(/\+/g, "-") + .replace(/\//g, "_") + .replace(/=+$/, ""); + + return { verifier, codeChallenge: base64Challenge }; +} + +// Function to exchange Facebook authorization code for token +export async function exchangeCodeForToken( + clientId: string, + redirectUri: string, + code: string, + codeVerifier: string, +): Promise<{ id_token: string }> { + const params = new URLSearchParams({ + client_id: clientId, + redirect_uri: redirectUri, + code_verifier: codeVerifier, + code: code, + grant_type: "authorization_code", + }); + + const response = await fetch(FACEBOOK_GRAPH_URL, { + method: "POST", + headers: { + "Content-Type": "application/x-www-form-urlencoded", + }, + body: params.toString(), + }); + + if (!response.ok) { + const errorData = await response.json(); + throw new Error( + `Facebook token exchange failed: ${JSON.stringify(errorData)}`, + ); + } + + return await response.json(); +} + +export async function handleFacebookPKCEFlow({ + code, + publicKey, + openModal, + clientId, + redirectURI, + callbacks, + completeOauth, + onPushPage, +}: { + code: string; + publicKey: string; + openModal?: string | null; + clientId: string; + redirectURI: string; + callbacks?: TurnkeyCallbacks | undefined; + completeOauth: (params: { + oidcToken: string; + publicKey: string; + }) => Promise; + onPushPage: (idToken: string) => void; +}): Promise { + // Retrieve the verifier stored during OAuth initiation + const verifier = sessionStorage.getItem("facebook_verifier"); + if (!verifier) { + throw new TurnkeyError( + "Missing PKCE verifier for Facebook authentication", + TurnkeyErrorCodes.OAUTH_SIGNUP_ERROR, + ); + } + + try { + // Exchange the code for a token + const tokenData = await exchangeCodeForToken( + clientId, + redirectURI, + code, + verifier, + ); + + // Clean up the verifier as it's no longer needed + sessionStorage.removeItem("facebook_verifier"); + + // Handle different UI flows based on openModal parameter + if (openModal === "true") { + onPushPage(tokenData.id_token); + } else if (callbacks?.onOauthRedirect) { + callbacks.onOauthRedirect({ + idToken: tokenData.id_token, + publicKey, + }); + } else { + await completeOauth({ + oidcToken: tokenData.id_token, + publicKey, + }); + } + + // Clean up the URL after processing + window.history.replaceState(null, document.title, window.location.pathname); + + return; + } catch (error) { + console.error("Error exchanging Facebook code for token:", error); + throw new TurnkeyError( + "Failed to complete Facebook authentication", + TurnkeyErrorCodes.OAUTH_SIGNUP_ERROR, + error, + ); + } +} diff --git a/packages/sdk-js/src/__clients__/core.ts b/packages/sdk-js/src/__clients__/core.ts index 7eb33e403..f6691f9b7 100644 --- a/packages/sdk-js/src/__clients__/core.ts +++ b/packages/sdk-js/src/__clients__/core.ts @@ -789,6 +789,7 @@ export class TurnkeyClient { completeOauth = async (params: { oidcToken: string; publicKey: string; + providerName?: string; sessionKey?: string; invalidateExisting?: boolean; createSubOrgParams?: CreateSubOrgParams; @@ -797,6 +798,7 @@ export class TurnkeyClient { oidcToken, publicKey, createSubOrgParams, + providerName = "OpenID Connect Provider" + Date.now(), sessionKey = SessionKey.DefaultSessionkey, invalidateExisting = false, } = params; @@ -840,7 +842,7 @@ export class TurnkeyClient { return this.signUpWithOauth({ oidcToken, publicKey, - providerName: "google", + providerName, ...(createSubOrgParams && { createSubOrgParams, }), From 461ee6064c3ccc0e2fa5444fecd2fe176e062139 Mon Sep 17 00:00:00 2001 From: Ethan Konkolowicz Date: Mon, 7 Jul 2025 15:10:51 -0400 Subject: [PATCH 049/184] fixed error bubbling up issue --- packages/sdk-js/src/__clients__/core.ts | 59 +++++++++++++++++++++---- packages/sdk-types/src/index.ts | 2 + 2 files changed, 52 insertions(+), 9 deletions(-) diff --git a/packages/sdk-js/src/__clients__/core.ts b/packages/sdk-js/src/__clients__/core.ts index f6691f9b7..a413001ac 100644 --- a/packages/sdk-js/src/__clients__/core.ts +++ b/packages/sdk-js/src/__clients__/core.ts @@ -178,12 +178,15 @@ export class TurnkeyClient { return passkey; } catch (error: any) { - if (error?.message?.includes("timed out or was not allowed")) + if (error?.message?.includes("timed out or was not allowed")) { throw new TurnkeyError( "Passkey creation was cancelled by the user.", TurnkeyErrorCodes.SELECT_PASSKEY_CANCELLED, error, ); + } else if (error instanceof TurnkeyError) { + throw error; + } throw new TurnkeyError( `Failed to create passkey`, TurnkeyErrorCodes.CREATE_PASSKEY_ERROR, @@ -212,6 +215,7 @@ export class TurnkeyClient { } } } catch (error) { + if (error instanceof TurnkeyError) throw error; throw new TurnkeyError( `Failed to log out`, TurnkeyErrorCodes.LOGOUT_ERROR, @@ -287,6 +291,7 @@ export class TurnkeyClient { TurnkeyErrorCodes.SELECT_PASSKEY_CANCELLED, error, ); + if (error instanceof TurnkeyError) throw error; throw new TurnkeyError( `Unable to log in with the provided passkey`, TurnkeyErrorCodes.PASSKEY_LOGIN_AUTH_ERROR, @@ -419,12 +424,7 @@ export class TurnkeyClient { return sessionResponse.session; } catch (error: unknown) { - if ( - error instanceof TurnkeyError && - error.code === TurnkeyErrorCodes.SELECT_PASSKEY_CANCELLED - ) { - throw error; // Re-throw the specific cancellation error - } + if (error instanceof TurnkeyError) throw error; throw new TurnkeyError( `Failed to sign up with passkey`, TurnkeyErrorCodes.PASSKEY_SIGNUP_AUTH_ERROR, @@ -465,17 +465,27 @@ export class TurnkeyClient { }); if (!otpRes.ok) { + const errorText = await otpRes.text(); + if (errorText.includes("Max number of OTPs have been initiated")) { + throw new TurnkeyNetworkError( + "Max number of OTPs have been initiated", + otpRes.status, + TurnkeyErrorCodes.MAX_OTP_INITIATED_ERROR, + errorText, + ); + } throw new TurnkeyNetworkError( `OTP initialization failed`, otpRes.status, TurnkeyErrorCodes.INIT_OTP_ERROR, - await otpRes.text(), + errorText, ); } const initOtpRes: v1InitOtpResult = await otpRes.json(); return initOtpRes.otpId; } catch (error) { + if (error instanceof TurnkeyError) throw error; throw new TurnkeyError( `Failed to initialize OTP`, TurnkeyErrorCodes.INIT_OTP_ERROR, @@ -530,7 +540,8 @@ export class TurnkeyClient { ); if (!verifyRes.ok) { const error = await verifyRes.text(); - if (error.includes("invalid OTP")) { + console.log(error); + if (error.includes("Invalid OTP code")) { throw new TurnkeyNetworkError( "Invalid OTP code provided", verifyRes.status, @@ -560,6 +571,7 @@ export class TurnkeyClient { verificationToken: verifyOtpRes.verificationToken, }; } catch (error) { + if (error instanceof TurnkeyError) throw error; throw new TurnkeyError( `Failed to verify OTP`, TurnkeyErrorCodes.VERIFY_OTP_ERROR, @@ -625,6 +637,7 @@ export class TurnkeyClient { return loginRes.session; } catch (error) { + if (error instanceof TurnkeyError) throw error; // Clean up the generated key pair if it wasn't successfully used if (publicKey) { try { @@ -710,6 +723,7 @@ export class TurnkeyClient { ...(sessionKey && { sessionKey }), }); } catch (error) { + if (error instanceof TurnkeyError) throw error; throw new TurnkeyError( `Failed to sign up with OTP`, TurnkeyErrorCodes.OTP_SIGNUP_ERROR, @@ -778,6 +792,7 @@ export class TurnkeyClient { }); } } catch (error) { + if (error instanceof TurnkeyError) throw error; throw new TurnkeyError( `Failed to complete OTP process`, TurnkeyErrorCodes.OTP_COMPLETION_ERROR, @@ -849,6 +864,7 @@ export class TurnkeyClient { }); } } catch (error) { + if (error instanceof TurnkeyError) throw error; throw new TurnkeyError( `Failed to handle Google OAuth login`, TurnkeyErrorCodes.OAUTH_LOGIN_ERROR, @@ -920,6 +936,7 @@ export class TurnkeyClient { return loginRes.session; } catch (error) { + if (error instanceof TurnkeyError) throw error; // Clean up the generated key pair if it wasn't successfully used if (publicKey) { try { @@ -995,6 +1012,7 @@ export class TurnkeyClient { publicKey: publicKey!, }); } catch (error) { + if (error instanceof TurnkeyError) throw error; throw new TurnkeyError( `Failed to sign up with OAuth`, TurnkeyErrorCodes.OAUTH_SIGNUP_ERROR, @@ -1047,6 +1065,7 @@ export class TurnkeyClient { } return wallets; } catch (error) { + if (error instanceof TurnkeyError) throw error; throw new TurnkeyError( `Failed to fetch wallets`, TurnkeyErrorCodes.FETCH_WALLETS_ERROR, @@ -1088,6 +1107,7 @@ export class TurnkeyClient { return walletAccountRes as TGetWalletAccountsResponse; } catch (error) { + if (error instanceof TurnkeyError) throw error; throw new TurnkeyError( `Failed to fetch wallet accounts`, TurnkeyErrorCodes.FETCH_WALLET_ACCOUNTS_ERROR, @@ -1141,6 +1161,7 @@ export class TurnkeyClient { return response.activity.result .signRawPayloadResult as v1SignRawPayloadResult; } catch (error) { + if (error instanceof TurnkeyError) throw error; throw new TurnkeyError( `Failed to sign message: ${error}`, TurnkeyErrorCodes.SIGN_MESSAGE_ERROR, @@ -1167,6 +1188,7 @@ export class TurnkeyClient { stampWith, ); } catch (error) { + if (error instanceof TurnkeyError) throw error; throw new TurnkeyError( `Failed to sign transaction`, TurnkeyErrorCodes.SIGN_TRANSACTION_ERROR, @@ -1212,6 +1234,7 @@ export class TurnkeyClient { return userResponse.user as User; } catch (error) { + if (error instanceof TurnkeyError) throw error; throw new TurnkeyError( `Failed to fetch user`, TurnkeyErrorCodes.FETCH_USER_ERROR, @@ -1255,6 +1278,7 @@ export class TurnkeyClient { const user = await this.fetchUser(); return user; } catch (error) { + if (error instanceof TurnkeyError) throw error; throw new TurnkeyError( `Failed to update user`, TurnkeyErrorCodes.UPDATE_USER_ERROR, @@ -1309,6 +1333,7 @@ export class TurnkeyClient { } return res.walletId; } catch (error) { + if (error instanceof TurnkeyError) throw error; throw new TurnkeyError( `Failed to create wallet`, TurnkeyErrorCodes.CREATE_WALLET_ERROR, @@ -1350,6 +1375,7 @@ export class TurnkeyClient { } return res.addresses; } catch (error) { + if (error instanceof TurnkeyError) throw error; throw new TurnkeyError( `Failed to create wallet account`, TurnkeyErrorCodes.CREATE_WALLET_ACCOUNT_ERROR, @@ -1391,6 +1417,7 @@ export class TurnkeyClient { } return res.exportBundle as ExportBundle; } catch (error) { + if (error instanceof TurnkeyError) throw error; throw new TurnkeyError( `Failed to export wallet`, TurnkeyErrorCodes.EXPORT_WALLET_ERROR, @@ -1435,6 +1462,7 @@ export class TurnkeyClient { } return res.walletId; } catch (error) { + if (error instanceof TurnkeyError) throw error; throw new TurnkeyError( `Failed to import wallet`, TurnkeyErrorCodes.IMPORT_WALLET_ERROR, @@ -1462,6 +1490,7 @@ export class TurnkeyClient { stamperWith, ); } catch (error) { + if (error instanceof TurnkeyError) throw error; throw new TurnkeyError( `Failed to delete sub-organization`, TurnkeyErrorCodes.DELETE_SUB_ORGANIZATION_ERROR, @@ -1536,6 +1565,7 @@ export class TurnkeyClient { } return response as TCreateSubOrganizationResponse; } catch (error) { + if (error instanceof TurnkeyError) throw error; throw new TurnkeyError( `Failed to create sub-organization`, TurnkeyErrorCodes.CREATE_SUB_ORGANIZATION_ERROR, @@ -1558,6 +1588,7 @@ export class TurnkeyClient { await this.storageManager.storeSession(sessionToken, sessionKey); } catch (error) { + if (error instanceof TurnkeyError) throw error; throw new TurnkeyError( `Failed to store session`, TurnkeyErrorCodes.STORE_SESSION_ERROR, @@ -1582,6 +1613,7 @@ export class TurnkeyClient { ); } } catch (error) { + if (error instanceof TurnkeyError) throw error; throw new TurnkeyError( `Failed to delete session`, TurnkeyErrorCodes.CLEAR_SESSION_ERROR, @@ -1603,6 +1635,7 @@ export class TurnkeyClient { this.clearSession({ sessionKey }); } } catch (error) { + if (error instanceof TurnkeyError) throw error; throw new TurnkeyError( `Failed to clear all sessions`, TurnkeyErrorCodes.CLEAR_ALL_SESSIONS_ERROR, @@ -1681,6 +1714,7 @@ export class TurnkeyClient { } } } catch (error) { + if (error instanceof TurnkeyError) throw error; throw new TurnkeyError( `Failed to refresh session`, TurnkeyErrorCodes.REFRESH_SESSION_ERROR, @@ -1697,6 +1731,7 @@ export class TurnkeyClient { params || {}; return this.storageManager.getSession(sessionKey); } catch (error) { + if (error instanceof TurnkeyError) throw error; throw new TurnkeyError( `Failed to get session with key`, TurnkeyErrorCodes.GET_SESSION_ERROR, @@ -1720,6 +1755,7 @@ export class TurnkeyClient { } return sessions; } catch (error) { + if (error instanceof TurnkeyError) throw error; throw new TurnkeyError( `Failed to get all sessions`, TurnkeyErrorCodes.GET_ALL_SESSIONS_ERROR, @@ -1733,6 +1769,7 @@ export class TurnkeyClient { try { await this.storageManager.setActiveSessionKey(sessionKey); } catch (error) { + if (error instanceof TurnkeyError) throw error; throw new TurnkeyError( `Failed to set active session`, TurnkeyErrorCodes.SET_ACTIVE_SESSION_ERROR, @@ -1745,6 +1782,7 @@ export class TurnkeyClient { try { return await this.storageManager.getActiveSessionKey(); } catch (error) { + if (error instanceof TurnkeyError) throw error; throw new TurnkeyError( `Failed to get active session key`, TurnkeyErrorCodes.GET_ACTIVE_SESSION_KEY_ERROR, @@ -1783,6 +1821,7 @@ export class TurnkeyClient { } } } catch (error) { + if (error instanceof TurnkeyError) throw error; throw new TurnkeyError( `Failed to clear unused key pairs`, TurnkeyErrorCodes.CLEAR_UNUSED_KEY_PAIRS_ERROR, @@ -1815,6 +1854,7 @@ export class TurnkeyClient { return publicKey; } catch (error) { + if (error instanceof TurnkeyError) throw error; throw new TurnkeyError( `Failed to create API key pair`, TurnkeyErrorCodes.CREATE_API_KEY_PAIR_ERROR, @@ -1850,6 +1890,7 @@ export class TurnkeyClient { return (await res.json()) as v1GetWalletKitConfigResponse; } catch (error) { + if (error instanceof TurnkeyError) throw error; throw new TurnkeyError( `Failed to get auth proxy config`, TurnkeyErrorCodes.GET_PROXY_AUTH_CONFIG_ERROR, diff --git a/packages/sdk-types/src/index.ts b/packages/sdk-types/src/index.ts index d81ae737f..18a66ec20 100644 --- a/packages/sdk-types/src/index.ts +++ b/packages/sdk-types/src/index.ts @@ -64,6 +64,8 @@ export enum TurnkeyErrorCodes { CREATE_API_KEY_PAIR_ERROR = "CREATE_API_KEY_PAIR_ERROR", GET_PROXY_AUTH_CONFIG_ERROR = "GET_PROXY_AUTH_CONFIG_ERROR", + MAX_OTP_INITIATED_ERROR = "MAX_OTP_INITIATED_ERROR", + CLIENT_NOT_INITIALIZED = "CLIENT_NOT_INITIALIZED", INITIALIZE_CLIENT_ERROR = "INITIALIZE_CLIENT_ERROR", INITIALIZE_SESSION_ERROR = "INITIALIZE_SESSION_ERROR", From 5c8aa3a5ec6b926e4f56ab7da5fbe42d187df493 Mon Sep 17 00:00:00 2001 From: Ethan Konkolowicz Date: Tue, 8 Jul 2025 14:54:31 -0400 Subject: [PATCH 050/184] added import and export modals --- examples/with-sdk-js/src/app/layout.tsx | 2 + examples/with-sdk-js/src/app/page.tsx | 27 ++ packages/react-wallet-kit/package.json | 2 + .../src/components/export/ExportWarn.tsx | 102 ++++++++ .../src/components/export/index.tsx | 144 +++++++++++ .../src/components/import/index.tsx | 242 ++++++++++++++++++ .../src/providers/client/Provider.tsx | 54 ++++ packages/sdk-js/src/__clients__/core.ts | 2 +- packages/sdk-js/src/__types__/base.ts | 2 + packages/sdk-js/src/index.ts | 4 + packages/sdk-js/src/utils.ts | 1 - pnpm-lock.yaml | 18 +- 12 files changed, 597 insertions(+), 3 deletions(-) create mode 100644 packages/react-wallet-kit/src/components/export/ExportWarn.tsx create mode 100644 packages/react-wallet-kit/src/components/export/index.tsx create mode 100644 packages/react-wallet-kit/src/components/import/index.tsx diff --git a/examples/with-sdk-js/src/app/layout.tsx b/examples/with-sdk-js/src/app/layout.tsx index d32dfcea2..fa2a16c85 100644 --- a/examples/with-sdk-js/src/app/layout.tsx +++ b/examples/with-sdk-js/src/app/layout.tsx @@ -22,6 +22,8 @@ function RootLayout({ children }: RootLayoutProps) { authProxyUrl: process.env.NEXT_PUBLIC_AUTH_PROXY_URL!, authProxyId: process.env.NEXT_PUBLIC_AUTH_PROXY_ID!, organizationId: process.env.NEXT_PUBLIC_ORGANIZATION_ID!, + importIframeUrl: process.env.NEXT_PUBLIC_IMPORT_IFRAME_URL!, + exportIframeUrl: process.env.NEXT_PUBLIC_EXPORT_IFRAME_URL!, auth: { oAuthConfig: { googleClientId: process.env.NEXT_PUBLIC_GOOGLE_CLIENT_ID, diff --git a/examples/with-sdk-js/src/app/page.tsx b/examples/with-sdk-js/src/app/page.tsx index 117b80482..ea6f1864b 100644 --- a/examples/with-sdk-js/src/app/page.tsx +++ b/examples/with-sdk-js/src/app/page.tsx @@ -36,6 +36,8 @@ export default function AuthPage() { createWallet, logout, setActiveSession, + handleExport, + handleImport, } = useTurnkey(); useEffect(() => { @@ -342,6 +344,31 @@ export default function AuthPage() { > Show Modal + + + + + {session ? ( + + + + + + = ({ config.passkeyConfig?.userVerification || "preferred", allowCredentials: config.passkeyConfig?.allowCredentials || [], }, + walletConfig: { + ethereum: config.walletConfig?.ethereum, + solana: config.walletConfig?.solana, + }, }); setAutoRefreshSession(config?.auth?.autoRefreshSession ?? false); @@ -735,6 +740,78 @@ export const ClientProvider: React.FC = ({ return res; } + function getWalletProviders(chain?: Chain): WalletProvider[] { + if (!client) { + throw new TurnkeyError( + "Client is not initialized.", + TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED, + ); + } + return client.getWalletProviders(chain); + } + + async function loginWithWallet(params: { + walletProvider: WalletProvider; + sessionType?: SessionType; + publicKey?: string; + sessionKey?: string; + }): Promise { + if (!client) { + throw new TurnkeyError( + "Client is not initialized.", + TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED, + ); + } + setAuthState(AuthState.Loading); + + const expirationSeconds = + masterConfig?.auth?.sessionExpirationSeconds?.passkey ?? + DEFAULT_SESSION_EXPIRATION_IN_SECONDS; + const res = await withTurnkeyErrorHandling( + () => client.loginWithWallet({ ...params, expirationSeconds }), + callbacks, + "Failed to login with wallet", + ); + if (res) { + await handlePostAuth(); + setAuthState(AuthState.Authenticated); + } else { + setAuthState(AuthState.Unauthenticated); + } + return res; + } + + async function signUpWithWallet(params: { + walletProvider: WalletProvider; + createSubOrgParams?: CreateSubOrgParams; + sessionType?: SessionType; + sessionKey?: string; + }): Promise { + if (!client) { + throw new TurnkeyError( + "Client is not initialized.", + TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED, + ); + } + setAuthState(AuthState.Loading); + + const expirationSeconds = + masterConfig?.auth?.sessionExpirationSeconds?.passkey ?? + DEFAULT_SESSION_EXPIRATION_IN_SECONDS; + const res = await withTurnkeyErrorHandling( + () => client.signUpWithWallet({ ...params, expirationSeconds }), + callbacks, + "Failed to sign up with wallet", + ); + if (res) { + await handlePostAuth(); + setAuthState(AuthState.Authenticated); + } else { + setAuthState(AuthState.Unauthenticated); + } + return res; + } + async function initOtp(params: { otpType: OtpType; contact: string; @@ -1160,7 +1237,7 @@ export const ClientProvider: React.FC = ({ customAccounts?: WalletAccount[]; wallet?: { publicKey: string; - type: WalletType; + type: Chain; }; }): Promise { if (!client) @@ -1945,6 +2022,9 @@ export const ClientProvider: React.FC = ({ logout, loginWithPasskey, signUpWithPasskey, + getWalletProviders, + loginWithWallet, + signUpWithWallet, initOtp, verifyOtp, loginWithOtp, diff --git a/packages/sdk-js/scripts/codegen.js b/packages/sdk-js/scripts/codegen.js index 2f61a3799..42f3753f2 100644 --- a/packages/sdk-js/scripts/codegen.js +++ b/packages/sdk-js/scripts/codegen.js @@ -280,6 +280,8 @@ const generateSDKClientFromSwagger = async (swaggerSpec, targetPath) => { // Store stampers private apiKeyStamper?: TStamper | undefined; private passkeyStamper?: TStamper | undefined; + private walletStamper?: TStamper | undefined; + // Storage manager private storageManager?: StorageBase | undefined; @@ -293,19 +295,24 @@ const generateSDKClientFromSwagger = async (swaggerSpec, targetPath) => { if (config.passkeyStamper) { this.passkeyStamper = config.passkeyStamper; } + if (config.walletStamper) { + this.walletStamper = config.walletStamper; + } if (config.storageManager) { this.storageManager = config.storageManager; } } private getStamper(stampWith?: StamperType): TStamper | undefined { - if (!stampWith) return this.apiKeyStamper || this.passkeyStamper; + if (!stampWith) return this.apiKeyStamper || this.passkeyStamper || this.walletStamper; switch (stampWith) { case StamperType.ApiKey: return this.apiKeyStamper; case StamperType.Passkey: return this.passkeyStamper; + case StamperType.Wallet: + return this.walletStamper; default: return this.apiKeyStamper; } diff --git a/packages/sdk-js/src/__clients__/core.ts b/packages/sdk-js/src/__clients__/core.ts index a36abb25a..0690389ce 100644 --- a/packages/sdk-js/src/__clients__/core.ts +++ b/packages/sdk-js/src/__clients__/core.ts @@ -36,6 +36,7 @@ import { OtpType, OtpTypeToFilterTypeMap, CreateSubOrgParams, + Chain, } from "@types"; // AHHHH, SDK-TYPES import { generateWalletAccountsFromAddressFormat, @@ -52,11 +53,12 @@ import { } from "../__storage__/base"; import { CrossPlatformApiKeyStamper } from "../__stampers__/api/base"; import { CrossPlatformPasskeyStamper } from "../__stampers__/passkey/base"; +import { CrossPlatformWalletStamper } from "../__stampers__/wallet/base"; import { DEFAULT_ETHEREUM_ACCOUNTS, DEFAULT_SOLANA_ACCOUNTS, } from "../turnkey-helpers"; -import { WalletType } from "@turnkey/wallet-stamper"; +import { WalletProvider, WalletType } from "@turnkey/wallet-stamper"; type PublicMethods = { [K in keyof T as K extends string | number | symbol @@ -84,6 +86,7 @@ export class TurnkeyClient { private apiKeyStamper?: CrossPlatformApiKeyStamper | undefined; // TODO (Amir): TEMPORARILY PUBLIC, MAKE PRIVATE LATER private passkeyStamper?: CrossPlatformPasskeyStamper | undefined; + private walletStamper?: CrossPlatformWalletStamper | undefined; private storageManager!: StorageBase; constructor( @@ -92,12 +95,14 @@ export class TurnkeyClient { // Users can pass in their own stampers, or we will create them. Should we remove this? apiKeyStamper?: CrossPlatformApiKeyStamper, passkeyStamper?: CrossPlatformPasskeyStamper, + walletStamper?: CrossPlatformWalletStamper, ) { this.config = config; // Just store any explicitly provided stampers this.apiKeyStamper = apiKeyStamper; this.passkeyStamper = passkeyStamper; + this.walletStamper = walletStamper; // Actual initialization will happen in init() } @@ -118,10 +123,21 @@ export class TurnkeyClient { await this.passkeyStamper.init(); } + if ( + this.config.walletConfig?.ethereum || + this.config.walletConfig?.solana + ) { + this.walletStamper = new CrossPlatformWalletStamper( + this.config.walletConfig, + ); + await this.walletStamper.init(); + } + // Initialize the HTTP client with the appropriate stampers this.httpClient = new TurnkeySDKClientBase({ apiKeyStamper: this.apiKeyStamper, passkeyStamper: this.passkeyStamper!, + walletStamper: this.walletStamper!, storageManager: this.storageManager, ...this.config, }); @@ -447,6 +463,206 @@ export class TurnkeyClient { } }; + getWalletProviders = (chain?: Chain): WalletProvider[] => { + try { + if (!this.walletStamper) { + throw new Error("Wallet stamper is not initialized"); + } + + return this.walletStamper.getProviders(chain); + } catch (error) { + throw new Error(`Unable to get wallet providers: ${error}`); + } + }; + + loginWithWallet = async (params: { + walletProvider: WalletProvider; + sessionType?: SessionType; + publicKey?: string; + sessionKey?: string; + expirationSeconds?: string; + }): Promise => { + if (!this.walletStamper) { + throw new Error("Wallet stamper is not initialized"); + } + + try { + const sessionType = params.sessionType || SessionType.READ_WRITE; + const publicKey = + params.publicKey || (await this.apiKeyStamper?.createKeyPair()); + const sessionKey = params.sessionKey || SessionKey.DefaultSessionkey; + const walletProvider = params.walletProvider; + + const expirationSeconds = + params?.expirationSeconds || DEFAULT_SESSION_EXPIRATION_IN_SECONDS; + + if (sessionType === SessionType.READ_WRITE) { + if (!publicKey) { + throw new Error( + "You must provide a publicKey to create a wallet read write session.", + ); + } + + this.walletStamper?.setProvider( + walletProvider.type, + walletProvider.provider, + ); + + const sessionResponse = await this.httpClient.stampLogin( + { + publicKey, + organizationId: this.config.organizationId, + expirationSeconds, + }, + StamperType.Wallet, + ); + + await this.storeSession({ + sessionToken: sessionResponse.session, + sessionKey, + }); + + return sessionResponse.session; + } else { + throw new Error(`Invalid session type passed: ${sessionType}`); + } + } catch (error) { + throw new Error(`Unable to log in with the provided wallet: ${error}`); + } + }; + + signUpWithWallet = async (params: { + walletProvider: WalletProvider; + createSubOrgParams?: CreateSubOrgParams; + sessionType?: SessionType; + sessionKey?: string; + expirationSeconds?: string; + }): Promise => { + const { + walletProvider, + createSubOrgParams, + sessionType = SessionType.READ_WRITE, + sessionKey = SessionKey.DefaultSessionkey, + expirationSeconds = DEFAULT_SESSION_EXPIRATION_IN_SECONDS, + } = params; + + if (!this.walletStamper) { + throw new Error("Wallet stamper is not initialized"); + } + + let generatedKeyPair = null; + try { + generatedKeyPair = await this.apiKeyStamper?.createKeyPair(); + + this.walletStamper?.setProvider( + walletProvider.type, + walletProvider.provider, + ); + + const publicKey = await this.walletStamper?.getPublicKey( + walletProvider.type, + walletProvider.provider, + ); + + if (!publicKey) { + throw new Error("Failed to get publicKey from wallet"); + } + + const { type } = this.walletStamper!.getWalletInterface( + walletProvider?.type, + ); + + // Build the request body for OTP init + const signUpBody = { + userName: + createSubOrgParams?.userName || + createSubOrgParams?.userEmail || + `user-${Date.now()}`, + userEmail: createSubOrgParams?.userEmail, + userPhoneNumber: createSubOrgParams?.userPhoneNumber, + userTag: createSubOrgParams?.userTag, + subOrgName: createSubOrgParams?.subOrgName || `sub-org-${Date.now()}`, + apiKeys: [ + { + apiKeyName: `wallet-auth:${publicKey}`, + publicKey: publicKey, + curveType: + type === WalletType.Ethereum + ? ("API_KEY_CURVE_SECP256K1" as const) + : ("API_KEY_CURVE_ED25519" as const), + }, + { + apiKeyName: `wallet-auth-${generatedKeyPair}`, + publicKey: generatedKeyPair, + curveType: "API_KEY_CURVE_P256", + expirationSeconds: "60", + }, + ], + oauthProviders: createSubOrgParams?.oauthProviders, + ...(createSubOrgParams?.customWallet && { + wallet: { + walletName: createSubOrgParams?.customWallet.walletName, + accounts: createSubOrgParams?.customWallet.walletAccounts, + }, + }), + }; + + // Set up headers, including X-Proxy-ID if needed + const headers: Record = { + "Content-Type": "application/json", + }; + if (this.config.authProxyId) { + headers["X-Proxy-ID"] = this.config.authProxyId; + } + + const res = await fetch(`${this.config.authProxyUrl}/v1/signup`, { + method: "POST", + headers, + body: JSON.stringify(signUpBody), + }); + + if (!res.ok) { + const errorText = await res.text(); + throw new Error(`Sign up failed: ${res.status} ${errorText}`); + } + + const newGeneratedKeyPair = await this.apiKeyStamper?.createKeyPair(); + this.apiKeyStamper?.setPublicKeyOverride(generatedKeyPair!); + + const sessionResponse = await this.httpClient.stampLogin({ + publicKey: newGeneratedKeyPair!, + organizationId: this.config.organizationId, + expirationSeconds, + }); + + await this.apiKeyStamper?.deleteKeyPair(generatedKeyPair!); + + await this.storeSession({ + sessionToken: sessionResponse.session, + sessionKey, + }); + + generatedKeyPair = null; // Key pair was successfully used, set to null to prevent cleanup + + return sessionResponse.session; + } catch (error) { + throw new Error(`Failed to sign up with wallet: ${error}`); + } finally { + // Clean up the generated key pair if it wasn't successfully used + console.log("Cleaning up generated key pair if any"); + this.apiKeyStamper?.clearOverridePublicKey(); + if (generatedKeyPair) { + try { + await this.apiKeyStamper?.deleteKeyPair(generatedKeyPair); + } catch (cleanupError) { + throw new Error( + `Failed to clean up generated key pair: ${cleanupError}`, + ); + } + } + } + }; + initOtp = async (params: { otpType: OtpType; contact: string; @@ -1509,7 +1725,7 @@ export class TurnkeyClient { customAccounts?: WalletAccount[]; wallet?: { publicKey: string; - type: WalletType; + type: Chain; }; }): Promise => { const { diff --git a/packages/sdk-js/src/__generated__/sdk-client-base.ts b/packages/sdk-js/src/__generated__/sdk-client-base.ts index d83aff838..1bebffe39 100644 --- a/packages/sdk-js/src/__generated__/sdk-client-base.ts +++ b/packages/sdk-js/src/__generated__/sdk-client-base.ts @@ -32,6 +32,7 @@ export class TurnkeySDKClientBase { // Store stampers private apiKeyStamper?: TStamper | undefined; private passkeyStamper?: TStamper | undefined; + private walletStamper?: TStamper | undefined; // Storage manager private storageManager?: StorageBase | undefined; @@ -45,19 +46,25 @@ export class TurnkeySDKClientBase { if (config.passkeyStamper) { this.passkeyStamper = config.passkeyStamper; } + if (config.walletStamper) { + this.walletStamper = config.walletStamper; + } if (config.storageManager) { this.storageManager = config.storageManager; } } private getStamper(stampWith?: StamperType): TStamper | undefined { - if (!stampWith) return this.apiKeyStamper || this.passkeyStamper; + if (!stampWith) + return this.apiKeyStamper || this.passkeyStamper || this.walletStamper; switch (stampWith) { case StamperType.ApiKey: return this.apiKeyStamper; case StamperType.Passkey: return this.passkeyStamper; + case StamperType.Wallet: + return this.walletStamper; default: return this.apiKeyStamper; } diff --git a/packages/sdk-js/src/__stampers__/wallet/base.ts b/packages/sdk-js/src/__stampers__/wallet/base.ts new file mode 100644 index 000000000..96c8d3e4d --- /dev/null +++ b/packages/sdk-js/src/__stampers__/wallet/base.ts @@ -0,0 +1,109 @@ +import { isWeb, isReactNative } from "@utils"; +import { + EthereumWallet, + SolanaWallet, + WalletInterface, + WalletProvider, + WalletRpcProvider, + WalletStamper, + WalletType, +} from "@turnkey/wallet-stamper"; +import { TStamp, TStamper } from "../.."; + +export type TWalletStamperConfig = { + ethereum?: boolean; + solana?: boolean; +}; + +interface WalletContext { + wallet: WalletInterface; + stamper: WalletStamper; + + // we set this later using setProvider() + provider?: WalletRpcProvider; +} + +type ContextMap = Partial>; + +export class CrossPlatformWalletStamper implements TStamper { + private readonly ctx: ContextMap = {}; + private activeChain?: WalletType; + + constructor(private readonly cfg: TWalletStamperConfig) {} + + async init(): Promise { + if (!isWeb()) { + if (isReactNative()) { + throw new Error("WalletStamper isn’t available on React Native (yet)"); + } + throw new Error("Unsupported runtime"); + } + + const add = (chain: WalletType, wallet: WalletInterface) => { + this.ctx[chain] = { + wallet, + stamper: new WalletStamper(wallet), + }; + }; + + if (this.cfg.ethereum) add(WalletType.Ethereum, new EthereumWallet()); + if (this.cfg.solana) add(WalletType.Solana, new SolanaWallet()); + + if (!Object.keys(this.ctx).length) { + throw new Error("No chains enabled in CrossPlatformWalletStamper config"); + } + } + + async stamp( + payload: string, + chain: WalletType = this.defaultChain(), + provider?: WalletRpcProvider, + ): Promise { + const c = this.getCtx(chain); + const p = provider ?? c.provider; + + if (!p) { + throw new Error(`Could not find a provider for chain '${chain}'.`); + } + + return c.stamper.stamp(payload, p); + } + + async getPublicKey( + chain: WalletType = this.defaultChain(), + provider: WalletRpcProvider, + ): Promise { + const c = this.getCtx(chain); + return c.wallet.getPublicKey(provider); + } + + getProviders(chain?: WalletType): WalletProvider[] { + if (chain) { + return this.getCtx(chain).wallet.getProviders(); + } + return Object.values(this.ctx).flatMap((c) => c.wallet.getProviders()); + } + + setProvider(chain: WalletType, provider: WalletRpcProvider): void { + this.getCtx(chain).provider = provider; + this.activeChain = chain; + } + + getWalletInterface(chain: WalletType = this.defaultChain()): WalletInterface { + return this.getCtx(chain).wallet; + } + + // ETH wins tie-break + private defaultChain(): WalletType { + if (this.activeChain) return this.activeChain; + if (this.cfg.ethereum) return WalletType.Ethereum; + if (this.cfg.solana) return WalletType.Solana; + throw new Error("No chains enabled"); + } + + private getCtx(chain: WalletType): WalletContext { + const c = this.ctx[chain]; + if (!c) throw new Error(`Chain '${chain}' not initialised`); + return c; + } +} diff --git a/packages/sdk-js/src/__types__/base.ts b/packages/sdk-js/src/__types__/base.ts index 785e953a0..1d4c3f13d 100644 --- a/packages/sdk-js/src/__types__/base.ts +++ b/packages/sdk-js/src/__types__/base.ts @@ -1,5 +1,5 @@ import type { TActivityId, TActivityStatus } from "@turnkey/http"; -import type { WalletStamper } from "@turnkey/wallet-stamper"; +import type { WalletStamper, WalletType } from "@turnkey/wallet-stamper"; import type { WebauthnStamper } from "@turnkey/webauthn-stamper"; import type { IndexedDbStamper } from "@turnkey/indexed-db-stamper"; import type { @@ -11,6 +11,7 @@ import type { } from "@turnkey/sdk-types"; import { StorageBase } from "../__storage__/base"; import { TPasskeyStamperConfig } from "../__stampers__/passkey/base"; +import { TWalletStamperConfig } from "../__stampers__/wallet/base"; // TODO (Amir): Get all this outta here and move to sdk-types. Or not, we could just have everything in this package @@ -114,6 +115,7 @@ export interface TurnkeyHttpClientConfig { activityPoller?: TActivityPollerConfig | undefined; apiKeyStamper?: TStamper | undefined; passkeyStamper?: TStamper | undefined; + walletStamper?: TStamper | undefined; storageManager?: StorageBase | undefined; readOnlySession?: string | undefined; // TODO (Amir): Shouldn't this be getten from the storage manager? } @@ -127,6 +129,7 @@ export interface TurnkeySDKClientConfig { importIframeUrl: string; passkeyConfig?: TPasskeyStamperConfig; + walletConfig?: TWalletStamperConfig; } export type Stamper = WebauthnStamper | WalletStamper | IndexedDbStamper; @@ -217,6 +220,7 @@ export enum AuthClient { export enum StamperType { ApiKey = "api-key", Passkey = "passkey", + Wallet = "wallet", } export enum OtpType { @@ -229,6 +233,8 @@ export enum FilterType { Sms = "SMS", } +export type Chain = WalletType; + export const OtpTypeToFilterTypeMap = { [OtpType.Email]: FilterType.Email, [OtpType.Sms]: FilterType.Sms, diff --git a/packages/wallet-stamper/package.json b/packages/wallet-stamper/package.json index d2cd6d7fa..d93874453 100644 --- a/packages/wallet-stamper/package.json +++ b/packages/wallet-stamper/package.json @@ -50,7 +50,9 @@ }, "dependencies": { "@turnkey/crypto": "workspace:*", - "@turnkey/encoding": "workspace:*" + "@turnkey/encoding": "workspace:*", + "@wallet-standard/app": "^1.1.0", + "@wallet-standard/base": "^1.1.0" }, "optionalDependencies": { "viem": "^2.21.35" diff --git a/packages/wallet-stamper/src/ethereum.ts b/packages/wallet-stamper/src/ethereum.ts index 01ab52f0f..3691f8aca 100644 --- a/packages/wallet-stamper/src/ethereum.ts +++ b/packages/wallet-stamper/src/ethereum.ts @@ -1,4 +1,10 @@ -import { EthereumWalletInterface, WalletType } from "./types"; +import { + EthereumWalletInterface, + WalletProvider, + WalletProviderInfo, + WalletRpcProvider, + WalletType, +} from "./types"; import { recoverPublicKey, hashMessage, @@ -10,6 +16,7 @@ import "viem/window"; import { WalletStamperError } from "./errors"; import { compressRawPublicKey } from "@turnkey/crypto"; +import { asEip1193 } from "./utils"; /** * Abstract class representing a base Ethereum wallet. @@ -28,20 +35,64 @@ export abstract class BaseEthereumWallet implements EthereumWalletInterface { * Must be implemented by subclasses to provide a custom signing function. * * @param message - The message to be signed, either as a string or a Hex. + * @param provider - Optional Ethereum provider to use for signing. * @returns A promise that resolves to a Hex string representing the signature. */ - abstract signMessage(message: string | Hex): Promise; + abstract signMessage( + message: string | Hex, + provider: WalletRpcProvider, + ): Promise; /** * Retrieves the public key associated with the wallet. * + * @param provider - Optional Ethereum provider to use for signing. * @returns A promise that resolves to a string representing the compressed public key. */ - async getPublicKey(): Promise { + async getPublicKey(provider: WalletRpcProvider): Promise { const message = "GET_PUBLIC_KEY"; - const signature = await this.signMessage(message); + const signature = await this.signMessage(message, provider); return getCompressedPublicKey(signature, message); } + + /** + * Retrieves the Ethereum provider from the window object. + * + * @returns The WalletProvider instance. + * + * This method checks if the Ethereum provider is available in the + * window object and throws an error if not found. + */ + getProviders(): WalletProvider[] { + const discovered: WalletProvider[] = []; + + type AnnounceEvent = CustomEvent<{ + info: WalletProviderInfo; + provider: WalletRpcProvider; + }>; + + const handler = (ev: AnnounceEvent): void => { + discovered.push({ + type: WalletType.Ethereum, + info: ev.detail.info, + provider: ev.detail.provider, + }); + }; + + window.addEventListener( + "eip6963:announceProvider", + handler as EventListener, + ); + + window.dispatchEvent(new Event("eip6963:requestProvider")); + + window.removeEventListener( + "eip6963:announceProvider", + handler as EventListener, + ); + + return discovered.length ? discovered : []; + } } /** @@ -58,15 +109,17 @@ export class EthereumWallet extends BaseEthereumWallet { * Signs a message using the Ethereum provider. * * @param message - The message to be signed, either as a string or a Hex. + * @param provider - Optional Ethereum provider to use. * @returns A promise that resolves to a Hex string representing the signature. * * This method uses the 'personal_sign' method of the Ethereum provider * to sign the message with the user's account. */ - async signMessage(message: string | Hex) { - const account = await this.getAccount(); + async signMessage(message: string | Hex, provider: WalletRpcProvider) { + const selectedProvider = asEip1193(provider); + const account = await this.getAccount(selectedProvider); - const signature = await this.getProvider().request({ + const signature = await selectedProvider.request({ method: "personal_sign" as const, params: [message as Hex, account], }); @@ -74,34 +127,17 @@ export class EthereumWallet extends BaseEthereumWallet { return signature; } - /** - * Retrieves the Ethereum provider from the window object. - * - * @returns The EIP1193Provider instance. - * - * This method checks if the Ethereum provider is available in the - * window object and throws an error if not found. - */ - private getProvider(): EIP1193Provider { - if (!window?.ethereum) { - throw new WalletStamperError("No ethereum provider found"); - } - - return window.ethereum; - } - /** * Requests the user's Ethereum account from the provider. * + * @param provider - The EIP1193 provider to request accounts from. * @returns A promise that resolves to the user's Ethereum address. * * This method uses the 'eth_requestAccounts' method of the Ethereum * provider to request access to the user's account. It throws an error * if no account is connected. */ - private async getAccount(): Promise
{ - const provider = this.getProvider(); - + private async getAccount(provider: EIP1193Provider): Promise
{ const [connectedAccount] = await provider.request({ method: "eth_requestAccounts", }); @@ -114,6 +150,13 @@ export class EthereumWallet extends BaseEthereumWallet { } } +/** + * Recovers and compresses the SECP256K1 public key from a signed message. + * + * @param signature - Hex string of the signature. + * @param message - The original signed message. + * @returns A promise that resolves to the compressed public key as a hex string. + */ export const getCompressedPublicKey = async ( signature: Hex, message: string, diff --git a/packages/wallet-stamper/src/index.ts b/packages/wallet-stamper/src/index.ts index 3f2bf2c6b..f8ac340ca 100644 --- a/packages/wallet-stamper/src/index.ts +++ b/packages/wallet-stamper/src/index.ts @@ -3,3 +3,4 @@ export * from "./errors"; export * from "./types"; export * from "./stamper"; export * from "./ethereum"; +export * from "./solana"; diff --git a/packages/wallet-stamper/src/solana.ts b/packages/wallet-stamper/src/solana.ts new file mode 100644 index 000000000..e18d1a471 --- /dev/null +++ b/packages/wallet-stamper/src/solana.ts @@ -0,0 +1,181 @@ +import { + WalletRpcProvider, + SolanaWalletInterface, + WalletType, + WalletProvider, +} from "./types"; + +import { WalletStamperError } from "./errors"; +import { Wallet as SWSWallet } from "@wallet-standard/base"; +import { getWallets } from "@wallet-standard/app"; +import { asSolana } from "./utils"; +import { PublicKey } from "@solana/web3.js"; + +declare global { + interface Window { + solana?: SWSWallet; + } + + interface Navigator { + wallets?: { + get: () => SWSWallet[]; + }; + } +} + +/** + * Abstract class representing a base Solana wallet. + * This class is used for stamping requests with a Solana wallet. + * + * To use this class, extend it and implement the `signMessage` method + * to provide a custom signing function. The `signMessage` method should + * return a promise that resolves to a hexadecimal string representing + * the signature of the provided message. + */ +export abstract class BaseSolanaWallet implements SolanaWalletInterface { + readonly type: WalletType.Solana = WalletType.Solana; + + /** + * Abstract method to sign a message. + * Must be implemented by subclasses to provide a custom signing function. + * + * @param message - The message to be signed, either as a string or Uint8Array. + * @param provider - Optional Solana provider to use for signing. + * @returns A promise that resolves to a hex string representing the signature. + */ + abstract signMessage( + message: string | Uint8Array, + provider: WalletRpcProvider, + ): Promise; + + /** + * Retrieves the public key associated with the wallet. + * + * @param provider - Optional Solana provider to use. + * @returns A promise that resolves to the base58-encoded public key string. + * + * This method accesses the first available account on the wallet and returns its address. + */ + async getPublicKey(provider: WalletRpcProvider): Promise { + const wallet = asSolana(provider); + await ensureConnected(wallet); + const account = wallet.accounts[0]; + if (!account) { + throw new WalletStamperError("No account in wallet"); + } + + // Convert from Base58 to hex + const publicKeyBytes = new PublicKey(account.address).toBytes(); + const publicKeyHex = Buffer.from(publicKeyBytes).toString("hex"); + + return publicKeyHex; + } + + /** + * Retrieves available Solana wallet providers using Wallet Standard. + * + * @returns An array of WalletProvider objects representing Solana wallets. + */ + getProviders(): WalletProvider[] { + const walletsApi = getWallets(); + return walletsApi + .get() + .filter((w) => w.chains.some((c) => c.startsWith("solana:"))) + .map((w) => ({ + type: WalletType.Solana, + info: { name: w.name, icon: w.icon }, + provider: w, + })); + } +} + +/** + * SolanaWallet class extends the BaseSolanaWallet to provide + * specific implementations for Solana-based wallets. + * + * This class is responsible for signing messages using the + * Solana provider available in the browser. It interacts with + * the Wallet Standard provider to connect and sign messages. + */ +export class SolanaWallet extends BaseSolanaWallet { + /** + * Signs a message using the Solana provider. + * + * @param message - The message to be signed, either as a string or Uint8Array. + * @param provider - Optional Solana provider to use. + * @returns A promise that resolves to a hex string representing the signature. + * + * This method uses the 'solana:signMessage' feature of the wallet to sign messages. + */ + async signMessage( + message: string | Uint8Array, + provider: WalletRpcProvider, + ): Promise { + const wallet = asSolana(provider); + await ensureConnected(wallet); + + const data = + typeof message === "string" ? new TextEncoder().encode(message) : message; + + const solanaSignMessage = wallet.features["solana:signMessage"] as + | { + signMessage: (args: { + account: (typeof wallet.accounts)[0]; + message: Uint8Array; + }) => Promise< + readonly { + signedMessage: Uint8Array; + signature: Uint8Array; + }[] + >; + } + | undefined; + + if (!solanaSignMessage) { + throw new WalletStamperError( + "No supported signing methods found. Tried: solana:signMessage", + ); + } + + const account = wallet.accounts[0]; + if (!account) throw new WalletStamperError("No account available"); + + const results = await solanaSignMessage.signMessage({ + account, + message: data, + }); + + if (!results?.length || !results[0]?.signature) { + throw new WalletStamperError("No signature returned from signing"); + } + + return Array.from(results[0].signature) + .map((b) => b.toString(16).padStart(2, "0")) + .join(""); + } +} + +/** + * Ensures the wallet is connected using Wallet Standard's `standard:connect` feature. + * + * @param w - The Wallet Standard wallet instance. + * @returns A promise that resolves once the wallet is connected. + * + * Throws an error if no account is connected and the wallet doesn't support `standard:connect`. + */ +async function ensureConnected(w: SWSWallet): Promise { + if (w.accounts.length) return; + + const stdConnect = w.features["standard:connect"] as + | { connect: () => Promise<{ accounts: readonly unknown[] }> } + | undefined; + + if (stdConnect) { + await stdConnect.connect(); + return; + } + + throw new WalletStamperError( + "Wallet is not connected and does not implement standard:connect", + ); +} diff --git a/packages/wallet-stamper/src/stamper.ts b/packages/wallet-stamper/src/stamper.ts index dde0ac975..eba7cb3c3 100644 --- a/packages/wallet-stamper/src/stamper.ts +++ b/packages/wallet-stamper/src/stamper.ts @@ -1,10 +1,10 @@ import { stringToBase64urlString } from "@turnkey/encoding"; import { WalletStamperError } from "./errors"; import { - type TStamper, type WalletInterface, type TStamp, WalletType, + WalletRpcProvider, } from "./types"; import { SIGNATURE_SCHEME_TK_API_SECP256K1_EIP191, @@ -15,17 +15,17 @@ import type { Hex } from "viem"; // WalletStamper class implements the TStamper interface to use wallet's signature and public key // to authenticate requests to Turnkey. -export class WalletStamper implements TStamper { +export class WalletStamper { private wallet: WalletInterface; constructor(wallet: WalletInterface) { this.wallet = wallet; } - async stamp(payload: string): Promise { + async stamp(payload: string, provider: WalletRpcProvider): Promise { let signature: string; try { - signature = await this.wallet.signMessage(payload); + signature = await this.wallet.signMessage(payload, provider); } catch (error) { throw new WalletStamperError("Failed to sign the message", error); } @@ -61,7 +61,7 @@ export class WalletStamper implements TStamper { signature = toDerSignature(signature.replace("0x", "")); } else { // For Solana, we can directly use the public key. - publicKey = await this.wallet.getPublicKey(); + publicKey = await this.wallet.getPublicKey(provider); } } catch (error) { throw new WalletStamperError("Failed to recover public key", error); diff --git a/packages/wallet-stamper/src/types.ts b/packages/wallet-stamper/src/types.ts index c412d615c..a92b41c27 100644 --- a/packages/wallet-stamper/src/types.ts +++ b/packages/wallet-stamper/src/types.ts @@ -1,3 +1,6 @@ +import { EIP1193Provider } from "viem"; +import type { Wallet as SWSWallet } from "@wallet-standard/base"; + /** * @typedef {Object} TStamp * @property {'X-Stamp'} stampHeaderName - The name of the stamp header. @@ -23,9 +26,13 @@ export interface TStamper { * @property {function(): Promise} getPublicKey - Retrieves the public key as a string. */ export interface BaseWalletInterface { - type: WalletType.Ethereum | WalletType.Solana; - signMessage: (message: string) => Promise; - getPublicKey: () => Promise; + type: WalletType; + signMessage: ( + message: string, + provider: WalletRpcProvider, + ) => Promise; + getPublicKey: (provider: WalletRpcProvider) => Promise; + getProviders: () => WalletProvider[]; } /** @@ -54,16 +61,32 @@ export interface EthereumWalletInterface extends BaseWalletInterface { type: WalletType.Ethereum; } +export interface SolanaWalletInterface extends BaseWalletInterface { + type: WalletType.Solana; +} + /** * Union type for wallet interfaces, supporting both Solana and Ethereum wallets. * @typedef {SolanaWalletInterface | EthereumWalletInterface} WalletInterface */ export type WalletInterface = SolanaWalletInterface | EthereumWalletInterface; -/** - * Enum representing the type of wallet the user is stamping with. - */ +export type WalletRpcProvider = EIP1193Provider | SWSWallet; + +export interface WalletProviderInfo { + name: string; + uuid?: string; + icon?: string; + rdns?: string; +} + export enum WalletType { Ethereum = "ethereum", Solana = "solana", } + +export interface WalletProvider { + type: WalletType; + info: WalletProviderInfo; + provider: WalletRpcProvider; +} diff --git a/packages/wallet-stamper/src/utils.ts b/packages/wallet-stamper/src/utils.ts new file mode 100644 index 000000000..4f1d13213 --- /dev/null +++ b/packages/wallet-stamper/src/utils.ts @@ -0,0 +1,19 @@ +import { EIP1193Provider } from "viem"; +import type { Wallet as SWSWallet } from "@wallet-standard/base"; +import { WalletRpcProvider } from "./types"; + +export function asEip1193(p: WalletRpcProvider): EIP1193Provider { + if (p && typeof (p as any).request === "function") { + return p as EIP1193Provider; + } + + throw new Error("Expected an EIP-1193 provider (Ethereum wallet)"); +} + +export function asSolana(p: WalletRpcProvider): SWSWallet { + if (p && "features" in p && "solana:signMessage" in (p as any).features) { + return p as SWSWallet; + } + + throw new Error("Expected a Wallet-Standard provider (Solana wallet)"); +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 97e09d4a7..051c5d7a5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1321,6 +1321,9 @@ importers: '@turnkey/sdk-types': specifier: workspace:* version: link:../../packages/sdk-types + '@turnkey/wallet-stamper': + specifier: workspace:* + version: link:../../packages/wallet-stamper '@types/node': specifier: 20.3.1 version: 20.3.1 @@ -2148,7 +2151,7 @@ importers: specifier: workspace:* version: link:../sdk-types '@turnkey/wallet-stamper': - specifier: ^1.0.5 + specifier: workspace:* version: link:../wallet-stamper '@types/react': specifier: ^18.2.75 @@ -2523,6 +2526,19 @@ importers: '@turnkey/encoding': specifier: workspace:* version: link:../encoding +<<<<<<< HEAD +======= + '@wallet-standard/app': + specifier: ^1.1.0 + version: 1.1.0 + '@wallet-standard/base': + specifier: ^1.1.0 + version: 1.1.0 + optionalDependencies: + viem: + specifier: ^2.21.35 + version: 2.26.2(typescript@5.4.3) +>>>>>>> a7b03ea6 (refactored wallet stamper and added to sdk-js, and ewk) devDependencies: '@solana/web3.js': specifier: ^1.95.8 @@ -7250,16 +7266,386 @@ packages: '@solana/web3.js': ^1.98.0 bs58: ^6.0.0 +<<<<<<< HEAD '@solana/wallet-standard-wallet-adapter-react@1.1.4': resolution: {integrity: sha512-xa4KVmPgB7bTiWo4U7lg0N6dVUtt2I2WhEnKlIv0jdihNvtyhOjCKMjucWet6KAVhir6I/mSWrJk1U9SvVvhCg==} +======= + /@solana/wallet-adapter-saifu@0.1.15(@solana/web3.js@1.95.8): + resolution: {integrity: sha512-4nrziKQ+4QInh+COsICpNNUlUt456EJ60SZLxvG/z1AOGpatuzT0gN1+RdMcwHGUtiPBPCkEneUVhFZhhbMJlg==} + engines: {node: '>=16'} + peerDependencies: + '@solana/web3.js': ^1.77.3 + dependencies: + '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.95.8) + '@solana/web3.js': 1.95.8(encoding@0.1.13) + dev: false + + /@solana/wallet-adapter-salmon@0.1.14(@solana/web3.js@1.95.8): + resolution: {integrity: sha512-CMXdbhaj3prloCJwvxO7e1wfAyRd58QiPB8pjvB4GBbznyoSnHbFXmpxZrKX1Dk6FoJOGBgjB71xnreGcc6oMw==} + engines: {node: '>=16'} + peerDependencies: + '@solana/web3.js': ^1.77.3 + dependencies: + '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.95.8) + '@solana/web3.js': 1.95.8(encoding@0.1.13) + salmon-adapter-sdk: 1.1.1(@solana/web3.js@1.95.8) + dev: false + + /@solana/wallet-adapter-sky@0.1.15(@solana/web3.js@1.95.8): + resolution: {integrity: sha512-1vlk1/jnlOC/WfDDgDoUk3XtEhB3hq1fKtUb+xj0pVuSOg2Db+8ka9vPPYlVaKHoGvjm30iGGfr3ZrCxVfG6OQ==} + engines: {node: '>=16'} + peerDependencies: + '@solana/web3.js': ^1.77.3 + dependencies: + '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.95.8) + '@solana/web3.js': 1.95.8(encoding@0.1.13) + dev: false + + /@solana/wallet-adapter-solflare@0.6.28(@solana/web3.js@1.95.8): + resolution: {integrity: sha512-iiUQtuXp8p4OdruDawsm1dRRnzUCcsu+lKo8OezESskHtbmZw2Ifej0P99AbJbBAcBw7q4GPI6987Vh05Si5rw==} + engines: {node: '>=16'} + peerDependencies: + '@solana/web3.js': ^1.77.3 + dependencies: + '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.95.8) + '@solana/wallet-standard-chains': 1.1.0 + '@solana/web3.js': 1.95.8(encoding@0.1.13) + '@solflare-wallet/metamask-sdk': 1.0.3(@solana/web3.js@1.95.8) + '@solflare-wallet/sdk': 1.4.2(@solana/web3.js@1.95.8) + '@wallet-standard/wallet': 1.0.1 + dev: false + + /@solana/wallet-adapter-solong@0.9.18(@solana/web3.js@1.95.8): + resolution: {integrity: sha512-n40eemFUbJlOP+FKvn8rgq+YAOW51lEsn7uVz5ZjmiaW6MnRQniId9KkGYPPOUjytFyM+6/4x6IXI+QJknlSqA==} + engines: {node: '>=16'} + peerDependencies: + '@solana/web3.js': ^1.77.3 + dependencies: + '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.95.8) + '@solana/web3.js': 1.95.8(encoding@0.1.13) + dev: false + + /@solana/wallet-adapter-spot@0.1.15(@solana/web3.js@1.95.8): + resolution: {integrity: sha512-daU2iBTSJp1RGfQrB2uV06+2WHfeyW0uhjoJ3zTkz24kXqv5/ycoPHr8Gi2jkDSGMFkewnjWF8g0KMEzq2VYug==} + engines: {node: '>=16'} + peerDependencies: + '@solana/web3.js': ^1.77.3 + dependencies: + '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.95.8) + '@solana/web3.js': 1.95.8(encoding@0.1.13) + dev: false + + /@solana/wallet-adapter-tokenary@0.1.12(@solana/web3.js@1.95.8): + resolution: {integrity: sha512-iIsOzzEHfRfDUiwYy2BAVGeMl+xBUu92qYK1yAKeKxQPF5McJrnjS3FXwT/onBU5WMdxI6dWm0HKZUiDwefN6A==} + engines: {node: '>=16'} + peerDependencies: + '@solana/web3.js': ^1.77.3 + dependencies: + '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.95.8) + '@solana/web3.js': 1.95.8(encoding@0.1.13) + dev: false + + /@solana/wallet-adapter-tokenpocket@0.4.19(@solana/web3.js@1.95.8): + resolution: {integrity: sha512-zKXTN+tuKIr/stSxUeG9XPBks9iqeliBWS9JF8eq+8u/Qb/bIDbNSQmd8Z5u1x2lf0puiStc9/iUu/+MLaOSVg==} + engines: {node: '>=16'} + peerDependencies: + '@solana/web3.js': ^1.77.3 + dependencies: + '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.95.8) + '@solana/web3.js': 1.95.8(encoding@0.1.13) + dev: false + + /@solana/wallet-adapter-torus@0.11.28(@babel/runtime@7.26.10)(@solana/web3.js@1.95.8): + resolution: {integrity: sha512-bu1oJQ+AoIZICxz8J1lVcdL+iBBrdbynnEs5N6dxwoM/cMGLbX7PGYqaH0J1dEXisA+1H5AzGAnW4UU05VBmLA==} + engines: {node: '>=16'} + peerDependencies: + '@solana/web3.js': ^1.77.3 + dependencies: + '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.95.8) + '@solana/web3.js': 1.95.8(encoding@0.1.13) + '@toruslabs/solana-embed': 0.3.4(@babel/runtime@7.26.10) + assert: 2.1.0 + crypto-browserify: 3.12.0 + process: 0.11.10 + stream-browserify: 3.0.0 + transitivePeerDependencies: + - '@babel/runtime' + - '@sentry/types' + - bufferutil + - encoding + - supports-color + - utf-8-validate + dev: false + + /@solana/wallet-adapter-trezor@0.1.2(@babel/core@7.26.9)(@solana/web3.js@1.95.8)(react-native@0.76.5)(tslib@2.8.1): + resolution: {integrity: sha512-x4nXntYi1SIv63ZdXWX/Rq/VKwguByKu67WpyUXsu8kOdviksb20bQMuAR7Ue41oJ9zSnLlTxAxA1SuWNkFRBg==} + engines: {node: '>=16'} + peerDependencies: + '@solana/web3.js': ^1.77.3 + dependencies: + '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.95.8) + '@solana/web3.js': 1.95.8(encoding@0.1.13) + '@trezor/connect-web': 9.3.0(@babel/core@7.26.9)(react-native@0.76.5)(tslib@2.8.1) + buffer: 6.0.3 + transitivePeerDependencies: + - '@babel/core' + - bufferutil + - encoding + - expo-constants + - expo-localization + - react-native + - supports-color + - tslib + - utf-8-validate + dev: false + + /@solana/wallet-adapter-trust@0.1.13(@solana/web3.js@1.95.8): + resolution: {integrity: sha512-lkmPfNdyRgx+z0K7i2cDa3a6SOKXpi3FiaYSo8Zozoxkp+Ga/NXVWxlXtMca4GAc/MnJMVp7yF/31kyFIee+3A==} + engines: {node: '>=16'} + peerDependencies: + '@solana/web3.js': ^1.77.3 + dependencies: + '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.95.8) + '@solana/web3.js': 1.95.8(encoding@0.1.13) + dev: false + + /@solana/wallet-adapter-unsafe-burner@0.1.7(@solana/web3.js@1.95.8): + resolution: {integrity: sha512-SuBVqQxA1NNUwP4Lo70rLPaM8aWkV1EFAlxkRoRLtwyw/gM8bxTO6+9EVyKCv+ix3yw1rCGIF3B0idXx0i37eQ==} + engines: {node: '>=16'} + peerDependencies: + '@solana/web3.js': ^1.77.3 + dependencies: + '@noble/curves': 1.9.0 + '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.95.8) + '@solana/wallet-standard-features': 1.2.0 + '@solana/wallet-standard-util': 1.1.1 + '@solana/web3.js': 1.95.8(encoding@0.1.13) + dev: false + + /@solana/wallet-adapter-walletconnect@0.1.16(@solana/web3.js@1.95.8): + resolution: {integrity: sha512-jNaQwSho8hT7gF1ifePE8TJc1FULx8jCF16KX3fZPtzXDxKrj0R4VUpHMGcw4MlDknrnZNLOJAVvyiawAkPCRQ==} + engines: {node: '>=16'} + peerDependencies: + '@solana/web3.js': ^1.77.3 + dependencies: + '@jnwng/walletconnect-solana': 0.2.0(@solana/web3.js@1.95.8) + '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.95.8) + '@solana/web3.js': 1.95.8(encoding@0.1.13) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/kv' + - bufferutil + - encoding + - ioredis + - uWebSockets.js + - utf-8-validate + dev: false + + /@solana/wallet-adapter-wallets@0.19.32(@babel/core@7.26.9)(@babel/runtime@7.26.10)(@solana/web3.js@1.95.8)(bs58@6.0.0)(react-dom@18.3.1)(react-native@0.76.5)(react@18.3.1)(tslib@2.8.1): + resolution: {integrity: sha512-voZYQiIy1yXuKvm7x7YpnQ53eiJC7NpIYSQjzApOUiswiBRVeYcnPO4O/MMPUwsGkS7iZKqKZjo5CnOaN44n+g==} + engines: {node: '>=16'} + peerDependencies: + '@solana/web3.js': ^1.77.3 + dependencies: + '@solana/wallet-adapter-alpha': 0.1.10(@solana/web3.js@1.95.8) + '@solana/wallet-adapter-avana': 0.1.13(@solana/web3.js@1.95.8) + '@solana/wallet-adapter-bitkeep': 0.3.20(@solana/web3.js@1.95.8) + '@solana/wallet-adapter-bitpie': 0.5.18(@solana/web3.js@1.95.8) + '@solana/wallet-adapter-clover': 0.4.19(@solana/web3.js@1.95.8) + '@solana/wallet-adapter-coin98': 0.5.20(@solana/web3.js@1.95.8) + '@solana/wallet-adapter-coinbase': 0.1.19(@solana/web3.js@1.95.8) + '@solana/wallet-adapter-coinhub': 0.3.18(@solana/web3.js@1.95.8) + '@solana/wallet-adapter-fractal': 0.1.8(@solana/web3.js@1.95.8)(react-dom@18.3.1)(react@18.3.1) + '@solana/wallet-adapter-huobi': 0.1.15(@solana/web3.js@1.95.8) + '@solana/wallet-adapter-hyperpay': 0.1.14(@solana/web3.js@1.95.8) + '@solana/wallet-adapter-keystone': 0.1.15(@solana/web3.js@1.95.8) + '@solana/wallet-adapter-krystal': 0.1.12(@solana/web3.js@1.95.8) + '@solana/wallet-adapter-ledger': 0.9.25(@solana/web3.js@1.95.8) + '@solana/wallet-adapter-mathwallet': 0.9.18(@solana/web3.js@1.95.8) + '@solana/wallet-adapter-neko': 0.2.12(@solana/web3.js@1.95.8) + '@solana/wallet-adapter-nightly': 0.1.16(@solana/web3.js@1.95.8) + '@solana/wallet-adapter-nufi': 0.1.17(@solana/web3.js@1.95.8) + '@solana/wallet-adapter-onto': 0.1.7(@solana/web3.js@1.95.8) + '@solana/wallet-adapter-particle': 0.1.12(@solana/web3.js@1.95.8)(bs58@6.0.0) + '@solana/wallet-adapter-phantom': 0.9.24(@solana/web3.js@1.95.8) + '@solana/wallet-adapter-safepal': 0.5.18(@solana/web3.js@1.95.8) + '@solana/wallet-adapter-saifu': 0.1.15(@solana/web3.js@1.95.8) + '@solana/wallet-adapter-salmon': 0.1.14(@solana/web3.js@1.95.8) + '@solana/wallet-adapter-sky': 0.1.15(@solana/web3.js@1.95.8) + '@solana/wallet-adapter-solflare': 0.6.28(@solana/web3.js@1.95.8) + '@solana/wallet-adapter-solong': 0.9.18(@solana/web3.js@1.95.8) + '@solana/wallet-adapter-spot': 0.1.15(@solana/web3.js@1.95.8) + '@solana/wallet-adapter-tokenary': 0.1.12(@solana/web3.js@1.95.8) + '@solana/wallet-adapter-tokenpocket': 0.4.19(@solana/web3.js@1.95.8) + '@solana/wallet-adapter-torus': 0.11.28(@babel/runtime@7.26.10)(@solana/web3.js@1.95.8) + '@solana/wallet-adapter-trezor': 0.1.2(@babel/core@7.26.9)(@solana/web3.js@1.95.8)(react-native@0.76.5)(tslib@2.8.1) + '@solana/wallet-adapter-trust': 0.1.13(@solana/web3.js@1.95.8) + '@solana/wallet-adapter-unsafe-burner': 0.1.7(@solana/web3.js@1.95.8) + '@solana/wallet-adapter-walletconnect': 0.1.16(@solana/web3.js@1.95.8) + '@solana/wallet-adapter-xdefi': 0.1.7(@solana/web3.js@1.95.8) + '@solana/web3.js': 1.95.8(encoding@0.1.13) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@babel/core' + - '@babel/runtime' + - '@capacitor/preferences' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@sentry/types' + - '@upstash/redis' + - '@vercel/kv' + - bs58 + - bufferutil + - encoding + - expo-constants + - expo-localization + - ioredis + - react + - react-dom + - react-native + - supports-color + - tslib + - uWebSockets.js + - utf-8-validate + dev: false + + /@solana/wallet-adapter-xdefi@0.1.7(@solana/web3.js@1.95.8): + resolution: {integrity: sha512-d0icfBOQyaY8kpsdU/wQwaBIahZZPzkXkXfBjpMGwjixD8oeZUFfsg8LC7T1rOIUObeczlocaR/lwtEqWpnaeg==} + engines: {node: '>=16'} + peerDependencies: + '@solana/web3.js': ^1.77.3 + dependencies: + '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.95.8) + '@solana/web3.js': 1.95.8(encoding@0.1.13) + dev: false + + /@solana/wallet-standard-chains@1.1.0: + resolution: {integrity: sha512-IRJHf94UZM8AaRRmY18d34xCJiVPJej1XVwXiTjihHnmwD0cxdQbc/CKjrawyqFyQAKJx7raE5g9mnJsAdspTg==} + engines: {node: '>=16'} + dependencies: + '@wallet-standard/base': 1.1.0 + dev: false + + /@solana/wallet-standard-core@1.1.1: + resolution: {integrity: sha512-DoQ5Ryly4GAZtxRUmW2rIWrgNvTYVCWrFCFFjZI5s4zu2QNsP7sHZUax3kc1GbmFLXNL1FWRZlPOXRs6e0ZEng==} + engines: {node: '>=16'} + dependencies: + '@solana/wallet-standard-chains': 1.1.0 + '@solana/wallet-standard-features': 1.2.0 + '@solana/wallet-standard-util': 1.1.1 + dev: false + + /@solana/wallet-standard-features@1.2.0: + resolution: {integrity: sha512-tUd9srDLkRpe1BYg7we+c4UhRQkq+XQWswsr/L1xfGmoRDF47BPSXf4zE7ZU2GRBGvxtGt7lwJVAufQyQYhxTQ==} + engines: {node: '>=16'} + dependencies: + '@wallet-standard/base': 1.1.0 + '@wallet-standard/features': 1.0.3 + dev: false + + /@solana/wallet-standard-util@1.1.1: + resolution: {integrity: sha512-dPObl4ntmfOc0VAGGyyFvrqhL8UkHXmVsgbj0K9RcznKV4KB3MgjGwzo8CTSX5El5lkb0rDeEzFqvToJXRz3dw==} + engines: {node: '>=16'} + dependencies: + '@noble/curves': 1.9.0 + '@solana/wallet-standard-chains': 1.1.0 + '@solana/wallet-standard-features': 1.2.0 + dev: false + + /@solana/wallet-standard-wallet-adapter-base@1.1.2(@solana/web3.js@1.95.8)(bs58@5.0.0): + resolution: {integrity: sha512-DqhzYbgh3disHMgcz6Du7fmpG29BYVapNEEiL+JoVMa+bU9d4P1wfwXUNyJyRpGGNXtwhyZjIk2umWbe5ZBNaQ==} + engines: {node: '>=16'} + peerDependencies: + '@solana/web3.js': ^1.58.0 + bs58: ^4.0.1 + dependencies: + '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.95.8) + '@solana/wallet-standard-chains': 1.1.0 + '@solana/wallet-standard-features': 1.2.0 + '@solana/wallet-standard-util': 1.1.1 + '@solana/web3.js': 1.95.8(encoding@0.1.13) + '@wallet-standard/app': 1.1.0 + '@wallet-standard/base': 1.1.0 + '@wallet-standard/features': 1.0.3 + '@wallet-standard/wallet': 1.0.1 + bs58: 5.0.0 + dev: false + + /@solana/wallet-standard-wallet-adapter-base@1.1.2(@solana/web3.js@1.95.8)(bs58@6.0.0): + resolution: {integrity: sha512-DqhzYbgh3disHMgcz6Du7fmpG29BYVapNEEiL+JoVMa+bU9d4P1wfwXUNyJyRpGGNXtwhyZjIk2umWbe5ZBNaQ==} + engines: {node: '>=16'} + peerDependencies: + '@solana/web3.js': ^1.58.0 + bs58: ^4.0.1 + dependencies: + '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.95.8) + '@solana/wallet-standard-chains': 1.1.0 + '@solana/wallet-standard-features': 1.2.0 + '@solana/wallet-standard-util': 1.1.1 + '@solana/web3.js': 1.95.8(encoding@0.1.13) + '@wallet-standard/app': 1.1.0 + '@wallet-standard/base': 1.1.0 + '@wallet-standard/features': 1.0.3 + '@wallet-standard/wallet': 1.0.1 + bs58: 6.0.0 + dev: false + + /@solana/wallet-standard-wallet-adapter-react@1.1.2(@solana/wallet-adapter-base@0.9.23)(@solana/web3.js@1.95.8)(bs58@5.0.0)(react@18.3.1): + resolution: {integrity: sha512-bN6W4QkzenyjUoUz3sC5PAed+z29icGtPh9VSmLl1ZrRO7NbFB49a8uwUUVXNxhL/ZbMsyVKhb9bNj47/p8uhQ==} +>>>>>>> a7b03ea6 (refactored wallet stamper and added to sdk-js, and ewk) engines: {node: '>=16'} peerDependencies: '@solana/wallet-adapter-base': '*' react: '*' +<<<<<<< HEAD +======= + dependencies: + '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.95.8) + '@solana/wallet-standard-wallet-adapter-base': 1.1.2(@solana/web3.js@1.95.8)(bs58@5.0.0) + '@wallet-standard/app': 1.1.0 + '@wallet-standard/base': 1.1.0 + react: 18.3.1 + transitivePeerDependencies: + - '@solana/web3.js' + - bs58 + dev: false +>>>>>>> a7b03ea6 (refactored wallet stamper and added to sdk-js, and ewk) '@solana/wallet-standard-wallet-adapter@1.1.4': resolution: {integrity: sha512-YSBrxwov4irg2hx9gcmM4VTew3ofNnkqsXQ42JwcS6ykF1P1ecVY8JCbrv75Nwe6UodnqeoZRbN7n/p3awtjNQ==} engines: {node: '>=16'} +<<<<<<< HEAD +======= + peerDependencies: + '@solana/wallet-adapter-base': '*' + react: '*' + dependencies: + '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.95.8) + '@solana/wallet-standard-wallet-adapter-base': 1.1.2(@solana/web3.js@1.95.8)(bs58@6.0.0) + '@wallet-standard/app': 1.1.0 + '@wallet-standard/base': 1.1.0 + react: 18.3.1 + transitivePeerDependencies: + - '@solana/web3.js' + - bs58 + dev: false +>>>>>>> a7b03ea6 (refactored wallet stamper and added to sdk-js, and ewk) '@solana/wallet-standard@1.1.4': resolution: {integrity: sha512-NF+MI5tOxyvfTU4A+O5idh/gJFmjm52bMwsPpFGRSL79GECSN0XLmpVOO/jqTKJgac2uIeYDpQw/eMaQuWuUXw==} @@ -7299,6 +7685,17 @@ packages: resolution: {integrity: sha512-os5Px5PTMYKGS5tzOoyjDxtOtj0jZKnbI1Uwt8+Jsw1HHIA+Ib2UACCGNhQ/un2f8sIbTfLD1WuucNMOy8KZpQ==} peerDependencies: '@solana/web3.js': '*' +<<<<<<< HEAD +======= + dependencies: + '@solana/wallet-standard-features': 1.2.0 + '@solana/web3.js': 1.95.8(encoding@0.1.13) + '@wallet-standard/base': 1.1.0 + bs58: 5.0.0 + eventemitter3: 5.0.1 + uuid: 9.0.1 + dev: false +>>>>>>> a7b03ea6 (refactored wallet stamper and added to sdk-js, and ewk) '@solflare-wallet/sdk@1.4.2': resolution: {integrity: sha512-jrseNWipwl9xXZgrzwZF3hhL0eIVxuEtoZOSLmuPuef7FgHjstuTtNJAeT4icA7pzdDV4hZvu54pI2r2f7SmrQ==} @@ -8116,6 +8513,7 @@ packages: engines: {node: '>=10'} deprecated: Please upgrade to 1.0.1 +<<<<<<< HEAD '@unrs/resolver-binding-darwin-arm64@1.7.6': resolution: {integrity: sha512-dDhh//8GrF4PynBubCUvnJ/mG2LStUEiaWqML4SAhz2iZvG769d6e25MoJBamDR251FBT3ULpXGJ7Mdnysp27w==} cpu: [arm64] @@ -8226,23 +8624,60 @@ packages: '@wallet-standard/app@1.1.0': resolution: {integrity: sha512-3CijvrO9utx598kjr45hTbbeeykQrQfKmSnxeWOgU25TOEpvcipD/bYDQWIqUv1Oc6KK4YStokSMu/FBNecGUQ==} engines: {node: '>=16'} +======= + /@wallet-standard/app@1.1.0: + resolution: {integrity: sha512-3CijvrO9utx598kjr45hTbbeeykQrQfKmSnxeWOgU25TOEpvcipD/bYDQWIqUv1Oc6KK4YStokSMu/FBNecGUQ==} + engines: {node: '>=16'} + dependencies: + '@wallet-standard/base': 1.1.0 + dev: false +>>>>>>> a7b03ea6 (refactored wallet stamper and added to sdk-js, and ewk) '@wallet-standard/base@1.1.0': resolution: {integrity: sha512-DJDQhjKmSNVLKWItoKThJS+CsJQjR9AOBOirBVT1F9YpRyC9oYHE+ZnSf8y8bxUphtKqdQMPVQ2mHohYdRvDVQ==} engines: {node: '>=16'} +<<<<<<< HEAD '@wallet-standard/core@1.1.1': resolution: {integrity: sha512-5Xmjc6+Oe0hcPfVc5n8F77NVLwx1JVAoCVgQpLyv/43/bhtIif+Gx3WUrDlaSDoM8i2kA2xd6YoFbHCxs+e0zA==} engines: {node: '>=16'} +======= + /@wallet-standard/base@1.1.0: + resolution: {integrity: sha512-DJDQhjKmSNVLKWItoKThJS+CsJQjR9AOBOirBVT1F9YpRyC9oYHE+ZnSf8y8bxUphtKqdQMPVQ2mHohYdRvDVQ==} + engines: {node: '>=16'} + dev: false + + /@wallet-standard/core@1.0.3: + resolution: {integrity: sha512-Jb33IIjC1wM1HoKkYD7xQ6d6PZ8EmMZvyc8R7dFgX66n/xkvksVTW04g9yLvQXrLFbcIjHrCxW6TXMhvpsAAzg==} + engines: {node: '>=16'} + dependencies: + '@wallet-standard/app': 1.1.0 + '@wallet-standard/base': 1.1.0 + '@wallet-standard/features': 1.0.3 + '@wallet-standard/wallet': 1.0.1 + dev: false +>>>>>>> a7b03ea6 (refactored wallet stamper and added to sdk-js, and ewk) '@wallet-standard/errors@0.1.1': resolution: {integrity: sha512-V8Ju1Wvol8i/VDyQOHhjhxmMVwmKiwyxUZBnHhtiPZJTWY0U/Shb2iEWyGngYEbAkp2sGTmEeNX1tVyGR7PqNw==} engines: {node: '>=16'} +<<<<<<< HEAD hasBin: true +======= + dependencies: + '@wallet-standard/base': 1.1.0 + dev: false +>>>>>>> a7b03ea6 (refactored wallet stamper and added to sdk-js, and ewk) '@wallet-standard/features@1.1.0': resolution: {integrity: sha512-hiEivWNztx73s+7iLxsuD1sOJ28xtRix58W7Xnz4XzzA/pF0+aicnWgjOdA10doVDEDZdUuZCIIqG96SFNlDUg==} engines: {node: '>=16'} +<<<<<<< HEAD +======= + dependencies: + '@wallet-standard/base': 1.1.0 + dev: false +>>>>>>> a7b03ea6 (refactored wallet stamper and added to sdk-js, and ewk) '@wallet-standard/wallet@1.1.0': resolution: {integrity: sha512-Gt8TnSlDZpAl+RWOOAB/kuvC7RpcdWAlFbHNoi4gsXsfaWa1QCT6LBcfIYTPdOZC9OVZUDwqGuGAcqZejDmHjg==} From 70eeb3b4fbb5efba730cb4b0c3facfbba74441dd Mon Sep 17 00:00:00 2001 From: Amir Cheikh Date: Tue, 8 Jul 2025 15:25:35 -0400 Subject: [PATCH 052/184] Signing modal. Modal changes. Customization --- examples/with-sdk-js/src/app/layout.tsx | 2 +- examples/with-sdk-js/src/app/page.tsx | 54 +++++++- packages/react-wallet-kit/package.json | 2 +- .../src/components/auth/OTP.tsx | 2 +- .../src/components/auth/index.tsx | 23 ++++ .../src/components/design/Inputs.tsx | 2 +- .../src/components/design/Success.tsx | 72 +++++++++++ .../src/components/design/Svg.tsx | 44 +++++++ .../src/components/sign/Message.tsx | 116 ++++++++++++++++++ .../src/providers/client/Provider.tsx | 61 ++++++++- .../src/providers/modal/Provider.tsx | 1 + .../src/providers/modal/Root.tsx | 46 ++++--- packages/sdk-js/src/__clients__/core.ts | 2 +- pnpm-lock.yaml | 34 +++-- 14 files changed, 420 insertions(+), 41 deletions(-) create mode 100644 packages/react-wallet-kit/src/components/design/Success.tsx create mode 100644 packages/react-wallet-kit/src/components/design/Svg.tsx create mode 100644 packages/react-wallet-kit/src/components/sign/Message.tsx diff --git a/examples/with-sdk-js/src/app/layout.tsx b/examples/with-sdk-js/src/app/layout.tsx index f149275e7..a4d821636 100644 --- a/examples/with-sdk-js/src/app/layout.tsx +++ b/examples/with-sdk-js/src/app/layout.tsx @@ -37,7 +37,7 @@ function RootLayout({ children }: RootLayoutProps) { autoRefreshSession: true, }, ui: { - darkMode: false, + darkMode: true, }, passkeyConfig: { rpId: process.env.NEXT_PUBLIC_RPID!, diff --git a/examples/with-sdk-js/src/app/page.tsx b/examples/with-sdk-js/src/app/page.tsx index 64dee9535..ccf0fcd2c 100644 --- a/examples/with-sdk-js/src/app/page.tsx +++ b/examples/with-sdk-js/src/app/page.tsx @@ -10,6 +10,7 @@ import { OtpType } from "@turnkey/sdk-js"; import { useModal, useTurnkey } from "@turnkey/react-wallet-kit"; import { SessionKey } from "@turnkey/sdk-js/dist/__storage__/base"; import { WalletType } from "@turnkey/wallet-stamper"; +import { ExportType } from "@turnkey/react-wallet-kit/dist/components/export"; export default function AuthPage() { const [email, setEmail] = useState(""); @@ -119,6 +120,7 @@ export default function AuthPage() { const res = await signMessage({ message: "Hello, Turnkey!", wallet: walletAccount, + modalOptions: { enabled: false }, }); console.log("Signed message response:", res); @@ -151,10 +153,28 @@ export default function AuthPage() { await setActiveSession({ sessionKey }); }; - const showModal = () => { + const showLoginModal = () => { login(); }; + const showSigningModal = async () => { + if ( + (wallets.length === 0 && !wallets[0]) || + !wallets[0].accounts || + wallets[0].accounts.length < 1 + ) { + console.error("No wallets available to sign message"); + return; + } + + const result = await signMessage({ + message: + "Lorem ipsum dolor sit amet, consectetur adipiscing elit. . Sed id maximus elit. Mauris lacus ligula, dictum nec purus sit amet, mollis tempor nisl. Morbi neque lectus, tempor sed tristique sit amet, ornare eget dui", + wallet: wallets[0].accounts[0], + }); + console.log("Signing result:", result); + }; + return (
+ +
); } diff --git a/packages/react-wallet-kit/src/components/design/Inputs.tsx b/packages/react-wallet-kit/src/components/design/Inputs.tsx index 5f87ab421..ca7baf029 100644 --- a/packages/react-wallet-kit/src/components/design/Inputs.tsx +++ b/packages/react-wallet-kit/src/components/design/Inputs.tsx @@ -213,7 +213,7 @@ export function PhoneInputBox(props: PhoneInputBoxProps) { {countries.map((c) => { diff --git a/packages/react-wallet-kit/src/components/design/Success.tsx b/packages/react-wallet-kit/src/components/design/Success.tsx new file mode 100644 index 000000000..a5427b6eb --- /dev/null +++ b/packages/react-wallet-kit/src/components/design/Success.tsx @@ -0,0 +1,72 @@ +import { faCheck } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { Player } from "@lottiefiles/react-lottie-player"; +import { useEffect, useState } from "react"; + +interface SuccessPageProps { + text?: string | undefined; + duration?: number | undefined; + onComplete: () => void; +} + +export function SuccessPage(props: SuccessPageProps) { + const { text = "Success", duration = 2000, onComplete } = props; + const [pulsing, setPulsing] = useState(false); + const [scale, setScale] = useState(0); + + useEffect(() => { + setScale(1); + const pulseTimer = setTimeout(() => { + setPulsing(true); + }, 300); + const totalTimer = setTimeout(() => { + onComplete(); + }, duration); + return () => { + clearTimeout(totalTimer); + clearTimeout(pulseTimer); + }; + }, [duration, onComplete]); + + return ( +
+
+
+ + {pulsing && ( + + )} +
+ + {/*@ts-ignore. I have no idea how to fix this error */} + +
+

{text}

+
+ ); +} diff --git a/packages/react-wallet-kit/src/components/design/Svg.tsx b/packages/react-wallet-kit/src/components/design/Svg.tsx new file mode 100644 index 000000000..fbe2e8407 --- /dev/null +++ b/packages/react-wallet-kit/src/components/design/Svg.tsx @@ -0,0 +1,44 @@ +interface TurnkeyLogoProps { + className?: string; + style?: React.CSSProperties; +} + +export function TurnkeyLogo(props: TurnkeyLogoProps) { + return ( + + + + + + + + + + + + + ); +} diff --git a/packages/react-wallet-kit/src/components/sign/Message.tsx b/packages/react-wallet-kit/src/components/sign/Message.tsx new file mode 100644 index 000000000..0e8722731 --- /dev/null +++ b/packages/react-wallet-kit/src/components/sign/Message.tsx @@ -0,0 +1,116 @@ +import { Textarea } from "@headlessui/react"; +import { StamperType } from "@turnkey/sdk-js"; +import { v1SignRawPayloadResult, v1WalletAccount } from "@turnkey/sdk-types"; +import { ActionButton } from "../design/Buttons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { faWallet } from "@fortawesome/free-solid-svg-icons"; +import { useRef, useEffect, useState } from "react"; +import { useModal, useTurnkey } from "../../providers"; +import { SuccessPage } from "../design/Success"; + +interface SignMessageModalProps { + message: string; + wallet: v1WalletAccount; + subText?: string | undefined; + stampWith?: StamperType | undefined; + successPageDuration?: number | undefined; // Duration in milliseconds for the success page to show. If 0, it will not show the success page. + onSuccess: (result: v1SignRawPayloadResult) => void; + onError: (error: any) => void; +} + +export function SignMessageModal(props: SignMessageModalProps) { + const { + message, + wallet, + subText = "Use your wallet to sign this message", + stampWith, + successPageDuration, + onSuccess, + onError, + } = props; + + const { signMessage } = useTurnkey(); + const { pushPage, closeModal } = useModal(); + const [loading, setLoading] = useState(false); + const textareaRef = useRef(null); + + useEffect(() => { + const textarea = textareaRef.current; + if (textarea) { + textarea.style.height = "auto"; // reset height + textarea.style.height = `${Math.min(textarea.scrollHeight, 288)}px`; // max-h-72 = 288px + } + }, [message]); + + const handleSign = async () => { + try { + setLoading(true); + const result = await signMessage({ + message, + wallet, + ...(stampWith ? { stampWith } : {}), + modalOptions: { enabled: false }, // Disable modal for direct signing + }); + handleSuccess(result); + } catch (error) { + onError(error); + } finally { + setLoading(false); + } + }; + + const handleSuccess = (result: v1SignRawPayloadResult) => { + onSuccess(result); // Run the success callback first before showing the success page. + + if (successPageDuration && successPageDuration === 0) return; + + pushPage({ + key: "success", + content: ( + { + closeModal(); + }} + /> + ), + preventBack: true, + showTitle: false, + }); + }; + + return ( +
+

+ {subText} +

+
+
+ +
+ + {wallet.address.length > 8 + ? `${wallet.address.slice(0, 4)}...${wallet.address.slice(-4)}` + : wallet.address} +
+ +
+