thirdweb 5.80.1-nightly-430475913d30ef7a30cb3092f6ef09c0c998a9b6-20250106000343 → 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 (214) 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/version.js.map +1 -1
  44. package/dist/cjs/wallets/create-wallet.js +16 -0
  45. package/dist/cjs/wallets/create-wallet.js.map +1 -1
  46. package/dist/cjs/wallets/in-app/core/wallet/in-app-core.js +9 -3
  47. package/dist/cjs/wallets/in-app/core/wallet/in-app-core.js.map +1 -1
  48. package/dist/cjs/wallets/in-app/core/wallet/index.js +8 -10
  49. package/dist/cjs/wallets/in-app/core/wallet/index.js.map +1 -1
  50. package/dist/cjs/wallets/private-key.js +9 -0
  51. package/dist/cjs/wallets/private-key.js.map +1 -1
  52. package/dist/cjs/wallets/smart/index.js +34 -32
  53. package/dist/cjs/wallets/smart/index.js.map +1 -1
  54. package/dist/cjs/wallets/smart/lib/signing.js +139 -54
  55. package/dist/cjs/wallets/smart/lib/signing.js.map +1 -1
  56. package/dist/cjs/wallets/smart/presets/7579.js +11 -10
  57. package/dist/cjs/wallets/smart/presets/7579.js.map +1 -1
  58. package/dist/cjs/wallets/smart/smart-wallet.js +12 -10
  59. package/dist/cjs/wallets/smart/smart-wallet.js.map +1 -1
  60. package/dist/esm/adapters/ethers5.js +1 -1
  61. package/dist/esm/adapters/ethers5.js.map +1 -1
  62. package/dist/esm/auth/verify-hash.js +13 -9
  63. package/dist/esm/auth/verify-hash.js.map +1 -1
  64. package/dist/esm/contract/types.js +2 -0
  65. package/dist/esm/contract/types.js.map +1 -0
  66. package/dist/esm/exports/thirdweb.js +2 -0
  67. package/dist/esm/exports/thirdweb.js.map +1 -1
  68. package/dist/esm/exports/transaction.js +1 -0
  69. package/dist/esm/exports/transaction.js.map +1 -1
  70. package/dist/esm/exports/wallets.js +1 -0
  71. package/dist/esm/exports/wallets.js.map +1 -1
  72. package/dist/esm/extensions/erc721/lazyMinting/read/getBatchesToReveal.js +1 -1
  73. package/dist/esm/extensions/erc721/lazyMinting/read/getBatchesToReveal.js.map +1 -1
  74. package/dist/esm/extensions/types.js +2 -0
  75. package/dist/esm/extensions/types.js.map +1 -0
  76. package/dist/esm/gas/estimate-l1-fee.js +2 -3
  77. package/dist/esm/gas/estimate-l1-fee.js.map +1 -1
  78. package/dist/esm/react/core/hooks/contract/useReadContract.js +31 -29
  79. package/dist/esm/react/core/hooks/contract/useReadContract.js.map +1 -1
  80. package/dist/esm/react/core/hooks/types.js +2 -0
  81. package/dist/esm/react/core/hooks/types.js.map +1 -0
  82. package/dist/esm/transaction/actions/eip7702/authorization.js +30 -0
  83. package/dist/esm/transaction/actions/eip7702/authorization.js.map +1 -0
  84. package/dist/esm/transaction/actions/estimate-gas.js +16 -4
  85. package/dist/esm/transaction/actions/estimate-gas.js.map +1 -1
  86. package/dist/esm/transaction/actions/send-transaction.js +32 -1
  87. package/dist/esm/transaction/actions/send-transaction.js.map +1 -1
  88. package/dist/esm/transaction/actions/to-serializable-transaction.js +13 -4
  89. package/dist/esm/transaction/actions/to-serializable-transaction.js.map +1 -1
  90. package/dist/esm/transaction/prepare-transaction.js.map +1 -1
  91. package/dist/esm/transaction/serialize-transaction.js +11 -0
  92. package/dist/esm/transaction/serialize-transaction.js.map +1 -1
  93. package/dist/esm/utils/abi/decodeError.js +3 -3
  94. package/dist/esm/utils/abi/decodeError.js.map +1 -1
  95. package/dist/esm/utils/abi/decodeFunctionData.js +3 -3
  96. package/dist/esm/utils/abi/decodeFunctionData.js.map +1 -1
  97. package/dist/esm/utils/abi/decodeFunctionResult.js +3 -3
  98. package/dist/esm/utils/abi/decodeFunctionResult.js.map +1 -1
  99. package/dist/esm/utils/hashing/hashMessage.js +1 -1
  100. package/dist/esm/utils/hashing/hashMessage.js.map +1 -1
  101. package/dist/esm/version.js +1 -1
  102. package/dist/esm/version.js.map +1 -1
  103. package/dist/esm/wallets/create-wallet.js +16 -0
  104. package/dist/esm/wallets/create-wallet.js.map +1 -1
  105. package/dist/esm/wallets/in-app/core/wallet/in-app-core.js +9 -3
  106. package/dist/esm/wallets/in-app/core/wallet/in-app-core.js.map +1 -1
  107. package/dist/esm/wallets/in-app/core/wallet/index.js +8 -10
  108. package/dist/esm/wallets/in-app/core/wallet/index.js.map +1 -1
  109. package/dist/esm/wallets/private-key.js +9 -0
  110. package/dist/esm/wallets/private-key.js.map +1 -1
  111. package/dist/esm/wallets/smart/index.js +32 -30
  112. package/dist/esm/wallets/smart/index.js.map +1 -1
  113. package/dist/esm/wallets/smart/lib/signing.js +137 -53
  114. package/dist/esm/wallets/smart/lib/signing.js.map +1 -1
  115. package/dist/esm/wallets/smart/presets/7579.js +11 -10
  116. package/dist/esm/wallets/smart/presets/7579.js.map +1 -1
  117. package/dist/esm/wallets/smart/smart-wallet.js +12 -10
  118. package/dist/esm/wallets/smart/smart-wallet.js.map +1 -1
  119. package/dist/types/auth/verify-hash.d.ts +6 -0
  120. package/dist/types/auth/verify-hash.d.ts.map +1 -1
  121. package/dist/types/contract/types.d.ts +7 -0
  122. package/dist/types/contract/types.d.ts.map +1 -0
  123. package/dist/types/exports/thirdweb.d.ts +6 -0
  124. package/dist/types/exports/thirdweb.d.ts.map +1 -1
  125. package/dist/types/exports/transaction.d.ts +5 -0
  126. package/dist/types/exports/transaction.d.ts.map +1 -1
  127. package/dist/types/exports/wallets.d.ts +1 -0
  128. package/dist/types/exports/wallets.d.ts.map +1 -1
  129. package/dist/types/extensions/erc721/lazyMinting/read/getBatchesToReveal.d.ts +1 -1
  130. package/dist/types/extensions/erc721/lazyMinting/read/getBatchesToReveal.d.ts.map +1 -1
  131. package/dist/types/extensions/types.d.ts +4 -0
  132. package/dist/types/extensions/types.d.ts.map +1 -0
  133. package/dist/types/gas/estimate-l1-fee.d.ts.map +1 -1
  134. package/dist/types/react/core/hooks/contract/useReadContract.d.ts +9 -16
  135. package/dist/types/react/core/hooks/contract/useReadContract.d.ts.map +1 -1
  136. package/dist/types/react/core/hooks/types.d.ts +13 -0
  137. package/dist/types/react/core/hooks/types.d.ts.map +1 -0
  138. package/dist/types/transaction/actions/eip7702/authorization.d.ts +48 -0
  139. package/dist/types/transaction/actions/eip7702/authorization.d.ts.map +1 -0
  140. package/dist/types/transaction/actions/estimate-gas.d.ts +3 -1
  141. package/dist/types/transaction/actions/estimate-gas.d.ts.map +1 -1
  142. package/dist/types/transaction/actions/send-transaction.d.ts +31 -0
  143. package/dist/types/transaction/actions/send-transaction.d.ts.map +1 -1
  144. package/dist/types/transaction/actions/to-serializable-transaction.d.ts +19 -2
  145. package/dist/types/transaction/actions/to-serializable-transaction.d.ts.map +1 -1
  146. package/dist/types/transaction/prepare-transaction.d.ts +2 -0
  147. package/dist/types/transaction/prepare-transaction.d.ts.map +1 -1
  148. package/dist/types/transaction/serialize-transaction.d.ts +2 -0
  149. package/dist/types/transaction/serialize-transaction.d.ts.map +1 -1
  150. package/dist/types/utils/abi/decodeError.d.ts +2 -2
  151. package/dist/types/utils/abi/decodeError.d.ts.map +1 -1
  152. package/dist/types/utils/abi/decodeFunctionData.d.ts +6 -4
  153. package/dist/types/utils/abi/decodeFunctionData.d.ts.map +1 -1
  154. package/dist/types/utils/abi/decodeFunctionResult.d.ts +6 -4
  155. package/dist/types/utils/abi/decodeFunctionResult.d.ts.map +1 -1
  156. package/dist/types/utils/hashing/hashMessage.d.ts +1 -1
  157. package/dist/types/utils/hashing/hashMessage.d.ts.map +1 -1
  158. package/dist/types/version.d.ts +1 -1
  159. package/dist/types/version.d.ts.map +1 -1
  160. package/dist/types/wallets/create-wallet.d.ts +16 -0
  161. package/dist/types/wallets/create-wallet.d.ts.map +1 -1
  162. package/dist/types/wallets/in-app/core/wallet/in-app-core.d.ts.map +1 -1
  163. package/dist/types/wallets/in-app/core/wallet/index.d.ts +10 -2
  164. package/dist/types/wallets/in-app/core/wallet/index.d.ts.map +1 -1
  165. package/dist/types/wallets/interfaces/wallet.d.ts +9 -0
  166. package/dist/types/wallets/interfaces/wallet.d.ts.map +1 -1
  167. package/dist/types/wallets/private-key.d.ts.map +1 -1
  168. package/dist/types/wallets/smart/index.d.ts +2 -2
  169. package/dist/types/wallets/smart/index.d.ts.map +1 -1
  170. package/dist/types/wallets/smart/lib/signing.d.ts +46 -2
  171. package/dist/types/wallets/smart/lib/signing.d.ts.map +1 -1
  172. package/dist/types/wallets/smart/presets/7579.d.ts.map +1 -1
  173. package/package.json +1 -1
  174. package/src/adapters/ethers5.ts +1 -1
  175. package/src/auth/verify-hash.ts +12 -9
  176. package/src/contract/types.ts +8 -0
  177. package/src/exports/thirdweb.ts +10 -0
  178. package/src/exports/transaction.ts +9 -0
  179. package/src/exports/wallets.ts +2 -0
  180. package/src/extensions/erc721/lazyMinting/read/getBatchesToReveal.ts +2 -2
  181. package/src/extensions/types.ts +6 -0
  182. package/src/gas/estimate-l1-fee.ts +2 -3
  183. package/src/react/core/hooks/contract/useReadContract.ts +83 -74
  184. package/src/react/core/hooks/types.ts +13 -0
  185. package/src/transaction/actions/eip7702/authorization.test.ts +27 -0
  186. package/src/transaction/actions/eip7702/authorization.ts +58 -0
  187. package/src/transaction/actions/estimate-gas.ts +26 -9
  188. package/src/transaction/actions/send-transaction.ts +32 -2
  189. package/src/transaction/actions/to-serializable-transaction.test.ts +68 -0
  190. package/src/transaction/actions/to-serializable-transaction.ts +42 -30
  191. package/src/transaction/prepare-transaction.test.ts +28 -0
  192. package/src/transaction/prepare-transaction.ts +3 -0
  193. package/src/transaction/serialize-transaction.test.ts +108 -1
  194. package/src/transaction/serialize-transaction.ts +18 -0
  195. package/src/utils/abi/decodeError.ts +5 -4
  196. package/src/utils/abi/decodeFunctionData.ts +7 -5
  197. package/src/utils/abi/decodeFunctionResult.ts +7 -5
  198. package/src/utils/hashing/hashMessage.ts +1 -1
  199. package/src/utils/signatures/sign-message.test.ts +2 -2
  200. package/src/version.ts +1 -1
  201. package/src/wallets/create-wallet.ts +16 -0
  202. package/src/wallets/in-app/core/wallet/in-app-core.test.ts +115 -54
  203. package/src/wallets/in-app/core/wallet/in-app-core.ts +22 -11
  204. package/src/wallets/in-app/core/wallet/index.ts +10 -13
  205. package/src/wallets/interfaces/wallet.ts +15 -0
  206. package/src/wallets/private-key.test.ts +1 -0
  207. package/src/wallets/private-key.ts +10 -0
  208. package/src/wallets/smart/index.ts +34 -37
  209. package/src/wallets/smart/lib/signing.ts +154 -59
  210. package/src/wallets/smart/presets/7579.ts +13 -12
  211. package/src/wallets/smart/smart-wallet-integration-v07.test.ts +49 -9
  212. package/src/wallets/smart/smart-wallet-integration.test.ts +48 -1
  213. package/src/wallets/smart/smart-wallet.ts +13 -13
  214. package/src/wallets/smart/smart.test.ts +19 -39
