Skip to content

[SDK] Engine search transactions and batch transaction support #7190

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 95 additions & 0 deletions .changeset/engine-enhancements.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
---
"thirdweb": minor
---

Enhanced Engine functionality with server wallet management, search transactions and batch transaction support:

- Added `Engine.createServerWallet()` to create a new server wallet with a custom label

```ts
import { Engine } from "thirdweb";

const serverWallet = await Engine.createServerWallet({
client,
label: "My Server Wallet",
});
console.log(serverWallet.address);
console.log(serverWallet.smartAccountAddress);
```

- Added `Engine.getServerWallets()` to list all existing server wallets

```ts
import { Engine } from "thirdweb";

const serverWallets = await Engine.getServerWallets({
client,
});
console.log(serverWallets);
```

- Added `Engine.searchTransactions()` to search for transactions by various filters (id, chainId, from address, etc.)

```ts
// Search by transaction IDs
const transactions = await Engine.searchTransactions({
client,
filters: [
{
field: "id",
values: ["1", "2", "3"],
},
],
});

// Search by chain ID and sender address
const transactions = await Engine.searchTransactions({
client,
filters: [
{
filters: [
{
field: "from",
values: ["0x1234567890123456789012345678901234567890"],
},
{
field: "chainId",
values: ["8453"],
},
],
operation: "AND",
},
],
pageSize: 100,
page: 0,
});
```

- Added `serverWallet.enqueueBatchTransaction()` to enqueue multiple transactions in a single batch

```ts
// Prepare multiple transactions
const transaction1 = claimTo({
contract,
to: firstRecipient,
quantity: 1n,
});
const transaction2 = claimTo({
contract,
to: secondRecipient,
quantity: 1n,
});

// Enqueue as a batch
const { transactionId } = await serverWallet.enqueueBatchTransaction({
transactions: [transaction1, transaction2],
});

// Wait for batch completion
const { transactionHash } = await Engine.waitForTransactionHash({
client,
transactionId,
});
```

- Improved server wallet transaction handling with better error reporting
5 changes: 5 additions & 0 deletions .changeset/stupid-adults-flow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@thirdweb-dev/engine": patch
---

Updated to latest API
54 changes: 54 additions & 0 deletions packages/engine/src/client/sdk.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import type {
} from "@hey-api/client-fetch";
import { client as _heyApiClient } from "./client.gen.js";
import type {
CreateAccountData,
CreateAccountResponse,
EncodeFunctionDataData,
EncodeFunctionDataResponse,
GetNativeBalanceData,
Expand All @@ -15,6 +17,8 @@ import type {
GetTransactionAnalyticsResponse,
GetTransactionAnalyticsSummaryData,
GetTransactionAnalyticsSummaryResponse,
ListAccountsData,
ListAccountsResponse,
ReadContractData,
ReadContractResponse,
SearchTransactionsData,
Expand Down Expand Up @@ -48,6 +52,56 @@ export type Options<
meta?: Record<string, unknown>;
};

/**
* 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 listAccounts = <ThrowOnError extends boolean = false>(
options?: Options<ListAccountsData, ThrowOnError>,
) => {
return (options?.client ?? _heyApiClient).get<
ListAccountsResponse,
unknown,
ThrowOnError
>({
security: [
{
name: "x-secret-key",
type: "apiKey",
},
],
url: "/v1/accounts",
...options,
});
};

/**
* 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 = <ThrowOnError extends boolean = false>(
options?: Options<CreateAccountData, ThrowOnError>,
) => {
return (options?.client ?? _heyApiClient).post<
CreateAccountResponse,
unknown,
ThrowOnError
>({
security: [
{
name: "x-secret-key",
type: "apiKey",
},
],
url: "/v1/accounts",
...options,
headers: {
"Content-Type": "application/json",
...options?.headers,
},
});
};

/**
* Write Contract
* Call a write function on a contract.
Expand Down
66 changes: 65 additions & 1 deletion packages/engine/src/client/types.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export type TransactionsFilterValue = {
| "smartAccountAddress"
| "chainId";
values: Array<string>;
operation: "AND" | "OR";
operation?: "AND" | "OR";
};

export type TransactionsFilterNested = {
Expand Down Expand Up @@ -92,6 +92,70 @@ export type AaZksyncExecutionOptions = {
chainId: string;
};

export type ListAccountsData = {
body?: never;
path?: never;
query?: never;
url: "/v1/accounts";
};

export type ListAccountsResponses = {
/**
* Accounts retrieved successfully
*/
200: {
result: Array<{
/**
* EVM address in hex format
*/
address: string;
/**
* The predicted smart account address for use with the default thirdweb v0.7 AccountFactory
*/
smartAccountAddress?: string;
}>;
};
};

