@alchemy/aa-infra 0.0.0-alpha.9 → 5.0.0-beta.2

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.
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2023 Alchemy Insights, Inc.
3
+ Copyright (c) 2026 Alchemy Insights, Inc.
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md ADDED
@@ -0,0 +1,35 @@
1
+ # @alchemy/aa-infra
2
+
3
+ Alchemy Account Abstraction infrastructure utilities. Provides Rundler-specific fee estimation and RPC types for use with viem's bundler client.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @alchemy/aa-infra @alchemy/common viem
9
+ ```
10
+
11
+ ## Key Exports
12
+
13
+ - **`estimateFeesPerGas`** - Custom fee estimation using Alchemy's `rundler_maxPriorityFeePerGas` RPC method. Pass this as `userOperation.estimateFeesPerGas` when creating a viem `BundlerClient` pointed at Alchemy's Rundler.
14
+ - **`RundlerClient`** / **`RundlerRpcSchema`** - TypeScript types extending viem's `BundlerClient` with Rundler-specific RPC methods
15
+
16
+ ## Usage
17
+
18
+ ```ts
19
+ import { estimateFeesPerGas } from "@alchemy/aa-infra";
20
+ import { createBundlerClient } from "viem/account-abstraction";
21
+ import { sepolia } from "viem/chains";
22
+ import { alchemyTransport } from "@alchemy/common";
23
+
24
+ const bundlerClient = createBundlerClient({
25
+ chain: sepolia,
26
+ transport: alchemyTransport({ apiKey: "YOUR_API_KEY" }),
27
+ userOperation: {
28
+ estimateFeesPerGas,
29
+ },
30
+ });
31
+ ```
32
+
33
+ ## License
34
+
35
+ MIT
@@ -1,7 +1,7 @@
1
1
  import { type Client, type Transport, type Chain, type Account } from "viem";
2
- import type { UserOperationRequest, SmartAccount } from "viem/account-abstraction";
2
+ import type { UserOperationRequest, SmartAccount, BundlerClient } from "viem/account-abstraction";
3
3
  import type { RundlerRpcSchema } from "./schema.js";
4
- export type RundlerClient<transport extends Transport = Transport, chain extends Chain | undefined = Chain | undefined, account extends Account | undefined = Account | undefined> = Client<transport, chain, account, RundlerRpcSchema>;
4
+ export type RundlerClient<transport extends Transport = Transport, chain extends Chain | undefined = Chain | undefined, account extends SmartAccount | undefined = SmartAccount | undefined> = BundlerClient<transport, chain, account, Client | undefined, RundlerRpcSchema>;
5
5
  /**
6
6
  * A custom `estimateFeesPerGas` function for viem bundler clients to use `rundler_maxPriorityFeePerGas` for priority fee estimation.
7
7
  *
@@ -17,7 +17,7 @@ export type RundlerClient<transport extends Transport = Transport, chain extends
17
17
  * @example
18
18
  * ```ts
19
19
  * import { createBundlerClient } from "viem/account-abstraction";
20
- * import { alchemyEstimateFeesPerGas } from "@alchemy/aa-infra";
20
+ * import { estimateFeesPerGas as alchemyEstimateFeesPerGas } from "@alchemy/aa-infra";
21
21
  *
22
22
  * const bundler = createBundlerClient({
23
23
  * transport: http("<rundler-url>"),
@@ -27,8 +27,8 @@ export type RundlerClient<transport extends Transport = Transport, chain extends
27
27
  * });
28
28
  * ```
29
29
  */
30
- export declare function estimateFeesPerGas<TTransport extends Transport = Transport, TChain extends Chain | undefined = Chain | undefined, TAccount extends Account | undefined = Account | undefined>({ bundlerClient, account: _account, userOperation: _userOperation, }: {
31
- bundlerClient: RundlerClient<TTransport, TChain, TAccount>;
30
+ export declare function estimateFeesPerGas<TTransport extends Transport = Transport, TChain extends Chain | undefined = Chain | undefined, TAccount extends SmartAccount | Account | undefined = SmartAccount | Account | undefined>({ bundlerClient, account: _account, userOperation: _userOperation, }: {
31
+ bundlerClient: Client<TTransport, TChain, TAccount>;
32
32
  account?: SmartAccount;
33
33
  userOperation?: UserOperationRequest;
34
34
  }): Promise<{
@@ -1,6 +1,6 @@
1
1
  import { getBlock } from "viem/actions";
2
2
  import { isHex, hexToBigInt, } from "viem";
3
- import { bigIntMultiply } from "@alchemy/common";
3
+ import { BaseError, bigIntMultiply } from "@alchemy/common";
4
4
  import { InvalidHexValueError } from "./errors.js";
5
5
  /**
6
6
  * A custom `estimateFeesPerGas` function for viem bundler clients to use `rundler_maxPriorityFeePerGas` for priority fee estimation.
@@ -17,7 +17,7 @@ import { InvalidHexValueError } from "./errors.js";
17
17
  * @example
18
18
  * ```ts