@@ -110,6 +110,37 @@ export interface SendTransactionOptions {
110
110
  * });
111
111
  * ```
112
112
  *
113
+ * ### Send an EIP-7702 Transaction
114
+ *
115
+ * **Note: This feature is in beta and is subject to breaking changes**
116
+ *
117
+ * ```ts
118
+ * import { sendTransaction, prepareTransaction, signAuthorization } from "thirdweb";
119
+ * import { sepolia } from "thirdweb/chains";
120
+ *
121
+ * const authorization = await signAuthorization({
122
+ * request: {
123
+ * address: "0x...",
124
+ * chainId: 1,
125
+ * nonce: 0n,
126
+ * },
127
+ * account: myAccount,
128
+ * });
129
+ *
130
+ * const transaction = prepareTransaction({
131
+ * chain: sepolia,
132
+ * client: client,
133
+ * to: "0x...",
134
+ * value: 0n,
135
+ * authorizationList: [authorization],
136
+ * });
137
+ *
138
+ * const { transactionHash } = await sendTransaction({
139
+ * account,
140
+ * transaction,
141
+ * });
142
+ * ```
143
+ *
113
144
  * ### Gasless usage with [thirdweb Engine](https://portal.thirdweb.com/engine)
114
145
  * ```ts
115
146
  * const { transactionHash } = await sendTransaction({
@@ -166,9 +197,8 @@ export async function sendTransaction(
166
197
 
167
198
  const serializableTransaction = await toSerializableTransaction({
168
199
  transaction: transaction,
169
- from: account.address,
200
+ from: account,
170
201
  });
171
-
172
202
  // branch for gasless transactions
173
203
  if (gasless) {
174
204
  // lazy load the gasless tx function because it's only needed for gasless transactions
@@ -3,6 +3,7 @@ import { beforeAll, describe, expect, test } from "vitest";
3
3
  import { TEST_WALLET_B } from "../../../test/src/addresses.js";
4
4
  import { FORKED_ETHEREUM_CHAIN } from "../../../test/src/chains.js";
5
5
  import { TEST_CLIENT } from "../../../test/src/test-clients.js";
6
+ import { TEST_ACCOUNT_A } from "../../../test/src/test-wallets.js";
6
7
  import { arbitrumSepolia } from "../../chains/chain-definitions/arbitrum-sepolia.js";
7
8
  import { toWei } from "../../utils/units.js";
8
9
  import {
@@ -10,6 +11,7 @@ import {
10
11
  prepareTransaction,
11
12
  } from "../prepare-transaction.js";
12
13
  import { serializeTransaction } from "../serialize-transaction.js";
14
+ import { signAuthorization } from "./eip7702/authorization.js";
13
15
  import { toSerializableTransaction } from "./to-serializable-transaction.js";
14
16
 
15
17
  describe.runIf(process.env.TW_SECRET_KEY)("toSerializableTransaction", () => {
@@ -272,6 +274,72 @@ describe.runIf(process.env.TW_SECRET_KEY)("toSerializableTransaction", () => {
272
274
  });
273
275
  });
274
276
 
277
+ describe("authorizations", () => {
278
+ test("should be able to be set", async () => {
279
+ const authorization = await signAuthorization({
280
+ account: TEST_ACCOUNT_A,
281
+ request: {
282
+ address: TEST_WALLET_B,
283
+ chainId: 1,
284
+ nonce: 100n,
285
+ },
286
+ });
287
+
288
+ const serializableTransaction = await toSerializableTransaction({
289
+ transaction: {
290
+ ...transaction,
291
+ authorizationList: [authorization],
292
+ },
293
+ from: TEST_ACCOUNT_A,
294
+ });
295
+
296
+ expect(serializableTransaction.authorizationList).toMatchInlineSnapshot(`
297
+ [
298
+ {
299
+ "address": "0x0000000000000000000000000000000000000002",
300
+ "chainId": 1,
301
+ "nonce": 100n,
302
+ "r": 80806665504145908662094143605220407474886149466352261863122583017203514896219n,
303
+ "s": 35406481756212480507222011619049260135807579374282360733409834151386668114999n,
304
+ "yParity": 1,
305
+ },
306
+ ]
307
+ `);
308
+ });
309
+
310
+ test("should be able to be a promised value", async () => {
311
+ const authorization = await signAuthorization({
312
+ account: TEST_ACCOUNT_A,
313
+ request: {
314
+ address: TEST_WALLET_B,
315
+ chainId: 1,
316
+ nonce: 100n,
317
+ },
318
+ });
319
+
320
+ const serializableTransaction = await toSerializableTransaction({
321
+ transaction: {
322
+ ...transaction,
323
+ authorizationList: async () => Promise.resolve([authorization]),
324
+ },
325
+ from: TEST_ACCOUNT_A,
326
+ });
327
+
328
+ expect(serializableTransaction.authorizationList).toMatchInlineSnapshot(`
329
+ [
330
+ {
331
+ "address": "0x0000000000000000000000000000000000000002",
332
+ "chainId": 1,
333
+ "nonce": 100n,
334
+ "r": 80806665504145908662094143605220407474886149466352261863122583017203514896219n,
335
+ "s": 35406481756212480507222011619049260135807579374282360733409834151386668114999n,
336
+ "yParity": 1,
337
+ },
338
+ ]
339
+ `);
340
+ });
341
+ });
342
+
275
343
  describe("extraGas override", () => {
276
344
  let gas: bigint;
277
345
  beforeAll(() => {
@@ -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.80.1-nightly-430475913d30ef7a30cb3092f6ef09c0c998a9b6-20250106000343";
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>(