export type ListAccountsResponse =
ListAccountsResponses[keyof ListAccountsResponses];

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";
};

export type CreateAccountResponses = {
/**
* Account created successfully
*/
201: {
result: {
/**
* EVM address in hex format
*/
address: string;
/**
* The predicted smart account address for use with the default thirdweb v0.7 AccountFactory
*/
smartAccountAddress?: string;
};
};
};

export type CreateAccountResponse =
CreateAccountResponses[keyof CreateAccountResponses];

export type WriteContractData = {
body?: {
/**
Expand Down
2 changes: 1 addition & 1 deletion packages/thirdweb/src/bridge/Chains.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { describe, expect, it } from "vitest";
import { TEST_CLIENT } from "~test/test-clients.js";
import { chains } from "./Chains.js";

describe("chains", () => {
describe.runIf(process.env.TW_SECRET_KEY)("chains", () => {
it("should fetch chains", async () => {
// Setup
const client = TEST_CLIENT;
Expand Down
57 changes: 57 additions & 0 deletions packages/thirdweb/src/engine/create-server-wallet.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { createAccount } from "@thirdweb-dev/engine";
import { stringify } from "viem";
import type { ThirdwebClient } from "../client/client.js";
import { getThirdwebBaseUrl } from "../utils/domains.js";
import { getClientFetch } from "../utils/fetch.js";

export type CreateServerWalletArgs = {
client: ThirdwebClient;
label: string;
};

/**
* Create a server wallet.
* @param params - The parameters for the server wallet.
* @param params.client - The thirdweb client to use.
* @param params.label - The label for the server wallet.
* @returns The server wallet signer address and the predicted smart account address.
* @engine
* @example
* ```ts
* import { Engine } from "thirdweb";
*
* const serverWallet = await Engine.createServerWallet({
* client,
* label: "My Server Wallet",
* });
* console.log(serverWallet.address);
* console.log(serverWallet.smartAccountAddress);
* ```
*/
export async function createServerWallet(params: CreateServerWalletArgs) {
const { client, label } = params;
const result = await createAccount({
baseUrl: getThirdwebBaseUrl("engineCloud"),
bodySerializer: stringify,
fetch: getClientFetch(client),
body: {
label,
},
});

Check warning on line 40 in packages/thirdweb/src/engine/create-server-wallet.ts

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/engine/create-server-wallet.ts#L31-L40

Added lines #L31 - L40 were not covered by tests

if (result.error) {
throw new Error(
`Error creating server wallet with label ${label}: ${stringify(
result.error,
)}`,
);
}

Check warning on line 48 in packages/thirdweb/src/engine/create-server-wallet.ts

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/engine/create-server-wallet.ts#L42-L48

Added lines #L42 - L48 were not covered by tests

const data = result.data?.result;

Check warning on line 50 in packages/thirdweb/src/engine/create-server-wallet.ts

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/engine/create-server-wallet.ts#L50

Added line #L50 was not covered by tests

if (!data) {
throw new Error(`No server wallet created with label ${label}`);
}

Check warning on line 54 in packages/thirdweb/src/engine/create-server-wallet.ts

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/engine/create-server-wallet.ts#L52-L54

Added lines #L52 - L54 were not covered by tests

return data;
}

Check warning on line 57 in packages/thirdweb/src/engine/create-server-wallet.ts

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/engine/create-server-wallet.ts#L56-L57

Added lines #L56 - L57 were not covered by tests
Loading
Loading