19
19
  * import { createBundlerClient } from "viem/account-abstraction";
20
- * import { alchemyEstimateFeesPerGas } from "@alchemy/aa-infra";
20
+ * import { estimateFeesPerGas as alchemyEstimateFeesPerGas } from "@alchemy/aa-infra";
21
21
  *
22
22
  * const bundler = createBundlerClient({
23
23
  * transport: http("<rundler-url>"),
@@ -28,27 +28,36 @@ import { InvalidHexValueError } from "./errors.js";
28
28
  * ```
29
29
  */
30
30
  export async function estimateFeesPerGas({ bundlerClient, account: _account, userOperation: _userOperation, }) {
31
+ // Cast to RundlerClient to access rundler-specific RPC methods and BundlerClient properties.
32
+ // This mirrors viem's pattern in prepareUserOperation.ts where they cast `client as unknown as BundlerClient`
33
+ // to access bundler-specific properties from a base Client type.
34
+ // See: https://github.com/wevm/viem/blob/d18b3b27/src/account-abstraction/actions/bundler/prepareUserOperation.ts#L355
35
+ const rundlerClient = bundlerClient;
31
36
  const [block, maxPriorityFeePerGasHex] = await Promise.all([
32
- getBlock(bundlerClient, { blockTag: "latest" }), // This is technically hitting the node rpc, not rundler.
33
- bundlerClient.request({
37
+ // If the node rpc url is different from the bundler url, the public
38
+ // client should be passed in when creating the bundler client, which
39
+ // we can access here for public actions.
40
+ getBlock(rundlerClient.client ?? rundlerClient, { blockTag: "latest" }),
41
+ rundlerClient.request({
34
42
  method: "rundler_maxPriorityFeePerGas",
35
43
  params: [],
36
44
  }),
37
45
  ]);
38
46
  const baseFeePerGas = block.baseFeePerGas;
39
47
  if (baseFeePerGas == null) {
40
- throw new Error("baseFeePerGas is null");
48
+ throw new BaseError("baseFeePerGas is null");
41
49
  }
42
50
  if (maxPriorityFeePerGasHex == null) {
43
- throw new Error("rundler_maxPriorityFeePerGas returned null or undefined");
51
+ throw new BaseError("rundler_maxPriorityFeePerGas returned null or undefined");
44
52
  }
45
53
  if (!isHex(maxPriorityFeePerGasHex)) {
46
54
  throw new InvalidHexValueError(maxPriorityFeePerGasHex);
47
55
  }
48
56
  const maxPriorityFeePerGas = hexToBigInt(maxPriorityFeePerGasHex);
57
+ const bufferedMaxPriorityFeePerGas = bigIntMultiply(maxPriorityFeePerGas, 1.5);
49
58
  return {
50
- maxPriorityFeePerGas,
51
- maxFeePerGas: bigIntMultiply(baseFeePerGas, 1.5) + maxPriorityFeePerGas,
59
+ maxPriorityFeePerGas: bufferedMaxPriorityFeePerGas,
60
+ maxFeePerGas: bigIntMultiply(baseFeePerGas, 1.5) + bufferedMaxPriorityFeePerGas,
52
61
  };
53
62
  }
54
63
  //# sourceMappingURL=estimateFeesPerGas.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"estimateFeesPerGas.js","sourceRoot":"","sources":["../../src/estimateFeesPerGas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAEL,KAAK,EAIL,WAAW,GACZ,MAAM,MAAM,CAAC;AAKd,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AASnD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAItC,EACA,aAAa,EACb,OAAO,EAAE,QAAQ,EACjB,aAAa,EAAE,cAAc,GAK9B;IAIC,MAAM,CAAC,KAAK,EAAE,uBAAuB,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACzD,QAAQ,CAAC,aAAa,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,EAAE,yDAAyD;QAC1G,aAAa,CAAC,OAAO,CAAC;YACpB,MAAM,EAAE,8BAA8B;YACtC,MAAM,EAAE,EAAE;SACX,CAAC;KACH,CAAC,CAAC;IAEH,MAAM,aAAa,GAAG,KAAK,CAAC,aAAa,CAAC;IAC1C,IAAI,aAAa,IAAI,IAAI,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;IAC3C,CAAC;IACD,IAAI,uBAAuB,IAAI,IAAI,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAC;IAC7E,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,uBAAuB,CAAC,EAAE,CAAC;QACpC,MAAM,IAAI,oBAAoB,CAAC,uBAAuB,CAAC,CAAC;IAC1D,CAAC;IACD,MAAM,oBAAoB,GAAG,WAAW,CAAC,uBAAuB,CAAC,CAAC;IAElE,OAAO;QACL,oBAAoB;QACpB,YAAY,EAAE,cAAc,CAAC,aAAa,EAAE,GAAG,CAAC,GAAG,oBAAoB;KACxE,CAAC;AACJ,CAAC","sourcesContent":["import { getBlock } from \"viem/actions\";\nimport {\n type Client,\n isHex,\n type Transport,\n type Chain,\n type Account,\n hexToBigInt,\n} from \"viem\";\nimport type {\n UserOperationRequest,\n SmartAccount,\n} from \"viem/account-abstraction\";\nimport { bigIntMultiply } from \"@alchemy/common\";\nimport type { RundlerRpcSchema } from \"./schema.js\";\nimport { InvalidHexValueError } from \"./errors.js\";\n\n// Extend client with Rundler rpc schema.\nexport type RundlerClient<\n transport extends Transport = Transport,\n chain extends Chain | undefined = Chain | undefined,\n account extends Account | undefined = Account | undefined,\n> = Client<transport, chain, account, RundlerRpcSchema>;\n\n/**\n * A custom `estimateFeesPerGas` function for viem bundler clients to use `rundler_maxPriorityFeePerGas` for priority fee estimation.\n *\n * It fetches:\n * 1. `baseFeePerGas` from the latest block.\n * 2. `maxPriorityFeePerGas` via `rundler_maxPriorityFeePerGas`.\n *\n * It then returns `maxFeePerGas = baseFee * 1.5 + priority` (aligns with viem default).\n *\n * @param {RundlerClient} bundlerClient Bundler client with the rundler RPC method.\n * @returns {Promise<{maxFeePerGas: bigint, maxPriorityFeePerGas: bigint}>} Estimated fee values.\n *\n * @example\n * ```ts\n * import { createBundlerClient } from \"viem/account-abstraction\";\n * import { alchemyEstimateFeesPerGas } from \"@alchemy/aa-infra\";\n *\n * const bundler = createBundlerClient({\n * transport: http(\"<rundler-url>\"),\n * userOperation: {\n * estimateFeesPerGas: alchemyEstimateFeesPerGas,\n * },\n * });\n * ```\n */\nexport async function estimateFeesPerGas<\n TTransport extends Transport = Transport,\n TChain extends Chain | undefined = Chain | undefined,\n TAccount extends Account | undefined = Account | undefined,\n>({\n bundlerClient,\n account: _account,\n userOperation: _userOperation,\n}: {\n bundlerClient: RundlerClient<TTransport, TChain, TAccount>;\n account?: SmartAccount;\n userOperation?: UserOperationRequest;\n}): Promise<{\n maxFeePerGas: bigint;\n maxPriorityFeePerGas: bigint;\n}> {\n const [block, maxPriorityFeePerGasHex] = await Promise.all([\n getBlock(bundlerClient, { blockTag: \"latest\" }), // This is technically hitting the node rpc, not rundler.\n bundlerClient.request({\n method: \"rundler_maxPriorityFeePerGas\",\n params: [],\n }),\n ]);\n\n const baseFeePerGas = block.baseFeePerGas;\n if (baseFeePerGas == null) {\n throw new Error(\"baseFeePerGas is null\");\n }\n if (maxPriorityFeePerGasHex == null) {\n throw new Error(\"rundler_maxPriorityFeePerGas returned null or undefined\");\n }\n if (!isHex(maxPriorityFeePerGasHex)) {\n throw new InvalidHexValueError(maxPriorityFeePerGasHex);\n }\n const maxPriorityFeePerGas = hexToBigInt(maxPriorityFeePerGasHex);\n\n return {\n maxPriorityFeePerGas,\n maxFeePerGas: bigIntMultiply(baseFeePerGas, 1.5) + maxPriorityFeePerGas,\n };\n}\n"]}
