diff --git a/.changeset/heavy-banks-think.md b/.changeset/heavy-banks-think.md
new file mode 100644
index 00000000000..bd67df35d64
--- /dev/null
+++ b/.changeset/heavy-banks-think.md
@@ -0,0 +1,5 @@
+---
+"@thirdweb-dev/engine": minor
+---
+
+New engine v3 APIs - see changelog for breaking changes
diff --git a/.changeset/lovely-brooms-relax.md b/.changeset/lovely-brooms-relax.md
new file mode 100644
index 00000000000..8f0cad5cd7e
--- /dev/null
+++ b/.changeset/lovely-brooms-relax.md
@@ -0,0 +1,5 @@
+---
+"thirdweb": patch
+---
+
+Support latest engine API
diff --git a/apps/dashboard/biome.json b/apps/dashboard/biome.json
index 780bbdcd1af..cec0f72abd0 100644
--- a/apps/dashboard/biome.json
+++ b/apps/dashboard/biome.json
@@ -1,4 +1,4 @@
{
- "$schema": "https://biomejs.dev/schemas/2.0.0/schema.json",
+ "$schema": "https://biomejs.dev/schemas/2.0.4/schema.json",
"extends": "//"
}
diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/analytics/tx-table/types.ts b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/analytics/tx-table/types.ts
index 482409932ff..f176f30c35b 100644
--- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/analytics/tx-table/types.ts
+++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/analytics/tx-table/types.ts
@@ -34,7 +34,14 @@ type ExecutionResult4337Serialized =
}
| {
status: "FAILED";
- error: string;
+ error: {
+ stage: string;
+ message: string;
+ errorCode: string;
+ inner_error: object;
+ nonce_used: string;
+ account_address: string;
+ };
}
| {
status: "SUBMITTED";
diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/tx/[id]/transaction-details-ui.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/tx/[id]/transaction-details-ui.tsx
index 951be2deb08..c745eaaf649 100644
--- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/tx/[id]/transaction-details-ui.tsx
+++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/tx/[id]/transaction-details-ui.tsx
@@ -3,7 +3,7 @@
import { format, formatDistanceToNowStrict } from "date-fns";
import { ExternalLinkIcon, InfoIcon } from "lucide-react";
import Link from "next/link";
-import { type ThirdwebClient, toEther } from "thirdweb";
+import { hexToNumber, isHex, type ThirdwebClient, toEther } from "thirdweb";
import type { Project } from "@/api/projects";
import { WalletAddress } from "@/components/blocks/wallet-address";
import { Badge } from "@/components/ui/badge";
@@ -43,10 +43,14 @@ export function TransactionDetailsUI({
const status = executionResult?.status as keyof typeof statusDetails;
const errorMessage =
executionResult && "error" in executionResult
- ? executionResult.error
+ ? executionResult.error.message
: executionResult && "revertData" in executionResult
? executionResult.revertData?.revertReason
: null;
+ const errorDetails =
+ executionResult && "error" in executionResult
+ ? executionResult.error
+ : undefined;
const chain = chainId ? idToChain.get(Number.parseInt(chainId)) : undefined;
const explorer = chain?.explorers?.[0];
@@ -64,7 +68,7 @@ export function TransactionDetailsUI({
// Gas information
const gasUsed =
executionResult && "actualGasUsed" in executionResult
- ? `${executionResult.actualGasUsed}`
+ ? `${isHex(executionResult.actualGasUsed) ? hexToNumber(executionResult.actualGasUsed) : executionResult.actualGasUsed}`
: "N/A";
const gasCost =
@@ -244,9 +248,16 @@ export function TransactionDetailsUI({
-
- {errorMessage}
-
+ {errorDetails ? (
+
+ ) : (
+
+ {errorMessage}
+
+ )}
)}
@@ -328,7 +339,9 @@ export function TransactionDetailsUI({
Block Number
- {transaction.confirmedAtBlockNumber}
+ {isHex(transaction.confirmedAtBlockNumber)
+ ? hexToNumber(transaction.confirmedAtBlockNumber)
+ : transaction.confirmedAtBlockNumber}
)}
diff --git a/apps/nebula/biome.json b/apps/nebula/biome.json
index 780bbdcd1af..cec0f72abd0 100644
--- a/apps/nebula/biome.json
+++ b/apps/nebula/biome.json
@@ -1,4 +1,4 @@
{
- "$schema": "https://biomejs.dev/schemas/2.0.0/schema.json",
+ "$schema": "https://biomejs.dev/schemas/2.0.4/schema.json",
"extends": "//"
}
diff --git a/apps/playground-web/biome.json b/apps/playground-web/biome.json
index 780bbdcd1af..cec0f72abd0 100644
--- a/apps/playground-web/biome.json
+++ b/apps/playground-web/biome.json
@@ -1,4 +1,4 @@
{
- "$schema": "https://biomejs.dev/schemas/2.0.0/schema.json",
+ "$schema": "https://biomejs.dev/schemas/2.0.4/schema.json",
"extends": "//"
}
diff --git a/apps/portal/biome.json b/apps/portal/biome.json
index 780bbdcd1af..cec0f72abd0 100644
--- a/apps/portal/biome.json
+++ b/apps/portal/biome.json
@@ -1,4 +1,4 @@
{
- "$schema": "https://biomejs.dev/schemas/2.0.0/schema.json",
+ "$schema": "https://biomejs.dev/schemas/2.0.4/schema.json",
"extends": "//"
}
diff --git a/apps/wallet-ui/biome.json b/apps/wallet-ui/biome.json
index 780bbdcd1af..cec0f72abd0 100644
--- a/apps/wallet-ui/biome.json
+++ b/apps/wallet-ui/biome.json
@@ -1,4 +1,4 @@
{
- "$schema": "https://biomejs.dev/schemas/2.0.0/schema.json",
+ "$schema": "https://biomejs.dev/schemas/2.0.4/schema.json",
"extends": "//"
}
diff --git a/biome.json b/biome.json
index 4ff11ff4f01..52c326583f0 100644
--- a/biome.json
+++ b/biome.json
@@ -1,5 +1,5 @@
{
- "$schema": "https://biomejs.dev/schemas/2.0.0/schema.json",
+ "$schema": "https://biomejs.dev/schemas/2.0.4/schema.json",
"assist": {
"actions": {
"source": {
diff --git a/packages/engine/biome.json b/packages/engine/biome.json
index 780bbdcd1af..c0390d3d0bc 100644
--- a/packages/engine/biome.json
+++ b/packages/engine/biome.json
@@ -1,4 +1,17 @@
{
- "$schema": "https://biomejs.dev/schemas/2.0.0/schema.json",
- "extends": "//"
+ "$schema": "https://biomejs.dev/schemas/2.0.4/schema.json",
+ "linter": {
+ "rules": {
+ "correctness": {
+ "useImportExtensions": {
+ "fix": "safe",
+ "level": "error",
+ "options": {
+ "forceJsExtensions": true
+ }
+ }
+ }
+ }
+ },
+ "root": true
}
diff --git a/packages/engine/openapi-ts.config.ts b/packages/engine/openapi-ts.config.ts
index 385d7ac7cb9..9633218c073 100644
--- a/packages/engine/openapi-ts.config.ts
+++ b/packages/engine/openapi-ts.config.ts
@@ -3,5 +3,4 @@ import { defineConfig } from "@hey-api/openapi-ts";
export default defineConfig({
input: "https://engine.thirdweb.com/openapi",
output: { format: "biome", lint: "biome", path: "src/client" },
- plugins: ["@hey-api/client-fetch"],
});
diff --git a/packages/engine/package.json b/packages/engine/package.json
index 625142fe9f4..2fbd8aaeb1e 100644
--- a/packages/engine/package.json
+++ b/packages/engine/package.json
@@ -5,16 +5,22 @@
"type": "git",
"url": "git+https://github.com/thirdweb-dev/js.git#main"
},
- "license": "Apache-2.0",
- "bugs": {
- "url": "https://github.com/thirdweb-dev/js/issues"
- },
"author": "thirdweb eng ",
"type": "module",
"main": "./dist/cjs/exports/thirdweb.js",
"module": "./dist/esm/exports/thirdweb.js",
"types": "./dist/types/exports/thirdweb.d.ts",
"typings": "./dist/types/exports/thirdweb.d.ts",
+ "license": "Apache-2.0",
+ "bugs": {
+ "url": "https://github.com/thirdweb-dev/js/issues"
+ },
+ "dependencies": {
+ "@hey-api/client-fetch": "0.10.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
"exports": {
".": {
"types": "./dist/types/exports/thirdweb.d.ts",
@@ -42,17 +48,14 @@
}
},
"scripts": {
- "format": "biome format ./src --write",
- "lint": "biome check ./src",
- "fix": "biome check ./src --fix",
"build": "pnpm clean && pnpm build:cjs && pnpm build:esm && pnpm build:types",
"build:cjs": "tsc --project ./tsconfig.build.json --module commonjs --outDir ./dist/cjs --verbatimModuleSyntax false && printf '{\"type\":\"commonjs\"}' > ./dist/cjs/package.json",
"build:esm": "tsc --project ./tsconfig.build.json --module es2020 --outDir ./dist/esm && printf '{\"type\": \"module\",\"sideEffects\":false}' > ./dist/esm/package.json",
+ "build:generate": "openapi-ts && pnpm format && pnpm fix",
"build:types": "tsc --project ./tsconfig.build.json --module esnext --declarationDir ./dist/types --emitDeclarationOnly --declaration --declarationMap",
"clean": "rimraf dist",
- "build:generate": "openapi-ts && pnpm format"
- },
- "engines": {
- "node": ">=18"
+ "fix": "biome check --write ./src",
+ "format": "biome format --write ./src",
+ "lint": "biome check ./src"
}
}
diff --git a/packages/engine/src/client/client.gen.ts b/packages/engine/src/client/client.gen.ts
index ff215a40ad1..805c0b97e50 100644
--- a/packages/engine/src/client/client.gen.ts
+++ b/packages/engine/src/client/client.gen.ts
@@ -1,10 +1,10 @@
// This file is auto-generated by @hey-api/openapi-ts
import {
- type Config,
- createClient,
- createConfig,
- type ClientOptions as DefaultClientOptions,
+ type Config,
+ createClient,
+ createConfig,
+ type ClientOptions as DefaultClientOptions,
} from "./client/index.js";
import type { ClientOptions } from "./types.gen.js";
@@ -17,12 +17,12 @@ import type { ClientOptions } from "./types.gen.js";
* to ensure your client always has the correct values.
*/
export type CreateClientConfig =
- (
- override?: Config,
- ) => Config & T>;
+ (
+ override?: Config,
+ ) => Config & T>;
export const client = createClient(
- createConfig({
- baseUrl: "https://engine.thirdweb.com",
- }),
+ createConfig({
+ baseUrl: "https://engine.thirdweb.com",
+ }),
);
diff --git a/packages/engine/src/client/client/client.ts b/packages/engine/src/client/client/client.ts
index 8cb5e5bde84..0b528190390 100644
--- a/packages/engine/src/client/client/client.ts
+++ b/packages/engine/src/client/client/client.ts
@@ -1,189 +1,189 @@
import type { Client, Config, RequestOptions } from "./types.js";
import {
- buildUrl,
- createConfig,
- createInterceptors,
- getParseAs,
- mergeConfigs,
- mergeHeaders,
- setAuthParams,
+ buildUrl,
+ createConfig,
+ createInterceptors,
+ getParseAs,
+ mergeConfigs,
+ mergeHeaders,
+ setAuthParams,
} from "./utils.js";
type ReqInit = Omit & {
- body?: any;
- headers: ReturnType;
+ body?: any;
+ headers: ReturnType;
};
export const createClient = (config: Config = {}): Client => {
- let _config = mergeConfigs(createConfig(), config);
-
- const getConfig = (): Config => ({ ..._config });
-
- const setConfig = (config: Config): Config => {
- _config = mergeConfigs(_config, config);
- return getConfig();
- };
-
- const interceptors = createInterceptors<
- Request,
- Response,
- unknown,
- RequestOptions
- >();
-
- const request: Client["request"] = async (options) => {
- const opts = {
- ..._config,
- ...options,
- fetch: options.fetch ?? _config.fetch ?? globalThis.fetch,
- headers: mergeHeaders(_config.headers, options.headers),
- };
-
- if (opts.security) {
- await setAuthParams({
- ...opts,
- security: opts.security,
- });
- }
-
- if (opts.body && opts.bodySerializer) {
- opts.body = opts.bodySerializer(opts.body);
- }
-
- // remove Content-Type header if body is empty to avoid sending invalid requests
- if (opts.body === undefined || opts.body === "") {
- opts.headers.delete("Content-Type");
- }
-
- const url = buildUrl(opts);
- const requestInit: ReqInit = {
- redirect: "follow",
- ...opts,
- };
-
- let request = new Request(url, requestInit);
-
- for (const fn of interceptors.request._fns) {
- if (fn) {
- request = await fn(request, opts);
- }
- }
-
- // fetch must be assigned here, otherwise it would throw the error:
- // TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation
- const _fetch = opts.fetch!;
- let response = await _fetch(request);
-
- for (const fn of interceptors.response._fns) {
- if (fn) {
- response = await fn(response, request, opts);
- }
- }
-
- const result = {
- request,
- response,
- };
-
- if (response.ok) {
- if (
- response.status === 204 ||
- response.headers.get("Content-Length") === "0"
- ) {
- return opts.responseStyle === "data"
- ? {}
- : {
- data: {},
- ...result,
- };
- }
-
- const parseAs =
- (opts.parseAs === "auto"
- ? getParseAs(response.headers.get("Content-Type"))
- : opts.parseAs) ?? "json";
-
- let data: any;
- switch (parseAs) {
- case "arrayBuffer":
- case "blob":
- case "formData":
- case "json":
- case "text":
- data = await response[parseAs]();
- break;
- case "stream":
- return opts.responseStyle === "data"
- ? response.body
- : {
- data: response.body,
- ...result,
- };
- }
-
- if (parseAs === "json") {
- if (opts.responseValidator) {
- await opts.responseValidator(data);
- }
-
- if (opts.responseTransformer) {
- data = await opts.responseTransformer(data);
- }
- }
-
- return opts.responseStyle === "data"
- ? data
- : {
- data,
- ...result,
- };
- }
-
- let error = await response.text();
-
- try {
- error = JSON.parse(error);
- } catch {
- // noop
- }
-
- let finalError = error;
-
- for (const fn of interceptors.error._fns) {
- if (fn) {
- finalError = (await fn(error, response, request, opts)) as string;
- }
- }
-
- finalError = finalError || ({} as string);
-
- if (opts.throwOnError) {
- throw finalError;
- }
-
- // TODO: we probably want to return error and improve types
- return opts.responseStyle === "data"
- ? undefined
- : {
- error: finalError,
- ...result,
- };
- };
-
- return {
- buildUrl,
- connect: (options) => request({ ...options, method: "CONNECT" }),
- delete: (options) => request({ ...options, method: "DELETE" }),
- get: (options) => request({ ...options, method: "GET" }),
- getConfig,
- head: (options) => request({ ...options, method: "HEAD" }),
- interceptors,
- options: (options) => request({ ...options, method: "OPTIONS" }),
- patch: (options) => request({ ...options, method: "PATCH" }),
- post: (options) => request({ ...options, method: "POST" }),
- put: (options) => request({ ...options, method: "PUT" }),
- request,
- setConfig,
- trace: (options) => request({ ...options, method: "TRACE" }),
- };
+ let _config = mergeConfigs(createConfig(), config);
+
+ const getConfig = (): Config => ({ ..._config });
+
+ const setConfig = (config: Config): Config => {
+ _config = mergeConfigs(_config, config);
+ return getConfig();
+ };
+
+ const interceptors = createInterceptors<
+ Request,
+ Response,
+ unknown,
+ RequestOptions
+ >();
+
+ const request: Client["request"] = async (options) => {
+ const opts = {
+ ..._config,
+ ...options,
+ fetch: options.fetch ?? _config.fetch ?? globalThis.fetch,
+ headers: mergeHeaders(_config.headers, options.headers),
+ };
+
+ if (opts.security) {
+ await setAuthParams({
+ ...opts,
+ security: opts.security,
+ });
+ }
+
+ if (opts.body && opts.bodySerializer) {
+ opts.body = opts.bodySerializer(opts.body);
+ }
+
+ // remove Content-Type header if body is empty to avoid sending invalid requests
+ if (opts.body === undefined || opts.body === "") {
+ opts.headers.delete("Content-Type");
+ }
+
+ const url = buildUrl(opts);
+ const requestInit: ReqInit = {
+ redirect: "follow",
+ ...opts,
+ };
+
+ let request = new Request(url, requestInit);
+
+ for (const fn of interceptors.request._fns) {
+ if (fn) {
+ request = await fn(request, opts);
+ }
+ }
+
+ // fetch must be assigned here, otherwise it would throw the error:
+ // TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation
+ const _fetch = opts.fetch!;
+ let response = await _fetch(request);
+
+ for (const fn of interceptors.response._fns) {
+ if (fn) {
+ response = await fn(response, request, opts);
+ }
+ }
+
+ const result = {
+ request,
+ response,
+ };
+
+ if (response.ok) {
+ if (
+ response.status === 204 ||
+ response.headers.get("Content-Length") === "0"
+ ) {
+ return opts.responseStyle === "data"
+ ? {}
+ : {
+ data: {},
+ ...result,
+ };
+ }
+
+ const parseAs =
+ (opts.parseAs === "auto"
+ ? getParseAs(response.headers.get("Content-Type"))
+ : opts.parseAs) ?? "json";
+
+ let data: any;
+ switch (parseAs) {
+ case "arrayBuffer":
+ case "blob":
+ case "formData":
+ case "json":
+ case "text":
+ data = await response[parseAs]();
+ break;
+ case "stream":
+ return opts.responseStyle === "data"
+ ? response.body
+ : {
+ data: response.body,
+ ...result,
+ };
+ }
+
+ if (parseAs === "json") {
+ if (opts.responseValidator) {
+ await opts.responseValidator(data);
+ }
+
+ if (opts.responseTransformer) {
+ data = await opts.responseTransformer(data);
+ }
+ }
+
+ return opts.responseStyle === "data"
+ ? data
+ : {
+ data,
+ ...result,
+ };
+ }
+
+ let error = await response.text();
+
+ try {
+ error = JSON.parse(error);
+ } catch {
+ // noop
+ }
+
+ let finalError = error;
+
+ for (const fn of interceptors.error._fns) {
+ if (fn) {
+ finalError = (await fn(error, response, request, opts)) as string;
+ }
+ }
+
+ finalError = finalError || ({} as string);
+
+ if (opts.throwOnError) {
+ throw finalError;
+ }
+
+ // TODO: we probably want to return error and improve types
+ return opts.responseStyle === "data"
+ ? undefined
+ : {
+ error: finalError,
+ ...result,
+ };
+ };
+
+ return {
+ buildUrl,
+ connect: (options) => request({ ...options, method: "CONNECT" }),
+ delete: (options) => request({ ...options, method: "DELETE" }),
+ get: (options) => request({ ...options, method: "GET" }),
+ getConfig,
+ head: (options) => request({ ...options, method: "HEAD" }),
+ interceptors,
+ options: (options) => request({ ...options, method: "OPTIONS" }),
+ patch: (options) => request({ ...options, method: "PATCH" }),
+ post: (options) => request({ ...options, method: "POST" }),
+ put: (options) => request({ ...options, method: "PUT" }),
+ request,
+ setConfig,
+ trace: (options) => request({ ...options, method: "TRACE" }),
+ };
};
diff --git a/packages/engine/src/client/client/index.ts b/packages/engine/src/client/client/index.ts
index 33d0123ce32..c0343af4092 100644
--- a/packages/engine/src/client/client/index.ts
+++ b/packages/engine/src/client/client/index.ts
@@ -1,22 +1,22 @@
export type { Auth } from "../core/auth.js";
export type { QuerySerializerOptions } from "../core/bodySerializer.js";
export {
- formDataBodySerializer,
- jsonBodySerializer,
- urlSearchParamsBodySerializer,
+ formDataBodySerializer,
+ jsonBodySerializer,
+ urlSearchParamsBodySerializer,
} from "../core/bodySerializer.js";
export { buildClientParams } from "../core/params.js";
export { createClient } from "./client.js";
export type {
- Client,
- ClientOptions,
- Config,
- CreateClientConfig,
- Options,
- OptionsLegacyParser,
- RequestOptions,
- RequestResult,
- ResponseStyle,
- TDataShape,
+ Client,
+ ClientOptions,
+ Config,
+ CreateClientConfig,
+ Options,
+ OptionsLegacyParser,
+ RequestOptions,
+ RequestResult,
+ ResponseStyle,
+ TDataShape,
} from "./types.js";
export { createConfig, mergeHeaders } from "./utils.js";
diff --git a/packages/engine/src/client/client/types.ts b/packages/engine/src/client/client/types.ts
index 6d37980f22f..ef3d74fd17d 100644
--- a/packages/engine/src/client/client/types.ts
+++ b/packages/engine/src/client/client/types.ts
@@ -1,169 +1,169 @@
import type { Auth } from "../core/auth.js";
import type {
- Client as CoreClient,
- Config as CoreConfig,
+ Client as CoreClient,
+ Config as CoreConfig,
} from "../core/types.js";
import type { Middleware } from "./utils.js";
export type ResponseStyle = "data" | "fields";
export interface Config
- extends Omit,
- CoreConfig {
- /**
- * Base URL for all requests made by this client.
- */
- baseUrl?: T["baseUrl"];
- /**
- * Fetch API implementation. You can use this option to provide a custom
- * fetch instance.
- *
- * @default globalThis.fetch
- */
- fetch?: (request: Request) => ReturnType;
- /**
- * Please don't use the Fetch client for Next.js applications. The `next`
- * options won't have any effect.
- *
- * Install {@link https://www.npmjs.com/package/@hey-api/client-next `@hey-api/client-next`} instead.
- */
- next?: never;
- /**
- * Return the response data parsed in a specified format. By default, `auto`
- * will infer the appropriate method from the `Content-Type` response header.
- * You can override this behavior with any of the {@link Body} methods.
- * Select `stream` if you don't want to parse response data at all.
- *
- * @default 'auto'
- */
- parseAs?:
- | "arrayBuffer"
- | "auto"
- | "blob"
- | "formData"
- | "json"
- | "stream"
- | "text";
- /**
- * Should we return only data or multiple fields (data, error, response, etc.)?
- *
- * @default 'fields'
- */
- responseStyle?: ResponseStyle;
- /**
- * Throw an error instead of returning it in the response?
- *
- * @default false
- */
- throwOnError?: T["throwOnError"];
+ extends Omit,
+ CoreConfig {
+ /**
+ * Base URL for all requests made by this client.
+ */
+ baseUrl?: T["baseUrl"];
+ /**
+ * Fetch API implementation. You can use this option to provide a custom
+ * fetch instance.
+ *
+ * @default globalThis.fetch
+ */
+ fetch?: (request: Request) => ReturnType;
+ /**
+ * Please don't use the Fetch client for Next.js applications. The `next`
+ * options won't have any effect.
+ *
+ * Install {@link https://www.npmjs.com/package/@hey-api/client-next `@hey-api/client-next`} instead.
+ */
+ next?: never;
+ /**
+ * Return the response data parsed in a specified format. By default, `auto`
+ * will infer the appropriate method from the `Content-Type` response header.
+ * You can override this behavior with any of the {@link Body} methods.
+ * Select `stream` if you don't want to parse response data at all.
+ *
+ * @default 'auto'
+ */
+ parseAs?:
+ | "arrayBuffer"
+ | "auto"
+ | "blob"
+ | "formData"
+ | "json"
+ | "stream"
+ | "text";
+ /**
+ * Should we return only data or multiple fields (data, error, response, etc.)?
+ *
+ * @default 'fields'
+ */
+ responseStyle?: ResponseStyle;
+ /**
+ * Throw an error instead of returning it in the response?
+ *
+ * @default false
+ */
+ throwOnError?: T["throwOnError"];
}
export interface RequestOptions<
- TResponseStyle extends ResponseStyle = "fields",
- ThrowOnError extends boolean = boolean,
- Url extends string = string,
+ TResponseStyle extends ResponseStyle = "fields",
+ ThrowOnError extends boolean = boolean,
+ Url extends string = string,
> extends Config<{
- responseStyle: TResponseStyle;
- throwOnError: ThrowOnError;
- }> {
- /**
- * Any body that you want to add to your request.
- *
- * {@link https://developer.mozilla.org/docs/Web/API/fetch#body}
- */
- body?: unknown;
- path?: Record;
- query?: Record;
- /**
- * Security mechanism(s) to use for the request.
- */
- security?: ReadonlyArray;
- url: Url;
+ responseStyle: TResponseStyle;
+ throwOnError: ThrowOnError;
+ }> {
+ /**
+ * Any body that you want to add to your request.
+ *
+ * {@link https://developer.mozilla.org/docs/Web/API/fetch#body}
+ */
+ body?: unknown;
+ path?: Record;
+ query?: Record;
+ /**
+ * Security mechanism(s) to use for the request.
+ */
+ security?: ReadonlyArray;
+ url: Url;
}
export type RequestResult<
- TData = unknown,
- TError = unknown,
- ThrowOnError extends boolean = boolean,
- TResponseStyle extends ResponseStyle = "fields",
+ TData = unknown,
+ TError = unknown,
+ ThrowOnError extends boolean = boolean,
+ TResponseStyle extends ResponseStyle = "fields",
> = ThrowOnError extends true
- ? Promise<
- TResponseStyle extends "data"
- ? TData extends Record
- ? TData[keyof TData]
- : TData
- : {
- data: TData extends Record
- ? TData[keyof TData]
- : TData;
- request: Request;
- response: Response;
- }
- >
- : Promise<
- TResponseStyle extends "data"
- ?
- | (TData extends Record
- ? TData[keyof TData]
- : TData)
- | undefined
- : (
- | {
- data: TData extends Record
- ? TData[keyof TData]
- : TData;
- error: undefined;
- }
- | {
- data: undefined;
- error: TError extends Record
- ? TError[keyof TError]
- : TError;
- }
- ) & {
- request: Request;
- response: Response;
- }
- >;
+ ? Promise<
+ TResponseStyle extends "data"
+ ? TData extends Record
+ ? TData[keyof TData]
+ : TData
+ : {
+ data: TData extends Record
+ ? TData[keyof TData]
+ : TData;
+ request: Request;
+ response: Response;
+ }
+ >
+ : Promise<
+ TResponseStyle extends "data"
+ ?
+ | (TData extends Record
+ ? TData[keyof TData]
+ : TData)
+ | undefined
+ : (
+ | {
+ data: TData extends Record
+ ? TData[keyof TData]
+ : TData;
+ error: undefined;
+ }
+ | {
+ data: undefined;
+ error: TError extends Record
+ ? TError[keyof TError]
+ : TError;
+ }
+ ) & {
+ request: Request;
+ response: Response;
+ }
+ >;
export interface ClientOptions {
- baseUrl?: string;
- responseStyle?: ResponseStyle;
- throwOnError?: boolean;
+ baseUrl?: string;
+ responseStyle?: ResponseStyle;
+ throwOnError?: boolean;
}
type MethodFn = <
- TData = unknown,
- TError = unknown,
- ThrowOnError extends boolean = false,
- TResponseStyle extends ResponseStyle = "fields",
+ TData = unknown,
+ TError = unknown,
+ ThrowOnError extends boolean = false,
+ TResponseStyle extends ResponseStyle = "fields",
>(
- options: Omit, "method">,
+ options: Omit, "method">,
) => RequestResult;
type RequestFn = <
- TData = unknown,
- TError = unknown,
- ThrowOnError extends boolean = false,
- TResponseStyle extends ResponseStyle = "fields",
+ TData = unknown,
+ TError = unknown,
+ ThrowOnError extends boolean = false,
+ TResponseStyle extends ResponseStyle = "fields",
>(
- options: Omit, "method"> &
- Pick>, "method">,
+ options: Omit, "method"> &
+ Pick>, "method">,
) => RequestResult;
type BuildUrlFn = <
- TData extends {
- body?: unknown;
- path?: Record;
- query?: Record;
- url: string;
- },
+ TData extends {
+ body?: unknown;
+ path?: Record;
+ query?: Record;
+ url: string;
+ },
>(
- options: Pick & Options,
+ options: Pick & Options,
) => string;
export type Client = CoreClient & {
- interceptors: Middleware;
+ interceptors: Middleware;
};
/**
@@ -175,48 +175,48 @@ export type Client = CoreClient & {
* to ensure your client always has the correct values.
*/
export type CreateClientConfig = (
- override?: Config,
+ override?: Config,
) => Config & T>;
export interface TDataShape {
- body?: unknown;
- headers?: unknown;
- path?: unknown;
- query?: unknown;
- url: string;
+ body?: unknown;
+ headers?: unknown;
+ path?: unknown;
+ query?: unknown;
+ url: string;
}
type OmitKeys = Pick>;
export type Options<
- TData extends TDataShape = TDataShape,
- ThrowOnError extends boolean = boolean,
- TResponseStyle extends ResponseStyle = "fields",
+ TData extends TDataShape = TDataShape,
+ ThrowOnError extends boolean = boolean,
+ TResponseStyle extends ResponseStyle = "fields",
> = OmitKeys<
- RequestOptions,
- "body" | "path" | "query" | "url"
+ RequestOptions,
+ "body" | "path" | "query" | "url"
> &
- Omit;
+ Omit;
export type OptionsLegacyParser<
- TData = unknown,
- ThrowOnError extends boolean = boolean,
- TResponseStyle extends ResponseStyle = "fields",
+ TData = unknown,
+ ThrowOnError extends boolean = boolean,
+ TResponseStyle extends ResponseStyle = "fields",
> = TData extends { body?: any }
- ? TData extends { headers?: any }
- ? OmitKeys<
- RequestOptions,
- "body" | "headers" | "url"
- > &
- TData
- : OmitKeys, "body" | "url"> &
- TData &
- Pick, "headers">
- : TData extends { headers?: any }
- ? OmitKeys<
- RequestOptions,
- "headers" | "url"
- > &
- TData &
- Pick, "body">
- : OmitKeys, "url"> & TData;
+ ? TData extends { headers?: any }
+ ? OmitKeys<
+ RequestOptions,
+ "body" | "headers" | "url"
+ > &
+ TData
+ : OmitKeys, "body" | "url"> &
+ TData &
+ Pick, "headers">
+ : TData extends { headers?: any }
+ ? OmitKeys<
+ RequestOptions,
+ "headers" | "url"
+ > &
+ TData &
+ Pick, "body">
+ : OmitKeys, "url"> & TData;
diff --git a/packages/engine/src/client/client/utils.ts b/packages/engine/src/client/client/utils.ts
index 103b5315f96..2b5bb778117 100644
--- a/packages/engine/src/client/client/utils.ts
+++ b/packages/engine/src/client/client/utils.ts
@@ -1,19 +1,19 @@
import { getAuthToken } from "../core/auth.js";
import type {
- QuerySerializer,
- QuerySerializerOptions,
+ QuerySerializer,
+ QuerySerializerOptions,
} from "../core/bodySerializer.js";
import { jsonBodySerializer } from "../core/bodySerializer.js";
import {
- serializeArrayParam,
- serializeObjectParam,
- serializePrimitiveParam,
+ serializeArrayParam,
+ serializeObjectParam,
+ serializePrimitiveParam,
} from "../core/pathSerializer.js";
import type { Client, ClientOptions, Config, RequestOptions } from "./types.js";
interface PathSerializer {
- path: Record;
- url: string;
+ path: Record;
+ url: string;
}
const PATH_PARAM_RE = /\{[^{}]+\}/g;
@@ -23,395 +23,395 @@ type MatrixStyle = "label" | "matrix" | "simple";
type ArraySeparatorStyle = ArrayStyle | MatrixStyle;
const defaultPathSerializer = ({ path, url: _url }: PathSerializer) => {
- let url = _url;
- const matches = _url.match(PATH_PARAM_RE);
- if (matches) {
- for (const match of matches) {
- let explode = false;
- let name = match.substring(1, match.length - 1);
- let style: ArraySeparatorStyle = "simple";
-
- if (name.endsWith("*")) {
- explode = true;
- name = name.substring(0, name.length - 1);
- }
-
- if (name.startsWith(".")) {
- name = name.substring(1);
- style = "label";
- } else if (name.startsWith(";")) {
- name = name.substring(1);
- style = "matrix";
- }
-
- const value = path[name];
-
- if (value === undefined || value === null) {
- continue;
- }
-
- if (Array.isArray(value)) {
- url = url.replace(
- match,
- serializeArrayParam({ explode, name, style, value }),
- );
- continue;
- }
-
- if (typeof value === "object") {
- url = url.replace(
- match,
- serializeObjectParam({
- explode,
- name,
- style,
- value: value as Record,
- valueOnly: true,
- }),
- );
- continue;
- }
-
- if (style === "matrix") {
- url = url.replace(
- match,
- `;${serializePrimitiveParam({
- name,
- value: value as string,
- })}`,
- );
- continue;
- }
-
- const replaceValue = encodeURIComponent(
- style === "label" ? `.${value as string}` : (value as string),
- );
- url = url.replace(match, replaceValue);
- }
- }
- return url;
+ let url = _url;
+ const matches = _url.match(PATH_PARAM_RE);
+ if (matches) {
+ for (const match of matches) {
+ let explode = false;
+ let name = match.substring(1, match.length - 1);
+ let style: ArraySeparatorStyle = "simple";
+
+ if (name.endsWith("*")) {
+ explode = true;
+ name = name.substring(0, name.length - 1);
+ }
+
+ if (name.startsWith(".")) {
+ name = name.substring(1);
+ style = "label";
+ } else if (name.startsWith(";")) {
+ name = name.substring(1);
+ style = "matrix";
+ }
+
+ const value = path[name];
+
+ if (value === undefined || value === null) {
+ continue;
+ }
+
+ if (Array.isArray(value)) {
+ url = url.replace(
+ match,
+ serializeArrayParam({ explode, name, style, value }),
+ );
+ continue;
+ }
+
+ if (typeof value === "object") {
+ url = url.replace(
+ match,
+ serializeObjectParam({
+ explode,
+ name,
+ style,
+ value: value as Record,
+ valueOnly: true,
+ }),
+ );
+ continue;
+ }
+
+ if (style === "matrix") {
+ url = url.replace(
+ match,
+ `;${serializePrimitiveParam({
+ name,
+ value: value as string,
+ })}`,
+ );
+ continue;
+ }
+
+ const replaceValue = encodeURIComponent(
+ style === "label" ? `.${value as string}` : (value as string),
+ );
+ url = url.replace(match, replaceValue);
+ }
+ }
+ return url;
};
export const createQuerySerializer = ({
- allowReserved,
- array,
- object,
+ allowReserved,
+ array,
+ object,
}: QuerySerializerOptions = {}) => {
- const querySerializer = (queryParams: T) => {
- const search: string[] = [];
- if (queryParams && typeof queryParams === "object") {
- for (const name in queryParams) {
- const value = queryParams[name];
-
- if (value === undefined || value === null) {
- continue;
- }
-
- if (Array.isArray(value)) {
- const serializedArray = serializeArrayParam({
- allowReserved,
- explode: true,
- name,
- style: "form",
- value,
- ...array,
- });
- if (serializedArray) search.push(serializedArray);
- } else if (typeof value === "object") {
- const serializedObject = serializeObjectParam({
- allowReserved,
- explode: true,
- name,
- style: "deepObject",
- value: value as Record,
- ...object,
- });
- if (serializedObject) search.push(serializedObject);
- } else {
- const serializedPrimitive = serializePrimitiveParam({
- allowReserved,
- name,
- value: value as string,
- });
- if (serializedPrimitive) search.push(serializedPrimitive);
- }
- }
- }
- return search.join("&");
- };
- return querySerializer;
+ const querySerializer = (queryParams: T) => {
+ const search: string[] = [];
+ if (queryParams && typeof queryParams === "object") {
+ for (const name in queryParams) {
+ const value = queryParams[name];
+
+ if (value === undefined || value === null) {
+ continue;
+ }
+
+ if (Array.isArray(value)) {
+ const serializedArray = serializeArrayParam({
+ allowReserved,
+ explode: true,
+ name,
+ style: "form",
+ value,
+ ...array,
+ });
+ if (serializedArray) search.push(serializedArray);
+ } else if (typeof value === "object") {
+ const serializedObject = serializeObjectParam({
+ allowReserved,
+ explode: true,
+ name,
+ style: "deepObject",
+ value: value as Record,
+ ...object,
+ });
+ if (serializedObject) search.push(serializedObject);
+ } else {
+ const serializedPrimitive = serializePrimitiveParam({
+ allowReserved,
+ name,
+ value: value as string,
+ });
+ if (serializedPrimitive) search.push(serializedPrimitive);
+ }
+ }
+ }
+ return search.join("&");
+ };
+ return querySerializer;
};
/**
* Infers parseAs value from provided Content-Type header.
*/
export const getParseAs = (
- contentType: string | null,
+ contentType: string | null,
): Exclude => {
- if (!contentType) {
- // If no Content-Type header is provided, the best we can do is return the raw response body,
- // which is effectively the same as the 'stream' option.
- return "stream";
- }
-
- const cleanContent = contentType.split(";")[0]?.trim();
-
- if (!cleanContent) {
- return;
- }
-
- if (
- cleanContent.startsWith("application/json") ||
- cleanContent.endsWith("+json")
- ) {
- return "json";
- }
-
- if (cleanContent === "multipart/form-data") {
- return "formData";
- }
-
- if (
- ["application/", "audio/", "image/", "video/"].some((type) =>
- cleanContent.startsWith(type),
- )
- ) {
- return "blob";
- }
-
- if (cleanContent.startsWith("text/")) {
- return "text";
- }
-
- return;
+ if (!contentType) {
+ // If no Content-Type header is provided, the best we can do is return the raw response body,
+ // which is effectively the same as the 'stream' option.
+ return "stream";
+ }
+
+ const cleanContent = contentType.split(";")[0]?.trim();
+
+ if (!cleanContent) {
+ return;
+ }
+
+ if (
+ cleanContent.startsWith("application/json") ||
+ cleanContent.endsWith("+json")
+ ) {
+ return "json";
+ }
+
+ if (cleanContent === "multipart/form-data") {
+ return "formData";
+ }
+
+ if (
+ ["application/", "audio/", "image/", "video/"].some((type) =>
+ cleanContent.startsWith(type),
+ )
+ ) {
+ return "blob";
+ }
+
+ if (cleanContent.startsWith("text/")) {
+ return "text";
+ }
+
+ return;
};
export const setAuthParams = async ({
- security,
- ...options
+ security,
+ ...options
}: Pick, "security"> &
- Pick & {
- headers: Headers;
- }) => {
- for (const auth of security) {
- const token = await getAuthToken(auth, options.auth);
-
- if (!token) {
- continue;
- }
-
- const name = auth.name ?? "Authorization";
-
- switch (auth.in) {
- case "query":
- if (!options.query) {
- options.query = {};
- }
- options.query[name] = token;
- break;
- case "cookie":
- options.headers.append("Cookie", `${name}=${token}`);
- break;
- case "header":
- default:
- options.headers.set(name, token);
- break;
- }
-
- return;
- }
+ Pick & {
+ headers: Headers;
+ }) => {
+ for (const auth of security) {
+ const token = await getAuthToken(auth, options.auth);
+
+ if (!token) {
+ continue;
+ }
+
+ const name = auth.name ?? "Authorization";
+
+ switch (auth.in) {
+ case "query":
+ if (!options.query) {
+ options.query = {};
+ }
+ options.query[name] = token;
+ break;
+ case "cookie":
+ options.headers.append("Cookie", `${name}=${token}`);
+ break;
+ case "header":
+ default:
+ options.headers.set(name, token);
+ break;
+ }
+
+ return;
+ }
};
export const buildUrl: Client["buildUrl"] = (options) => {
- const url = getUrl({
- baseUrl: options.baseUrl as string,
- path: options.path,
- query: options.query,
- querySerializer:
- typeof options.querySerializer === "function"
- ? options.querySerializer
- : createQuerySerializer(options.querySerializer),
- url: options.url,
- });
- return url;
+ const url = getUrl({
+ baseUrl: options.baseUrl as string,
+ path: options.path,
+ query: options.query,
+ querySerializer:
+ typeof options.querySerializer === "function"
+ ? options.querySerializer
+ : createQuerySerializer(options.querySerializer),
+ url: options.url,
+ });
+ return url;
};
export const getUrl = ({
- baseUrl,
- path,
- query,
- querySerializer,
- url: _url,
+ baseUrl,
+ path,
+ query,
+ querySerializer,
+ url: _url,
}: {
- baseUrl?: string;
- path?: Record;
- query?: Record;
- querySerializer: QuerySerializer;
- url: string;
+ baseUrl?: string;
+ path?: Record;
+ query?: Record;
+ querySerializer: QuerySerializer;
+ url: string;
}) => {
- const pathUrl = _url.startsWith("/") ? _url : `/${_url}`;
- let url = (baseUrl ?? "") + pathUrl;
- if (path) {
- url = defaultPathSerializer({ path, url });
- }
- let search = query ? querySerializer(query) : "";
- if (search.startsWith("?")) {
- search = search.substring(1);
- }
- if (search) {
- url += `?${search}`;
- }
- return url;
+ const pathUrl = _url.startsWith("/") ? _url : `/${_url}`;
+ let url = (baseUrl ?? "") + pathUrl;
+ if (path) {
+ url = defaultPathSerializer({ path, url });
+ }
+ let search = query ? querySerializer(query) : "";
+ if (search.startsWith("?")) {
+ search = search.substring(1);
+ }
+ if (search) {
+ url += `?${search}`;
+ }
+ return url;
};
export const mergeConfigs = (a: Config, b: Config): Config => {
- const config = { ...a, ...b };
- if (config.baseUrl?.endsWith("/")) {
- config.baseUrl = config.baseUrl.substring(0, config.baseUrl.length - 1);
- }
- config.headers = mergeHeaders(a.headers, b.headers);
- return config;
+ const config = { ...a, ...b };
+ if (config.baseUrl?.endsWith("/")) {
+ config.baseUrl = config.baseUrl.substring(0, config.baseUrl.length - 1);
+ }
+ config.headers = mergeHeaders(a.headers, b.headers);
+ return config;
};
export const mergeHeaders = (
- ...headers: Array["headers"] | undefined>
+ ...headers: Array["headers"] | undefined>
): Headers => {
- const mergedHeaders = new Headers();
- for (const header of headers) {
- if (!header || typeof header !== "object") {
- continue;
- }
-
- const iterator =
- header instanceof Headers ? header.entries() : Object.entries(header);
-
- for (const [key, value] of iterator) {
- if (value === null) {
- mergedHeaders.delete(key);
- } else if (Array.isArray(value)) {
- for (const v of value) {
- mergedHeaders.append(key, v as string);
- }
- } else if (value !== undefined) {
- // assume object headers are meant to be JSON stringified, i.e. their
- // content value in OpenAPI specification is 'application/json'
- mergedHeaders.set(
- key,
- typeof value === "object" ? JSON.stringify(value) : (value as string),
- );
- }
- }
- }
- return mergedHeaders;
+ const mergedHeaders = new Headers();
+ for (const header of headers) {
+ if (!header || typeof header !== "object") {
+ continue;
+ }
+
+ const iterator =
+ header instanceof Headers ? header.entries() : Object.entries(header);
+
+ for (const [key, value] of iterator) {
+ if (value === null) {
+ mergedHeaders.delete(key);
+ } else if (Array.isArray(value)) {
+ for (const v of value) {
+ mergedHeaders.append(key, v as string);
+ }
+ } else if (value !== undefined) {
+ // assume object headers are meant to be JSON stringified, i.e. their
+ // content value in OpenAPI specification is 'application/json'
+ mergedHeaders.set(
+ key,
+ typeof value === "object" ? JSON.stringify(value) : (value as string),
+ );
+ }
+ }
+ }
+ return mergedHeaders;
};
type ErrInterceptor = (
- error: Err,
- response: Res,
- request: Req,
- options: Options,
+ error: Err,
+ response: Res,
+ request: Req,
+ options: Options,
) => Err | Promise;
type ReqInterceptor = (
- request: Req,
- options: Options,
+ request: Req,
+ options: Options,
) => Req | Promise;
type ResInterceptor = (
- response: Res,
- request: Req,
- options: Options,
+ response: Res,
+ request: Req,
+ options: Options,
) => Res | Promise;
class Interceptors {
- _fns: (Interceptor | null)[];
-
- constructor() {
- this._fns = [];
- }
-
- clear() {
- this._fns = [];
- }
-
- getInterceptorIndex(id: number | Interceptor): number {
- if (typeof id === "number") {
- return this._fns[id] ? id : -1;
- } else {
- return this._fns.indexOf(id);
- }
- }
- exists(id: number | Interceptor) {
- const index = this.getInterceptorIndex(id);
- return !!this._fns[index];
- }
-
- eject(id: number | Interceptor) {
- const index = this.getInterceptorIndex(id);
- if (this._fns[index]) {
- this._fns[index] = null;
- }
- }
-
- update(id: number | Interceptor, fn: Interceptor) {
- const index = this.getInterceptorIndex(id);
- if (this._fns[index]) {
- this._fns[index] = fn;
- return id;
- } else {
- return false;
- }
- }
-
- use(fn: Interceptor) {
- this._fns = [...this._fns, fn];
- return this._fns.length - 1;
- }
+ _fns: (Interceptor | null)[];
+
+ constructor() {
+ this._fns = [];
+ }
+
+ clear() {
+ this._fns = [];
+ }
+
+ getInterceptorIndex(id: number | Interceptor): number {
+ if (typeof id === "number") {
+ return this._fns[id] ? id : -1;
+ } else {
+ return this._fns.indexOf(id);
+ }
+ }
+ exists(id: number | Interceptor) {
+ const index = this.getInterceptorIndex(id);
+ return !!this._fns[index];
+ }
+
+ eject(id: number | Interceptor) {
+ const index = this.getInterceptorIndex(id);
+ if (this._fns[index]) {
+ this._fns[index] = null;
+ }
+ }
+
+ update(id: number | Interceptor, fn: Interceptor) {
+ const index = this.getInterceptorIndex(id);
+ if (this._fns[index]) {
+ this._fns[index] = fn;
+ return id;
+ } else {
+ return false;
+ }
+ }
+
+ use(fn: Interceptor) {
+ this._fns = [...this._fns, fn];
+ return this._fns.length - 1;
+ }
}
// `createInterceptors()` response, meant for external use as it does not
// expose internals
export interface Middleware {
- error: Pick<
- Interceptors>,
- "eject" | "use"
- >;
- request: Pick>, "eject" | "use">;
- response: Pick<
- Interceptors>,
- "eject" | "use"
- >;
+ error: Pick<
+ Interceptors>,
+ "eject" | "use"
+ >;
+ request: Pick>, "eject" | "use">;
+ response: Pick<
+ Interceptors>,
+ "eject" | "use"
+ >;
}
// do not add `Middleware` as return type so we can use _fns internally
export const createInterceptors = () => ({
- error: new Interceptors>(),
- request: new Interceptors>(),
- response: new Interceptors>(),
+ error: new Interceptors>(),
+ request: new Interceptors>(),
+ response: new Interceptors>(),
});
const defaultQuerySerializer = createQuerySerializer({
- allowReserved: false,
- array: {
- explode: true,
- style: "form",
- },
- object: {
- explode: true,
- style: "deepObject",
- },
+ allowReserved: false,
+ array: {
+ explode: true,
+ style: "form",
+ },
+ object: {
+ explode: true,
+ style: "deepObject",
+ },
});
const defaultHeaders = {
- "Content-Type": "application/json",
+ "Content-Type": "application/json",
};
export const createConfig = (
- override: Config & T> = {},
+ override: Config & T> = {},
): Config & T> => ({
- ...jsonBodySerializer,
- headers: defaultHeaders,
- parseAs: "auto",
- querySerializer: defaultQuerySerializer,
- ...override,
+ ...jsonBodySerializer,
+ headers: defaultHeaders,
+ parseAs: "auto",
+ querySerializer: defaultQuerySerializer,
+ ...override,
});
diff --git a/packages/engine/src/client/core/auth.ts b/packages/engine/src/client/core/auth.ts
index 70e9d5dba5e..f9012011fc2 100644
--- a/packages/engine/src/client/core/auth.ts
+++ b/packages/engine/src/client/core/auth.ts
@@ -1,40 +1,40 @@
export type AuthToken = string | undefined;
export interface Auth {
- /**
- * Which part of the request do we use to send the auth?
- *
- * @default 'header'
- */
- in?: "header" | "query" | "cookie";
- /**
- * Header or query parameter name.
- *
- * @default 'Authorization'
- */
- name?: string;
- scheme?: "basic" | "bearer";
- type: "apiKey" | "http";
+ /**
+ * Which part of the request do we use to send the auth?
+ *
+ * @default 'header'
+ */
+ in?: "header" | "query" | "cookie";
+ /**
+ * Header or query parameter name.
+ *
+ * @default 'Authorization'
+ */
+ name?: string;
+ scheme?: "basic" | "bearer";
+ type: "apiKey" | "http";
}
export const getAuthToken = async (
- auth: Auth,
- callback: ((auth: Auth) => Promise | AuthToken) | AuthToken,
+ auth: Auth,
+ callback: ((auth: Auth) => Promise | AuthToken) | AuthToken,
): Promise => {
- const token =
- typeof callback === "function" ? await callback(auth) : callback;
+ const token =
+ typeof callback === "function" ? await callback(auth) : callback;
- if (!token) {
- return;
- }
+ if (!token) {
+ return;
+ }
- if (auth.scheme === "bearer") {
- return `Bearer ${token}`;
- }
+ if (auth.scheme === "bearer") {
+ return `Bearer ${token}`;
+ }
- if (auth.scheme === "basic") {
- return `Basic ${btoa(token)}`;
- }
+ if (auth.scheme === "basic") {
+ return `Basic ${btoa(token)}`;
+ }
- return token;
+ return token;
};
diff --git a/packages/engine/src/client/core/bodySerializer.ts b/packages/engine/src/client/core/bodySerializer.ts
index e68daa47a7b..7d254a96ebe 100644
--- a/packages/engine/src/client/core/bodySerializer.ts
+++ b/packages/engine/src/client/core/bodySerializer.ts
@@ -1,7 +1,7 @@
import type {
- ArrayStyle,
- ObjectStyle,
- SerializerOptions,
+ ArrayStyle,
+ ObjectStyle,
+ SerializerOptions,
} from "./pathSerializer.js";
export type QuerySerializer = (query: Record) => string;
@@ -9,76 +9,76 @@ export type QuerySerializer = (query: Record) => string;
export type BodySerializer = (body: any) => any;
export interface QuerySerializerOptions {
- allowReserved?: boolean;
- array?: SerializerOptions;
- object?: SerializerOptions;
+ allowReserved?: boolean;
+ array?: SerializerOptions;
+ object?: SerializerOptions;
}
const serializeFormDataPair = (data: FormData, key: string, value: unknown) => {
- if (typeof value === "string" || value instanceof Blob) {
- data.append(key, value);
- } else {
- data.append(key, JSON.stringify(value));
- }
+ if (typeof value === "string" || value instanceof Blob) {
+ data.append(key, value);
+ } else {
+ data.append(key, JSON.stringify(value));
+ }
};
const serializeUrlSearchParamsPair = (
- data: URLSearchParams,
- key: string,
- value: unknown,
+ data: URLSearchParams,
+ key: string,
+ value: unknown,
) => {
- if (typeof value === "string") {
- data.append(key, value);
- } else {
- data.append(key, JSON.stringify(value));
- }
+ if (typeof value === "string") {
+ data.append(key, value);
+ } else {
+ data.append(key, JSON.stringify(value));
+ }
};
export const formDataBodySerializer = {
- bodySerializer: | Array>>(
- body: T,
- ) => {
- const data = new FormData();
+ bodySerializer: | Array>>(
+ body: T,
+ ) => {
+ const data = new FormData();
- Object.entries(body).forEach(([key, value]) => {
- if (value === undefined || value === null) {
- return;
- }
- if (Array.isArray(value)) {
- value.forEach((v) => serializeFormDataPair(data, key, v));
- } else {
- serializeFormDataPair(data, key, value);
- }
- });
+ Object.entries(body).forEach(([key, value]) => {
+ if (value === undefined || value === null) {
+ return;
+ }
+ if (Array.isArray(value)) {
+ value.forEach((v) => serializeFormDataPair(data, key, v));
+ } else {
+ serializeFormDataPair(data, key, value);
+ }
+ });
- return data;
- },
+ return data;
+ },
};
export const jsonBodySerializer = {
- bodySerializer: (body: T) =>
- JSON.stringify(body, (_key, value) =>
- typeof value === "bigint" ? value.toString() : value,
- ),
+ bodySerializer: (body: T) =>
+ JSON.stringify(body, (_key, value) =>
+ typeof value === "bigint" ? value.toString() : value,
+ ),
};
export const urlSearchParamsBodySerializer = {
- bodySerializer: | Array>>(
- body: T,
- ) => {
- const data = new URLSearchParams();
+ bodySerializer: | Array>>(
+ body: T,
+ ) => {
+ const data = new URLSearchParams();
- Object.entries(body).forEach(([key, value]) => {
- if (value === undefined || value === null) {
- return;
- }
- if (Array.isArray(value)) {
- value.forEach((v) => serializeUrlSearchParamsPair(data, key, v));
- } else {
- serializeUrlSearchParamsPair(data, key, value);
- }
- });
+ Object.entries(body).forEach(([key, value]) => {
+ if (value === undefined || value === null) {
+ return;
+ }
+ if (Array.isArray(value)) {
+ value.forEach((v) => serializeUrlSearchParamsPair(data, key, v));
+ } else {
+ serializeUrlSearchParamsPair(data, key, value);
+ }
+ });
- return data.toString();
- },
+ return data.toString();
+ },
};
diff --git a/packages/engine/src/client/core/params.ts b/packages/engine/src/client/core/params.ts
index 0771542b148..2b3490369bc 100644
--- a/packages/engine/src/client/core/params.ts
+++ b/packages/engine/src/client/core/params.ts
@@ -1,141 +1,141 @@
type Slot = "body" | "headers" | "path" | "query";
export type Field =
- | {
- in: Exclude;
- key: string;
- map?: string;
- }
- | {
- in: Extract;
- key?: string;
- map?: string;
- };
+ | {
+ in: Exclude;
+ key: string;
+ map?: string;
+ }
+ | {
+ in: Extract;
+ key?: string;
+ map?: string;
+ };
export interface Fields {
- allowExtra?: Partial>;
- args?: ReadonlyArray;
+ allowExtra?: Partial>;
+ args?: ReadonlyArray;
}
export type FieldsConfig = ReadonlyArray;
const extraPrefixesMap: Record = {
- $body_: "body",
- $headers_: "headers",
- $path_: "path",
- $query_: "query",
+ $body_: "body",
+ $headers_: "headers",
+ $path_: "path",
+ $query_: "query",
};
const extraPrefixes = Object.entries(extraPrefixesMap);
type KeyMap = Map<
- string,
- {
- in: Slot;
- map?: string;
- }
+ string,
+ {
+ in: Slot;
+ map?: string;
+ }
>;
const buildKeyMap = (fields: FieldsConfig, map?: KeyMap): KeyMap => {
- if (!map) {
- map = new Map();
- }
-
- for (const config of fields) {
- if ("in" in config) {
- if (config.key) {
- map.set(config.key, {
- in: config.in,
- map: config.map,
- });
- }
- } else if (config.args) {
- buildKeyMap(config.args, map);
- }
- }
-
- return map;
+ if (!map) {
+ map = new Map();
+ }
+
+ for (const config of fields) {
+ if ("in" in config) {
+ if (config.key) {
+ map.set(config.key, {
+ in: config.in,
+ map: config.map,
+ });
+ }
+ } else if (config.args) {
+ buildKeyMap(config.args, map);
+ }
+ }
+
+ return map;
};
interface Params {
- body: unknown;
- headers: Record;
- path: Record;
- query: Record;
+ body: unknown;
+ headers: Record;
+ path: Record;
+ query: Record;
}
const stripEmptySlots = (params: Params) => {
- for (const [slot, value] of Object.entries(params)) {
- if (value && typeof value === "object" && !Object.keys(value).length) {
- delete params[slot as Slot];
- }
- }
+ for (const [slot, value] of Object.entries(params)) {
+ if (value && typeof value === "object" && !Object.keys(value).length) {
+ delete params[slot as Slot];
+ }
+ }
};
export const buildClientParams = (
- args: ReadonlyArray,
- fields: FieldsConfig,
+ args: ReadonlyArray,
+ fields: FieldsConfig,
) => {
- const params: Params = {
- body: {},
- headers: {},
- path: {},
- query: {},
- };
-
- const map = buildKeyMap(fields);
-
- let config: FieldsConfig[number] | undefined;
-
- for (const [index, arg] of args.entries()) {
- if (fields[index]) {
- config = fields[index];
- }
-
- if (!config) {
- continue;
- }
-
- if ("in" in config) {
- if (config.key) {
- const field = map.get(config.key)!;
- const name = field.map || config.key;
- (params[field.in] as Record)[name] = arg;
- } else {
- params.body = arg;
- }
- } else {
- for (const [key, value] of Object.entries(arg ?? {})) {
- const field = map.get(key);
-
- if (field) {
- const name = field.map || key;
- (params[field.in] as Record)[name] = value;
- } else {
- const extra = extraPrefixes.find(([prefix]) =>
- key.startsWith(prefix),
- );
-
- if (extra) {
- const [prefix, slot] = extra;
- (params[slot] as Record)[
- key.slice(prefix.length)
- ] = value;
- } else {
- for (const [slot, allowed] of Object.entries(
- config.allowExtra ?? {},
- )) {
- if (allowed) {
- (params[slot as Slot] as Record)[key] = value;
- break;
- }
- }
- }
- }
- }
- }
- }
-
- stripEmptySlots(params);
-
- return params;
+ const params: Params = {
+ body: {},
+ headers: {},
+ path: {},
+ query: {},
+ };
+
+ const map = buildKeyMap(fields);
+
+ let config: FieldsConfig[number] | undefined;
+
+ for (const [index, arg] of args.entries()) {
+ if (fields[index]) {
+ config = fields[index];
+ }
+
+ if (!config) {
+ continue;
+ }
+
+ if ("in" in config) {
+ if (config.key) {
+ const field = map.get(config.key)!;
+ const name = field.map || config.key;
+ (params[field.in] as Record)[name] = arg;
+ } else {
+ params.body = arg;
+ }
+ } else {
+ for (const [key, value] of Object.entries(arg ?? {})) {
+ const field = map.get(key);
+
+ if (field) {
+ const name = field.map || key;
+ (params[field.in] as Record)[name] = value;
+ } else {
+ const extra = extraPrefixes.find(([prefix]) =>
+ key.startsWith(prefix),
+ );
+
+ if (extra) {
+ const [prefix, slot] = extra;
+ (params[slot] as Record)[
+ key.slice(prefix.length)
+ ] = value;
+ } else {
+ for (const [slot, allowed] of Object.entries(
+ config.allowExtra ?? {},
+ )) {
+ if (allowed) {
+ (params[slot as Slot] as Record)[key] = value;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ stripEmptySlots(params);
+
+ return params;
};
diff --git a/packages/engine/src/client/core/pathSerializer.ts b/packages/engine/src/client/core/pathSerializer.ts
index 4052ad12795..2f5d1bf4148 100644
--- a/packages/engine/src/client/core/pathSerializer.ts
+++ b/packages/engine/src/client/core/pathSerializer.ts
@@ -1,18 +1,18 @@
interface SerializeOptions
- extends SerializePrimitiveOptions,
- SerializerOptions {}
+ extends SerializePrimitiveOptions,
+ SerializerOptions {}
interface SerializePrimitiveOptions {
- allowReserved?: boolean;
- name: string;
+ allowReserved?: boolean;
+ name: string;
}
export interface SerializerOptions {
- /**
- * @default true
- */
- explode: boolean;
- style: T;
+ /**
+ * @default true
+ */
+ explode: boolean;
+ style: T;
}
export type ArrayStyle = "form" | "spaceDelimited" | "pipeDelimited";
@@ -22,158 +22,158 @@ export type ObjectStyle = "form" | "deepObject";
type ObjectSeparatorStyle = ObjectStyle | MatrixStyle;
interface SerializePrimitiveParam extends SerializePrimitiveOptions {
- value: string;
+ value: string;
}
export const separatorArrayExplode = (style: ArraySeparatorStyle) => {
- switch (style) {
- case "label":
- return ".";
- case "matrix":
- return ";";
- case "simple":
- return ",";
- default:
- return "&";
- }
+ switch (style) {
+ case "label":
+ return ".";
+ case "matrix":
+ return ";";
+ case "simple":
+ return ",";
+ default:
+ return "&";
+ }
};
export const separatorArrayNoExplode = (style: ArraySeparatorStyle) => {
- switch (style) {
- case "form":
- return ",";
- case "pipeDelimited":
- return "|";
- case "spaceDelimited":
- return "%20";
- default:
- return ",";
- }
+ switch (style) {
+ case "form":
+ return ",";
+ case "pipeDelimited":
+ return "|";
+ case "spaceDelimited":
+ return "%20";
+ default:
+ return ",";
+ }
};
export const separatorObjectExplode = (style: ObjectSeparatorStyle) => {
- switch (style) {
- case "label":
- return ".";
- case "matrix":
- return ";";
- case "simple":
- return ",";
- default:
- return "&";
- }
+ switch (style) {
+ case "label":
+ return ".";
+ case "matrix":
+ return ";";
+ case "simple":
+ return ",";
+ default:
+ return "&";
+ }
};
export const serializeArrayParam = ({
- allowReserved,
- explode,
- name,
- style,
- value,
+ allowReserved,
+ explode,
+ name,
+ style,
+ value,
}: SerializeOptions & {
- value: unknown[];
+ value: unknown[];
}) => {
- if (!explode) {
- const joinedValues = (
- allowReserved ? value : value.map((v) => encodeURIComponent(v as string))
- ).join(separatorArrayNoExplode(style));
- switch (style) {
- case "label":
- return `.${joinedValues}`;
- case "matrix":
- return `;${name}=${joinedValues}`;
- case "simple":
- return joinedValues;
- default:
- return `${name}=${joinedValues}`;
- }
- }
-
- const separator = separatorArrayExplode(style);
- const joinedValues = value
- .map((v) => {
- if (style === "label" || style === "simple") {
- return allowReserved ? v : encodeURIComponent(v as string);
- }
-
- return serializePrimitiveParam({
- allowReserved,
- name,
- value: v as string,
- });
- })
- .join(separator);
- return style === "label" || style === "matrix"
- ? separator + joinedValues
- : joinedValues;
+ if (!explode) {
+ const joinedValues = (
+ allowReserved ? value : value.map((v) => encodeURIComponent(v as string))
+ ).join(separatorArrayNoExplode(style));
+ switch (style) {
+ case "label":
+ return `.${joinedValues}`;
+ case "matrix":
+ return `;${name}=${joinedValues}`;
+ case "simple":
+ return joinedValues;
+ default:
+ return `${name}=${joinedValues}`;
+ }
+ }
+
+ const separator = separatorArrayExplode(style);
+ const joinedValues = value
+ .map((v) => {
+ if (style === "label" || style === "simple") {
+ return allowReserved ? v : encodeURIComponent(v as string);
+ }
+
+ return serializePrimitiveParam({
+ allowReserved,
+ name,
+ value: v as string,
+ });
+ })
+ .join(separator);
+ return style === "label" || style === "matrix"
+ ? separator + joinedValues
+ : joinedValues;
};
export const serializePrimitiveParam = ({
- allowReserved,
- name,
- value,
+ allowReserved,
+ name,
+ value,
}: SerializePrimitiveParam) => {
- if (value === undefined || value === null) {
- return "";
- }
+ if (value === undefined || value === null) {
+ return "";
+ }
- if (typeof value === "object") {
- throw new Error(
- "Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.",
- );
- }
+ if (typeof value === "object") {
+ throw new Error(
+ "Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.",
+ );
+ }
- return `${name}=${allowReserved ? value : encodeURIComponent(value)}`;
+ return `${name}=${allowReserved ? value : encodeURIComponent(value)}`;
};
export const serializeObjectParam = ({
- allowReserved,
- explode,
- name,
- style,
- value,
- valueOnly,
+ allowReserved,
+ explode,
+ name,
+ style,
+ value,
+ valueOnly,
}: SerializeOptions & {
- value: Record | Date;
- valueOnly?: boolean;
+ value: Record | Date;
+ valueOnly?: boolean;
}) => {
- if (value instanceof Date) {
- return valueOnly ? value.toISOString() : `${name}=${value.toISOString()}`;
- }
-
- if (style !== "deepObject" && !explode) {
- let values: string[] = [];
- Object.entries(value).forEach(([key, v]) => {
- values = [
- ...values,
- key,
- allowReserved ? (v as string) : encodeURIComponent(v as string),
- ];
- });
- const joinedValues = values.join(",");
- switch (style) {
- case "form":
- return `${name}=${joinedValues}`;
- case "label":
- return `.${joinedValues}`;
- case "matrix":
- return `;${name}=${joinedValues}`;
- default:
- return joinedValues;
- }
- }
-
- const separator = separatorObjectExplode(style);
- const joinedValues = Object.entries(value)
- .map(([key, v]) =>
- serializePrimitiveParam({
- allowReserved,
- name: style === "deepObject" ? `${name}[${key}]` : key,
- value: v as string,
- }),
- )
- .join(separator);
- return style === "label" || style === "matrix"
- ? separator + joinedValues
- : joinedValues;
+ if (value instanceof Date) {
+ return valueOnly ? value.toISOString() : `${name}=${value.toISOString()}`;
+ }
+
+ if (style !== "deepObject" && !explode) {
+ let values: string[] = [];
+ Object.entries(value).forEach(([key, v]) => {
+ values = [
+ ...values,
+ key,
+ allowReserved ? (v as string) : encodeURIComponent(v as string),
+ ];
+ });
+ const joinedValues = values.join(",");
+ switch (style) {
+ case "form":
+ return `${name}=${joinedValues}`;
+ case "label":
+ return `.${joinedValues}`;
+ case "matrix":
+ return `;${name}=${joinedValues}`;
+ default:
+ return joinedValues;
+ }
+ }
+
+ const separator = separatorObjectExplode(style);
+ const joinedValues = Object.entries(value)
+ .map(([key, v]) =>
+ serializePrimitiveParam({
+ allowReserved,
+ name: style === "deepObject" ? `${name}[${key}]` : key,
+ value: v as string,
+ }),
+ )
+ .join(separator);
+ return style === "label" || style === "matrix"
+ ? separator + joinedValues
+ : joinedValues;
};
diff --git a/packages/engine/src/client/core/types.ts b/packages/engine/src/client/core/types.ts
index 41322e707cb..e5ee754b86e 100644
--- a/packages/engine/src/client/core/types.ts
+++ b/packages/engine/src/client/core/types.ts
@@ -1,98 +1,98 @@
import type { Auth, AuthToken } from "./auth.js";
import type {
- BodySerializer,
- QuerySerializer,
- QuerySerializerOptions,
+ BodySerializer,
+ QuerySerializer,
+ QuerySerializerOptions,
} from "./bodySerializer.js";
export interface Client<
- RequestFn = never,
- Config = unknown,
- MethodFn = never,
- BuildUrlFn = never,
+ RequestFn = never,
+ Config = unknown,
+ MethodFn = never,
+ BuildUrlFn = never,
> {
- /**
- * Returns the final request URL.
- */
- buildUrl: BuildUrlFn;
- connect: MethodFn;
- delete: MethodFn;
- get: MethodFn;
- getConfig: () => Config;
- head: MethodFn;
- options: MethodFn;
- patch: MethodFn;
- post: MethodFn;
- put: MethodFn;
- request: RequestFn;
- setConfig: (config: Config) => Config;
- trace: MethodFn;
+ /**
+ * Returns the final request URL.
+ */
+ buildUrl: BuildUrlFn;
+ connect: MethodFn;
+ delete: MethodFn;
+ get: MethodFn;
+ getConfig: () => Config;
+ head: MethodFn;
+ options: MethodFn;
+ patch: MethodFn;
+ post: MethodFn;
+ put: MethodFn;
+ request: RequestFn;
+ setConfig: (config: Config) => Config;
+ trace: MethodFn;
}
export interface Config {
- /**
- * Auth token or a function returning auth token. The resolved value will be
- * added to the request payload as defined by its `security` array.
- */
- auth?: ((auth: Auth) => Promise | AuthToken) | AuthToken;
- /**
- * A function for serializing request body parameter. By default,
- * {@link JSON.stringify()} will be used.
- */
- bodySerializer?: BodySerializer | null;
- /**
- * An object containing any HTTP headers that you want to pre-populate your
- * `Headers` object with.
- *
- * {@link https://developer.mozilla.org/docs/Web/API/Headers/Headers#init See more}
- */
- headers?:
- | RequestInit["headers"]
- | Record<
- string,
- | string
- | number
- | boolean
- | (string | number | boolean)[]
- | null
- | undefined
- | unknown
- >;
- /**
- * The request method.
- *
- * {@link https://developer.mozilla.org/docs/Web/API/fetch#method See more}
- */
- method?:
- | "CONNECT"
- | "DELETE"
- | "GET"
- | "HEAD"
- | "OPTIONS"
- | "PATCH"
- | "POST"
- | "PUT"
- | "TRACE";
- /**
- * A function for serializing request query parameters. By default, arrays
- * will be exploded in form style, objects will be exploded in deepObject
- * style, and reserved characters are percent-encoded.
- *
- * This method will have no effect if the native `paramsSerializer()` Axios
- * API function is used.
- *
- * {@link https://swagger.io/docs/specification/serialization/#query View examples}
- */
- querySerializer?: QuerySerializer | QuerySerializerOptions;
- /**
- * A function transforming response data before it's returned. This is useful
- * for post-processing data, e.g. converting ISO strings into Date objects.
- */
- responseTransformer?: (data: unknown) => Promise;
- /**
- * A function validating response data. This is useful if you want to ensure
- * the response conforms to the desired shape, so it can be safely passed to
- * the transformers and returned to the user.
- */
- responseValidator?: (data: unknown) => Promise;
+ /**
+ * Auth token or a function returning auth token. The resolved value will be
+ * added to the request payload as defined by its `security` array.
+ */
+ auth?: ((auth: Auth) => Promise | AuthToken) | AuthToken;
+ /**
+ * A function for serializing request body parameter. By default,
+ * {@link JSON.stringify()} will be used.
+ */
+ bodySerializer?: BodySerializer | null;
+ /**
+ * An object containing any HTTP headers that you want to pre-populate your
+ * `Headers` object with.
+ *
+ * {@link https://developer.mozilla.org/docs/Web/API/Headers/Headers#init See more}
+ */
+ headers?:
+ | RequestInit["headers"]
+ | Record<
+ string,
+ | string
+ | number
+ | boolean
+ | (string | number | boolean)[]
+ | null
+ | undefined
+ | unknown
+ >;
+ /**
+ * The request method.
+ *
+ * {@link https://developer.mozilla.org/docs/Web/API/fetch#method See more}
+ */
+ method?:
+ | "CONNECT"
+ | "DELETE"
+ | "GET"
+ | "HEAD"
+ | "OPTIONS"
+ | "PATCH"
+ | "POST"
+ | "PUT"
+ | "TRACE";
+ /**
+ * A function for serializing request query parameters. By default, arrays
+ * will be exploded in form style, objects will be exploded in deepObject
+ * style, and reserved characters are percent-encoded.
+ *
+ * This method will have no effect if the native `paramsSerializer()` Axios
+ * API function is used.
+ *
+ * {@link https://swagger.io/docs/specification/serialization/#query View examples}
+ */
+ querySerializer?: QuerySerializer | QuerySerializerOptions;
+ /**
+ * A function transforming response data before it's returned. This is useful
+ * for post-processing data, e.g. converting ISO strings into Date objects.
+ */
+ responseTransformer?: (data: unknown) => Promise;
+ /**
+ * A function validating response data. This is useful if you want to ensure
+ * the response conforms to the desired shape, so it can be safely passed to
+ * the transformers and returned to the user.
+ */
+ responseValidator?: (data: unknown) => Promise;
}
diff --git a/packages/engine/src/client/sdk.gen.ts b/packages/engine/src/client/sdk.gen.ts
index 5c9c02a09d2..d5d63f1a4b4 100644
--- a/packages/engine/src/client/sdk.gen.ts
+++ b/packages/engine/src/client/sdk.gen.ts
@@ -1,323 +1,376 @@
// This file is auto-generated by @hey-api/openapi-ts
import type {
- Client,
- Options as ClientOptions,
- TDataShape,
+ Client,
+ Options as ClientOptions,
+ TDataShape,
} from "./client/index.js";
import { client as _heyApiClient } from "./client.gen.js";
import type {
- CreateAccountData,
- CreateAccountResponses,
- EncodeFunctionDataData,
- EncodeFunctionDataResponses,
- GetNativeBalanceData,
- GetNativeBalanceErrors,
- GetNativeBalanceResponses,
- GetTransactionAnalyticsData,
- GetTransactionAnalyticsResponses,
- GetTransactionAnalyticsSummaryData,
- GetTransactionAnalyticsSummaryErrors,
- GetTransactionAnalyticsSummaryResponses,
- ListAccountsData,
- ListAccountsResponses,
- ReadContractData,
- ReadContractResponses,
- SearchTransactionsData,
- SearchTransactionsResponses,
- SendTransactionData,
- SendTransactionResponses,
- SignMessageData,
- SignMessageResponses,
- SignTransactionData,
- SignTransactionResponses,
- SignTypedDataData,
- SignTypedDataResponses,
- WriteContractData,
- WriteContractResponses,
+ CancelTransactionData,
+ CancelTransactionResponses,
+ CreateAccountData,
+ CreateAccountResponses,
+ EncodeContractData,
+ EncodeContractResponses,
+ GetActivityLogsData,
+ GetActivityLogsErrors,
+ GetActivityLogsResponses,
+ GetTransactionAnalyticsData,
+ GetTransactionAnalyticsResponses,
+ GetTransactionAnalyticsSummaryData,
+ GetTransactionAnalyticsSummaryErrors,
+ GetTransactionAnalyticsSummaryResponses,
+ GetTransactionsData,
+ GetTransactionsResponses,
+ ListAccountsData,
+ ListAccountsResponses,
+ ReadContractData,
+ ReadContractResponses,
+ SearchActivityLogsData,
+ SearchActivityLogsErrors,
+ SearchActivityLogsResponses,
+ SearchTransactionsData,
+ SearchTransactionsResponses,
+ SendTransactionData,
+ SendTransactionResponses,
+ SignMessageData,
+ SignMessageResponses,
+ SignTypedDataData,
+ SignTypedDataResponses,
+ WriteContractData,
+ WriteContractResponses,
} from "./types.gen.js";
export type Options<
- TData extends TDataShape = TDataShape,
- ThrowOnError extends boolean = boolean,
+ TData extends TDataShape = TDataShape,
+ ThrowOnError extends boolean = boolean,
> = ClientOptions & {
- /**
- * You can provide a client instance returned by `createClient()` instead of
- * individual options. This might be also useful if you want to implement a
- * custom client.
- */
- client?: Client;
- /**
- * You can pass arbitrary values through the `meta` object. This can be
- * used to access values that aren't defined as part of the SDK function.
- */
- meta?: Record;
+ /**
+ * You can provide a client instance returned by `createClient()` instead of
+ * individual options. This might be also useful if you want to implement a
+ * custom client.
+ */
+ client?: Client;
+ /**
+ * You can pass arbitrary values through the `meta` object. This can be
+ * used to access values that aren't defined as part of the SDK function.
+ */
+ meta?: Record;
};
/**
- * List Server Wallets
- * List all engine server wallets for the current project. Returns an array of EOA addresses with their corresponding predicted smart account addresses.
+ * Write Contract
+ * Call a contract function with a transaction
*/
-export const listAccounts = (
- options?: Options,
+export const writeContract = (
+ options: Options,
) => {
- return (options?.client ?? _heyApiClient).get<
- ListAccountsResponses,
- unknown,
- ThrowOnError
- >({
- security: [
- {
- name: "x-secret-key",
- type: "apiKey",
- },
- ],
- url: "/v1/accounts",
- ...options,
- });
+ return (options.client ?? _heyApiClient).post<
+ WriteContractResponses,
+ unknown,
+ ThrowOnError
+ >({
+ security: [
+ {
+ name: "x-secret-key",
+ type: "apiKey",
+ },
+ ],
+ url: "/v1/write/contract",
+ ...options,
+ headers: {
+ "Content-Type": "application/json",
+ ...options.headers,
+ },
+ });
};
/**
- * Create Server Wallet
- * Create a new engine server wallet. This is a helper route for creating a new EOA with your KMS provider, provided as a convenient alternative to creating an EOA directly with your KMS provider. Your KMS credentials are not stored, and usage of created accounts require your KMS credentials to be sent with requests.
+ * Write Transaction
+ * Execute raw transactions
*/
-export const createAccount = (
- options?: Options,
+export const sendTransaction = (
+ options: Options,
) => {
- return (options?.client ?? _heyApiClient).post<
- CreateAccountResponses,
- unknown,
- ThrowOnError
- >({
- security: [
- {
- name: "x-secret-key",
- type: "apiKey",
- },
- ],
- url: "/v1/accounts",
- ...options,
- headers: {
- "Content-Type": "application/json",
- ...options?.headers,
- },
- });
+ return (options.client ?? _heyApiClient).post<
+ SendTransactionResponses,
+ unknown,
+ ThrowOnError
+ >({
+ security: [
+ {
+ name: "x-secret-key",
+ type: "apiKey",
+ },
+ ],
+ url: "/v1/write/transaction",
+ ...options,
+ headers: {
+ "Content-Type": "application/json",
+ ...options.headers,
+ },
+ });
};
/**
- * Write Contract
- * Call a write function on a contract.
+ * Sign Message
+ * Sign messages using either EOA or Smart Account
*/
-export const writeContract = (
- options?: Options,
+export const signMessage = (
+ options: Options,
) => {
- return (options?.client ?? _heyApiClient).post<
- WriteContractResponses,
- unknown,
- ThrowOnError
- >({
- security: [
- {
- name: "x-secret-key",
- type: "apiKey",
- },
- ],
- url: "/v1/write/contract",
- ...options,
- headers: {
- "Content-Type": "application/json",
- ...options?.headers,
- },
- });
+ return (options.client ?? _heyApiClient).post<
+ SignMessageResponses,
+ unknown,
+ ThrowOnError
+ >({
+ security: [
+ {
+ name: "x-secret-key",
+ type: "apiKey",
+ },
+ ],
+ url: "/v1/sign/message",
+ ...options,
+ headers: {
+ "Content-Type": "application/json",
+ ...options.headers,
+ },
+ });
};
/**
- * Send Transaction
- * Send an encoded transaction or a batch of transactions
+ * Sign Typed Data
+ * Sign EIP-712 typed data using either EOA or Smart Account
*/
-export const sendTransaction = (
- options?: Options,
+export const signTypedData = (
+ options: Options,
) => {
- return (options?.client ?? _heyApiClient).post<
- SendTransactionResponses,
- unknown,
- ThrowOnError
- >({
- security: [
- {
- name: "x-secret-key",
- type: "apiKey",
- },
- ],
- url: "/v1/write/transaction",
- ...options,
- headers: {
- "Content-Type": "application/json",
- ...options?.headers,
- },
- });
+ return (options.client ?? _heyApiClient).post<
+ SignTypedDataResponses,
+ unknown,
+ ThrowOnError
+ >({
+ security: [
+ {
+ name: "x-secret-key",
+ type: "apiKey",
+ },
+ ],
+ url: "/v1/sign/typed-data",
+ ...options,
+ headers: {
+ "Content-Type": "application/json",
+ ...options.headers,
+ },
+ });
};
/**
- * Sign Transaction
- * Sign transactions without sending them.
+ * Read Contract
+ * Read from multiple smart contracts using multicall
*/
-export const signTransaction = (
- options?: Options,
+export const readContract = (
+ options: Options,
) => {
- return (options?.client ?? _heyApiClient).post<
- SignTransactionResponses,
- unknown,
- ThrowOnError
- >({
- security: [
- {
- name: "x-secret-key",
- type: "apiKey",
- },
- ],
- url: "/v1/sign/transaction",
- ...options,
- headers: {
- "Content-Type": "application/json",
- ...options?.headers,
- },
- });
+ return (options.client ?? _heyApiClient).post<
+ ReadContractResponses,
+ unknown,
+ ThrowOnError
+ >({
+ security: [
+ {
+ name: "x-secret-key",
+ type: "apiKey",
+ },
+ ],
+ url: "/v1/read/contract",
+ ...options,
+ headers: {
+ "Content-Type": "application/json",
+ ...options.headers,
+ },
+ });
};
/**
- * Sign Message
- * Sign arbitrary messages.
+ * Encode Contract
+ * Encode contract function calls without execution
*/
-export const signMessage = (
- options?: Options,
+export const encodeContract = (
+ options: Options,
) => {
- return (options?.client ?? _heyApiClient).post<
- SignMessageResponses,
- unknown,
- ThrowOnError
- >({
- security: [
- {
- name: "x-secret-key",
- type: "apiKey",
- },
- ],
- url: "/v1/sign/message",
- ...options,
- headers: {
- "Content-Type": "application/json",
- ...options?.headers,
- },
- });
+ return (options.client ?? _heyApiClient).post<
+ EncodeContractResponses,
+ unknown,
+ ThrowOnError
+ >({
+ security: [
+ {
+ name: "x-secret-key",
+ type: "apiKey",
+ },
+ ],
+ url: "/v1/encode/contract",
+ ...options,
+ headers: {
+ "Content-Type": "application/json",
+ ...options.headers,
+ },
+ });
};
/**
- * Sign Typed Data
- * Sign EIP-712 typed data.
+ * Cancel Transaction
+ * Attempt to cancel a queued transaction. Transactions that have been sent and are waiting for mine cannot be cancelled.
*/
-export const signTypedData = (
- options?: Options,
+export const cancelTransaction = (
+ options: Options,
) => {
- return (options?.client ?? _heyApiClient).post<
- SignTypedDataResponses,
- unknown,
- ThrowOnError
- >({
- security: [
- {
- name: "x-secret-key",
- type: "apiKey",
- },
- ],
- url: "/v1/sign/typed-data",
- ...options,
- headers: {
- "Content-Type": "application/json",
- ...options?.headers,
- },
- });
+ return (options.client ?? _heyApiClient).post<
+ CancelTransactionResponses,
+ unknown,
+ ThrowOnError
+ >({
+ security: [
+ {
+ name: "x-secret-key",
+ type: "apiKey",
+ },
+ ],
+ url: "/v1/transactions/{id}/cancel",
+ ...options,
+ });
};
/**
- * Read Contract
- * Call read-only contract functions or batch read using multicall.
+ * List Server Wallets
+ * List all engine server wallets for the current project. Returns an array of EOA addresses with their corresponding predicted smart account addresses.
*/
-export const readContract = (
- options?: Options,
+export const listAccounts = (
+ options?: Options,
) => {
- return (options?.client ?? _heyApiClient).post<
- ReadContractResponses,
- unknown,
- ThrowOnError
- >({
- security: [
- {
- name: "x-secret-key",
- type: "apiKey",
- },
- ],
- url: "/v1/read/contract",
- ...options,
- headers: {
- "Content-Type": "application/json",
- ...options?.headers,
- },
- });
+ return (options?.client ?? _heyApiClient).get<
+ ListAccountsResponses,
+ unknown,
+ ThrowOnError
+ >({
+ security: [
+ {
+ name: "x-secret-key",
+ type: "apiKey",
+ },
+ ],
+ url: "/v1/accounts",
+ ...options,
+ });
};
/**
- * Read Native Balance
- * Fetches the native cryptocurrency balance (e.g., ETH, MATIC) for a given address on a specific chain.
+ * Create Server Wallet
+ * Create a new engine server wallet. This is a helper route for creating a new EOA with your KMS provider, provided as a convenient alternative to creating an EOA directly with your KMS provider. Your KMS credentials are not stored, and usage of created accounts require your KMS credentials to be sent with requests.
+ */
+export const createAccount = (
+ options?: Options,
+) => {
+ return (options?.client ?? _heyApiClient).post<
+ CreateAccountResponses,
+ unknown,
+ ThrowOnError
+ >({
+ security: [
+ {
+ name: "x-secret-key",
+ type: "apiKey",
+ },
+ ],
+ url: "/v1/accounts",
+ ...options,
+ headers: {
+ "Content-Type": "application/json",
+ ...options?.headers,
+ },
+ });
+};
+
+/**
+ * Get Transactions
+ * Search transactions with various filters and pagination
*/
-export const getNativeBalance = (
- options?: Options,
+export const getTransactions = (
+ options?: Options,
) => {
- return (options?.client ?? _heyApiClient).post<
- GetNativeBalanceResponses,
- GetNativeBalanceErrors,
- ThrowOnError
- >({
- security: [
- {
- name: "x-secret-key",
- type: "apiKey",
- },
- ],
- url: "/v1/read/balance",
- ...options,
- headers: {
- "Content-Type": "application/json",
- ...options?.headers,
- },
- });
+ return (options?.client ?? _heyApiClient).get<
+ GetTransactionsResponses,
+ unknown,
+ ThrowOnError
+ >({
+ security: [
+ {
+ name: "x-secret-key",
+ type: "apiKey",
+ },
+ ],
+ url: "/v1/transactions",
+ ...options,
+ });
};
/**
- * Encode Function Data
- * Encode a contract call into transaction parameters (to, data, value).
+ * Transaction Analytics
+ * Get transaction count analytics over time with filtering
*/
-export const encodeFunctionData = (
- options?: Options,
+export const getTransactionAnalytics = (
+ options?: Options,
) => {
- return (options?.client ?? _heyApiClient).post<
- EncodeFunctionDataResponses,
- unknown,
- ThrowOnError
- >({
- security: [
- {
- name: "x-secret-key",
- type: "apiKey",
- },
- ],
- url: "/v1/encode/contract",
- ...options,
- headers: {
- "Content-Type": "application/json",
- ...options?.headers,
- },
- });
+ return (options?.client ?? _heyApiClient).post<
+ GetTransactionAnalyticsResponses,
+ unknown,
+ ThrowOnError
+ >({
+ security: [
+ {
+ name: "x-secret-key",
+ type: "apiKey",
+ },
+ ],
+ url: "/v1/transactions/analytics",
+ ...options,
+ headers: {
+ "Content-Type": "application/json",
+ ...options?.headers,
+ },
+ });
+};
+
+/**
+ * Transaction Analytics Summary
+ * Get a summary (total count and total gas calculation) for transactions within a time range, supporting complex nested filters.
+ */
+export const getTransactionAnalyticsSummary = <
+ ThrowOnError extends boolean = false,
+>(
+ options?: Options,
+) => {
+ return (options?.client ?? _heyApiClient).post<
+ GetTransactionAnalyticsSummaryResponses,
+ GetTransactionAnalyticsSummaryErrors,
+ ThrowOnError
+ >({
+ security: [
+ {
+ name: "x-secret-key",
+ type: "apiKey",
+ },
+ ],
+ url: "/v1/transactions/analytics-summary",
+ ...options,
+ headers: {
+ "Content-Type": "application/json",
+ ...options?.headers,
+ },
+ });
};
/**
@@ -325,80 +378,74 @@ export const encodeFunctionData = (
* Advanced search for transactions with complex nested filters
*/
export const searchTransactions = (
- options?: Options,
+ options?: Options,
) => {
- return (options?.client ?? _heyApiClient).post<
- SearchTransactionsResponses,
- unknown,
- ThrowOnError
- >({
- security: [
- {
- name: "x-secret-key",
- type: "apiKey",
- },
- ],
- url: "/v1/transactions/search",
- ...options,
- headers: {
- "Content-Type": "application/json",
- ...options?.headers,
- },
- });
+ return (options?.client ?? _heyApiClient).post<
+ SearchTransactionsResponses,
+ unknown,
+ ThrowOnError
+ >({
+ security: [
+ {
+ name: "x-secret-key",
+ type: "apiKey",
+ },
+ ],
+ url: "/v1/transactions/search",
+ ...options,
+ headers: {
+ "Content-Type": "application/json",
+ ...options?.headers,
+ },
+ });
};
/**
- * Transaction Analytics
- * Get transaction count analytics over time with filtering
+ * Get Activity Logs
+ * Get paginated activity logs for a specific transaction with tenancy enforcement
*/
-export const getTransactionAnalytics = (
- options?: Options,
+export const getActivityLogs = (
+ options: Options,
) => {
- return (options?.client ?? _heyApiClient).post<
- GetTransactionAnalyticsResponses,
- unknown,
- ThrowOnError
- >({
- security: [
- {
- name: "x-secret-key",
- type: "apiKey",
- },
- ],
- url: "/v1/transactions/analytics",
- ...options,
- headers: {
- "Content-Type": "application/json",
- ...options?.headers,
- },
- });
+ return (options.client ?? _heyApiClient).get<
+ GetActivityLogsResponses,
+ GetActivityLogsErrors,
+ ThrowOnError
+ >({
+ security: [
+ {
+ name: "x-secret-key",
+ type: "apiKey",
+ },
+ ],
+ url: "/v1/transactions/activity-logs",
+ ...options,
+ });
};
/**
- * Transaction Analytics Summary
- * Get a summary (total count and total gas calculation) for transactions within a time range, supporting complex nested filters.
+ * Search Activity Logs
+ * Search activity logs across transactions with advanced filtering and tenancy enforcement
*/
-export const getTransactionAnalyticsSummary = <
- ThrowOnError extends boolean = false,
->(
- options?: Options,
+export const searchActivityLogs = (
+ options?: Options,
) => {
- return (options?.client ?? _heyApiClient).post<
- GetTransactionAnalyticsSummaryResponses,
- GetTransactionAnalyticsSummaryErrors,
- ThrowOnError
- >({
- security: [
- {
- name: "x-secret-key",
- type: "apiKey",
- },
- ],
- url: "/v1/transactions/analytics-summary",
- ...options,
- headers: {
- "Content-Type": "application/json",
- ...options?.headers,
- },
- });
+ return (options?.client ?? _heyApiClient).post<
+ SearchActivityLogsResponses,
+ SearchActivityLogsErrors,
+ ThrowOnError
+ >({
+ security: [
+ {
+ name: "x-secret-key",
+ type: "apiKey",
+ },
+ ],
+ url: "/v1/transactions/activity-logs/search",
+ ...options,
+ headers: {
+ "Content-Type": "application/json",
+ ...options?.headers,
+ },
+ });
};
diff --git a/packages/engine/src/client/types.gen.ts b/packages/engine/src/client/types.gen.ts
index 56424f028fb..2dce1b1aae4 100644
--- a/packages/engine/src/client/types.gen.ts
+++ b/packages/engine/src/client/types.gen.ts
@@ -1,1120 +1,1701 @@
// This file is auto-generated by @hey-api/openapi-ts
export type TransactionsFilterValue = {
- field:
- | "id"
- | "batchIndex"
- | "from"
- | "signerAddress"
- | "smartAccountAddress"
- | "chainId";
- values: Array;
- operation?: "AND" | "OR";
+ field:
+ | "id"
+ | "batchIndex"
+ | "from"
+ | "signerAddress"
+ | "smartAccountAddress"
+ | "chainId";
+ values: Array;
+ operation: "AND" | "OR";
};
export type TransactionsFilterNested = {
- operation: "AND" | "OR";
- filters: Array;
+ operation: "AND" | "OR";
+ filters: Array;
};
/**
- * Auto-determine Best Execution Options
- * This is the default execution option. If you do not specify an execution type, and only specify a "from" string, engine will automatically determine the most optimal options for you. If you would like to specify granular options about execution strategy choose one of the other `executionOptions` type and provide them.
+ * ### Address
+ * Used to represent an EVM address. This is a string of length 42 with a `0x` prefix. Non-checksummed addresses are also supported, but will be converted to checksummed.
+ */
+export type AddressDef = string;
+
+/**
+ * Auto Determine Execution
+ * This is the default execution option.
+ * If you do not specify an execution type, and only specify a "from" string,
+ * engine will automatically determine the most optimal options for you.
+ * If you would like to specify granular options about execution strategy
+ * choose one of the other executionOptions type and provide them.
*/
export type AutoExecutionOptions = {
- /**
- * This is the default, a `type` does not need to be specified
- */
- type?: "auto";
- /**
- * The address of the account to send the transaction from. Can be the address of a smart account or an EOA.
- */
- from: string;
- /**
- * The idempotency key of the transaction. Transaction requests sent with the same idempotency key will be de-duplicated. If not provided, a randomUUID will be generated. This is also used as the ID of a queued/stored transaction.
- */
- idempotencyKey?: string;
- /**
- * The chain id of the transaction
- */
- chainId: string;
+ /**
+ * The identifier of the entity to send the transaction from.
+ * Automatically picks best execution strategy based on the identifier.
+ * - If EOA address, execution uses EIP7702 based smart-wallet execution
+ * - If 7702 not supported on chain, falls back to smart-contract wallet (ERC4337) with default smart account for this EOA (v0.7)
+ * - UNLESS this is a zk-chain, in which case, zk-sync native-aa is used
+ */
+ from: string;
};
+export type BaseExecutionOptions = {
+ chainId: number;
+ idempotencyKey?: string;
+};
+
+/**
+ * Result of a single contract encode operation
+ *
+ * Each result can either be successful (containing the encoded transaction data)
+ * or failed (containing detailed error information).
+ */
+export type BatchResultItemEncodeResultSuccessItemEngineError =
+ | {
+ /**
+ * Successful result from a contract encode operation
+ */
+ result: {
+ /**
+ * The contract address that would be called
+ */
+ target: string;
+ /**
+ * The encoded function call data
+ *
+ * This includes the function selector and encoded parameters,
+ * ready to be used in a transaction
+ */
+ callData: string;
+ /**
+ * The 4-byte function selector (first 4 bytes of call_data)
+ */
+ functionSelector: string;
+ /**
+ * The name of the function being called
+ */
+ functionName: string;
+ };
+ }
+ | {
+ error:
+ | {
+ /**
+ * Detailed RPC error information
+ */
+ chain_id: number;
+ rpc_url: string;
+ message: string;
+ kind: RpcErrorKind;
+ type: "RPC_ERROR";
+ }
+ | {
+ /**
+ * Detailed RPC error information
+ */
+ chain_id: number;
+ rpc_url: string;
+ message: string;
+ kind: RpcErrorKind;
+ type: "PAYMASTER_ERROR";
+ }
+ | {
+ /**
+ * Detailed RPC error information
+ */
+ chain_id: number;
+ rpc_url: string;
+ message: string;
+ kind: RpcErrorKind;
+ type: "BUNDLER_ERROR";
+ }
+ | {
+ message: string;
+ type: "VAULT_ERROR";
+ }
+ | {
+ error: IawError;
+ type: "IAW_ERROR";
+ }
+ | {
+ message: string;
+ type: "RPC_CONFIG_ERROR";
+ }
+ | {
+ contractAddress?: null | AddressDef;
+ /**
+ * Chain ID
+ */
+ chainId: number;
+ /**
+ * Human-readable error message
+ */
+ message: string;
+ /**
+ * Specific error kind
+ */
+ kind: ContractInteractionErrorKind;
+ type: "CONTRACT_INTERACTION_ERROR";
+ }
+ | {
+ message: string;
+ type: "VALIDATION_ERROR";
+ }
+ | {
+ message: string;
+ type: "THIRDWEB_ERROR";
+ }
+ | {
+ message: string;
+ type: "INTERNAL_ERROR";
+ };
+ };
+
+/**
+ * Result of a single contract encode operation
+ *
+ * Each result can either be successful (containing the encoded transaction data)
+ * or failed (containing detailed error information).
+ */
+export type BatchResultItemReadResultSuccessItemEngineError =
+ | {
+ /**
+ * Successful result from a contract read operation
+ */
+ result: Value;
+ }
+ | {
+ error:
+ | {
+ /**
+ * Detailed RPC error information
+ */
+ chain_id: number;
+ rpc_url: string;
+ message: string;
+ kind: RpcErrorKind;
+ type: "RPC_ERROR";
+ }
+ | {
+ /**
+ * Detailed RPC error information
+ */
+ chain_id: number;
+ rpc_url: string;
+ message: string;
+ kind: RpcErrorKind;
+ type: "PAYMASTER_ERROR";
+ }
+ | {
+ /**
+ * Detailed RPC error information
+ */
+ chain_id: number;
+ rpc_url: string;
+ message: string;
+ kind: RpcErrorKind;
+ type: "BUNDLER_ERROR";
+ }
+ | {
+ message: string;
+ type: "VAULT_ERROR";
+ }
+ | {
+ error: IawError;
+ type: "IAW_ERROR";
+ }
+ | {
+ message: string;
+ type: "RPC_CONFIG_ERROR";
+ }
+ | {
+ contractAddress?: null | AddressDef;
+ /**
+ * Chain ID
+ */
+ chainId: number;
+ /**
+ * Human-readable error message
+ */
+ message: string;
+ /**
+ * Specific error kind
+ */
+ kind: ContractInteractionErrorKind;
+ type: "CONTRACT_INTERACTION_ERROR";
+ }
+ | {
+ message: string;
+ type: "VALIDATION_ERROR";
+ }
+ | {
+ message: string;
+ type: "THIRDWEB_ERROR";
+ }
+ | {
+ message: string;
+ type: "INTERNAL_ERROR";
+ };
+ };
+
/**
- * ERC4337 Execution (Smart Account)
+ * Result of a single contract encode operation
+ *
+ * Each result can either be successful (containing the encoded transaction data)
+ * or failed (containing detailed error information).
*/
-export type AaExecutionOptions = {
- type: "ERC4337";
- /**
- * The address of the engine managed account which can send transactions from your smart account
- */
- signerAddress: string;
- sponsorGas?: boolean;
- /**
- * The address of the smart account factory. Defaults to thirdweb default v0.7 Account Factory. Only specify this if you are using a custom account factory.
- */
- factoryAddress?: string;
- /**
- * The address of the entrypoint contract. Defaults to the v0.7 entrypoint for the chain. Only specify this if you want to specify a different version.
- */
- entrypointAddress?: string;
- /**
- * The address of the smart account to send the transaction from. Either specify this, or the salt. If not specified, the inferred smart account will be with null salt. If both are specified, the salt will be ignored.
- */
- smartAccountAddress?: string;
- /**
- * The salt of the smart account to send the transaction from. Only specify this if you want to specify a custom salt. If omitted, and smart account address is not provided, the inferred smart account will be with null salt. If a smart account address is provided, the salt will be ignored.
- */
- accountSalt?: string;
- /**
- * The idempotency key of the transaction. Transaction requests sent with the same idempotency key will be de-duplicated. If not provided, a randomUUID will be generated. This is also used as the ID of a queued/stored transaction.
- */
- idempotencyKey?: string;
- /**
- * The chain id of the transaction
- */
- chainId: string;
+export type BatchResultItemSignResultDataEngineError =
+ | {
+ /**
+ * Data returned from successful signing
+ */
+ result: {
+ /**
+ * The resulting signature
+ */
+ signature: string;
+ /**
+ * The data that was signed (stringified typed data)
+ */
+ signedData: string;
+ };
+ }
+ | {
+ error:
+ | {
+ /**
+ * Detailed RPC error information
+ */
+ chain_id: number;
+ rpc_url: string;
+ message: string;
+ kind: RpcErrorKind;
+ type: "RPC_ERROR";
+ }
+ | {
+ /**
+ * Detailed RPC error information
+ */
+ chain_id: number;
+ rpc_url: string;
+ message: string;
+ kind: RpcErrorKind;
+ type: "PAYMASTER_ERROR";
+ }
+ | {
+ /**
+ * Detailed RPC error information
+ */
+ chain_id: number;
+ rpc_url: string;
+ message: string;
+ kind: RpcErrorKind;
+ type: "BUNDLER_ERROR";
+ }
+ | {
+ message: string;
+ type: "VAULT_ERROR";
+ }
+ | {
+ error: IawError;
+ type: "IAW_ERROR";
+ }
+ | {
+ message: string;
+ type: "RPC_CONFIG_ERROR";
+ }
+ | {
+ contractAddress?: null | AddressDef;
+ /**
+ * Chain ID
+ */
+ chainId: number;
+ /**
+ * Human-readable error message
+ */
+ message: string;
+ /**
+ * Specific error kind
+ */
+ kind: ContractInteractionErrorKind;
+ type: "CONTRACT_INTERACTION_ERROR";
+ }
+ | {
+ message: string;
+ type: "VALIDATION_ERROR";
+ }
+ | {
+ message: string;
+ type: "THIRDWEB_ERROR";
+ }
+ | {
+ message: string;
+ type: "INTERNAL_ERROR";
+ };
+ };
+
+/**
+ * Collection of results from multiple contract encode operations
+ */
+export type BatchResultsEncodeResultSuccessItem = {
+ /**
+ * Array of results, one for each input contract call
+ */
+ result: Array;
};
/**
- * AA:zksync Execution Options
- * Uses zkSync native AA for execution. This type of execution is only available on zkSync chains.
+ * Collection of results from multiple contract encode operations
*/
-export type AaZksyncExecutionOptions = {
- type: "zksync";
- /**
- * The EOA address of the account to send the zksync native AA transaction from.
- */
- accountAddress: string;
- sponsorGas?: boolean;
- /**
- * The idempotency key of the transaction. Transaction requests sent with the same idempotency key will be de-duplicated. If not provided, a randomUUID will be generated. This is also used as the ID of a queued/stored transaction.
- */
- idempotencyKey?: string;
- /**
- * The chain id of the transaction
- */
- chainId: string;
+export type BatchResultsReadResultSuccessItem = {
+ /**
+ * Array of results, one for each input contract call
+ */
+ result: Array;
};
/**
- * Uses EOA for execution. Only supported for signing currently.
+ * Collection of results from multiple contract encode operations
*/
-export type EoaExecutionOptions = {
- type: "eoa";
+export type BatchResultsSignResultData = {
+ /**
+ * Array of results, one for each input contract call
+ */
+ result: Array;
+};
- /**
- * The EOA address
- */
- address: string;
+/**
+ * # Bytes
+ * Used to represent "bytes". This is a 0x prefixed hex string.
+ */
+export type BytesDef = string;
- /**
- * The chain id of the transaction
- */
- chainId: string;
+export type CancelResult =
+ | "CANCELLED_IMMEDIATELY"
+ | "CANCELLATION_PENDING"
+ | {
+ CANNOT_CANCEL: {
+ reason: string;
+ };
+ }
+ | "NOT_FOUND";
- /**
- * The idempotency key of the transaction. Transaction requests sent with the same idempotency key will be de-duplicated. If not provided, a randomUUID will be generated. This is also used as the ID of a queued/stored transaction.
- */
- idempotencyKey?: string;
+/**
+ * Represents a contract function call with parameters
+ *
+ * This is the base type used by all contract interaction endpoints.
+ * It supports both function names and full function signatures, with
+ * automatic ABI resolution when needed.
+ */
+export type ContractCall = {
+ /**
+ * The address of the smart contract to call
+ */
+ contractAddress: AddressDef;
+ /**
+ * The function to call - can be a name like "transfer" or full signature like "transfer(address,uint256)"
+ */
+ method: string;
+ /**
+ * Array of parameters to pass to the function
+ */
+ params: Array;
+ abi?: null | Value;
};
-export type ListAccountsData = {
- body?: never;
- path?: never;
- query?: never;
- url: "/v1/accounts";
+/**
+ * A serializable contract interaction error type
+ */
+export type ContractInteractionErrorKind =
+ | {
+ functionName: string;
+ type: "UNKNOWN_FUNCTION";
+ }
+ | {
+ functionSelector: string;
+ type: "UNKNOWN_SELECTOR";
+ }
+ | {
+ type: "NOT_A_DEPLOYMENT_TRANSACTION";
+ }
+ | {
+ type: "CONTRACT_NOT_DEPLOYED";
+ }
+ | {
+ function: string;
+ message: string;
+ type: "ZERO_DATA";
+ }
+ | {
+ message: string;
+ type: "ABI_ERROR";
+ }
+ | {
+ message: string;
+ type: "TRANSPORT_ERROR";
+ }
+ | {
+ message: string;
+ type: "PENDING_TRANSACTION_ERROR";
+ }
+ | {
+ message: string;
+ type: "PREPARATION_FAILED";
+ }
+ | {
+ message: string;
+ type: "MULTICALL_EXECUTION_FAILED";
+ }
+ | {
+ message: string;
+ type: "RESULT_DECODING_FAILED";
+ }
+ | {
+ message: string;
+ type: "PARAMETER_VALIDATION_FAILED";
+ }
+ | {
+ message: string;
+ type: "FUNCTION_RESOLUTION_FAILED";
+ };
+
+/**
+ * A contract function call with optional ETH value to send
+ */
+export type ContractWrite = ContractCall & {
+ value?: null | U256Def;
};
-export type ListAccountsResponses = {
- /**
- * Accounts retrieved successfully
- */
- 200: {
- result: Array<{
- /**
- * EVM address in hex format
- */
- address: string;
- label?: string;
- /**
- * The predicted smart account address for use with the default thirdweb v0.7 AccountFactory
- */
- smartAccountAddress?: string;
- }>;
- };
+/**
+ * Options for encoding contract function calls
+ */
+export type EncodeOptions = {
+ /**
+ * The blockchain network ID to encode for
+ *
+ * This is used to fetch the correct ABI if not provided inline
+ */
+ chainId: string;
};
-export type ListAccountsResponse =
- ListAccountsResponses[keyof ListAccountsResponses];
+/**
+ * Request to encode contract function calls
+ */
+export type EncodeRequest = {
+ /**
+ * Configuration options for encoding
+ */
+ encodeOptions: EncodeOptions;
+ /**
+ * List of contract function calls to encode
+ *
+ * Each call will be encoded to its raw transaction data
+ */
+ params: Array;
+};
-export type CreateAccountData = {
- body?: {
- label: string;
- };
- headers?: {
- /**
- * Vault Access Token used to access your EOA
- */
- "x-vault-access-token"?: string;
- };
- path?: never;
- query?: never;
- url: "/v1/accounts";
+/**
+ * Successful result from a contract encode operation
+ */
+export type EncodeResultSuccessItem = {
+ /**
+ * The contract address that would be called
+ */
+ target: string;
+ /**
+ * The encoded function call data
+ *
+ * This includes the function selector and encoded parameters,
+ * ready to be used in a transaction
+ */
+ callData: string;
+ /**
+ * The 4-byte function selector (first 4 bytes of call_data)
+ */
+ functionSelector: string;
+ /**
+ * The name of the function being called
+ */
+ functionName: string;
};
-export type CreateAccountResponses = {
- /**
- * Account created successfully
- */
- 201: {
- result: {
- /**
- * EVM address in hex format
- */
- address: string;
- label?: string;
- /**
- * The predicted smart account address for use with the default thirdweb v0.7 AccountFactory
- */
- smartAccountAddress?: string;
- };
- };
+export type EntrypointAndFactoryDetailsDeserHelper = {
+ entrypointAddress?: null | AddressDef;
+ entrypointVersion?: null | EntrypointVersion;
+ factoryAddress?: null | AddressDef;
};
-export type CreateAccountResponse =
- CreateAccountResponses[keyof CreateAccountResponses];
+export type EntrypointVersion = "0.6" | "0.7";
+
+/**
+ * EOA signing options
+ */
+export type EoaSigningOptions = {
+ /**
+ * The EOA address to sign with
+ */
+ from: AddressDef;
+ chainId?: null | U64;
+};
+
+/**
+ * ### ERC-4337 Execution Options
+ * This struct allows flexible configuration of ERC-4337 execution options,
+ * with intelligent defaults and inferences based on provided values.
+ *
+ * ### Field Inference
+ * When fields are omitted, the system uses the following inference rules:
+ *
+ * 1. Version Inference:
+ * - If `entrypointVersion` is provided, it's used directly
+ * - Otherwise, tries to infer from `entrypointAddress` (if provided)
+ * - If that fails, tries to infer from `factoryAddress` (if provided)
+ * - Defaults to version 0.7 if no inference is possible
+ *
+ * 2. Entrypoint Address Inference:
+ * - If provided explicitly, it's used as-is
+ * - Otherwise, uses the default address corresponding to the inferred version:
+ * - V0.6: 0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789
+ * - V0.7: 0x0576a174D229E3cFA37253523E645A78A0C91B57
+ *
+ * 3. Factory Address Inference:
+ * - If provided explicitly, it's used as-is
+ * - Otherwise, uses the default factory corresponding to the inferred version:
+ * - V0.6: 0x85e23b94e7F5E9cC1fF78BCe78cfb15B81f0DF00 [DEFAULT_FACTORY_ADDRESS_V0_6]
+ * - V0.7: 0x4bE0ddfebcA9A5A4a617dee4DeCe99E7c862dceb [DEFAULT_FACTORY_ADDRESS_V0_7]
+ *
+ * 4. Account Salt:
+ * - If provided explicitly, it's used as-is
+ * - Otherwise, defaults to "0x" (commonly used as the defauult "null" salt for smart accounts)
+ *
+ * 5. Smart Account Address:
+ * - If provided explicitly, it's used as-is
+ * - Otherwise, it's read from the smart account factory
+ *
+ * All optional fields can be omitted for a minimal configuration using version 0.7 defaults.
+ *
+ * The most minimal usage only requires `signerAddress` + `chainId`
+ */
+export type Erc4337ExecutionOptions = EntrypointAndFactoryDetailsDeserHelper & {
+ signerAddress: AddressDef;
+ accountSalt?: string;
+ smartAccountAddress?: null | AddressDef;
+};
+
+/**
+ * ### ERC4337 (Smart Account) Signing Options
+ * This struct allows flexible configuration of ERC-4337 signing options,
+ * with intelligent defaults and inferences based on provided values.
+ *
+ * ### Field Inference
+ * When fields are omitted, the system uses the following inference rules:
+ *
+ * 1. Version Inference:
+ * - If `entrypointVersion` is provided, it's used directly
+ * - Otherwise, tries to infer from `entrypointAddress` (if provided)
+ * - If that fails, tries to infer from `factoryAddress` (if provided)
+ * - Defaults to version 0.7 if no inference is possible
+ *
+ * 2. Entrypoint Address Inference:
+ * - If provided explicitly, it's used as-is
+ * - Otherwise, uses the default address corresponding to the inferred version:
+ * - V0.6: 0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789
+ * - V0.7: 0x0576a174D229E3cFA37253523E645A78A0C91B57
+ *
+ * 3. Factory Address Inference:
+ * - If provided explicitly, it's used as-is
+ * - Otherwise, uses the default factory corresponding to the inferred version:
+ * - V0.6: 0x85e23b94e7F5E9cC1fF78BCe78cfb15B81f0DF00 [DEFAULT_FACTORY_ADDRESS_V0_6]
+ * - V0.7: 0x4bE0ddfebcA9A5A4a617dee4DeCe99E7c862dceb [DEFAULT_FACTORY_ADDRESS_V0_7]
+ *
+ * 4. Account Salt:
+ * - If provided explicitly, it's used as-is
+ * - Otherwise, defaults to "0x" (commonly used as the defauult "null" salt for smart accounts)
+ *
+ * 5. Smart Account Address:
+ * - If provided explicitly, it's used as-is
+ * - Otherwise, it's read from the smart account factory
+ *
+ * All optional fields can be omitted for a minimal configuration using version 0.7 defaults.
+ *
+ * The most minimal usage only requires `signerAddress` + `chainId`
+ */
+export type Erc4337SigningOptions = EntrypointAndFactoryDetailsDeserHelper & {
+ smartAccountAddress?: null | AddressDef;
+ /**
+ * The EOA that controls the smart account
+ */
+ signerAddress: AddressDef;
+ /**
+ * Account salt for deterministic addresses
+ */
+ accountSalt?: string;
+ /**
+ * Chain ID for smart account operations
+ */
+ chainId: U64;
+};
+
+/**
+ * This is the exposed API for execution options
+ * Base and specific execution options are both flattened together
+ */
+export type ExecutionOptions = BaseExecutionOptions & SpecificExecutionOptions;
+
+/**
+ * Error types for IAW operations
+ */
+export type IawError =
+ | {
+ message: string;
+ type: "API_ERROR";
+ }
+ | {
+ message: string;
+ type: "SERIALIZATION_ERROR";
+ }
+ | {
+ error: SerializableReqwestError;
+ type: "NETWORK_ERROR";
+ }
+ | {
+ type: "AUTH_ERROR";
+ }
+ | (ThirdwebError & {
+ type: "THIRDWEB_ERROR";
+ })
+ | {
+ type: "UNEXPECTED_ERROR";
+ }
+ | (UserOpError & {
+ type: "USER_OP_ERROR";
+ });
+
+/**
+ * # InnerTransaction
+ * This is the actual encoded inner transaction data that will be sent to the blockchain.
+ */
+export type InnerTransaction = {
+ to?: null | AddressDef;
+ data?: BytesDef;
+ value?: U256Def;
+};
+
+export type MessageFormatDef = "text" | "hex";
+
+/**
+ * Individual message to sign
+ */
+export type MessageInput = {
+ /**
+ * The message to sign
+ */
+ message: string;
+ /**
+ * Message format (text or hex)
+ */
+ format?: MessageFormatDef;
+};
+
+/**
+ * # QueuedTransaction
+ * Response for any request that queues one or more transactions
+ */
+export type QueuedTransaction = {
+ /**
+ * The idempotency key this transaction was queued with
+ * Either autogenerated UUID or provided by the user
+ * Multiple queued transactions can have the same idempotency key
+ * A "blockchain transaction" is uniquely identified by the idempotency key + batchIndex
+ */
+ id: string;
+ /**
+ * When multiple transactions are sent together via an execution mode that doesn't support atomic batching,
+ * each transaction will have a unique batchIndex but the same id (idempotency key)
+ * This maintains the relationship between different atomically sent blockchain transactions that were queued together
+ */
+ batchIndex: number;
+ /**
+ * The fully resolved execution options for this transaction, derived from the resolution of user specific execution options
+ * Difference in naming is to prevent confusion when response executionParams contain different values than the request executionOptions
+ */
+ executionParams: ExecutionOptions;
+ /**
+ * This is the actual encoded inner transaction data that will be sent to the blockchain.
+ * For non-atomic transactions, this will be a single transaction
+ * For atomic transactions, this will be a list of transactions, because they were atomically sent together
+ */
+ transactionParams: Array;
+};
+
+export type QueuedTransactionsResponse = {
+ transactions: Array;
+};
+
+/**
+ * Options for reading from smart contracts
+ */
+export type ReadOptions = {
+ /**
+ * The blockchain network ID to read from
+ */
+ chainId: string;
+ /**
+ * Address of the Multicall3 contract to use for batching calls
+ *
+ * Defaults to the standard Multicall3 address: 0xcA11bde05977b3631167028862bE2a173976CA11
+ * which is deployed on most networks
+ */
+ multicallAddress?: AddressDef;
+ from?: null | AddressDef;
+};
+
+/**
+ * Request to read from multiple smart contracts
+ */
+export type ReadRequest = {
+ /**
+ * Configuration options for the read operation
+ */
+ readOptions: ReadOptions;
+ /**
+ * List of contract function calls to execute
+ *
+ * All calls will be batched together using Multicall3 for efficiency
+ */
+ params: Array;
+};
+
+/**
+ * Successful result from a contract read operation
+ */
+export type ReadResultSuccessItem = Value;
+
+export type RpcErrorKind =
+ | (RpcErrorResponse & {
+ type: "ERROR_RESP";
+ })
+ | {
+ type: "NULL_RESP";
+ }
+ | {
+ type: "UNSUPPORTED_FEATURE";
+ }
+ | {
+ type: "INTERNAL_ERROR";
+ }
+ | {
+ /**
+ * The underlying serde_json error.
+ */
+ message: string;
+ type: "SER_ERROR";
+ }
+ | {
+ /**
+ * The underlying serde_json error.
+ */
+ message: string;
+ /**
+ * For deser errors, the text that failed to deserialize.
+ */
+ text: string;
+ type: "DESER_ERROR";
+ }
+ | {
+ status: number;
+ body: string;
+ type: "TRANSPORT_HTTP_ERROR";
+ }
+ | {
+ type: "OTHER_TRANSPORT_ERROR";
+ };
+
+export type RpcErrorResponse = {
+ /**
+ * The error code.
+ */
+ code: number;
+ /**
+ * The error message (if any).
+ */
+ message: string;
+ /**
+ * The error data (if any).
+ */
+ data?: string | null;
+};
+
+/**
+ * Incoming transaction request, parsed into InnerTransaction
+ * Exposed API will have varying `params` but will all parse into InnerTransaction before execution
+ */
+export type SendTransactionRequest = {
+ executionOptions: ExecutionOptions;
+ params: Array;
+ webhookOptions?: Array | null;
+};
+
+export type SerializableReqwestError =
+ | {
+ Builder: {
+ message: string;
+ url?: string | null;
+ };
+ }
+ | {
+ Request: {
+ message: string;
+ url?: string | null;
+ };
+ }
+ | {
+ Timeout: {
+ message: string;
+ url?: string | null;
+ };
+ }
+ | {
+ Connect: {
+ message: string;
+ url?: string | null;
+ };
+ }
+ | {
+ Redirect: {
+ message: string;
+ url?: string | null;
+ };
+ }
+ | {
+ ClientError: {
+ status: number;
+ message: string;
+ url?: string | null;
+ };
+ }
+ | {
+ ServerError: {
+ status: number;
+ message: string;
+ url?: string | null;
+ };
+ }
+ | {
+ Body: {
+ message: string;
+ url?: string | null;
+ };
+ }
+ | {
+ Decode: {
+ message: string;
+ url?: string | null;
+ };
+ }
+ | {
+ Upgrade: {
+ message: string;
+ url?: string | null;
+ };
+ }
+ | {
+ Unknown: {
+ message: string;
+ url?: string | null;
+ };
+ };
+
+/**
+ * Request to sign messages
+ */
+export type SignMessageRequest = {
+ /**
+ * Configuration options for signing
+ */
+ signingOptions: SigningOptions;
+ /**
+ * List of messages to sign
+ */
+ params: Array;
+};
+
+/**
+ * Data returned from successful signing
+ */
+export type SignResultData = {
+ /**
+ * The resulting signature
+ */
+ signature: string;
+ /**
+ * The data that was signed (stringified typed data)
+ */
+ signedData: string;
+};
+
+/**
+ * Request to sign typed data
+ */
+export type SignTypedDataRequest = {
+ /**
+ * Configuration options for signing
+ */
+ signingOptions: SigningOptions;
+ /**
+ * List of typed data to sign
+ */
+ params: Array;
+};
+
+/**
+ * Configuration options for signing operations
+ */
+export type SigningOptions =
+ | (EoaSigningOptions & {
+ type: "eoa";
+ })
+ | (Erc4337SigningOptions & {
+ type: "ERC4337";
+ })
+ | {
+ type: "auto";
+ /**
+ * The address to sign from
+ */
+ from: string;
+ /**
+ * The chain ID for the signing operation
+ */
+ chainId: number;
+ };
+
+/**
+ * Execution Option Variants
+ * All supported specific execution options are contained here
+ */
+export type SpecificExecutionOptions =
+ | (AutoExecutionOptions & {
+ type: "auto";
+ })
+ | (Erc4337ExecutionOptions & {
+ type: "ERC4337";
+ });
+
+export type SuccessResponseQueuedTransactionsResponse = {
+ result: {
+ transactions: Array;
+ };
+};
+
+export type ThirdwebError =
+ | {
+ error: ThirdwebSerializationError;
+ type: "SERIALIZATION_ERROR";
+ }
+ | {
+ value: string;
+ message: string;
+ type: "URL_PARSE_ERROR";
+ }
+ | {
+ message: string;
+ type: "HTTP_CLIENT_BACKEND_ERROR";
+ }
+ | {
+ error: SerializableReqwestError;
+ type: "HTTP_ERROR";
+ };
+
+export type ThirdwebSerializationError = {
+ HeaderValue: {
+ value: string;
+ };
+};
+
+export type TransactionCancelResponse = {
+ transactionId: string;
+ result: CancelResult;
+};
+
+export type TypedDataDef = {
+ /**
+ * Signing domain metadata. The signing domain is the intended context for
+ * the signature (e.g. the dapp, protocol, etc. that it's intended for).
+ * This data is used to construct the domain separator of the message.
+ */
+ domain: TypedDataDomainDef;
+ /**
+ * The custom types used by this message.
+ */
+ types: unknown;
+ /**
+ * The type of the message.
+ */
+ primaryType: string;
+ /**
+ * The message to be signed.
+ */
+ message: unknown;
+};
+
+export type TypedDataDomainDef = {
+ name?: string | null;
+ /**
+ * The current major version of the signing domain. Signatures from
+ * different versions are not compatible.
+ */
+ version?: string | null;
+ chainId?: null | U256Def;
+ verifyingContract?: null | AddressDef;
+ /**
+ * A disambiguating salt for the protocol. This can be used as a domain
+ * separator of last resort.
+ */
+ salt?: string | null;
+};
+
+/**
+ * # U256
+ * Used to represent a 256-bit unsigned integer. Engine can parse these from any valid encoding of the Ethereum "quantity" format.
+ */
+export type U256Def = string;
+
+/**
+ * Error type for UserOp operations
+ */
+export type UserOpError = {
+ type: "UNEXPECTED_ERROR";
+};
+
+export type Value = unknown;
+
+export type WebhookOptions = {
+ url: string;
+ secret?: string | null;
+};
+
+/**
+ * Request to execute write transactions to smart contracts
+ */
+export type WriteContractRequest = {
+ /**
+ * Execution configuration including chain, account, and transaction options
+ */
+ executionOptions: ExecutionOptions;
+ /**
+ * List of contract function calls to execute
+ *
+ * All calls will be executed in a single transaction if possible,
+ * or as separate transactions if atomic batching is not supported
+ */
+ params: Array;
+ webhookOptions?: Array | null;
+};
+
+export type U64 = number;
export type WriteContractData = {
- body?: {
- /**
- * Use a specific execution type and provide options to configure engine's execution strategy. The default execution option is `auto`, (doesn't need to be specified) which will automatically determine the most optimal options for you. If you would like to specify granular options about execution strategy choose one of the other `executionOptions` type and provide them.
- */
- executionOptions:
- | AutoExecutionOptions
- | AaExecutionOptions
- | AaZksyncExecutionOptions
- | EoaExecutionOptions;
- params: Array<{
- /**
- * The function to call on the contract
- */
- method: string;
- /**
- * The parameters to pass to the function
- */
- params: Array;
- /**
- * The contract address to call
- */
- contractAddress: string;
- /**
- * The ABI of the contract
- */
- abi?: Array;
- /**
- * The value to send with the transaction
- */
- value?: string;
- }>;
- };
- headers?: {
- /**
- * Vault Access Token used to access your EOA
- */
- "x-vault-access-token"?: string;
- };
- path?: never;
- query?: never;
- url: "/v1/write/contract";
+ /**
+ * Write contract request
+ */
+ body: WriteContractRequest;
+ headers?: {
+ /**
+ * Vault access token
+ */
+ "x-vault-access-token"?: string | null;
+ };
+ path?: never;
+ query?: never;
+ url: "/v1/write/contract";
};
export type WriteContractResponses = {
- /**
- * Transaction sent successfully
- */
- 200: {
- result: {
- transactions: Array<{
- id: string;
- batchIndex: number;
- clientId: string;
- chainId: string;
- from: string | null;
- transactionParams:
- | (string | number | boolean | null)
- | {
- [key: string]: unknown;
- }
- | Array