@account-kit/infra 4.0.0-beta.6 → 4.0.0-beta.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/dist/esm/alchemyTransport.d.ts +69 -0
  2. package/dist/esm/alchemyTransport.js +139 -0
  3. package/dist/esm/alchemyTransport.js.map +1 -0
  4. package/dist/esm/chains.d.ts +1 -0
  5. package/dist/esm/chains.js +17 -0
  6. package/dist/esm/chains.js.map +1 -1
  7. package/dist/esm/client/decorators/alchemyEnhancedApis.d.ts +2 -2
  8. package/dist/esm/client/decorators/alchemyEnhancedApis.js +3 -7
  9. package/dist/esm/client/decorators/alchemyEnhancedApis.js.map +1 -1
  10. package/dist/esm/client/isAlchemySmartAccountClient.d.ts +1 -1
  11. package/dist/esm/client/isAlchemySmartAccountClient.js +2 -6
  12. package/dist/esm/client/isAlchemySmartAccountClient.js.map +1 -1
  13. package/dist/esm/client/rpcClient.d.ts +9 -10
  14. package/dist/esm/client/rpcClient.js +9 -33
  15. package/dist/esm/client/rpcClient.js.map +1 -1
  16. package/dist/esm/client/smartAccountClient.d.ts +12 -9
  17. package/dist/esm/client/smartAccountClient.js +34 -20
  18. package/dist/esm/client/smartAccountClient.js.map +1 -1
  19. package/dist/esm/client/types.d.ts +8 -7
  20. package/dist/esm/client/types.js.map +1 -1
  21. package/dist/esm/index.d.ts +3 -4
  22. package/dist/esm/index.js +2 -3
  23. package/dist/esm/index.js.map +1 -1
  24. package/dist/esm/middleware/feeEstimator.d.ts +10 -6
  25. package/dist/esm/middleware/feeEstimator.js +11 -6
  26. package/dist/esm/middleware/feeEstimator.js.map +1 -1
  27. package/dist/esm/middleware/gasManager.d.ts +5 -6
  28. package/dist/esm/middleware/gasManager.js +5 -6
  29. package/dist/esm/middleware/gasManager.js.map +1 -1
  30. package/dist/esm/middleware/userOperationSimulator.d.ts +11 -7
  31. package/dist/esm/middleware/userOperationSimulator.js +12 -8
  32. package/dist/esm/middleware/userOperationSimulator.js.map +1 -1
  33. package/dist/esm/schema.d.ts +0 -391
  34. package/dist/esm/schema.js +1 -5
  35. package/dist/esm/schema.js.map +1 -1
  36. package/dist/esm/version.d.ts +1 -1
  37. package/dist/esm/version.js +1 -1
  38. package/dist/esm/version.js.map +1 -1
  39. package/dist/types/alchemyTransport.d.ts +70 -0
  40. package/dist/types/alchemyTransport.d.ts.map +1 -0
  41. package/dist/types/chains.d.ts +1 -0
  42. package/dist/types/chains.d.ts.map +1 -1
  43. package/dist/types/client/decorators/alchemyEnhancedApis.d.ts +2 -2
  44. package/dist/types/client/decorators/alchemyEnhancedApis.d.ts.map +1 -1
  45. package/dist/types/client/isAlchemySmartAccountClient.d.ts +1 -1
  46. package/dist/types/client/isAlchemySmartAccountClient.d.ts.map +1 -1
  47. package/dist/types/client/rpcClient.d.ts +9 -10
  48. package/dist/types/client/rpcClient.d.ts.map +1 -1
  49. package/dist/types/client/smartAccountClient.d.ts +12 -9
  50. package/dist/types/client/smartAccountClient.d.ts.map +1 -1
  51. package/dist/types/client/types.d.ts +8 -7
  52. package/dist/types/client/types.d.ts.map +1 -1
  53. package/dist/types/index.d.ts +3 -4
  54. package/dist/types/index.d.ts.map +1 -1
  55. package/dist/types/middleware/feeEstimator.d.ts +10 -6
  56. package/dist/types/middleware/feeEstimator.d.ts.map +1 -1
  57. package/dist/types/middleware/gasManager.d.ts +5 -6
  58. package/dist/types/middleware/gasManager.d.ts.map +1 -1
  59. package/dist/types/middleware/userOperationSimulator.d.ts +11 -7
  60. package/dist/types/middleware/userOperationSimulator.d.ts.map +1 -1
  61. package/dist/types/schema.d.ts +0 -391
  62. package/dist/types/schema.d.ts.map +1 -1
  63. package/dist/types/version.d.ts +1 -1
  64. package/package.json +3 -3
  65. package/src/alchemyTransport.ts +214 -0
  66. package/src/chains.ts +18 -0
  67. package/src/client/decorators/alchemyEnhancedApis.ts +9 -16
  68. package/src/client/isAlchemySmartAccountClient.ts +4 -9
  69. package/src/client/rpcClient.ts +14 -47
  70. package/src/client/smartAccountClient.ts +64 -57
  71. package/src/client/types.ts +10 -7
  72. package/src/index.ts +3 -3
  73. package/src/middleware/feeEstimator.ts +15 -10
  74. package/src/middleware/gasManager.ts +5 -6
  75. package/src/middleware/userOperationSimulator.ts +13 -10
  76. package/src/schema.ts +1 -14
  77. package/src/version.ts +1 -1
  78. package/dist/esm/client/internal/smartAccountClientFromRpc.d.ts +0 -18
  79. package/dist/esm/client/internal/smartAccountClientFromRpc.js +0 -56
  80. package/dist/esm/client/internal/smartAccountClientFromRpc.js.map +0 -1
  81. package/dist/esm/type.d.ts +0 -3
  82. package/dist/esm/type.js +0 -2
  83. package/dist/esm/type.js.map +0 -1
  84. package/dist/types/client/internal/smartAccountClientFromRpc.d.ts +0 -19
  85. package/dist/types/client/internal/smartAccountClientFromRpc.d.ts.map +0 -1
  86. package/dist/types/type.d.ts +0 -4
  87. package/dist/types/type.d.ts.map +0 -1
  88. package/src/client/internal/smartAccountClientFromRpc.ts +0 -125
  89. package/src/type.ts +0 -4
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "4.0.0-beta.6";
1
+ export declare const VERSION = "4.0.0-beta.8";
2
2
  //# sourceMappingURL=version.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@account-kit/infra",
