@account-kit/wallet-client 0.1.0-alpha.1 → 0.1.0-alpha.3

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 (188) hide show
  1. package/dist/esm/capabilities/index.d.ts +5 -2
  2. package/dist/esm/capabilities/index.js +1 -1
  3. package/dist/esm/capabilities/index.js.map +1 -1
  4. package/dist/esm/capabilities/overrides.js +8 -8
  5. package/dist/esm/capabilities/overrides.js.map +1 -1
  6. package/dist/esm/capabilities/permissions/index.d.ts +10 -3
  7. package/dist/esm/capabilities/permissions/index.js +11 -2
  8. package/dist/esm/capabilities/permissions/index.js.map +1 -1
  9. package/dist/esm/capabilities/permissions/mav2.d.ts +3 -3
  10. package/dist/esm/capabilities/permissions/mav2.js +9 -1
  11. package/dist/esm/capabilities/permissions/mav2.js.map +1 -1
  12. package/dist/esm/client/actions/createAccount.d.ts +27 -2
  13. package/dist/esm/client/actions/createAccount.js +25 -0
  14. package/dist/esm/client/actions/createAccount.js.map +1 -1
  15. package/dist/esm/client/actions/getCallsStatus.d.ts +21 -2
  16. package/dist/esm/client/actions/getCallsStatus.js.map +1 -1
  17. package/dist/esm/client/actions/grantPermissions.d.ts +114 -2
  18. package/dist/esm/client/actions/grantPermissions.js +1 -0
  19. package/dist/esm/client/actions/grantPermissions.js.map +1 -1
  20. package/dist/esm/client/actions/listAccounts.d.ts +26 -2
  21. package/dist/esm/client/actions/listAccounts.js +24 -0
  22. package/dist/esm/client/actions/listAccounts.js.map +1 -1
  23. package/dist/esm/client/actions/prepareCalls.d.ts +28 -2
  24. package/dist/esm/client/actions/prepareCalls.js.map +1 -1
  25. package/dist/esm/client/actions/requestAccount.d.ts +21 -2
  26. package/dist/esm/client/actions/requestAccount.js +15 -4
  27. package/dist/esm/client/actions/requestAccount.js.map +1 -1
  28. package/dist/esm/client/actions/sendPreparedCalls.d.ts +39 -2
  29. package/dist/esm/client/actions/sendPreparedCalls.js +37 -0
  30. package/dist/esm/client/actions/sendPreparedCalls.js.map +1 -1
  31. package/dist/esm/client/actions/signMessage.d.ts +22 -2
  32. package/dist/esm/client/actions/signMessage.js +4 -2
  33. package/dist/esm/client/actions/signMessage.js.map +1 -1
  34. package/dist/esm/client/actions/signSignatureRequest.d.ts +34 -0
  35. package/dist/esm/client/actions/signSignatureRequest.js +22 -1
  36. package/dist/esm/client/actions/signSignatureRequest.js.map +1 -1
  37. package/dist/esm/client/actions/signTypedData.d.ts +35 -2
  38. package/dist/esm/client/actions/signTypedData.js +3 -1
  39. package/dist/esm/client/actions/signTypedData.js.map +1 -1
  40. package/dist/esm/client/client.e2e-test.js +112 -30
  41. package/dist/esm/client/client.e2e-test.js.map +1 -1
  42. package/dist/esm/client/decorator.d.ts +7 -5
  43. package/dist/esm/client/decorator.js +1 -1
  44. package/dist/esm/client/decorator.js.map +1 -1
  45. package/dist/esm/client/index.d.ts +4 -4
  46. package/dist/esm/client/index.js +29 -3
  47. package/dist/esm/client/index.js.map +1 -1
  48. package/dist/esm/exports/index.d.ts +1 -0
  49. package/dist/esm/exports/index.js +1 -0
  50. package/dist/esm/exports/index.js.map +1 -1
  51. package/dist/esm/exports/internal.d.ts +1 -1
  52. package/dist/esm/exports/internal.js.map +1 -1
  53. package/dist/esm/internal/decorator.d.ts +2 -0
  54. package/dist/esm/internal/decorator.js +10 -0
  55. package/dist/esm/internal/decorator.js.map +1 -0
  56. package/dist/esm/isomorphic/actions/createSession.js +25 -7
  57. package/dist/esm/isomorphic/actions/createSession.js.map +1 -1
  58. package/dist/esm/isomorphic/actions/prepareCalls.js +35 -12
  59. package/dist/esm/isomorphic/actions/prepareCalls.js.map +1 -1
  60. package/dist/esm/isomorphic/actions/sendPreparedCalls.js +26 -6
  61. package/dist/esm/isomorphic/actions/sendPreparedCalls.js.map +1 -1
  62. package/dist/esm/isomorphic/client.d.ts +11 -5
  63. package/dist/esm/isomorphic/utils/7702.d.ts +11 -0
  64. package/dist/esm/isomorphic/utils/7702.js +26 -0
  65. package/dist/esm/isomorphic/utils/7702.js.map +1 -0
  66. package/dist/esm/isomorphic/utils/createAccount.d.ts +2 -1
  67. package/dist/esm/isomorphic/utils/createAccount.js +30 -5
  68. package/dist/esm/isomorphic/utils/createAccount.js.map +1 -1
  69. package/dist/esm/isomorphic/utils/createDummySigner.js +3 -3
  70. package/dist/esm/isomorphic/utils/createDummySigner.js.map +1 -1
  71. package/dist/esm/isomorphic/utils/parsePermissionsContext.d.ts +2 -1
  72. package/dist/esm/isomorphic/utils/parsePermissionsContext.js +17 -5
  73. package/dist/esm/isomorphic/utils/parsePermissionsContext.js.map +1 -1
  74. package/dist/esm/local/client.d.ts +1 -1
  75. package/dist/esm/local/client.js +10 -2
  76. package/dist/esm/local/client.js.map +1 -1
  77. package/dist/esm/remote/client.d.ts +1 -1
  78. package/dist/esm/remote/client.js +12 -3
  79. package/dist/esm/remote/client.js.map +1 -1
  80. package/dist/esm/rpc/examples.d.ts +230 -0
  81. package/dist/esm/rpc/examples.js +314 -0
  82. package/dist/esm/rpc/examples.js.map +1 -0
  83. package/dist/esm/rpc/request.d.ts +48 -17
  84. package/dist/esm/rpc/request.js +53 -14
  85. package/dist/esm/rpc/request.js.map +1 -1
  86. package/dist/esm/rpc/schema.d.ts +43 -12
  87. package/dist/esm/schemas.d.ts +29 -7
  88. package/dist/esm/schemas.js +120 -38
  89. package/dist/esm/schemas.js.map +1 -1
  90. package/dist/esm/types.d.ts +15 -4
  91. package/dist/esm/types.js.map +1 -1
  92. package/dist/types/capabilities/index.d.ts +5 -2
  93. package/dist/types/capabilities/index.d.ts.map +1 -1
  94. package/dist/types/capabilities/overrides.d.ts.map +1 -1
  95. package/dist/types/capabilities/permissions/index.d.ts +10 -3
  96. package/dist/types/capabilities/permissions/index.d.ts.map +1 -1
  97. package/dist/types/capabilities/permissions/mav2.d.ts +3 -3
  98. package/dist/types/capabilities/permissions/mav2.d.ts.map +1 -1
  99. package/dist/types/client/actions/createAccount.d.ts +27 -2
  100. package/dist/types/client/actions/createAccount.d.ts.map +1 -1
  101. package/dist/types/client/actions/getCallsStatus.d.ts +21 -2
  102. package/dist/types/client/actions/getCallsStatus.d.ts.map +1 -1
  103. package/dist/types/client/actions/grantPermissions.d.ts +114 -2
  104. package/dist/types/client/actions/grantPermissions.d.ts.map +1 -1
  105. package/dist/types/client/actions/listAccounts.d.ts +26 -2
  106. package/dist/types/client/actions/listAccounts.d.ts.map +1 -1
  107. package/dist/types/client/actions/prepareCalls.d.ts +28 -2
  108. package/dist/types/client/actions/prepareCalls.d.ts.map +1 -1
  109. package/dist/types/client/actions/requestAccount.d.ts +21 -2
  110. package/dist/types/client/actions/requestAccount.d.ts.map +1 -1
  111. package/dist/types/client/actions/sendPreparedCalls.d.ts +39 -2
  112. package/dist/types/client/actions/sendPreparedCalls.d.ts.map +1 -1
  113. package/dist/types/client/actions/signMessage.d.ts +22 -2
  114. package/dist/types/client/actions/signMessage.d.ts.map +1 -1
  115. package/dist/types/client/actions/signSignatureRequest.d.ts +34 -0
  116. package/dist/types/client/actions/signSignatureRequest.d.ts.map +1 -1
  117. package/dist/types/client/actions/signTypedData.d.ts +35 -2
  118. package/dist/types/client/actions/signTypedData.d.ts.map +1 -1
  119. package/dist/types/client/decorator.d.ts +7 -5
  120. package/dist/types/client/decorator.d.ts.map +1 -1
  121. package/dist/types/client/index.d.ts +4 -4
  122. package/dist/types/client/index.d.ts.map +1 -1
  123. package/dist/types/exports/index.d.ts +1 -0
  124. package/dist/types/exports/index.d.ts.map +1 -1
  125. package/dist/types/exports/internal.d.ts +1 -1
  126. package/dist/types/exports/internal.d.ts.map +1 -1
  127. package/dist/types/internal/decorator.d.ts +3 -0
  128. package/dist/types/internal/decorator.d.ts.map +1 -0
  129. package/dist/types/isomorphic/actions/createSession.d.ts.map +1 -1
  130. package/dist/types/isomorphic/actions/prepareCalls.d.ts.map +1 -1
  131. package/dist/types/isomorphic/actions/sendPreparedCalls.d.ts.map +1 -1
  132. package/dist/types/isomorphic/client.d.ts +11 -5
  133. package/dist/types/isomorphic/client.d.ts.map +1 -1
  134. package/dist/types/isomorphic/utils/7702.d.ts +12 -0
  135. package/dist/types/isomorphic/utils/7702.d.ts.map +1 -0
  136. package/dist/types/isomorphic/utils/createAccount.d.ts +2 -1
  137. package/dist/types/isomorphic/utils/createAccount.d.ts.map +1 -1
  138. package/dist/types/isomorphic/utils/createDummySigner.d.ts.map +1 -1
  139. package/dist/types/isomorphic/utils/parsePermissionsContext.d.ts +2 -1
  140. package/dist/types/isomorphic/utils/parsePermissionsContext.d.ts.map +1 -1
  141. package/dist/types/local/client.d.ts +1 -1
  142. package/dist/types/local/client.d.ts.map +1 -1
  143. package/dist/types/remote/client.d.ts +1 -1
  144. package/dist/types/remote/client.d.ts.map +1 -1
  145. package/dist/types/rpc/examples.d.ts +231 -0
  146. package/dist/types/rpc/examples.d.ts.map +1 -0
  147. package/dist/types/rpc/request.d.ts +48 -17
  148. package/dist/types/rpc/request.d.ts.map +1 -1
  149. package/dist/types/rpc/schema.d.ts +43 -12
  150. package/dist/types/rpc/schema.d.ts.map +1 -1
  151. package/dist/types/schemas.d.ts +29 -7
  152. package/dist/types/schemas.d.ts.map +1 -1
  153. package/dist/types/types.d.ts +15 -4
  154. package/dist/types/types.d.ts.map +1 -1
  155. package/package.json +8 -6
  156. package/src/capabilities/index.ts +5 -8
  157. package/src/capabilities/overrides.ts +23 -8
  158. package/src/capabilities/permissions/index.ts +21 -5
  159. package/src/capabilities/permissions/mav2.ts +13 -3
  160. package/src/client/actions/createAccount.ts +27 -2
  161. package/src/client/actions/getCallsStatus.ts +21 -2
  162. package/src/client/actions/grantPermissions.ts +114 -2
  163. package/src/client/actions/listAccounts.ts +26 -2
  164. package/src/client/actions/prepareCalls.ts +28 -2
  165. package/src/client/actions/requestAccount.ts +41 -7
  166. package/src/client/actions/sendPreparedCalls.ts +39 -2
  167. package/src/client/actions/signMessage.ts +24 -4
  168. package/src/client/actions/signSignatureRequest.ts +61 -2
  169. package/src/client/actions/signTypedData.ts +39 -3
  170. package/src/client/client.e2e-test.ts +134 -32
  171. package/src/client/decorator.ts +10 -12
  172. package/src/client/index.ts +41 -10
  173. package/src/exports/index.ts +1 -0
  174. package/src/exports/internal.ts +1 -1
  175. package/src/internal/decorator.ts +12 -0
  176. package/src/isomorphic/actions/createSession.ts +28 -7
  177. package/src/isomorphic/actions/prepareCalls.ts +38 -11
  178. package/src/isomorphic/actions/sendPreparedCalls.ts +47 -20
  179. package/src/isomorphic/utils/7702.ts +58 -0
  180. package/src/isomorphic/utils/createAccount.ts +38 -6
  181. package/src/isomorphic/utils/createDummySigner.ts +3 -2
  182. package/src/isomorphic/utils/parsePermissionsContext.ts +23 -7
  183. package/src/local/client.ts +54 -45
  184. package/src/remote/client.ts +22 -7
  185. package/src/rpc/examples.ts +343 -0
  186. package/src/rpc/request.ts +75 -26
  187. package/src/schemas.ts +218 -87
  188. package/src/types.ts +18 -4