1
+ {"version":3,"file":"estimateFeesPerGas.js","sourceRoot":"","sources":["../../src/estimateFeesPerGas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAEL,KAAK,EAGL,WAAW,GAEZ,MAAM,MAAM,CAAC;AAMd,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAE5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAenD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAOtC,EACA,aAAa,EACb,OAAO,EAAE,QAAQ,EACjB,aAAa,EAAE,cAAc,GAK9B;IAIC,6FAA6F;IAC7F,8GAA8G;IAC9G,iEAAiE;IACjE,uHAAuH;IACvH,MAAM,aAAa,GAAG,aAAyC,CAAC;IAEhE,MAAM,CAAC,KAAK,EAAE,uBAAuB,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACzD,oEAAoE;QACpE,qEAAqE;QACrE,yCAAyC;QACzC,QAAQ,CAAC,aAAa,CAAC,MAAM,IAAI,aAAa,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;QACvE,aAAa,CAAC,OAAO,CAAC;YACpB,MAAM,EAAE,8BAA8B;YACtC,MAAM,EAAE,EAAE;SACX,CAAC;KACH,CAAC,CAAC;IAEH,MAAM,aAAa,GAAG,KAAK,CAAC,aAAa,CAAC;IAC1C,IAAI,aAAa,IAAI,IAAI,EAAE,CAAC;QAC1B,MAAM,IAAI,SAAS,CAAC,uBAAuB,CAAC,CAAC;IAC/C,CAAC;IACD,IAAI,uBAAuB,IAAI,IAAI,EAAE,CAAC;QACpC,MAAM,IAAI,SAAS,CACjB,yDAAyD,CAC1D,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,uBAAuB,CAAC,EAAE,CAAC;QACpC,MAAM,IAAI,oBAAoB,CAAC,uBAAuB,CAAC,CAAC;IAC1D,CAAC;IACD,MAAM,oBAAoB,GAAG,WAAW,CAAC,uBAAuB,CAAC,CAAC;IAElE,MAAM,4BAA4B,GAAG,cAAc,CACjD,oBAAoB,EACpB,GAAG,CACJ,CAAC;IAEF,OAAO;QACL,oBAAoB,EAAE,4BAA4B;QAClD,YAAY,EACV,cAAc,CAAC,aAAa,EAAE,GAAG,CAAC,GAAG,4BAA4B;KACpE,CAAC;AACJ,CAAC","sourcesContent":["import { getBlock } from \"viem/actions\";\nimport {\n type Client,\n isHex,\n type Transport,\n type Chain,\n hexToBigInt,\n type Account,\n} from \"viem\";\nimport type {\n UserOperationRequest,\n SmartAccount,\n BundlerClient,\n} from \"viem/account-abstraction\";\nimport { BaseError, bigIntMultiply } from \"@alchemy/common\";\nimport type { RundlerRpcSchema } from \"./schema.js\";\nimport { InvalidHexValueError } from \"./errors.js\";\n\n// Extend client with Rundler rpc schema.\nexport type RundlerClient<\n transport extends Transport = Transport,\n chain extends Chain | undefined = Chain | undefined,\n account extends SmartAccount | undefined = SmartAccount | undefined,\n> = BundlerClient<\n transport,\n chain,\n account,\n Client | undefined,\n RundlerRpcSchema\n>;\n\n/**\n * A custom `estimateFeesPerGas` function for viem bundler clients to use `rundler_maxPriorityFeePerGas` for priority fee estimation.\n *\n * It fetches:\n * 1. `baseFeePerGas` from the latest block.\n * 2. `maxPriorityFeePerGas` via `rundler_maxPriorityFeePerGas`.\n *\n * It then returns `maxFeePerGas = baseFee * 1.5 + priority` (aligns with viem default).\n *\n * @param {RundlerClient} bundlerClient Bundler client with the rundler RPC method.\n * @returns {Promise<{maxFeePerGas: bigint, maxPriorityFeePerGas: bigint}>} Estimated fee values.\n *\n * @example\n * ```ts\n * import { createBundlerClient } from \"viem/account-abstraction\";\n * import { estimateFeesPerGas as alchemyEstimateFeesPerGas } from \"@alchemy/aa-infra\";\n *\n * const bundler = createBundlerClient({\n * transport: http(\"<rundler-url>\"),\n * userOperation: {\n * estimateFeesPerGas: alchemyEstimateFeesPerGas,\n * },\n * });\n * ```\n */\nexport async function estimateFeesPerGas<\n TTransport extends Transport = Transport,\n TChain extends Chain | undefined = Chain | undefined,\n TAccount extends SmartAccount | Account | undefined =\n | SmartAccount\n | Account\n | undefined,\n>({\n bundlerClient,\n account: _account,\n userOperation: _userOperation,\n}: {\n bundlerClient: Client<TTransport, TChain, TAccount>;\n account?: SmartAccount;\n userOperation?: UserOperationRequest;\n}): Promise<{\n maxFeePerGas: bigint;\n maxPriorityFeePerGas: bigint;\n}> {\n // Cast to RundlerClient to access rundler-specific RPC methods and BundlerClient properties.\n // This mirrors viem's pattern in prepareUserOperation.ts where they cast `client as unknown as BundlerClient`\n // to access bundler-specific properties from a base Client type.\n // See: https://github.com/wevm/viem/blob/d18b3b27/src/account-abstraction/actions/bundler/prepareUserOperation.ts#L355\n const rundlerClient = bundlerClient as unknown as RundlerClient;\n\n const [block, maxPriorityFeePerGasHex] = await Promise.all([\n // If the node rpc url is different from the bundler url, the public\n // client should be passed in when creating the bundler client, which\n // we can access here for public actions.\n getBlock(rundlerClient.client ?? rundlerClient, { blockTag: \"latest\" }),\n rundlerClient.request({\n method: \"rundler_maxPriorityFeePerGas\",\n params: [],\n }),\n ]);\n\n const baseFeePerGas = block.baseFeePerGas;\n if (baseFeePerGas == null) {\n throw new BaseError(\"baseFeePerGas is null\");\n }\n if (maxPriorityFeePerGasHex == null) {\n throw new BaseError(\n \"rundler_maxPriorityFeePerGas returned null or undefined\",\n );\n }\n if (!isHex(maxPriorityFeePerGasHex)) {\n throw new InvalidHexValueError(maxPriorityFeePerGasHex);\n }\n const maxPriorityFeePerGas = hexToBigInt(maxPriorityFeePerGasHex);\n\n const bufferedMaxPriorityFeePerGas = bigIntMultiply(\n maxPriorityFeePerGas,\n 1.5,\n );\n\n return {\n maxPriorityFeePerGas: bufferedMaxPriorityFeePerGas,\n maxFeePerGas:\n bigIntMultiply(baseFeePerGas, 1.5) + bufferedMaxPriorityFeePerGas,\n };\n}\n"]}
@@ -1,2 +1,2 @@
1
- import type { DiagnosticsLogger } from "@alchemy/common";
1
+ import type { DiagnosticsLogger } from "@alchemy/common/internal";
2
2
  export declare const LOGGER: DiagnosticsLogger;
@@ -1,4 +1,4 @@
1
- import { createLogger } from "@alchemy/common";
1
+ import { createLogger } from "@alchemy/common/internal";
2
2
  import { VERSION } from "./version.js";
3
3
  export const LOGGER = createLogger({
4
4
  package: "@alchemy/aa-infra",
@@ -1 +1 @@
1
- {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,MAAM,CAAC,MAAM,MAAM,GAAsB,YAAY,CAAC;IACpD,OAAO,EAAE,mBAAmB;IAC5B,OAAO,EAAE,OAAO;IAChB,SAAS,EAAE,UAAU;CACtB,CAAC,CAAC","sourcesContent":["import { createLogger } from \"@alchemy/common\";\nimport type { DiagnosticsLogger } from \"@alchemy/common\";\nimport { VERSION } from \"./version.js\";\n\nexport const LOGGER: DiagnosticsLogger = createLogger({\n package: \"@alchemy/aa-infra\",\n version: VERSION,\n namespace: \"aa-infra\",\n});\n"]}
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAExD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,MAAM,CAAC,MAAM,MAAM,GAAsB,YAAY,CAAC;IACpD,OAAO,EAAE,mBAAmB;IAC5B,OAAO,EAAE,OAAO;IAChB,SAAS,EAAE,UAAU;CACtB,CAAC,CAAC","sourcesContent":["import { createLogger } from \"@alchemy/common/internal\";\nimport type { DiagnosticsLogger } from \"@alchemy/common/internal\";\nimport { VERSION } from \"./version.js\";\n\nexport const LOGGER: DiagnosticsLogger = createLogger({\n package: \"@alchemy/aa-infra\",\n version: VERSION,\n namespace: \"aa-infra\",\n});\n"]}
@@ -1 +1 @@
1
- export declare const VERSION = "0.0.0-alpha.8";
1
+ export declare const VERSION = "5.0.0-beta.1";
@@ -1,4 +1,4 @@
1
1
  // This file is autogenerated by inject-version.ts. Any changes will be
