thirdweb 5.81.0 → 5.82.0

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 (189) hide show
  1. package/dist/cjs/adapters/ethers5.js +1 -1
  2. package/dist/cjs/adapters/ethers5.js.map +1 -1
  3. package/dist/cjs/auth/verify-hash.js +13 -8
  4. package/dist/cjs/auth/verify-hash.js.map +1 -1
  5. package/dist/cjs/contract/types.js +3 -0
  6. package/dist/cjs/contract/types.js.map +1 -0
  7. package/dist/cjs/exports/thirdweb.js +5 -1
  8. package/dist/cjs/exports/thirdweb.js.map +1 -1
  9. package/dist/cjs/exports/transaction.js +3 -1
  10. package/dist/cjs/exports/transaction.js.map +1 -1
  11. package/dist/cjs/exports/wallets.js +3 -1
  12. package/dist/cjs/exports/wallets.js.map +1 -1
  13. package/dist/cjs/extensions/erc721/lazyMinting/read/getBatchesToReveal.js +1 -1
  14. package/dist/cjs/extensions/erc721/lazyMinting/read/getBatchesToReveal.js.map +1 -1
  15. package/dist/cjs/extensions/types.js +3 -0
  16. package/dist/cjs/extensions/types.js.map +1 -0
  17. package/dist/cjs/gas/estimate-l1-fee.js +3 -4
  18. package/dist/cjs/gas/estimate-l1-fee.js.map +1 -1
  19. package/dist/cjs/react/core/hooks/contract/useReadContract.js +31 -29
  20. package/dist/cjs/react/core/hooks/contract/useReadContract.js.map +1 -1
  21. package/dist/cjs/react/core/hooks/types.js +3 -0
  22. package/dist/cjs/react/core/hooks/types.js.map +1 -0
  23. package/dist/cjs/transaction/actions/eip7702/authorization.js +33 -0
  24. package/dist/cjs/transaction/actions/eip7702/authorization.js.map +1 -0
  25. package/dist/cjs/transaction/actions/estimate-gas.js +16 -4
  26. package/dist/cjs/transaction/actions/estimate-gas.js.map +1 -1
  27. package/dist/cjs/transaction/actions/send-transaction.js +32 -1
  28. package/dist/cjs/transaction/actions/send-transaction.js.map +1 -1
  29. package/dist/cjs/transaction/actions/to-serializable-transaction.js +13 -4
  30. package/dist/cjs/transaction/actions/to-serializable-transaction.js.map +1 -1
  31. package/dist/cjs/transaction/prepare-transaction.js.map +1 -1
  32. package/dist/cjs/transaction/serialize-transaction.js +11 -0
  33. package/dist/cjs/transaction/serialize-transaction.js.map +1 -1
  34. package/dist/cjs/utils/abi/decodeError.js +3 -3
  35. package/dist/cjs/utils/abi/decodeError.js.map +1 -1
  36. package/dist/cjs/utils/abi/decodeFunctionData.js +3 -3
  37. package/dist/cjs/utils/abi/decodeFunctionData.js.map +1 -1
  38. package/dist/cjs/utils/abi/decodeFunctionResult.js +3 -3
  39. package/dist/cjs/utils/abi/decodeFunctionResult.js.map +1 -1
  40. package/dist/cjs/utils/hashing/hashMessage.js +2 -2
  41. package/dist/cjs/utils/hashing/hashMessage.js.map +1 -1
  42. package/dist/cjs/version.js +1 -1
  43. package/dist/cjs/wallets/create-wallet.js +16 -0
  44. package/dist/cjs/wallets/create-wallet.js.map +1 -1
  45. package/dist/cjs/wallets/private-key.js +9 -0
  46. package/dist/cjs/wallets/private-key.js.map +1 -1
  47. package/dist/cjs/wallets/smart/index.js +20 -19
  48. package/dist/cjs/wallets/smart/index.js.map +1 -1
  49. package/dist/cjs/wallets/smart/lib/signing.js +139 -54
  50. package/dist/cjs/wallets/smart/lib/signing.js.map +1 -1
  51. package/dist/cjs/wallets/smart/presets/7579.js +11 -10
  52. package/dist/cjs/wallets/smart/presets/7579.js.map +1 -1
  53. package/dist/esm/adapters/ethers5.js +1 -1
  54. package/dist/esm/adapters/ethers5.js.map +1 -1
  55. package/dist/esm/auth/verify-hash.js +13 -9
  56. package/dist/esm/auth/verify-hash.js.map +1 -1
  57. package/dist/esm/contract/types.js +2 -0
  58. package/dist/esm/contract/types.js.map +1 -0
  59. package/dist/esm/exports/thirdweb.js +2 -0
  60. package/dist/esm/exports/thirdweb.js.map +1 -1
  61. package/dist/esm/exports/transaction.js +1 -0
  62. package/dist/esm/exports/transaction.js.map +1 -1
  63. package/dist/esm/exports/wallets.js +1 -0
  64. package/dist/esm/exports/wallets.js.map +1 -1
  65. package/dist/esm/extensions/erc721/lazyMinting/read/getBatchesToReveal.js +1 -1
  66. package/dist/esm/extensions/erc721/lazyMinting/read/getBatchesToReveal.js.map +1 -1
  67. package/dist/esm/extensions/types.js +2 -0
  68. package/dist/esm/extensions/types.js.map +1 -0
  69. package/dist/esm/gas/estimate-l1-fee.js +2 -3
  70. package/dist/esm/gas/estimate-l1-fee.js.map +1 -1
  71. package/dist/esm/react/core/hooks/contract/useReadContract.js +31 -29
  72. package/dist/esm/react/core/hooks/contract/useReadContract.js.map +1 -1
  73. package/dist/esm/react/core/hooks/types.js +2 -0
  74. package/dist/esm/react/core/hooks/types.js.map +1 -0
  75. package/dist/esm/transaction/actions/eip7702/authorization.js +30 -0
  76. package/dist/esm/transaction/actions/eip7702/authorization.js.map +1 -0
  77. package/dist/esm/transaction/actions/estimate-gas.js +16 -4
  78. package/dist/esm/transaction/actions/estimate-gas.js.map +1 -1
  79. package/dist/esm/transaction/actions/send-transaction.js +32 -1
  80. package/dist/esm/transaction/actions/send-transaction.js.map +1 -1
  81. package/dist/esm/transaction/actions/to-serializable-transaction.js +13 -4
  82. package/dist/esm/transaction/actions/to-serializable-transaction.js.map +1 -1
  83. package/dist/esm/transaction/prepare-transaction.js.map +1 -1
  84. package/dist/esm/transaction/serialize-transaction.js +11 -0
  85. package/dist/esm/transaction/serialize-transaction.js.map +1 -1
  86. package/dist/esm/utils/abi/decodeError.js +3 -3
  87. package/dist/esm/utils/abi/decodeError.js.map +1 -1
  88. package/dist/esm/utils/abi/decodeFunctionData.js +3 -3
  89. package/dist/esm/utils/abi/decodeFunctionData.js.map +1 -1
  90. package/dist/esm/utils/abi/decodeFunctionResult.js +3 -3
  91. package/dist/esm/utils/abi/decodeFunctionResult.js.map +1 -1
  92. package/dist/esm/utils/hashing/hashMessage.js +1 -1
  93. package/dist/esm/utils/hashing/hashMessage.js.map +1 -1
  94. package/dist/esm/version.js +1 -1
  95. package/dist/esm/wallets/create-wallet.js +16 -0
  96. package/dist/esm/wallets/create-wallet.js.map +1 -1
  97. package/dist/esm/wallets/private-key.js +9 -0
  98. package/dist/esm/wallets/private-key.js.map +1 -1
  99. package/dist/esm/wallets/smart/index.js +20 -19
  100. package/dist/esm/wallets/smart/index.js.map +1 -1
  101. package/dist/esm/wallets/smart/lib/signing.js +137 -53
  102. package/dist/esm/wallets/smart/lib/signing.js.map +1 -1
  103. package/dist/esm/wallets/smart/presets/7579.js +11 -10
  104. package/dist/esm/wallets/smart/presets/7579.js.map +1 -1
  105. package/dist/types/auth/verify-hash.d.ts +6 -0
  106. package/dist/types/auth/verify-hash.d.ts.map +1 -1
  107. package/dist/types/contract/types.d.ts +7 -0
  108. package/dist/types/contract/types.d.ts.map +1 -0
  109. package/dist/types/exports/thirdweb.d.ts +6 -0
  110. package/dist/types/exports/thirdweb.d.ts.map +1 -1
  111. package/dist/types/exports/transaction.d.ts +5 -0
  112. package/dist/types/exports/transaction.d.ts.map +1 -1
  113. package/dist/types/exports/wallets.d.ts +1 -0
  114. package/dist/types/exports/wallets.d.ts.map +1 -1
  115. package/dist/types/extensions/erc721/lazyMinting/read/getBatchesToReveal.d.ts +1 -1
  116. package/dist/types/extensions/erc721/lazyMinting/read/getBatchesToReveal.d.ts.map +1 -1
  117. package/dist/types/extensions/types.d.ts +4 -0
  118. package/dist/types/extensions/types.d.ts.map +1 -0
  119. package/dist/types/gas/estimate-l1-fee.d.ts.map +1 -1
  120. package/dist/types/react/core/hooks/contract/useReadContract.d.ts +9 -16
  121. package/dist/types/react/core/hooks/contract/useReadContract.d.ts.map +1 -1
  122. package/dist/types/react/core/hooks/types.d.ts +13 -0
  123. package/dist/types/react/core/hooks/types.d.ts.map +1 -0
  124. package/dist/types/transaction/actions/eip7702/authorization.d.ts +48 -0
  125. package/dist/types/transaction/actions/eip7702/authorization.d.ts.map +1 -0
  126. package/dist/types/transaction/actions/estimate-gas.d.ts +3 -1
  127. package/dist/types/transaction/actions/estimate-gas.d.ts.map +1 -1
  128. package/dist/types/transaction/actions/send-transaction.d.ts +31 -0
  129. package/dist/types/transaction/actions/send-transaction.d.ts.map +1 -1
  130. package/dist/types/transaction/actions/to-serializable-transaction.d.ts +19 -2
  131. package/dist/types/transaction/actions/to-serializable-transaction.d.ts.map +1 -1
  132. package/dist/types/transaction/prepare-transaction.d.ts +2 -0
  133. package/dist/types/transaction/prepare-transaction.d.ts.map +1 -1
  134. package/dist/types/transaction/serialize-transaction.d.ts +2 -0
  135. package/dist/types/transaction/serialize-transaction.d.ts.map +1 -1
  136. package/dist/types/utils/abi/decodeError.d.ts +2 -2
  137. package/dist/types/utils/abi/decodeError.d.ts.map +1 -1
  138. package/dist/types/utils/abi/decodeFunctionData.d.ts +6 -4
  139. package/dist/types/utils/abi/decodeFunctionData.d.ts.map +1 -1
  140. package/dist/types/utils/abi/decodeFunctionResult.d.ts +6 -4
  141. package/dist/types/utils/abi/decodeFunctionResult.d.ts.map +1 -1
  142. package/dist/types/utils/hashing/hashMessage.d.ts +1 -1
  143. package/dist/types/utils/hashing/hashMessage.d.ts.map +1 -1
  144. package/dist/types/version.d.ts +1 -1
  145. package/dist/types/wallets/create-wallet.d.ts +16 -0
  146. package/dist/types/wallets/create-wallet.d.ts.map +1 -1
  147. package/dist/types/wallets/interfaces/wallet.d.ts +9 -0
  148. package/dist/types/wallets/interfaces/wallet.d.ts.map +1 -1
  149. package/dist/types/wallets/private-key.d.ts.map +1 -1
  150. package/dist/types/wallets/smart/lib/signing.d.ts +46 -2
  151. package/dist/types/wallets/smart/lib/signing.d.ts.map +1 -1
  152. package/dist/types/wallets/smart/presets/7579.d.ts.map +1 -1
  153. package/package.json +1 -1
  154. package/src/adapters/ethers5.ts +1 -1
  155. package/src/auth/verify-hash.ts +12 -9
  156. package/src/contract/types.ts +8 -0
  157. package/src/exports/thirdweb.ts +10 -0
  158. package/src/exports/transaction.ts +9 -0
  159. package/src/exports/wallets.ts +2 -0
  160. package/src/extensions/erc721/lazyMinting/read/getBatchesToReveal.ts +2 -2
  161. package/src/extensions/types.ts +6 -0
  162. package/src/gas/estimate-l1-fee.ts +2 -3
  163. package/src/react/core/hooks/contract/useReadContract.ts +83 -74
  164. package/src/react/core/hooks/types.ts +13 -0
  165. package/src/transaction/actions/eip7702/authorization.test.ts +27 -0
  166. package/src/transaction/actions/eip7702/authorization.ts +58 -0
  167. package/src/transaction/actions/estimate-gas.ts +26 -9
  168. package/src/transaction/actions/send-transaction.ts +32 -2
  169. package/src/transaction/actions/to-serializable-transaction.test.ts +68 -0
  170. package/src/transaction/actions/to-serializable-transaction.ts +42 -30
  171. package/src/transaction/prepare-transaction.test.ts +28 -0
  172. package/src/transaction/prepare-transaction.ts +3 -0
  173. package/src/transaction/serialize-transaction.test.ts +108 -1
  174. package/src/transaction/serialize-transaction.ts +18 -0
  175. package/src/utils/abi/decodeError.ts +5 -4
  176. package/src/utils/abi/decodeFunctionData.ts +7 -5
  177. package/src/utils/abi/decodeFunctionResult.ts +7 -5
  178. package/src/utils/hashing/hashMessage.ts +1 -1
  179. package/src/utils/signatures/sign-message.test.ts +2 -2
  180. package/src/version.ts +1 -1
  181. package/src/wallets/create-wallet.ts +16 -0
  182. package/src/wallets/interfaces/wallet.ts +15 -0
  183. package/src/wallets/private-key.test.ts +1 -0
  184. package/src/wallets/private-key.ts +10 -0
  185. package/src/wallets/smart/index.ts +20 -19
  186. package/src/wallets/smart/lib/signing.ts +154 -59
  187. package/src/wallets/smart/presets/7579.ts +13 -12
  188. package/src/wallets/smart/smart-wallet-integration-v07.test.ts +49 -9
  189. package/src/wallets/smart/smart-wallet-integration.test.ts +48 -1