@@ -5,13 +5,46 @@ import {
5
5
  type JsonRpcAccount,
6
6
  type TypedDataDefinition,
7
7
  } from "viem";
8
- import type { InnerWalletApiClient } from "../../types";
8
+ import type { InnerWalletApiClient } from "../../types.ts";
9
9
  import { requestAccount } from "./requestAccount.js";
10
10
 
11
- export type SignTypedDataParams = TypedDataDefinition;
11
+ export type SignTypedDataParams = TypedDataDefinition & {
12
+ account?: Address;
13
+ };
12
14
 
13
15
  export type SignTypedDataResult = Hex;
14
16
 
17
+ /**
18
+ * Signs typed data (EIP-712) using the smart account.
19
+ * This method requests the account associated with the signer and uses it to sign the typed data.
20
+ *
21
+ * @param {InnerWalletApiClient} client - The wallet API client to use for the request
22
+ * @param {SmartAccountSigner} signer - The signer of the smart account
23
+ * @param {TypedDataDefinition} params - The typed data to sign, following EIP-712 format
24
+ * @returns {Promise<SignTypedDataResult>} A Promise that resolves to the signature as a hex string
25
+ *
26
+ * @example
27
+ * // Sign typed data
28
+ * const signature = await client.signTypedData({
29
+ * domain: {
30
+ * name: 'Example DApp',
31
+ * version: '1',
32
+ * chainId: 1,
33
+ * verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC'
34
+ * },
35
+ * types: {
36
+ * Person: [
37
+ * { name: 'name', type: 'string' },
38
+ * { name: 'wallet', type: 'address' }
39
+ * ]
40
+ * },
41
+ * primaryType: 'Person',
42
+ * message: {
43
+ * name: 'John Doe',
44
+ * wallet: '0xAaAaAaAaAaAaAaAaAaAAAAAAAAaaaAaAaAaaAaAa'
45
+ * }
46
+ * });
47
+ */
15
48
  export async function signTypedData<