2
2
  // overwritten on commit!
3
- export const VERSION = "0.0.0-alpha.8";
3
+ export const VERSION = "5.0.0-beta.1";
4
4
  //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,yBAAyB;AACzB,MAAM,CAAC,MAAM,OAAO,GAAG,eAAe,CAAC","sourcesContent":["// This file is autogenerated by inject-version.ts. Any changes will be\n// overwritten on commit!\nexport const VERSION = \"0.0.0-alpha.8\";\n"]}
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,yBAAyB;AACzB,MAAM,CAAC,MAAM,OAAO,GAAG,cAAc,CAAC","sourcesContent":["// This file is autogenerated by inject-version.ts. Any changes will be\n// overwritten on commit!\nexport const VERSION = \"5.0.0-beta.1\";\n"]}
@@ -1,7 +1,7 @@
1
1
  import { type Client, type Transport, type Chain, type Account } from "viem";
2
- import type { UserOperationRequest, SmartAccount } from "viem/account-abstraction";
2
+ import type { UserOperationRequest, SmartAccount, BundlerClient } from "viem/account-abstraction";
3
3
  import type { RundlerRpcSchema } from "./schema.js";
4
- export type RundlerClient<transport extends Transport = Transport, chain extends Chain | undefined = Chain | undefined, account extends Account | undefined = Account | undefined> = Client<transport, chain, account, RundlerRpcSchema>;
4
+ export type RundlerClient<transport extends Transport = Transport, chain extends Chain | undefined = Chain | undefined, account extends SmartAccount | undefined = SmartAccount | undefined> = BundlerClient<transport, chain, account, Client | undefined, RundlerRpcSchema>;
5
5
  /**
6
6
  * A custom `estimateFeesPerGas` function for viem bundler clients to use `rundler_maxPriorityFeePerGas` for priority fee estimation.
7
7
  *
@@ -17,7 +17,7 @@ export type RundlerClient<transport extends Transport = Transport, chain extends
17
17
  * @example
18
18
  * ```ts
19
19
  * import { createBundlerClient } from "viem/account-abstraction";
20
- * import { alchemyEstimateFeesPerGas } from "@alchemy/aa-infra";
20
+ * import { estimateFeesPerGas as alchemyEstimateFeesPerGas } from "@alchemy/aa-infra";
21
21
  *
22
22
  * const bundler = createBundlerClient({
23
23
  * transport: http("<rundler-url>"),
@@ -27,8 +27,8 @@ export type RundlerClient<transport extends Transport = Transport, chain extends
27
27
  * });
28
28
  * ```
29
29
  */