@@ -3,6 +3,7 @@ import { getRpcClient } from "../../rpc/rpc.js";
3
3
  import { getAddress } from "../../utils/address.js";
4
4
  import { isZkSyncChain } from "../../utils/any-evm/zksync/isZkSyncChain.js";
5
5
  import { resolvePromisedValue } from "../../utils/promise/resolve-promised-value.js";
6
+ import type { Account } from "../../wallets/interfaces/wallet.js";
6
7
  import type { PreparedTransaction } from "../prepare-transaction.js";
7
8
  import type { SerializableTransaction } from "../serialize-transaction.js";
8
9
  import { encode } from "./encode.js";
@@ -15,9 +16,9 @@ export type ToSerializableTransactionOptions = {
15
16
  // biome-ignore lint/suspicious/noExplicitAny: TODO: fix later
16
17
  transaction: PreparedTransaction<any>;
17
18
  /**
18
- * The from address to use for gas estimation.
19
+ * The from address or account to use for gas estimation and authorization signing.
19
20
  */
20
- from?: string;
21
+ from?: string | Account;
21
22
  };
22
23
 
23
24
  /**
@@ -55,7 +56,12 @@ export async function toSerializableTransaction(
55
56
  );
56
57
  const { gas, maxFeePerGas, maxPriorityFeePerGas } = await getZkGasFees({
57
58
  transaction: options.transaction,
58
- from: options.from ? getAddress(options.from) : undefined,
59
+ from:
60
+ typeof options.from === "string" // Is this just an address?
61
+ ? getAddress(options.from)
62
+ : options.from !== undefined // Is this an account?
63
+ ? getAddress(options.from.address)
64
+ : undefined,
59
65
  });
60
66
  // passing these values here will avoid re-fetching them below
61
67
  options.transaction = {
@@ -69,34 +75,39 @@ export async function toSerializableTransaction(
69
75
  const rpcRequest = getRpcClient(options.transaction);
70
76
  const chainId = options.transaction.chain.id;
71
77
  const from = options.from;
72
- let [data, nonce, gas, feeData, to, accessList, value] = await Promise.all([
73
- encode(options.transaction),
74
- (async () => {
75
- // if the user has specified a nonce, use that
76
- const resolvedNonce = await resolvePromisedValue(
77
- options.transaction.nonce,
78
- );
79
- if (resolvedNonce !== undefined) {
80
- return resolvedNonce;
81
- }
78
+ let [data, nonce, gas, feeData, to, accessList, value, authorizationList] =
79
+ await Promise.all([
80
+ encode(options.transaction),
81
+ (async () => {
82
+ // if the user has specified a nonce, use that
83
+ const resolvedNonce = await resolvePromisedValue(
84
+ options.transaction.nonce,
85
+ );
86
+ if (resolvedNonce !== undefined) {
87
+ return resolvedNonce;
88
+ }
82
89
 
83
- return from // otherwise get the next nonce (import the method to do so)
84
- ? await import("../../rpc/actions/eth_getTransactionCount.js").then(
85
- ({ eth_getTransactionCount }) =>
86
- eth_getTransactionCount(rpcRequest, {
87
- address: from,
88
- blockTag: "pending",
89
- }),
90
- )
91
- : undefined;
92
- })(),
93
- // takes the same options as the sendTransaction function thankfully!
94
- estimateGas(options),
95
- getGasOverridesForTransaction(options.transaction),
96
- resolvePromisedValue(options.transaction.to),
97
- resolvePromisedValue(options.transaction.accessList),
98
- resolvePromisedValue(options.transaction.value),
99
- ]);
90
+ return from // otherwise get the next nonce (import the method to do so)
91
+ ? await import("../../rpc/actions/eth_getTransactionCount.js").then(
92
+ ({ eth_getTransactionCount }) =>
93
+ eth_getTransactionCount(rpcRequest, {
94
+ address: typeof from === "string" ? from : from?.address,
95
+ blockTag: "pending",
96
+ }),
97
+ )
98
+ : undefined;
99
+ })(),
100
+ // takes the same options as the sendTransaction function thankfully!
101
+ estimateGas({
102
+ ...options,
103
+ from: options.from,
104
+ }),
105
+ getGasOverridesForTransaction(options.transaction),
106
+ resolvePromisedValue(options.transaction.to),
107
+ resolvePromisedValue(options.transaction.accessList),
108
+ resolvePromisedValue(options.transaction.value),
109
+ resolvePromisedValue(options.transaction.authorizationList),
110
+ ]);
100
111
 
101
112
  const extraGas = await resolvePromisedValue(options.transaction.extraGas);
102
113
  if (extraGas) {
@@ -111,6 +122,7 @@ export async function toSerializableTransaction(
111
122
  nonce,
112
123
  accessList,
113
124
  value,
125
+ authorizationList,
114
126
  ...feeData,
115
127
  } satisfies SerializableTransaction;
116
128
  }
@@ -1,9 +1,13 @@
1
1
  import { describe, expect, test as it } from "vitest";
2
+ import { TEST_ACCOUNT_B } from "~test/test-wallets.js";
2
3
  import { TEST_WALLET_A, TEST_WALLET_B } from "../../test/src/addresses.js";
3
4
  import { FORKED_ETHEREUM_CHAIN } from "../../test/src/chains.js";
4
5
  import { TEST_CLIENT } from "../../test/src/test-clients.js";
6
+ import { defineChain } from "../chains/utils.js";
5
7
  import { toWei } from "../utils/units.js";
8
+ import { signAuthorization } from "./actions/eip7702/authorization.js";
6
9
  import { estimateGas } from "./actions/estimate-gas.js";
10
+ import { toSerializableTransaction } from "./actions/to-serializable-transaction.js";
7
11
  import { prepareTransaction } from "./prepare-transaction.js";
8
12
 
9
13
  describe.runIf(process.env.TW_SECRET_KEY)("prepareTransaction", () => {
@@ -18,6 +22,30 @@ describe.runIf(process.env.TW_SECRET_KEY)("prepareTransaction", () => {
18
22
  expect(preparedTx.value).toMatchInlineSnapshot("100000000000000000n");
19
23
  });
20
24
 
25
+ it("should accept an authorization list", async () => {
26
+ const authorization = await signAuthorization({
27
+ account: TEST_ACCOUNT_B,
28
+ request: {
29
+ address: TEST_WALLET_B,
30
+ chainId: 911867,
31
+ nonce: 0n,
32
+ },
33
+ });
34
+ const preparedTx = prepareTransaction({
35
+ chain: defineChain(911867),
36
+ client: TEST_CLIENT,
37
+ to: TEST_WALLET_B,
38
+ value: 0n,
39
+ authorizationList: [authorization],
40
+ });
41
+
42
+ const serializableTx = await toSerializableTransaction({
43
+ transaction: preparedTx,
44
+ });
45
+
46
+ expect(serializableTx.authorizationList).toEqual([authorization]);
47
+ });
48
+
21
49
  // skip this test if there is no secret key available to test with
22
50
  // TODO: remove reliance on secret key during unit tests entirely
23
51
  it.runIf(process.env.TW_SECRET_KEY)(
@@ -5,6 +5,7 @@ import type { ThirdwebClient } from "../client/client.js";
5
5
  import type { ThirdwebContract } from "../contract/contract.js";
6
6
  import type { PreparedMethod } from "../utils/abi/prepare-method.js";
7
7
  import type { PromisedObject } from "../utils/promise/resolve-promised-value.js";
8
+ import type { SignedAuthorization } from "./actions/eip7702/authorization.js";
8
9
 
9
10
  export type StaticPrepareTransactionOptions = {
10
11
  accessList?: AccessList | undefined;
@@ -18,6 +19,8 @@ export type StaticPrepareTransactionOptions = {
18
19
  maxFeePerBlobGas?: bigint | undefined;
19
20
  nonce?: number | undefined;
20
21
  extraGas?: bigint | undefined;
22
+ // eip7702
23
+ authorizationList?: SignedAuthorization[] | undefined;
21
24
  // zksync specific
22
25
  eip712?: EIP712TransactionOptions | undefined;
23
26
  // tw specific
@@ -1,13 +1,15 @@
1
1
  import * as ox__Hex from "ox/Hex";
2
2
  import * as ox__TransactionEnvelopeEip1559 from "ox/TransactionEnvelopeEip1559";
3
3
  import * as ox__TransactionEnvelopeEip2930 from "ox/TransactionEnvelopeEip2930";
4
+ import * as ox__TransactionEnvelopeEip7702 from "ox/TransactionEnvelopeEip7702";
4
5
  import * as ox__TransactionEnvelopeLegacy from "ox/TransactionEnvelopeLegacy";
5
- import { describe, expect, test } from "vitest";
6
+ import { assertType, describe, expect, test } from "vitest";
6
7
 
7
8
  import { type Address, checksumAddress } from "../utils/address.js";
8
9
  import { fromGwei, toWei } from "../utils/units.js";
9
10
  import { serializeTransaction } from "./serialize-transaction.js";
10
11
 
12
+ import { wagmiTokenContractConfig } from "../../test/src/abis/wagmiToken.js";
11
13
  import { ANVIL_PKEY_A, TEST_ACCOUNT_B } from "../../test/src/test-wallets.js";
12
14
  import { keccak256 } from "../utils/hashing/keccak256.js";
13
15
  import { sign } from "../utils/signatures/sign.js";
@@ -530,6 +532,111 @@ describe("eip2930", () => {
530
532
  });
531
533
  });
532
534
 
535
+ describe("eip7702", () => {
536
+ const baseEip7702 = {
537
+ ...BASE_TRANSACTION,
538
+ authorizationList: [
539
+ {
540
+ address: wagmiTokenContractConfig.address.toLowerCase() as Address,
541
+ chainId: 1,
542
+ nonce: 420n,
543
+ r: ox__Hex.toBigInt(
544
+ "0x60fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fe",
545
+ ),
546
+ s: ox__Hex.toBigInt(
547
+ "0x60fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fe",
548
+ ),
549
+ yParity: 0,
550
+ },
551
+ {
552
+ address: "0x0000000000000000000000000000000000000000",
553
+ chainId: 10,
554
+ nonce: 69n,
555
+ r: ox__Hex.toBigInt(
556
+ "0x60fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fe",
557
+ ),
558
+ s: ox__Hex.toBigInt(
559
+ "0x60fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fe",
560
+ ),
561
+ yParity: 1,
562
+ },
563
+ ],
564
+ chainId: 1,
565
+ } as const;
566
+
567
+ test("default", () => {
568
+ const serialized = serializeTransaction({ transaction: baseEip7702 });
569
+ assertType<ox__TransactionEnvelopeEip7702.Serialized>(
570
+ serialized as `0x04${string}`,
571
+ );
572
+ expect(serialized).toMatchInlineSnapshot(
573
+ `"0x04f8e3018203118080809470997970c51812dc3a010c7d01b50e0d17dc79c8880de0b6b3a764000080c0f8baf85c0194fba3912ca04dd458c843e2ee08967fc04f3579c28201a480a060fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fea060fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fef85a0a9400000000000000000000000000000000000000004501a060fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fea060fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fe"`,
574
+ );
575
+ const tx = ox__TransactionEnvelopeEip7702.deserialize(
576
+ serialized as ox__TransactionEnvelopeEip7702.Serialized,
577
+ );
578
+ expect({
579
+ ...tx,
580
+ to: tx.to ? checksumAddress(tx.to) : undefined,
581
+ }).toEqual({
582
+ ...baseEip7702,
583
+ nonce: BigInt(baseEip7702.nonce),
584
+ type: "eip7702",
585
+ });
586
+ });
587
+
588
+ test("signature", () => {
589
+ expect(
590
+ serializeTransaction({
591
+ transaction: {
592
+ ...baseEip7702,
593
+ r: "0x60fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fe",
594
+ s: "0x60fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fe",
595
+ yParity: 1,
596
+ },
597
+ }),
598
+ ).toMatchInlineSnapshot(
599
+ `"0x04f90126018203118080809470997970c51812dc3a010c7d01b50e0d17dc79c8880de0b6b3a764000080c0f8baf85c0194fba3912ca04dd458c843e2ee08967fc04f3579c28201a480a060fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fea060fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fef85a0a9400000000000000000000000000000000000000004501a060fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fea060fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fe01a060fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fea060fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fe"`,
600
+ );
601
+ expect(
602
+ serializeTransaction({
603
+ transaction: {
604
+ ...baseEip7702,
605
+ r: "0x60fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fe",
606
+ s: "0x60fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fe",
607
+ yParity: 0,
608
+ },
609
+ }),
610
+ ).toMatchInlineSnapshot(
611
+ `"0x04f90126018203118080809470997970c51812dc3a010c7d01b50e0d17dc79c8880de0b6b3a764000080c0f8baf85c0194fba3912ca04dd458c843e2ee08967fc04f3579c28201a480a060fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fea060fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fef85a0a9400000000000000000000000000000000000000004501a060fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fea060fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fe80a060fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fea060fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fe"`,
612
+ );
613
+ expect(
614
+ serializeTransaction({
615
+ transaction: {
616
+ ...baseEip7702,
617
+ r: "0x60fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fe",
618
+ s: "0x60fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fe",
619
+ v: 0n,
620
+ },
621
+ }),
622
+ ).toMatchInlineSnapshot(
623
+ `"0x04f90126018203118080809470997970c51812dc3a010c7d01b50e0d17dc79c8880de0b6b3a764000080c0f8baf85c0194fba3912ca04dd458c843e2ee08967fc04f3579c28201a480a060fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fea060fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fef85a0a9400000000000000000000000000000000000000004501a060fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fea060fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fe80a060fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fea060fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fe"`,
624
+ );
625
+ expect(
626
+ serializeTransaction({
627
+ transaction: {
628
+ ...baseEip7702,
629
+ r: "0x60fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fe",
630
+ s: "0x60fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fe",
631
+ v: 1n,
632
+ },
633
+ }),
634
+ ).toMatchInlineSnapshot(
635
+ `"0x04f90126018203118080809470997970c51812dc3a010c7d01b50e0d17dc79c8880de0b6b3a764000080c0f8baf85c0194fba3912ca04dd458c843e2ee08967fc04f3579c28201a480a060fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fea060fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fef85a0a9400000000000000000000000000000000000000004501a060fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fea060fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fe01a060fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fea060fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fe"`,
636
+ );
637
+ });
638
+ });
639
+
533
640
  describe("legacy", () => {
534
641
  const BASE_LEGACY_TRANSACTION = {
535
642
  ...BASE_TRANSACTION,
@@ -2,6 +2,7 @@ import * as ox__Hex from "ox/Hex";
2
2
  import * as ox__Signature from "ox/Signature";
3
3
  import * as ox__TransactionEnvelopeEip1559 from "ox/TransactionEnvelopeEip1559";
4
4
  import * as ox__TransactionEnvelopeEip2930 from "ox/TransactionEnvelopeEip2930";
5
+ import * as ox__TransactionEnvelopeEip7702 from "ox/TransactionEnvelopeEip7702";
5
6
  import * as ox__TransactionEnvelopeLegacy from "ox/TransactionEnvelopeLegacy";
6
7
  import type { Hex } from "../utils/encoding/hex.js";
7
8
 
@@ -24,6 +25,9 @@ export type SerializableTransaction = {
24
25
  value?: bigint | undefined;
25
26
  gas?: bigint | undefined;
26
27
  gasLimit?: bigint | undefined;
28
+ authorizationList?:
29
+ | ox__TransactionEnvelopeEip7702.TransactionEnvelopeEip7702["authorizationList"]
30
+ | undefined;
27
31
  };
28
32
 
29
33
  export type SerializeTransactionOptions = {
@@ -141,6 +145,16 @@ export function serializeTransaction(
141
145
  });
142
146
  }
143
147
 
148
+ if (type === "eip7702") {
149
+ const typedTransaction =
150
+ transaction as ox__TransactionEnvelopeEip7702.TransactionEnvelopeEip7702;
151
+ ox__TransactionEnvelopeEip7702.assert(typedTransaction);
152
+
153
+ return ox__TransactionEnvelopeEip7702.serialize(typedTransaction, {
154
+ signature,
155
+ });
156
+ }
157
+
144
158
  throw new Error("Invalid transaction type");
145
159
  }
146
160
 
@@ -154,6 +168,10 @@ function getTransactionEnvelopeType(
154
168
  return transactionEnvelope.type;
155
169
  }
156
170
 
171
+ if (typeof transactionEnvelope.authorizationList !== "undefined") {
172
+ return "eip7702";
173
+ }
174
+
157
175
  if (
158
176
  typeof transactionEnvelope.maxFeePerGas !== "undefined" ||
159
177
  typeof transactionEnvelope.maxPriorityFeePerGas !== "undefined"
@@ -1,4 +1,5 @@
1
- import { type Abi, AbiError } from "ox";
1
+ import type * as ox__Abi from "ox/Abi";
2
+ import * as ox__AbiError from "ox/AbiError";
2
3
  import { resolveContractAbi } from "../../contract/actions/resolve-abi.js";
3
4
  import type { ThirdwebContract } from "../../contract/contract.js";
4
5
  import type { Hex } from "../encoding/hex.js";
@@ -17,7 +18,7 @@ import type { Hex } from "../encoding/hex.js";
17
18
  *
18
19
  * @utils
19
20
  */