3
- "version": "4.0.0-beta.6",
3
+ "version": "4.0.0-beta.8",
4
4
  "description": "adapters for @aa-sdk/core for interacting with alchemy services",
5
5
  "author": "Alchemy",
6
6
  "license": "MIT",
@@ -45,7 +45,7 @@
45
45
  "vitest": "^2.0.4"
46
46
  },
47
47
  "dependencies": {
48
- "@aa-sdk/core": "^4.0.0-beta.6",
48
+ "@aa-sdk/core": "^4.0.0-beta.8",
49
49
  "eventemitter3": "^5.0.1",
50
50
  "zod": "^3.22.4"
51
51
  },
@@ -64,7 +64,7 @@
64
64
  "url": "https://github.com/alchemyplatform/aa-sdk/issues"
65
65
  },
66
66
  "homepage": "https://github.com/alchemyplatform/aa-sdk#readme",
67
- "gitHead": "c25850c8617a78ee1956896b64c85db7a9ad6c08",
67
+ "gitHead": "de91f21bd8a8578a5cb119624fad7cc9b3726fee",
68
68
  "optionalDependencies": {
69
69
  "alchemy-sdk": "^3.0.0"
70
70
  }
@@ -0,0 +1,214 @@
1
+ import {
2
+ ChainNotFoundError,
3
+ ConnectionConfigSchema,
4
+ split,
5
+ type ConnectionConfig,
6
+ type NoUndefined,
7
+ } from "@aa-sdk/core";
8
+ import {
9
+ createTransport,
10
+ http,
11
+ type EIP1193RequestFn,
12
+ type HttpTransportConfig,
13
+ type PublicRpcSchema,
14
+ type Transport,
15
+ type TransportConfig,
16
+ } from "viem";
17
+ import type { AlchemyRpcSchema } from "./client/types.js";
18
+ import { AlchemyChainSchema } from "./schema.js";
19
+ import { VERSION } from "./version.js";
20
+
21
+ type Never<T> = T extends object
22
+ ? {
23
+ [K in keyof T]?: never;
24
+ }
25
+ : never;
26
+
27
+ type SplitTransportConfig = {
28
+ alchemyConnection: ConnectionConfig;
29
+ nodeRpcUrl: string;
30
+ };
31
+
32
+ const alchemyMethods = [
33
+ "eth_sendUserOperation",
34
+ "eth_estimateUserOperationGas",
35
+ "eth_getUserOperationReceipt",
36
+ "eth_getUserOperationByHash",
37
+ "eth_supportedEntryPoints",
38
+ "rundler_maxPriorityFeePerGas",
39
+ "pm_getPaymasterData",
40
+ "pm_getPaymasterStubData",
41
+ ];
42
+
43
+ export type AlchemyTransportConfig = (
44
+ | (ConnectionConfig & Never<SplitTransportConfig>)
45
+ | (SplitTransportConfig & Never<ConnectionConfig>)
46
+ ) & {
47
+ /** The max number of times to retry. */
48
+ retryCount?: TransportConfig["retryCount"] | undefined;
49
+ /** The base delay (in ms) between retries. */
50
+ retryDelay?: TransportConfig["retryDelay"] | undefined;
51
+ fetchOptions?: NoUndefined<HttpTransportConfig["fetchOptions"]>;
52
+ };
53
+
54
+ type AlchemyTransportBase = Transport<
55
+ "alchemy",
56
+ {
57
+ alchemyRpcUrl: string;
58
+ fetchOptions?: AlchemyTransportConfig["fetchOptions"];
59
+ },
60
+ EIP1193RequestFn<[...PublicRpcSchema, ...AlchemyRpcSchema]>
61
+ >;
62
+
63
+ export type AlchemyTransport = AlchemyTransportBase & {
64
+ updateHeaders(newHeaders: HeadersInit): void;
65
+ config: AlchemyTransportConfig;
66
+ };
67
+
68
+ /**
69
+ * Creates an Alchemy transport with the specified configuration options.
70
+ * When sending all traffic to Alchemy, you must pass in one of rpcUrl, apiKey, or jwt.
71
+ * If you want to send Bundler and Paymaster traffic to Alchemy and Node traffic to a different RPC, you must pass in alchemyConnection and nodeRpcUrl.
72
+ *
73
+ * @example
74
+ * ### Basic Example
75
+ * If the chain you're using is supported for both Bundler and Node RPCs, then you can do the following:
76
+ * ```ts
77
+ * import { alchemy } from "@account-kit/infra";
78
+ *
79
+ * const transport = alchemy({
80
+ * // NOTE: you can also pass in an rpcUrl or jwt here or rpcUrl and jwt
81
+ * apiKey: "your-api-key",
82
+ * });
83
+ * ```
84
+ *
85
+ * ### AA Only Chains
86
+ * For AA-only chains, you need to specify the alchemyConnection and nodeRpcUrl since Alchemy only
87
+ * handles the Bundler and Paymaster RPCs for these chains.
88
+ * ```ts
89
+ * import { alchemy } from "@account-kit/infra";
90
+ *
91
+ * const transport = alchemy({
92
+ * alchemyConnection: {
93
+ * apiKey: "your-api-key",
94
+ * },
95
+ * nodeRpcUrl: "https://zora.rpc.url",
96
+ * });
97
+ * ```
98
+ *
99
+ * @param {AlchemyTransportConfig} config The configuration object for the Alchemy transport.
100
+ * @param {number} config.retryDelay Optional The delay between retries, in milliseconds.
101
+ * @param {number} config.retryCount Optional The number of retry attempts.
102
+ * @param {string} [config.alchemyConnection] Optional Alchemy connection configuration (if this is passed in, nodeRpcUrl is required).
103
+ * @param {string} [config.fetchOptions] Optional fetch options for HTTP requests.
104
+ * @param {string} [config.nodeRpcUrl] Optional RPC URL for node (if this is passed in, alchemyConnection is required).
105
+ * @param {string} [config.rpcUrl] Optional RPC URL.
106
+ * @param {string} [config.apiKey] Optional API key for Alchemy.
107
+ * @param {string} [config.jwt] Optional JSON Web Token for authorization.
108
+ * @returns {AlchemyTransport} The configured Alchemy transport object.
109
+ */
110
+ export function alchemy(config: AlchemyTransportConfig): AlchemyTransport {
111
+ const { retryDelay, retryCount } = config;
112
+ // we create a copy here in case we create a split transport down below
113
+ // we don't want to add alchemy headers to 3rd party nodes
114
+ const fetchOptions = { ...config.fetchOptions };
115
+
116
+ const connectionConfig = ConnectionConfigSchema.parse(
117
+ config.alchemyConnection ?? config
118
+ );
119
+
120
+ const headersAsObject = convertHeadersToObject(fetchOptions.headers);
121
+
122
+ // TODO: we probably should just log these headers during telemetry logging instead of doing this mutable header stuff
123
+ fetchOptions.headers = {
124
+ ...headersAsObject,
125
+ "Alchemy-AA-Sdk-Version": VERSION,
126
+ };
127
+
128
+ if (connectionConfig.jwt != null) {
129
+ fetchOptions.headers = {
130
+ ...fetchOptions.headers,
131
+ Authorization: `Bearer ${connectionConfig.jwt}`,
132
+ };
133
+ }
134
+
135
+ const transport: AlchemyTransportBase = (opts) => {
136
+ const { chain: chain_ } = opts;
137
+ if (!chain_) {
138
+ throw new ChainNotFoundError();
139
+ }
140
+ const chain = AlchemyChainSchema.parse(chain_);
141
+
142
+ const rpcUrl =
143
+ connectionConfig.rpcUrl == null
144
+ ? `${chain.rpcUrls.alchemy.http[0]}/${connectionConfig.apiKey ?? ""}`
145
+ : connectionConfig.rpcUrl;
146
+
147
+ const innerTransport = (() => {
148
+ if (config.alchemyConnection && config.nodeRpcUrl) {
149
+ return split({
150
+ overrides: [
151
+ {
152
+ methods: alchemyMethods,
153
+ transport: http(rpcUrl, { fetchOptions }),
154
+ },
155
+ ],
156
+ fallback: http(config.nodeRpcUrl, {
157
+ fetchOptions: config.fetchOptions,
158
+ }),
159
+ });
160
+ }
161
+
162
+ return http(rpcUrl, { fetchOptions });
163
+ })();
164
+
165
+ return createTransport(
166
+ {
167
+ key: "alchemy",
168
+ name: "Alchemy Transport",
169
+ request: innerTransport(opts).request,
170
+ retryCount: retryCount ?? opts?.retryCount,
171
+ retryDelay,
172
+ type: "alchemy",
173
+ },
174
+ { alchemyRpcUrl: rpcUrl, fetchOptions }
175
+ );
176
+ };
177
+
178
+ return Object.assign(transport, {
179
+ updateHeaders(newHeaders_: HeadersInit) {
180
+ const newHeaders = convertHeadersToObject(newHeaders_);
181
+
182
+ fetchOptions.headers = {
183
+ ...fetchOptions.headers,
184
+ ...newHeaders,
185
+ };
186
+ },
187
+ config,
188
+ });
189
+ }
190
+
191
+ const convertHeadersToObject = (
192
+ headers?: HeadersInit
193
+ ): Record<string, string> => {
194
+ if (!headers) {
195
+ return {};
196
+ }
197
+
198
+ if (headers instanceof Headers) {
199
+ const headersObject = {} as Record<string, string>;
200
+ headers.forEach((value, key) => {
201
+ headersObject[key] = value;
202
+ });
203
+ return headersObject;
204
+ }
205
+
206
+ if (Array.isArray(headers)) {
207
+ return headers.reduce((acc, header) => {
208
+ acc[header[0]] = header[1];
209
+ return acc;
210
+ }, {} as Record<string, string>);
211
+ }
212
+
213
+ return headers;
214
+ };
package/src/chains.ts CHANGED
@@ -310,6 +310,24 @@ export const shape: Chain = defineChain({
310
310
  },
311
311
  });