16
49
  TAccount extends JsonRpcAccount<Address> | undefined =
17
50
  | JsonRpcAccount<Address>
@@ -27,6 +60,9 @@ export async function signTypedData(
27
60
  signer: SmartAccountSigner,
28
61
  params: SignTypedDataParams,
29
62
  ): Promise<SignTypedDataResult> {
30
- const account = await requestAccount(client, signer);
63
+ const account = await requestAccount(client, signer, {
64
+ accountAddress: params.account ?? client.account?.address,
65
+ });
66
+
31
67
  return account.signTypedDataWith6492(params);
32
68
  }
@@ -32,6 +32,27 @@ describe("Client E2E Tests", () => {
32
32
  transport,
33
33
  });
34
34
 
35
+ it("should successfully request account with different salt", async () => {
36
+ const account = await client.requestAccount({
37
+ id: "2d00c64e-2e55-4925-832e-e288dbf1139e",
38
+ creationHint: { salt: "0x1" },
39
+ });
40
+
41
+ expect(account.address).toMatchInlineSnapshot(
42
+ `"0x569bCECaC47Ef9706c4b2370f2891bccd4cdE30c"`,
43
+ );
44
+ });
45
+
46
+ it("should not cache account if different inputs provided", async () => {
47
+ const account = await client.requestAccount();
48
+ const account2 = await client.requestAccount({
49
+ id: "2d00c64e-2e55-4925-832e-e288dbf1139e",
50
+ creationHint: { salt: "0x1" },
51
+ });
52
+
53
+ expect(account.address).not.toEqual(account2.address);
54
+ });
55
+
35
56
  it("should successfully get a counterfactual address", async () => {
36
57
  const account = await client.requestAccount();
37
58
  expect(account.address).toMatchInlineSnapshot(
@@ -42,14 +63,10 @@ describe("Client E2E Tests", () => {
42
63
  it("can correctly sign a message", async () => {
43
64
  const account = await client.requestAccount();
44
65
  const message = "hello world";
45
- const signature = await client.signMessage(message);
46
- const publicClient = createPublicClient({
47
- chain: arbitrumSepolia,
48
- transport,
49
- });
66
+ const signature = await client.signMessage({ message });
50
67
  const isValid = await publicClient.verifyMessage({
51
68
  address: account.address,
52
- message: "hello world",
69
+ message,
53
70
  signature,
54
71
  });
55
72
  expect(isValid).toBeTrue();
@@ -66,9 +83,46 @@ describe("Client E2E Tests", () => {
66
83
  expect(isValid).toBeTrue();
67
84
  });
68
85
 
86
+ it("can correctly sign a message with a different account", async () => {
87
+ const account = await client.requestAccount({
88
+ id: "2d00c64e-2e55-4925-832e-e288dbf1139e",
89
+ creationHint: { salt: "0x1" },
90
+ });
91
+ const message = "hello world";
92
+
93
+ const signature = await client.signMessage({
94
+ message,
95
+ account: account.address,
96
+ });
97
+ const isValid = await publicClient.verifyMessage({
98
+ address: account.address,
99
+ message,
100
+ signature,
101
+ });
102
+ expect(isValid).toBeTrue();
103
+ });
104
+
105
+ it("can correctly sign typed data with a different account", async () => {
106
+ const account = await client.requestAccount({
107
+ id: "2d00c64e-2e55-4925-832e-e288dbf1139e",
108
+ creationHint: { salt: "0x1" },
109
+ });
110
+
111
+ const signature = await client.signTypedData({
112
+ ...givenTypedData,
113
+ account: account.address,
114
+ });
115
+ const isValid = await publicClient.verifyTypedData({
116
+ ...givenTypedData,
117
+ signature,
118
+ address: account.address,
119
+ });
120
+ expect(isValid).toBeTrue();
121
+ });
122
+
69
123
  it("should successfully send a UO with paymaster", async () => {
70
124
  const account = await client.requestAccount();
71
- const preparedUO = await client.prepareCalls({
125
+ const preparedCall = await client.prepareCalls({
72
126
  calls: [{ to: zeroAddress, value: "0x0" }],
73
127
  from: account.address,
74
128
  capabilities: {
@@ -78,20 +132,13 @@ describe("Client E2E Tests", () => {
78
132
  },
79
133
  });
80
134
 
81
- if (preparedUO.signatureRequest.type !== "personal_sign") {
82
- throw new Error("Invalid signature request type");
83
- }
84
-
85
- const signature = await signer.signMessage(
86
- preparedUO.signatureRequest.data,
135
+ const signature = await client.signSignatureRequest(
136
+ preparedCall.signatureRequest,
87
137
  );
88
138
 
89
139
  const result = await client.sendPreparedCalls({
90
- ...preparedUO,
91
- signature: {
92
- type: "ecdsa",
93
- signature,
94
- },
140
+ ...preparedCall,
141
+ signature,
95
142
  });
96
143
 
97
144
  expect(result.preparedCallIds).toBeArrayOfSize(1);
@@ -112,7 +159,7 @@ describe("Client E2E Tests", () => {
112
159
  permissions: [{ type: "root" }],
113
160
  });
114
161
 
115
- const preparedUO = await client.prepareCalls({
162
+ const preparedCall = await client.prepareCalls({
116
163
  calls: [{ to: zeroAddress, value: "0x0" }],
117
164
  from: account.address,
118
165
  capabilities: {
@@ -125,11 +172,11 @@ describe("Client E2E Tests", () => {
125
172
 
126
173
  const signature = await signSignatureRequest(
127
174
  sessionKey,
128
- preparedUO.signatureRequest,
175
+ preparedCall.signatureRequest,
129
176
  );
130
177
 
131
178
  const result = await client.sendPreparedCalls({
132
- ...preparedUO,
179
+ ...preparedCall,
133
180
  signature,
134
181
  capabilities: {
135
182
  permissions,
@@ -164,14 +211,31 @@ describe("Client E2E Tests", () => {
164
211
  );
165
212
  });
166
213
 
214
+ it("should successfully request account with different salt", async () => {
215
+ const account = await client.requestAccount({
216
+ id: "8670d2d8-2781-49e9-a75c-1eb980271ca9",
217
+ creationHint: { salt: "0x1" },
218
+ });
219
+
220
+ expect(account.address).toMatchInlineSnapshot(
221
+ `"0xC9B8271E44f14be83CecfDE1dDb325e9fa15e9Ff"`,
222
+ );
223
+ });
224
+
225
+ it("should not cache account if different inputs provided", async () => {
226
+ const account = await client.requestAccount();
227
+ const account2 = await client.requestAccount({
228
+ id: "8670d2d8-2781-49e9-a75c-1eb980271ca9",
229
+ creationHint: { salt: "0x1" },
230
+ });
231
+
232
+ expect(account.address).not.toEqual(account2.address);
233
+ });
234
+
167
235
  it("can correctly sign a message", async () => {
168
236
  const account = await client.requestAccount();
169
237
  const message = "hello world";
170
- const signature = await client.signMessage(message);
171
- const publicClient = createPublicClient({
172
- chain: arbitrumSepolia,
173
- transport,
174
- });
238
+ const signature = await client.signMessage({ message });
175
239
  const isValid = await publicClient.verifyMessage({
176
240
  address: account.address,
177
241
  message: "hello world",
@@ -191,9 +255,47 @@ describe("Client E2E Tests", () => {
191
255
  expect(isValid).toBeTrue();
192
256
  });
193
257
 
258
+ it("can correctly sign a message with a different account", async () => {
259
+ const account = await client.requestAccount({
260
+ id: "8670d2d8-2781-49e9-a75c-1eb980271ca9",
261
+ creationHint: { salt: "0x1" },
262
+ });
263
+
264
+ const message = "hello world";
265
+ const signature = await client.signMessage({
266
+ message,
267
+ account: account.address,
268
+ });
269
+ const isValid = await publicClient.verifyMessage({
270
+ address: account.address,
271
+ message: "hello world",
272
+ signature,
273
+ });
274
+ expect(isValid).toBeTrue();
275
+ });
276
+
277
+ it("can correctly sign typed data with a different account", async () => {
278
+ const account = await client.requestAccount({
279
+ id: "8670d2d8-2781-49e9-a75c-1eb980271ca9",
280
+ creationHint: { salt: "0x1" },
281
+ });
282
+
283
+ const signature = await client.signTypedData({
284
+ ...givenTypedData,
285
+ account: account.address,
286
+ });
287
+
288
+ const isValid = await publicClient.verifyTypedData({
289
+ ...givenTypedData,
290
+ signature,
291
+ address: account.address,
292
+ });
293
+ expect(isValid).toBeTrue();
294
+ });
295
+
194
296
  it("should successfully send a UO with paymaster", async () => {
195
297
  const account = await client.requestAccount();
196
- const preparedUO = await client.prepareCalls({
298
+ const preparedCall = await client.prepareCalls({
197
299
  calls: [{ to: zeroAddress, value: "0x0" }],
198
300
  from: account.address,
199
301
  capabilities: {
@@ -204,11 +306,11 @@ describe("Client E2E Tests", () => {
204
306
  });
205
307
 
206
308
  const signature = await client.signSignatureRequest(
207
- preparedUO.signatureRequest,
309
+ preparedCall.signatureRequest,
208
310
  );
209
311
 
210
312
  const result = await client.sendPreparedCalls({
211
- ...preparedUO,
313
+ ...preparedCall,
212
314
  signature,
213
315
  });
214
316
 
@@ -230,7 +332,7 @@ describe("Client E2E Tests", () => {
230
332
  permissions: [{ type: "root" }],
231
333
  });
232
334
 
233
- const preparedUO = await client.prepareCalls({
335
+ const preparedCall = await client.prepareCalls({
234
336
  calls: [{ to: zeroAddress, value: "0x0" }],
235
337
  from: account.address,
236
338
  capabilities: {
@@ -243,11 +345,11 @@ describe("Client E2E Tests", () => {
243
345
 
244
346
  const signature = await signSignatureRequest(
245
347
  sessionKey,
246
- preparedUO.signatureRequest,
348
+ preparedCall.signatureRequest,
247
349
  );
248
350
 
249
351
  const result = await client.sendPreparedCalls({
250
- ...preparedUO,
352
+ ...preparedCall,
251
353
  signature,
252
354
  capabilities: {
253
355
  permissions,
@@ -1,15 +1,10 @@
1
1
  import type { SmartAccountSigner } from "@aa-sdk/core";
2
- import type {
3
- Hex,
4
- JsonRpcAccount,
5
- SignableMessage,
6
- TypedDataDefinition,
7
- } from "viem";
2
+ import type { Hex, JsonRpcAccount } from "viem";
8
3
  import type {
9
4
  SendPreparedCallsParams,
10
5
  SendPreparedCallsResult,
11
- } from "../isomorphic/actions/sendPreparedCalls";
12
- import type { InnerWalletApiClient } from "../types";
6
+ } from "../isomorphic/actions/sendPreparedCalls.ts";
7
+ import type { InnerWalletApiClient } from "../types.ts";
13
8
  import {
14
9
  createAccount,
15
10
  type CreateAccountParams,
@@ -41,13 +36,16 @@ import {
41
36
  type RequestAccountResult,
42
37
  } from "./actions/requestAccount.js";
43
38
  import { sendPreparedCalls } from "./actions/sendPreparedCalls.js";
44
- import { signMessage } from "./actions/signMessage.js";
39
+ import { signMessage, type SignMessageParams } from "./actions/signMessage.js";
45
40
  import {
46
41
  signSignatureRequest,
47
42
  type SignSignatureRequestParams,
48
43
  type SignSignatureRequestResult,
49
44
  } from "./actions/signSignatureRequest.js";
50
- import { signTypedData } from "./actions/signTypedData.js";
45
+ import {
46
+ signTypedData,
47
+ type SignTypedDataParams,
48
+ } from "./actions/signTypedData.js";
51
49
 
52
50
  export type SmartWalletActions<
53
51
  TAccount extends JsonRpcAccount | undefined = JsonRpcAccount | undefined,
@@ -69,8 +67,8 @@ export type SmartWalletActions<
69
67
  signSignatureRequest: (
70
68
  params: SignSignatureRequestParams,
71
69
  ) => Promise<SignSignatureRequestResult>;
72
- signMessage: (params: SignableMessage) => Promise<Hex>;
73
- signTypedData: (params: TypedDataDefinition) => Promise<Hex>;
70
+ signMessage: (params: SignMessageParams) => Promise<Hex>;
71
+ signTypedData: (params: SignTypedDataParams) => Promise<Hex>;
74
72
  grantPermissions: (
75
73
  params: GrantPermissionsParams<TAccount>,
76
74
  ) => Promise<GrantPermissionsResult>;
@@ -1,19 +1,19 @@
1
- import { type SmartAccountSigner } from "@aa-sdk/core";
2
- import { type AlchemyTransport } from "@account-kit/infra";
3
- import {
4
- type Address,
5
- type Chain,
6
- type IsUndefined,
7
- type JsonRpcAccount,
8
- type Prettify,
1
+ import type { SmartAccountSigner } from "@aa-sdk/core";
2
+ import type {
3
+ Address,
4
+ Chain,
5
+ IsUndefined,
6
+ JsonRpcAccount,
7
+ Prettify,
9
8
  } from "viem";
10
9
  import { createLocalClient } from "../local/client.js";
11
10
  import { createRemoteClient } from "../remote/client.js";
12
- import type { InnerWalletApiClient } from "../types";
11
+ import type { InnerWalletApiClient } from "../types.ts";
13
12
  import {
14
13
  smartWalletClientActions,
15
14
  type SmartWalletActions,
16
15
  } from "./decorator.js";
16
+ import type { AlchemyTransport } from "@account-kit/infra";
17
17
 
18
18
  export type SmartWalletClientParams<
19
19
  TAccount extends JsonRpcAccount<Address> | undefined =
@@ -49,7 +49,38 @@ export function createSmartWalletClient<
49
49
  params: SmartWalletClientParams<TAccount>,
50
50
  ): InnerWalletApiClient<TAccount> & SmartWalletActions<TAccount>;
51
51
 
52
- export function createSmartWalletClient(params: SmartWalletClientParams) {
52
+ /**
53
+ * Creates a smart wallet client that can be used to interact with a smart account.
54
+ *
55
+ * @param {SmartWalletClientParams} params - The parameters for creating the smart wallet client
56
+ * @param {AlchemyTransport} params.transport - The Alchemy transport to use
57
+ * @param {Chain} params.chain - The chain to use
58
+ * @param {SmartAccountSigner} params.signer - The signer to use for the smart account
59
+ * @param {"local" | "remote"} params.mode - The client's mode (local or remote).
60
+ * @param {string} [params.policyId] - The policy ID for gas sponsorship (optional)
61
+ * @param {Address} [params.account] - The smart account address to use (optional)
62
+ * @returns {InnerWalletApiClient & SmartWalletActions} - A viem-compatible client
63
+ *
64
+ * @example
65
+ * import { LocalAccountSigner } from "@aa-sdk/core";
66
+ * import { alchemy, arbitrumSepolia } from "@account-kit/infra";
67
+ * import { generatePrivateKey } from "viem/accounts";
68
+ * import { createSmartWalletClient } from "@account-kit/wallet-client";
69
+ *
70
+ * const signer = LocalAccountSigner.privateKeyToAccountSigner(generatePrivateKey());
71
+ * const transport = alchemy({
72
+ * apiKey: "your-alchemy-api-key",
73
+ * });
74
+ * const client = createSmartWalletClient({
75
+ * transport,
76
+ * chain: arbitrumSepolia,
77
+ * mode: "remote",
78
+ * signer,
79
+ * });
80
+ */
81
+ export function createSmartWalletClient(
82
+ params: SmartWalletClientParams,
83
+ ): InnerWalletApiClient & SmartWalletActions {
53
84
  const { transport, chain, policyId, mode, account, signer } = params;
54
85
 
55
86
  const innerClient =
@@ -30,3 +30,4 @@ export { requestAccount } from "../client/actions/requestAccount.js";
30
30
  export { signMessage } from "../client/actions/signMessage.js";
31
31
  export { signSignatureRequest } from "../client/actions/signSignatureRequest.js";
32
32
  export { signTypedData } from "../client/actions/signTypedData.js";
33
+ export { grantPermissions } from "../client/actions/grantPermissions.js";
@@ -12,5 +12,5 @@ export * from "../rpc/request.js";
12
12
  export * as RpcSchemas from "../rpc/request.js";
13
13
  export * from "../rpc/schema.js";
14
14
  export * from "../schemas.js";
15
- export type * from "../types";
15
+ export type * from "../types.ts";
16
16
  export * from "../utils.js";
@@ -0,0 +1,12 @@
1
+ import type { CachedAccount, InternalState } from "../types.ts";
2
+
3
+ export function internalStateDecorator(): InternalState {
4
+ let account: CachedAccount | undefined = undefined;
5
+
6
+ return {
7
+ setAccount: (newAccount: CachedAccount) => {
8
+ account = newAccount;
9
+ },
10
+ getAccount: () => account,
11
+ };
12
+ }
@@ -24,6 +24,8 @@ import type { wallet_createSession } from "../../rpc/request.js";
24
24
  import type { WalletServerViemRpcSchema } from "../../rpc/schema.js";
25
25
  import { createAccount, isModularAccountV2 } from "../utils/createAccount.js";
26
26
  import { createDummySigner } from "../utils/createDummySigner.js";
27
+ import { createAuthorization } from "../utils/7702.js";
28
+ import { InvalidRequestError } from "ox/RpcResponse";
27
29
 
28
30
  export type CreateSessionParams = Omit<
29
31
  Static<
@@ -57,17 +59,20 @@ export async function createSession(
57
59
  throw new ChainNotFoundError();
58
60
  }
59
61
 
60
- const { counterfactualInfo } = await client.request({
62
+ const { counterfactualInfo, delegation } = await client.request({
61
63
  method: "wallet_requestAccount",
62
64
  params: [
63
65
  {
64
- includeCounterfactualInfo: true,
65
66
  accountAddress: params.account,
67
+ includeCounterfactualInfo: true,
66
68
  },
67
69
  ],
68
70
  });
69
- if (!counterfactualInfo) {
70
- throw new Error("No counterfactual info found.");
71
+ if (!counterfactualInfo && !delegation) {
72
+ throw new InvalidRequestError({
73
+ message:
74
+ "No counterfactual info or delegated implementation address found.",
75
+ });
71
76
  }
72
77
 
73
78
  const account = await createAccount({
@@ -76,10 +81,13 @@ export async function createSession(
76
81
  signer: createDummySigner(params.account),
77
82
  accountAddress: params.account,
78
83
  counterfactualInfo,
84
+ delegation,
79
85
  });
80
86
 
81
87
  if (!isModularAccountV2(account)) {
82
- throw new Error("Sessions are currently only supported by MAv2 accounts.");
88
+ throw new InvalidRequestError({
89
+ message: "Sessions are currently only supported by MAv2 accounts.",
90
+ });
83
91
  }
84
92
 
85
93
  const _client = createSmartAccountClient({
@@ -108,12 +116,25 @@ export async function createSession(
108
116
  })
109
117
  .compileDeferred();
110
118
 
119
+ // If using 7702, we need an Authorization (unless it's already authorized).
120
+ const authorizationRequest = delegation
121
+ ? await createAuthorization(client, {
122
+ address: account.address,
123
+ delegation,
124
+ })
125
+ : undefined;
126
+
127
+ const signatureRequest = {
128
+ type: "eth_signTypedData_v4" as const,
129
+ data: typedData,
130
+ };
131
+
111
132
  return {
112
133
  sessionId: null, // In remote mode, the server will set this later.
113
134
  entityId: toHex(entityId),
114
135
  signatureRequest: {
115
- type: "eth_signTypedData_v4",
116
- data: typedData,
136
+ ...signatureRequest,
137
+ ...(authorizationRequest ? { authorizationRequest } : {}),
117
138
  },
118
139
  fullPreSignatureDeferredActionDigest,
119
140
  };
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  deepHexlify,
3
+ default7702GasEstimator,
3
4
  type SmartAccountClient,
4
5
  type SmartContractAccount,
5
6
  } from "@aa-sdk/core";
@@ -9,7 +10,6 @@ import {
9
10
  custom,
10
11
  fromHex,
11
12
  toHex,
12
- zeroAddress,
13
13
  type Chain,
14
14
  type Transport,
15
15
  } from "viem";
@@ -17,6 +17,8 @@ import type { wallet_prepareCalls } from "../../rpc/request.js";
17
17
  import type { WalletServerViemRpcSchema } from "../../rpc/schema.js";
18
18
  import { createAccount } from "../utils/createAccount.js";
19
19
  import { createDummySigner } from "../utils/createDummySigner.js";
20
+ import { createAuthorization } from "../utils/7702.js";
21
+ import { InvalidRequestError } from "ox/RpcResponse";
20
22
 
21
23
  export type PrepareCallsParams = Omit<
22
24
  Static<
@@ -29,7 +31,6 @@ export type PrepareCallsResult = Static<
29
31
  (typeof wallet_prepareCalls)["properties"]["ReturnType"]
30
32
  >;
31
33
 
32
- // TODO: handle capabilities like permissions and paymaster here
33
34
  export async function prepareCalls(
34
35
  client: SmartAccountClient<
35
36
  Transport,
@@ -45,7 +46,7 @@ export async function prepareCalls(
45
46
  }
46
47
 
47
48
  // in local mode, we probably want some kind of caching for this
48
- const { counterfactualInfo } = await client.request({
49
+ const { counterfactualInfo, delegation } = await client.request({
49
50
  method: "wallet_requestAccount",
50
51
  params: [
51
52
  {
@@ -54,19 +55,37 @@ export async function prepareCalls(
54
55
  },
55
56
  ],
56
57
  });
57
- if (!counterfactualInfo) {
58
- throw new Error("No counterfactual info found.");
58
+
59
+ if (!counterfactualInfo && !delegation) {
60
+ throw new InvalidRequestError({
61
+ message:
62
+ "No counterfactual info or delegated implementation address found.",
63
+ });
59
64
  }
60
65
 
61
66
  const account = await createAccount({
62
67
  chain: client.chain,
63
68
  transport: custom(client.transport),
64
- signer: createDummySigner(zeroAddress),
69
+ signer: createDummySigner(params.from),
65
70
  accountAddress: params.from,
66
71
  counterfactualInfo,
67
72
  capabilities: params.capabilities,
73
+ delegation,
68
74
  });
69
75
 
76
+ // If using 7702, we need an Authorization (unless it's already authorized).
77
+ const authorizationRequest = delegation
78
+ ? await createAuthorization(client, {
79
+ address: account.address,
80
+ delegation,
81
+ })
82
+ : undefined;
83
+
84
+ if (authorizationRequest) {
85
+ // @ts-expect-error - this is available but not typed as public
86
+ client.middleware.gasEstimator = default7702GasEstimator();
87
+ }
88
+
70
89
  // TODO: oops we don't actually support setting the policyId as an override here
71
90
  // if we assume that the the isomorphic client is never used directly, then we can assume that this is handled upstream correctly
72
91
  const builtUo = await client.buildUserOperation({
@@ -79,9 +98,19 @@ export async function prepareCalls(
79
98
  overrides: params.capabilities?.gasParamsOverride,
80
99
  });
81
100
 
101
+ // The eip7702Auth field should never be included in the UO sig
102
+ // request. It's handled by the separate authorization request.
103
+ if ("eip7702Auth" in builtUo) {
104
+ builtUo.eip7702Auth = undefined;
105
+ }
82
106
  const uoRequest = deepHexlify(builtUo);
83
107
 
84
- const hash = account.getEntryPoint().getUserOperationHash(uoRequest);
108
+ const signatureRequest = {
109
+ type: "personal_sign" as const,
110
+ data: {
111
+ raw: account.getEntryPoint().getUserOperationHash(uoRequest),
112
+ },
113
+ };
85
114
 
86
115
  return {
87
116
  type:
@@ -91,10 +120,8 @@ export async function prepareCalls(
91
120
  data: uoRequest,
92
121
  chainId: toHex(client.chain.id),
93
122
  signatureRequest: {
94
- type: "personal_sign",
95
- data: {
96
- raw: hash,
97
- },
123
+ ...signatureRequest,
124
+ ...(authorizationRequest ? { authorizationRequest } : {}),
98
125
  },
99
126
  };
100
127
  }