20
- export async function decodeError<abi extends Abi.Abi>(options: {
21
+ export async function decodeError<abi extends ox__Abi.Abi>(options: {
21
22
  contract: ThirdwebContract<abi>;
22
23
  data: Hex;
23
24
  }) {
@@ -31,6 +32,6 @@ export async function decodeError<abi extends Abi.Abi>(options: {
31
32
  `No ABI found for contract ${contract.address} on chain ${contract.chain.id}`,
32
33
  );
33
34
  }
34
- const abiError = AbiError.fromAbi(abi, data) as AbiError.AbiError;
35
- return AbiError.decode(abiError, data);
35
+ const abiError = ox__AbiError.fromAbi(abi, data) as ox__AbiError.AbiError;
36
+ return ox__AbiError.decode(abiError, data);
36
37
  }
@@ -1,4 +1,6 @@
1
- import { type Abi, AbiFunction, type Hex } from "ox";
1
+ import type * as ox__Abi from "ox/Abi";
2
+ import * as ox__AbiFunction from "ox/AbiFunction";
3
+ import type * as ox__Hex from "ox/Hex";
2
4
  import { resolveContractAbi } from "../../contract/actions/resolve-abi.js";
3
5
  import type { ThirdwebContract } from "../../contract/contract.js";
4
6
 
@@ -16,9 +18,9 @@ import type { ThirdwebContract } from "../../contract/contract.js";
16
18
  *
17
19
  * @utils
18
20
  */
19
- export async function decodeFunctionData<abi extends Abi.Abi>(options: {
21
+ export async function decodeFunctionData<abi extends ox__Abi.Abi>(options: {
20
22
  contract: ThirdwebContract<abi>;
21
- data: Hex.Hex;
23
+ data: ox__Hex.Hex;
22
24
  }) {
23
25
  const { contract, data } = options;
24
26
  let abi = contract?.abi;
@@ -30,6 +32,6 @@ export async function decodeFunctionData<abi extends Abi.Abi>(options: {
30
32
  `No ABI found for contract ${contract.address} on chain ${contract.chain.id}`,
31
33
  );
32
34
  }
33
- const abiFunction = AbiFunction.fromAbi(abi, data);
34
- return AbiFunction.decodeData(abiFunction, data);
35
+ const abiFunction = ox__AbiFunction.fromAbi(abi, data);
36
+ return ox__AbiFunction.decodeData(abiFunction, data);
35
37
  }
@@ -1,4 +1,6 @@
1
- import { type Abi, AbiFunction, type Hex } from "ox";
1
+ import type * as ox__Abi from "ox/Abi";
2
+ import * as ox__AbiFunction from "ox/AbiFunction";
3
+ import type * as ox__Hex from "ox/Hex";
2
4
  import { resolveContractAbi } from "../../contract/actions/resolve-abi.js";
3
5
  import type { ThirdwebContract } from "../../contract/contract.js";
4
6
 
@@ -16,9 +18,9 @@ import type { ThirdwebContract } from "../../contract/contract.js";
16
18
  *
17
19
  * @utils
18
20
  */
19
- export async function decodeFunctionResult<abi extends Abi.Abi>(options: {
21
+ export async function decodeFunctionResult<abi extends ox__Abi.Abi>(options: {
20
22
  contract: ThirdwebContract<abi>;
21
- data: Hex.Hex;
23
+ data: ox__Hex.Hex;
22
24
  }) {
23
25
  const { contract, ...rest } = options;
24
26
  let abi = contract?.abi;
@@ -30,6 +32,6 @@ export async function decodeFunctionResult<abi extends Abi.Abi>(options: {
30
32
  `No ABI found for contract ${contract.address} on chain ${contract.chain.id}`,
31
33
  );
32
34
  }
33
- const abiFunction = AbiFunction.fromAbi(abi, rest.data);
34
- return AbiFunction.decodeResult(abiFunction, rest.data);
35
+ const abiFunction = ox__AbiFunction.fromAbi(abi, rest.data);
36
+ return ox__AbiFunction.decodeResult(abiFunction, rest.data);
35
37
  }
@@ -1,4 +1,4 @@
1
- import { Bytes as ox__Bytes } from "ox";
1
+ import * as ox__Bytes from "ox/Bytes";
2
2
  import type { Hex } from "../encoding/hex.js";
3
3
  import { stringToBytes, toBytes } from "../encoding/to-bytes.js";
4
4
  import type { SignableMessage } from "../types.js";
@@ -40,7 +40,7 @@ describe("signMessage", async () => {
40
40
  privateKey: ANVIL_PKEY_A,
41
41
  }),
42
42
  ).toMatchInlineSnapshot(
43
- '"0xa461f509887bd19e312c0c58467ce8ff8e300d3c1a90b608a760c5b80318eaf15fe57c96f9175d6cd4daad4663763baa7e78836e067d0163e9a2ccf2ff753f5b1b"',
43
+ `"0xa461f509887bd19e312c0c58467ce8ff8e300d3c1a90b608a760c5b80318eaf15fe57c96f9175d6cd4daad4663763baa7e78836e067d0163e9a2ccf2ff753f5b1b"`,
44
44
  );
45
45
 
46
46
  expect(
@@ -53,7 +53,7 @@ describe("signMessage", async () => {
53
53
  privateKey: ANVIL_PKEY_A,
54
54
  }),
55
55
  ).toMatchInlineSnapshot(
56
- '"0xa461f509887bd19e312c0c58467ce8ff8e300d3c1a90b608a760c5b80318eaf15fe57c96f9175d6cd4daad4663763baa7e78836e067d0163e9a2ccf2ff753f5b1b"',
56
+ `"0xa461f509887bd19e312c0c58467ce8ff8e300d3c1a90b608a760c5b80318eaf15fe57c96f9175d6cd4daad4663763baa7e78836e067d0163e9a2ccf2ff753f5b1b"`,
57
57
  );
58
58
  });
59
59
 
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const version = "5.81.0";
1
+ export const version = "5.82.0";
@@ -116,6 +116,22 @@ import { createWalletEmitter } from "./wallet-emitter.js";
116
116
  *
117
117
  * [View Coinbase wallet creation options](https://portal.thirdweb.com/references/typescript/v5/CoinbaseWalletCreationOptions)
118
118
  *
119
+ * ## Connecting with a smart wallet
120
+ *
121
+ * ```ts
122
+ * import { createWallet } from "thirdweb/wallets";
123
+ *
124
+ * const wallet = createWallet("smart", {
125
+ * chain: sepolia,
126
+ * sponsorGas: true,
127
+ * });
128
+ *
129
+ * const account = await wallet.connect({
130
+ * client,
131
+ * personalAccount, // pass the admin account
132
+ * });
133
+ * ```
134
+ *
119
135
  * @wallet
120
136
  */
121
137
  export function createWallet<const ID extends WalletId>(
@@ -2,6 +2,10 @@ import type { Address } from "abitype";
2
2
  import type * as ox__TypedData from "ox/TypedData";
3
3
  import type { Hex, SignableMessage } from "viem";
4
4
  import type { Chain } from "../../chains/types.js";
5
+ import type {
6
+ AuthorizationRequest,
7
+ SignedAuthorization,
8
+ } from "../../transaction/actions/eip7702/authorization.js";
5
9
  import type {
6
10
  EIP712TransactionOptions,
7
11
  PreparedTransaction,
@@ -195,6 +199,17 @@ export type Account = {
195
199
 
196
200
  // OPTIONAL
197
201
 
202
+ /**
203
+ * Sign the given EIP-7702 authorization object.
204
+ * @example
205
+ * ```ts
206
+ * const signedAuthorization = await account.signAuthorization({ address: "0x...", chainId: 1, nonce: 1n });
207
+ * ```
208
+ */
209
+ signAuthorization?: (
210
+ authorization: AuthorizationRequest,
211
+ ) => Promise<SignedAuthorization>;
212
+
198
213
  /**
199
214
  * Estimate the gas required to execute the given transaction.
200
215
  *
@@ -17,6 +17,7 @@ test("default", () => {
17
17
  {
18
18
  "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
19
19
  "sendTransaction": [Function],
20
+ "signAuthorization": [Function],
20
21
  "signMessage": [Function],
21
22
  "signTransaction": [Function],
22
23
  "signTypedData": [Function],
@@ -1,10 +1,13 @@
1
1
  import { secp256k1 } from "@noble/curves/secp256k1";
2
+ import * as ox__Authorization from "ox/Authorization";
3
+ import * as ox__Secp256k1 from "ox/Secp256k1";
2
4
  import type * as ox__TypedData from "ox/TypedData";
3
5
  import { publicKeyToAddress } from "viem/utils";
4
6
  import { getCachedChain } from "../chains/utils.js";
5
7
  import type { ThirdwebClient } from "../client/client.js";
6
8
  import { eth_sendRawTransaction } from "../rpc/actions/eth_sendRawTransaction.js";
7
9
  import { getRpcClient } from "../rpc/rpc.js";
10
+ import type { AuthorizationRequest } from "../transaction/actions/eip7702/authorization.js";
8
11
  import { signTransaction } from "../transaction/actions/sign-transaction.js";
9
12
  import type { SerializableTransaction } from "../transaction/serialize-transaction.js";
10
13
  import { type Hex, toHex } from "../utils/encoding/hex.js";
@@ -119,6 +122,13 @@ export function privateKeyToAccount(
119
122
  privateKey,
120
123
  });
121
124
  },
125
+ signAuthorization: async (authorization: AuthorizationRequest) => {
126
+ const signature = ox__Secp256k1.sign({
127
+ payload: ox__Authorization.getSignPayload(authorization),
128
+ privateKey: privateKey,
129
+ });
130
+ return ox__Authorization.from(authorization, { signature });
131
+ },
122
132
  };
123
133
 
124
134
  return account satisfies Account;
@@ -210,7 +210,7 @@ async function createSmartAccount(
210
210
  }
211
211
  }
212
212
 
213
- const { accountContract } = options;
213
+ let accountContract = options.accountContract;
214
214
  const account: Account = {
215
215
  address: getAddress(accountContract.address),
216
216
  async sendTransaction(transaction: SendTransactionOption) {
@@ -237,21 +237,17 @@ async function createSmartAccount(
237
237
  paymasterOverride = options.overrides?.paymaster;
238
238
  }
239
239
 
240
- const accountContractForTransaction = (() => {
241
- // If this transaction is for a different chain than the initial one, get the account contract for that chain
242
- if (transaction.chainId !== accountContract.chain.id) {
243
- return getContract({
244
- address: account.address,
245
- chain: getCachedChain(transaction.chainId),
246
- client: options.client,
247
- });
248
- }
249
- // Default to the existing account contract
250
- return accountContract;
251
- })();
240
+ // If this transaction is for a different chain than the initial one, get the account contract for that chain
241
+ if (transaction.chainId !== accountContract.chain.id) {
242
+ accountContract = getContract({
243
+ address: account.address,
244
+ chain: getCachedChain(transaction.chainId),
245
+ client: options.client,
246
+ });
247
+ }
252
248
 
253
249
  const executeTx = prepareExecute({
254
- accountContract: accountContractForTransaction,
250
+ accountContract: accountContract,
255
251
  transaction,
256
252
  executeOverride: options.overrides?.execute,
257
253
  });
@@ -260,6 +256,7 @@ async function createSmartAccount(
260
256
  options: {
261
257
  ...options,
262
258
  chain: getCachedChain(transaction.chainId),
259
+ accountContract,
263
260
  overrides: {
264
261
  ...options.overrides,
265
262
  paymaster: paymasterOverride,
@@ -275,7 +272,11 @@ async function createSmartAccount(
275
272
  });
276
273
  return _sendUserOp({
277
274
  executeTx,
278
- options,
275
+ options: {
276
+ ...options,
277
+ chain: getCachedChain(transactions[0]?.chainId ?? options.chain.id),
278
+ accountContract,
279
+ },
279
280
  });
280
281
  },
281
282
  async signMessage({ message }: { message: SignableMessage }) {
@@ -288,8 +289,8 @@ async function createSmartAccount(
288
289
  });
289
290
  }
290
291
 
291
- const { deployAndSignMessage } = await import("./lib/signing.js");
292
- return deployAndSignMessage({
292
+ const { smartAccountSignMessage } = await import("./lib/signing.js");
293
+ return smartAccountSignMessage({
293
294
  accountContract,
294
295
  factoryContract: options.factoryContract,
295
296
  options,
@@ -309,8 +310,8 @@ async function createSmartAccount(
309
310
  });
310
311
  }
311
312
 
312
- const { deployAndSignTypedData } = await import("./lib/signing.js");
313
- return deployAndSignTypedData({
313
+ const { smartAccountSignTypedData } = await import("./lib/signing.js");
314
+ return smartAccountSignTypedData({
314
315
  accountContract,
315
316
  factoryContract: options.factoryContract,
316
317
  options,