30
- export declare function estimateFeesPerGas<TTransport extends Transport = Transport, TChain extends Chain | undefined = Chain | undefined, TAccount extends Account | undefined = Account | undefined>({ bundlerClient, account: _account, userOperation: _userOperation, }: {
31
- bundlerClient: RundlerClient<TTransport, TChain, TAccount>;
30
+ export declare function estimateFeesPerGas<TTransport extends Transport = Transport, TChain extends Chain | undefined = Chain | undefined, TAccount extends SmartAccount | Account | undefined = SmartAccount | Account | undefined>({ bundlerClient, account: _account, userOperation: _userOperation, }: {
31
+ bundlerClient: Client<TTransport, TChain, TAccount>;
32
32
  account?: SmartAccount;
33
33
  userOperation?: UserOperationRequest;
34
34
  }): Promise<{
@@ -1 +1 @@
1
- {"version":3,"file":"estimateFeesPerGas.d.ts","sourceRoot":"","sources":["../../src/estimateFeesPerGas.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,MAAM,EAEX,KAAK,SAAS,EACd,KAAK,KAAK,EACV,KAAK,OAAO,EAEb,MAAM,MAAM,CAAC;AACd,OAAO,KAAK,EACV,oBAAoB,EACpB,YAAY,EACb,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAIpD,MAAM,MAAM,aAAa,CACvB,SAAS,SAAS,SAAS,GAAG,SAAS,EACvC,KAAK,SAAS,KAAK,GAAG,SAAS,GAAG,KAAK,GAAG,SAAS,EACnD,OAAO,SAAS,OAAO,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,IACvD,MAAM,CAAC,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;AAExD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAsB,kBAAkB,CACtC,UAAU,SAAS,SAAS,GAAG,SAAS,EACxC,MAAM,SAAS,KAAK,GAAG,SAAS,GAAG,KAAK,GAAG,SAAS,EACpD,QAAQ,SAAS,OAAO,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,EAC1D,EACA,aAAa,EACb,OAAO,EAAE,QAAQ,EACjB,aAAa,EAAE,cAAc,GAC9B,EAAE;IACD,aAAa,EAAE,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC3D,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,aAAa,CAAC,EAAE,oBAAoB,CAAC;CACtC,GAAG,OAAO,CAAC;IACV,YAAY,EAAE,MAAM,CAAC;IACrB,oBAAoB,EAAE,MAAM,CAAC;CAC9B,CAAC,CAyBD"}
1
+ {"version":3,"file":"estimateFeesPerGas.d.ts","sourceRoot":"","sources":["../../src/estimateFeesPerGas.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,MAAM,EAEX,KAAK,SAAS,EACd,KAAK,KAAK,EAEV,KAAK,OAAO,EACb,MAAM,MAAM,CAAC;AACd,OAAO,KAAK,EACV,oBAAoB,EACpB,YAAY,EACZ,aAAa,EACd,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAIpD,MAAM,MAAM,aAAa,CACvB,SAAS,SAAS,SAAS,GAAG,SAAS,EACvC,KAAK,SAAS,KAAK,GAAG,SAAS,GAAG,KAAK,GAAG,SAAS,EACnD,OAAO,SAAS,YAAY,GAAG,SAAS,GAAG,YAAY,GAAG,SAAS,IACjE,aAAa,CACf,SAAS,EACT,KAAK,EACL,OAAO,EACP,MAAM,GAAG,SAAS,EAClB,gBAAgB,CACjB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAsB,kBAAkB,CACtC,UAAU,SAAS,SAAS,GAAG,SAAS,EACxC,MAAM,SAAS,KAAK,GAAG,SAAS,GAAG,KAAK,GAAG,SAAS,EACpD,QAAQ,SAAS,YAAY,GAAG,OAAO,GAAG,SAAS,GAC/C,YAAY,GACZ,OAAO,GACP,SAAS,EACb,EACA,aAAa,EACb,OAAO,EAAE,QAAQ,EACjB,aAAa,EAAE,cAAc,GAC9B,EAAE;IACD,aAAa,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;IACpD,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,aAAa,CAAC,EAAE,oBAAoB,CAAC;CACtC,GAAG,OAAO,CAAC;IACV,YAAY,EAAE,MAAM,CAAC;IACrB,oBAAoB,EAAE,MAAM,CAAC;CAC9B,CAAC,CA0CD"}
@@ -1,3 +1,3 @@
1
- import type { DiagnosticsLogger } from "@alchemy/common";
1
+ import type { DiagnosticsLogger } from "@alchemy/common/internal";
2
2
  export declare const LOGGER: DiagnosticsLogger;
3
3
  //# sourceMappingURL=logger.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/logger.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAGzD,eAAO,MAAM,MAAM,EAAE,iBAInB,CAAC"}
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/logger.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAGlE,eAAO,MAAM,MAAM,EAAE,iBAInB,CAAC"}
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "0.0.0-alpha.8";
1
+ export declare const VERSION = "5.0.0-beta.1";
2
2
  //# sourceMappingURL=version.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,OAAO,kBAAkB,CAAC"}
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,OAAO,iBAAiB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alchemy/aa-infra",
3
- "version": "0.0.0-alpha.9",
3
+ "version": "5.0.0-beta.2",
4
4
  "description": "Alchemy Account Abstraction Infrastructure",
5
5
  "author": "Alchemy",
6
6
  "license": "MIT",
@@ -34,17 +34,19 @@
34
34
  "build": "yarn clean && yarn build:esm && yarn build:types",
35
35
  "build:esm": "tsc --project tsconfig.build.json --outDir ./dist/esm",
36
36
  "build:types": "tsc --project tsconfig.build.json --declarationDir ./dist/types --emitDeclarationOnly --declaration --declarationMap",
37
- "fern:gen": "node ../../doc-gen/dist/esm/cli.js generate --in ./src/index.ts --out ../../docs/pages/reference/alchemy/aa-infra",
38
37
  "clean": "rm -rf ./dist",
39
38
  "test": "vitest",
40
39
  "test:run": "vitest run"
41
40
  },
42
41
  "devDependencies": {
43
- "typescript-template": "*"
42
+ "typescript-template": "*",
43
+ "viem": "^2.45.0"
44
44
  },
45
45
  "dependencies": {
46
- "@alchemy/common": "^0.0.0-alpha.9",
47
- "viem": "^2.32.0"
46
+ "@alchemy/common": "^5.0.0-beta.2"
47
+ },
48
+ "peerDependencies": {
49
+ "viem": "^2.45.0"
48
50
  },
49
51
  "publishConfig": {
50
52
  "access": "public",
@@ -58,5 +60,5 @@
58
60
  "url": "https://github.com/alchemyplatform/aa-sdk/issues"
59
61
  },
60
62
  "homepage": "https://github.com/alchemyplatform/aa-sdk#readme",
61
- "gitHead": "54eef9b1cadf5376a4c809375c7cf012bce3e392"
63
+ "gitHead": "9042002b7414ac2ae8a6251ee4cf96555b091eca"
62
64
  }
@@ -4,14 +4,15 @@ import {
4
4
  isHex,
5
5
  type Transport,
6
6
  type Chain,
7
- type Account,
8
7
  hexToBigInt,
8
+ type Account,
9
9
  } from "viem";
10
10
  import type {
11
11
  UserOperationRequest,
12
12
  SmartAccount,
13
+ BundlerClient,
13
14
  } from "viem/account-abstraction";
14
- import { bigIntMultiply } from "@alchemy/common";
15
+ import { BaseError, bigIntMultiply } from "@alchemy/common";
15
16
  import type { RundlerRpcSchema } from "./schema.js";
16
17
  import { InvalidHexValueError } from "./errors.js";
17
18
 
@@ -19,8 +20,14 @@ import { InvalidHexValueError } from "./errors.js";
19
20
  export type RundlerClient<
20
21
  transport extends Transport = Transport,
21
22
  chain extends Chain | undefined = Chain | undefined,
22
- account extends Account | undefined = Account | undefined,
23
- > = Client<transport, chain, account, RundlerRpcSchema>;
23
+ account extends SmartAccount | undefined = SmartAccount | undefined,
24
+ > = BundlerClient<
25
+ transport,
26
+ chain,
27
+ account,
28
+ Client | undefined,
29
+ RundlerRpcSchema
30
+ >;
24
31
 
25
32
  /**
26
33
  * A custom `estimateFeesPerGas` function for viem bundler clients to use `rundler_maxPriorityFeePerGas` for priority fee estimation.
@@ -37,7 +44,7 @@ export type RundlerClient<
37
44
  * @example
38
45
  * ```ts
39
46
  * import { createBundlerClient } from "viem/account-abstraction";
40
- * import { alchemyEstimateFeesPerGas } from "@alchemy/aa-infra";
47
+ * import { estimateFeesPerGas as alchemyEstimateFeesPerGas } from "@alchemy/aa-infra";
41
48
  *
42
49
  * const bundler = createBundlerClient({
43
50
  * transport: http("<rundler-url>"),
@@ -50,22 +57,34 @@ export type RundlerClient<
50
57
  export async function estimateFeesPerGas<
51
58
  TTransport extends Transport = Transport,
52
59
  TChain extends Chain | undefined = Chain | undefined,
53
- TAccount extends Account | undefined = Account | undefined,
60
+ TAccount extends SmartAccount | Account | undefined =
61
+ | SmartAccount
62
+ | Account
63
+ | undefined,
54
64
  >({
55
65
  bundlerClient,
56
66
  account: _account,
57
67
  userOperation: _userOperation,
58
68
  }: {
59
- bundlerClient: RundlerClient<TTransport, TChain, TAccount>;
69
+ bundlerClient: Client<TTransport, TChain, TAccount>;
60
70
  account?: SmartAccount;
61
71
  userOperation?: UserOperationRequest;
62
72
  }): Promise<{
63
73
  maxFeePerGas: bigint;
64
74
  maxPriorityFeePerGas: bigint;
65
75
  }> {
76
+ // Cast to RundlerClient to access rundler-specific RPC methods and BundlerClient properties.
77
+ // This mirrors viem's pattern in prepareUserOperation.ts where they cast `client as unknown as BundlerClient`
78
+ // to access bundler-specific properties from a base Client type.
79
+ // See: https://github.com/wevm/viem/blob/d18b3b27/src/account-abstraction/actions/bundler/prepareUserOperation.ts#L355
80
+ const rundlerClient = bundlerClient as unknown as RundlerClient;
81
+
66
82
  const [block, maxPriorityFeePerGasHex] = await Promise.all([
67
- getBlock(bundlerClient, { blockTag: "latest" }), // This is technically hitting the node rpc, not rundler.
68
- bundlerClient.request({
83
+ // If the node rpc url is different from the bundler url, the public
84
+ // client should be passed in when creating the bundler client, which
85
+ // we can access here for public actions.
86
+ getBlock(rundlerClient.client ?? rundlerClient, { blockTag: "latest" }),
87
+ rundlerClient.request({
69
88
  method: "rundler_maxPriorityFeePerGas",
70
89
  params: [],
71
90
  }),
@@ -73,18 +92,26 @@ export async function estimateFeesPerGas<
73
92
 
74
93
  const baseFeePerGas = block.baseFeePerGas;
75
94
  if (baseFeePerGas == null) {
76
- throw new Error("baseFeePerGas is null");
95
+ throw new BaseError("baseFeePerGas is null");
77
96
  }
78
97
  if (maxPriorityFeePerGasHex == null) {
79
- throw new Error("rundler_maxPriorityFeePerGas returned null or undefined");
98
+ throw new BaseError(
99
+ "rundler_maxPriorityFeePerGas returned null or undefined",
100
+ );
80
101
  }
81
102
  if (!isHex(maxPriorityFeePerGasHex)) {
82
103
  throw new InvalidHexValueError(maxPriorityFeePerGasHex);
83
104
  }
84
105
  const maxPriorityFeePerGas = hexToBigInt(maxPriorityFeePerGasHex);
85
106
 
86
- return {
107
+ const bufferedMaxPriorityFeePerGas = bigIntMultiply(
87
108
  maxPriorityFeePerGas,
88
- maxFeePerGas: bigIntMultiply(baseFeePerGas, 1.5) + maxPriorityFeePerGas,
109
+ 1.5,
110
+ );
111
+
112
+ return {
113
+ maxPriorityFeePerGas: bufferedMaxPriorityFeePerGas,
114
+ maxFeePerGas:
115
+ bigIntMultiply(baseFeePerGas, 1.5) + bufferedMaxPriorityFeePerGas,
89
116
  };
90
117
  }
package/src/logger.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { createLogger } from "@alchemy/common";
2
- import type { DiagnosticsLogger } from "@alchemy/common";
1
+ import { createLogger } from "@alchemy/common/internal";
2
+ import type { DiagnosticsLogger } from "@alchemy/common/internal";
3
3
  import { VERSION } from "./version.js";
4
4
 
5
5
  export const LOGGER: DiagnosticsLogger = createLogger({
package/src/version.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  // This file is autogenerated by inject-version.ts. Any changes will be
2
2
  // overwritten on commit!
3
- export const VERSION = "0.0.0-alpha.8";
3
+ export const VERSION = "5.0.0-beta.2";