312
312
 
313
+ export const beraChainBartio: Chain = defineChain({
314
+ id: 80084,
315
+ name: "BeraChain Bartio",
316
+ network: "BeraChain Bartio",
317
+ nativeCurrency: { name: "Bera", symbol: "BERA", decimals: 18 },
318
+ rpcUrls: {
319
+ default: {
320
+ http: ["https://berachain-bartio.g.alchemy.com/v2"],
321
+ },
322
+ public: {
323
+ http: ["https://berachain-bartio.g.alchemy.com/v2"],
324
+ },
325
+ alchemy: {
326
+ http: ["https://berachain-bartio.g.alchemy.com/v2"],
327
+ },
328
+ },
329
+ });
330
+
313
331
  export const arbitrumNova: Chain = {
314
332
  ...vabn,
315
333
  rpcUrls: {
@@ -1,6 +1,6 @@
1
1
  import type { SmartContractAccount } from "@aa-sdk/core";
2
2
  import type { Alchemy } from "alchemy-sdk";
3
- import type { Chain, HttpTransport, Transport } from "viem";
3
+ import type { Chain } from "viem";
4
4
  import { AlchemySdkClientSchema } from "../../schema.js";
5
5
  import type { AlchemySmartAccountClient } from "../smartAccountClient.js";
6
6
 
@@ -34,30 +34,23 @@ export type AlchemyEnhancedApis = {
34
34
  export function alchemyEnhancedApiActions(
35
35
  alchemy: Alchemy
36
36
  ): <
37
- TTransport extends Transport = Transport,
38
37
  TChain extends Chain | undefined = Chain | undefined,
39
38
  TAccount extends SmartContractAccount | undefined =
40
39
  | SmartContractAccount
41
40
  | undefined
42
41
  >(
43
- client: AlchemySmartAccountClient<TTransport, TChain, TAccount>
42
+ client: AlchemySmartAccountClient<TChain, TAccount>
44
43
  ) => AlchemyEnhancedApis {
45
44
  return (client) => {
46
45
  const alchemySdk = AlchemySdkClientSchema.parse(alchemy);
47
46
 
48
- if (client.transport.type === "http") {
49
- const { url } = client.transport as ReturnType<HttpTransport>["config"] &
50
- ReturnType<HttpTransport>["value"];
51
-
52
- if (
53
- client.transport.type === "http" &&
54
- alchemy.config.url &&
55
- alchemy.config.url !== url
56
- ) {
57
- throw new Error(
58
- "Alchemy SDK client JSON-RPC URL must match AlchemyProvider JSON-RPC URL"
59
- );
60
- }
47
+ if (
48
+ alchemy.config.url &&
49
+ alchemy.config.url !== client.transport.alchemyRpcUrl
50
+ ) {
51
+ throw new Error(
52
+ "Alchemy SDK client JSON-RPC URL must match AlchemyProvider JSON-RPC URL"
53
+ );
61
54
  }
62
55
 
63
56
  return {
@@ -1,4 +1,4 @@
1
- import { isSmartAccountClient, type SmartContractAccount } from "@aa-sdk/core";
1
+ import { type SmartContractAccount } from "@aa-sdk/core";
2
2
  import type { Chain, Client, Transport } from "viem";
3
3
  import type { AlchemySmartAccountClient } from "./smartAccountClient";
4
4
 
@@ -18,17 +18,12 @@ import type { AlchemySmartAccountClient } from "./smartAccountClient";
18
18
  * @returns {boolean} `true` if the client is an Alchemy Smart Account Client, otherwise `false`
19
19
  */
20
20
  export function isAlchemySmartAccountClient<
21
- TTransport extends Transport = Transport,
22
21
  TChain extends Chain | undefined = Chain | undefined,
23
22
  TAccount extends SmartContractAccount | undefined =
24
23
  | SmartContractAccount
25
24
  | undefined
26
25
  >(
27
- client: Client<TTransport, TChain, TAccount>
28
- ): client is AlchemySmartAccountClient<TTransport, TChain, TAccount> {
29
- // TODO: the goal of this check is to make sure that the client supports certain RPC methods
30
- // we should probably do this by checking the client's transport and configured URL, since alchemy
31
- // clients have to be RPC clients. this is difficult to do though because the transport might
32
- // point to a proxy url :/
33
- return isSmartAccountClient(client);
26
+ client: Client<Transport, TChain, TAccount>
27
+ ): client is AlchemySmartAccountClient<TChain, TAccount> {
28
+ return client.transport.type === "alchemy";
34
29
  }
@@ -1,11 +1,6 @@
1
- import {
2
- createBundlerClient,
3
- type ConnectionConfig,
4
- type NoUndefined,
5
- } from "@aa-sdk/core";
6
- import { http, type Chain, type HttpTransportConfig } from "viem";
7
- import { AlchemyChainSchema } from "../schema.js";
8
- import { VERSION } from "../version.js";
1
+ import { createBundlerClient } from "@aa-sdk/core";
2
+ import type { Chain } from "viem";
3
+ import type { AlchemyTransport } from "../alchemyTransport.js";
9
4
  import type { ClientWithAlchemyMethods } from "./types.js";
10
5
 
11
6
  /**
@@ -13,14 +8,14 @@ import type { ClientWithAlchemyMethods } from "./types.js";
13
8
  *
14
9
  * @example
15
10
  * ```ts
16
- * import { createAlchemyPublicRpcClient } from "@account-kit/infra";
11
+ * import { createAlchemyPublicRpcClient, alchemy } from "@account-kit/infra";
17
12
  * import { sepolia } from "@account-kit/infra";
18
13
  *
19
14
  * const client = createAlchemyPublicRpcClient({
15
+ * transport: alchemy({
16
+ * apiKey: "ALCHEMY_API_KEY"
17
+ * }),
20
18
  * chain: sepolia,
21
- * connectionConfig: {
22
- * apiKey: "your-api-key",
23
- * }
24
19
  * });
25
20
  * ```
26
21
  *
@@ -31,42 +26,14 @@ import type { ClientWithAlchemyMethods } from "./types.js";
31
26
  * @returns {ClientWithAlchemyMethods} A client object tailored with Alchemy methods and capabilities to interact with the blockchain
32
27
  */
33
28
  export const createAlchemyPublicRpcClient = ({
34
- chain: chain_,
35
- connectionConfig,
36
- fetchOptions = {},
29
+ transport,
30
+ chain,
37
31
  }: {
38
- connectionConfig: ConnectionConfig;
39
- chain: Chain;
40
- fetchOptions?: NoUndefined<HttpTransportConfig["fetchOptions"]>;
32
+ transport: AlchemyTransport;
33
+ chain: Chain | undefined;
41
34
  }): ClientWithAlchemyMethods => {
42
- const chain = AlchemyChainSchema.parse(chain_);
43
-
44
- const rpcUrl =
45
- connectionConfig.rpcUrl == null
46
- ? `${chain.rpcUrls.alchemy.http[0]}/${connectionConfig.apiKey ?? ""}`
47
- : connectionConfig.rpcUrl;
48
-
49
- fetchOptions.headers = {
50
- ...fetchOptions.headers,
51
- "Alchemy-AA-Sdk-Version": VERSION,
52
- };
53
-
54
- if (connectionConfig.jwt != null) {
55
- fetchOptions.headers = {
56
- ...fetchOptions.headers,
57
- Authorization: `Bearer ${connectionConfig.jwt}`,
58
- };
59
- }
60
-
61
35
  return createBundlerClient({
62
- chain: chain,
63
- transport: http(rpcUrl, { fetchOptions }),
64
- }).extend(() => ({
65
- updateHeaders(newHeaders: HeadersInit) {
66
- fetchOptions.headers = {
67
- ...fetchOptions.headers,
68
- ...newHeaders,
69
- };
70
- },
71
- }));
36
+ chain,
37
+ transport,
38
+ });
72
39
  };
@@ -1,24 +1,36 @@
1
1
  import {
2
+ ChainNotFoundError,
3
+ createSmartAccountClient,
4
+ isSmartAccountWithSigner,
2
5
  type Prettify,
3
6
  type SmartAccountClient,
4
7
  type SmartAccountClientActions,
5
8
  type SmartAccountClientConfig,
6
9
  type SmartAccountClientRpcSchema,
7
10
  type SmartContractAccount,
11
+ type SmartContractAccountWithSigner,
8
12
  type UserOperationContext,
9
13
  } from "@aa-sdk/core";
10
- import { type Chain, type Transport } from "viem";
14
+ import { type Chain } from "viem";
15
+ import type { AlchemyTransport } from "../alchemyTransport.js";
11
16
  import { getDefaultUserOperationFeeOptions } from "../defaults.js";
12
- import { AlchemyProviderConfigSchema } from "../schema.js";
13
- import type { AlchemyProviderConfig } from "../type.js";
14
- import type { AlchemySmartAccountClientActions } from "./decorators/smartAccount.js";
15
- import { createAlchemySmartAccountClientFromRpcClient } from "./internal/smartAccountClientFromRpc.js";
16
- import { createAlchemyPublicRpcClient } from "./rpcClient.js";
17
+ import { alchemyFeeEstimator } from "../middleware/feeEstimator.js";
18
+ import { alchemyGasManagerMiddleware } from "../middleware/gasManager.js";
19
+ import { alchemyUserOperationSimulator } from "../middleware/userOperationSimulator.js";
20
+ import {
21
+ alchemyActions,
22
+ type AlchemySmartAccountClientActions,
23
+ } from "./decorators/smartAccount.js";
17
24
  import type { AlchemyRpcSchema } from "./types.js";
18
25
 
26
+ export function getSignerTypeHeader<
27
+ TAccount extends SmartContractAccountWithSigner
28
+ >(account: TAccount) {
29
+ return { "Alchemy-Aa-Sdk-Signer": account.getSigner().signerType };
30
+ }
31
+
19
32
  // #region AlchemySmartAccountClientConfig
20
33
  export type AlchemySmartAccountClientConfig<
21
- transport extends Transport = Transport,
22
34
  chain extends Chain | undefined = Chain | undefined,
23
35
  account extends SmartContractAccount | undefined =
24
36
  | SmartContractAccount
@@ -30,11 +42,16 @@ export type AlchemySmartAccountClientConfig<
30
42
  account?: account;
31
43
  useSimulation?: boolean;
32
44
  policyId?: string;
33
- } & AlchemyProviderConfig &
34
- Pick<
35
- SmartAccountClientConfig<transport, chain, account, context>,
36
- "customMiddleware" | "feeEstimator" | "gasEstimator" | "signUserOperation"
37
- >;
45
+ } & Pick<
46
+ SmartAccountClientConfig<AlchemyTransport, chain, account, context>,
47
+ | "customMiddleware"
48
+ | "feeEstimator"
49
+ | "gasEstimator"
50
+ | "signUserOperation"
51
+ | "transport"
52
+ | "chain"
53
+ | "opts"
54
+ >;
38
55
  // #endregion AlchemySmartAccountClientConfig
39
56
 
40
57
  export type BaseAlchemyActions<
@@ -49,7 +66,6 @@ export type BaseAlchemyActions<
49
66
  AlchemySmartAccountClientActions<account, context>;
50
67
 
51
68
  export type AlchemySmartAccountClient_Base<
52
- transport extends Transport = Transport,
53
69
  chain extends Chain | undefined = Chain | undefined,
54
70
  account extends SmartContractAccount | undefined =
55
71
  | SmartContractAccount
@@ -60,7 +76,7 @@ export type AlchemySmartAccountClient_Base<
60
76
  | undefined
61
77
  > = Prettify<
62
78
  SmartAccountClient<
63
- transport,
79
+ AlchemyTransport,
64
80
  chain,
65
81
  account,
66
82
  actions & BaseAlchemyActions<chain, account, context>,
@@ -70,7 +86,6 @@ export type AlchemySmartAccountClient_Base<
70
86
  >;
71
87
 
72
88
  export type AlchemySmartAccountClient<
73
- transport extends Transport = Transport,
74
89
  chain extends Chain | undefined = Chain | undefined,
75
90
  account extends SmartContractAccount | undefined =
76
91
  | SmartContractAccount
@@ -79,12 +94,9 @@ export type AlchemySmartAccountClient<
79
94
  context extends UserOperationContext | undefined =
80
95
  | UserOperationContext
81
96
  | undefined
82
- > = Prettify<
83
- AlchemySmartAccountClient_Base<transport, chain, account, actions, context>
84
- >;
97
+ > = Prettify<AlchemySmartAccountClient_Base<chain, account, actions, context>>;
85
98
 
86
99
  export function createAlchemySmartAccountClient<
87
- TTransport extends Transport = Transport,
88
100
  TChain extends Chain = Chain,
89
101
  TAccount extends SmartContractAccount | undefined =
90
102
  | SmartContractAccount
@@ -92,39 +104,21 @@ export function createAlchemySmartAccountClient<
92
104
  TContext extends UserOperationContext | undefined =
93
105
  | UserOperationContext
94
106
  | undefined
95
- >({
96
- account,
97
- policyId,
98
- useSimulation,
99
- feeEstimator,
100
- customMiddleware,
101
- gasEstimator,
102
- signUserOperation,
103
- ...config_
104
- }: AlchemySmartAccountClientConfig<
105
- TTransport,
106
- TChain,
107
- TAccount,
108
- TContext
109
- >): AlchemySmartAccountClient<
110
- TTransport,
111
- TChain,
112
- TAccount,
113
- Record<string, never>,
114
- TContext
115
- >;
107
+ >(
108
+ params: AlchemySmartAccountClientConfig<TChain, TAccount, TContext>
109
+ ): AlchemySmartAccountClient<TChain, TAccount, Record<string, never>, TContext>;
116
110
 
117
111
  /**
118
112
  * Creates an Alchemy smart account client using the provided configuration options, including account details, gas manager configuration, and custom middleware.
119
113
  *
120
114
  * @example
121
115
  * ```ts
122
- * import { createAlchemySmartAccountClient } from "@account-kit/infra";
116
+ * import { createAlchemySmartAccountClient, alchemy } from "@account-kit/infra";
123
117
  * import { sepolia } from "@account-kit/infra/chain";
124
118
  *
125
119
  * const client = createAlchemySmartAccountClient({
126
120
  * chain: sepolia,
127
- * apiKey: "your-api-key",
121
+ * transport: alchemy({ apiKey: "your-api-key" }),
128
122
  * });
129
123
  * ```
130
124
  *
@@ -139,31 +133,44 @@ export function createAlchemySmartAccountClient({
139
133
  customMiddleware,
140
134
  gasEstimator,
141
135
  signUserOperation,
142
- ...config_
136
+ transport,
137
+ chain,
138
+ opts,
143
139
  }: AlchemySmartAccountClientConfig): AlchemySmartAccountClient {
144
- const config = AlchemyProviderConfigSchema.parse(config_);
145
- const { chain, opts, ...connectionConfig } = config;
146
-
147
- const client = createAlchemyPublicRpcClient({
148
- chain,
149
- connectionConfig,
150
- });
140
+ if (!chain) {
141
+ throw new ChainNotFoundError();
142
+ }
151
143
 
152
144
  const feeOptions =
153
145
  opts?.feeOptions ?? getDefaultUserOperationFeeOptions(chain);
154
146
 
155
- return createAlchemySmartAccountClientFromRpcClient({
156
- client,
147
+ const scaClient = createSmartAccountClient({
157
148
  account,
149
+ transport,
150
+ chain,
151
+ type: "AlchemySmartAccountClient",
158
152
  opts: {
159
153
  ...opts,
160
154
  feeOptions,
161
155
  },
162
- policyId,
163
- useSimulation,
164
- feeEstimator,
165
- customMiddleware,
156
+ customMiddleware: async (struct, args) => {
157
+ if (isSmartAccountWithSigner(args.account)) {
158
+ transport.updateHeaders(getSignerTypeHeader(args.account));
159
+ }
160
+ return customMiddleware ? customMiddleware(struct, args) : struct;
161
+ },
162
+ feeEstimator: feeEstimator ?? alchemyFeeEstimator(transport),
163
+ userOperationSimulator: useSimulation
164
+ ? alchemyUserOperationSimulator(transport)
165
+ : undefined,
166
166
  gasEstimator,
167
+ ...(policyId && alchemyGasManagerMiddleware(policyId)),
167
168
  signUserOperation,
168
- });
169
+ }).extend(alchemyActions);
170
+
171
+ if (account && isSmartAccountWithSigner(account)) {
172
+ transport.updateHeaders(getSignerTypeHeader(account));
173
+ }
174
+
175
+ return scaClient;
169
176
  }
@@ -1,9 +1,13 @@
1
- import { type BundlerClient, type UserOperationRequest } from "@aa-sdk/core";
2
- import type { HttpTransport } from "viem";
1
+ import {
2
+ type BundlerClient,
3
+ type Erc7677RpcSchema,
4
+ type UserOperationRequest,
5
+ } from "@aa-sdk/core";
3
6
  import type {
4
7
  SimulateUserOperationAssetChangesRequest,
5
8
  SimulateUserOperationAssetChangesResponse,
6
9
  } from "../actions/types";
10
+ import type { AlchemyTransport } from "../alchemyTransport";
7
11
 
8
12
  export type AlchemyRpcSchema = [
9
13
  {
@@ -15,11 +19,12 @@ export type AlchemyRpcSchema = [
15
19
  Method: "rundler_maxPriorityFeePerGas";
16
20
  Parameters: [];
17
21
  ReturnType: UserOperationRequest["maxPriorityFeePerGas"];
18
- }
22
+ },
23
+ ...Erc7677RpcSchema<{ policyId: string }>
19
24
  ];
20
25
 
21
- export type ClientWithAlchemyMethods = BundlerClient<HttpTransport> & {
22
- request: BundlerClient<HttpTransport>["request"] &
26
+ export type ClientWithAlchemyMethods = BundlerClient<AlchemyTransport> & {
27
+ request: BundlerClient<AlchemyTransport>["request"] &
23
28
  {
24
29
  request(args: {
25
30
  method: "alchemy_simulateUserOperationAssetChanges";
@@ -31,6 +36,4 @@ export type ClientWithAlchemyMethods = BundlerClient<HttpTransport> & {
31
36
  params: [];
32
37
  }): Promise<UserOperationRequest["maxPriorityFeePerGas"]>;
33
38
  }["request"];
34
- } & {
35
- updateHeaders: (headers: HeadersInit) => void;
36
39
  };