@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
@@ -24,7 +24,7 @@ const Permission = <
24
24
  type: Type.Literal(typeEnum),
25
25
  data,
26
26
  },
27
- { description },
27
+ { description, title: `${typeString}` },
28
28
  ),
29
29
  )
30
30
  .Decode((value) => ({
@@ -124,19 +124,35 @@ export const TypePermission = Type.Union([
124
124
 
125
125
  export const PermissionsArray = Type.Array(TypePermission, { minItems: 1 });
126
126
 
127
- export const PermissionsContext = Type.Object({
128
- context: TypeHex(),
129
- });
127
+ export const PermissionsContext = Type.Object(
128
+ {
129
+ context: TypeHex(),
130
+ },
131
+ {
132
+ title: "Permissions context",
133
+ },
134
+ );
135
+
136
+ export const RemotePermission = Type.Object(
137
+ {
138
+ sessionId: TypeHex(),
139
+ signature: TypeHex(),
140
+ },
141
+ {
142
+ title: "Remote permission",
143
+ },
144
+ );
130
145
 
131
146
  export const PermissionsData = Type.Object({
132
147
  chainId: TypeHex(),
133
- expiry: Type.Optional(Type.Number()),
148
+ expiry: Type.Optional(Type.Integer()),
134
149
  key: KeySigner,
135
150
  permissions: PermissionsArray,
136
151
  });
137
152
 
138
153
  export const PermissionsCapability = Type.Union([
139
154
  PermissionsContext,
155
+ RemotePermission,
140
156
  // TODO: support permissions object here instead of only context-encoded permissions
141
157
  // PermissionsData,
142
158
  ]);
@@ -1,9 +1,9 @@
1
1
  import { PermissionType } from "@account-kit/smart-contracts/experimental";
2
2
  import type { Static } from "@sinclair/typebox";
3
3
  import { concatHex, sliceHex, type Hex } from "viem";
4
- import type { PermissionsData } from ".";
5
- import type { KeySigner } from "../../schemas";
4
+ import type { KeySigner } from "../../schemas.ts";
6
5
  import { assertNever } from "../../utils.js";
6
+ import type { PermissionsCapability, PermissionsData } from "./index.ts";
7
7
 
8
8
  export const SESSION_ID_LENGTH_BYTES = 16;
9
9
  export const ENTITY_ID_LENGTH_BYTES = 4;
@@ -69,8 +69,18 @@ export const encodePermissionsContext = (
69
69
  };
70
70
 
71
71
  export const decodePermissionsContext = (
72
- input: Hex,
72
+ capability: Static<typeof PermissionsCapability>,
73
73
  ): DecodedPermissionsContext => {
74
+ if (!("context" in capability)) {
75
+ return {
76
+ contextVersion: "REMOTE_MODE_DEFERRED_ACTION",
77
+ sessionId: capability.sessionId,
78
+ signature: capability.signature,
79
+ };
80
+ }
81
+
82
+ const input = capability.context;
83
+
74
84
  const contextVersion = sliceHex(input, 0, 1) as ContextVersionHex;
75
85
  switch (contextVersion) {
76
86
  case "0x00": {
@@ -1,8 +1,8 @@
1
1
  import type { SmartAccountSigner } from "@aa-sdk/core";
2
2
  import type { Static } from "@sinclair/typebox";
3
3
  import type { Address } from "abitype";
4
- import type { wallet_createAccount } from "../../rpc/request";
5
- import type { InnerWalletApiClient } from "../../types";
4
+ import type { wallet_createAccount } from "../../rpc/request.ts";
5
+ import type { InnerWalletApiClient } from "../../types.ts";
6
6
 
7
7
  export type CreateAccountParams = Omit<
8
8
  Extract<
@@ -16,6 +16,31 @@ export type CreateAccountResult = Static<
16
16
  typeof wallet_createAccount
17
17
  >["ReturnType"];
18
18
 
19
+ /**
20
+ * Creates a new account for the provided signer using the wallet API client.
21
+ * This method is primarily used to import existing accounts.
22
+ * For most cases, you should use requestAccount instead.
23
+ * If the account already exists, an error will be thrown.
24
+ *
25
+ * @param {InnerWalletApiClient} client - The wallet API client to use for the request
26
+ * @param {SmartAccountSigner} signer - The signer that will be associated with the account
27
+ * @param {CreateAccountParams} params - Parameters for creating the account
28
+ * @param {string} [params.id] - Optional UUID v4 identifier for the account
29
+ * @param {object} params.creationOptions - Options for account creation
30
+ * @param {string} [params.creationOptions.accountType] - Currently only "sma-b" (Modular Account v2) is supported
31
+ * @param {string} [params.creationOptions.salt] - Optional hex string to use as salt for account creation
32
+ * @returns {Promise<CreateAccountResult>} A Promise that resolves to the created account information
33
+ *
34
+ * @example
35
+ * // Create a new account with a custom salt
36
+ * const account = await client.createAccount({
37
+ * creationOptions: {
38
+ * accountType: "sma-b",
39
+ * salt: "0x04"
40
+ * }
41
+ * });
42
+ * console.log(`Created account at address: ${account.accountAddress}`);
43
+ */
19
44
  export async function createAccount(
20
45
  client: InnerWalletApiClient,
21
46
  signer: SmartAccountSigner,
@@ -2,13 +2,32 @@ import type { Address, JsonRpcAccount } from "viem";
2
2
  import type {
3
3
  GetCallsStatusParams as IsomorphicGetCallsStatusParams,
4
4
  GetCallsStatusResponse as IsomorphicGetCallsStatusResult,
5
- } from "../../isomorphic/actions/getCallsStatus";
6
- import type { InnerWalletApiClient } from "../../types";
5
+ } from "../../isomorphic/actions/getCallsStatus.ts";
6
+ import type { InnerWalletApiClient } from "../../types.ts";
7
7
 
8
8
  export type GetCallsStatusParams = IsomorphicGetCallsStatusParams;
9
9
 
10
10
  export type GetCallsStatusResult = IsomorphicGetCallsStatusResult;
11
11
 
12
+ /**
13
+ * Gets the status of a prepared call by its ID.
14
+ * This method is used to check the execution status of calls sent via sendPreparedCalls.
15
+ *
16
+ * @param {InnerWalletApiClient} client - The wallet API client to use for the request
17
+ * @param {GetCallsStatusParams} params - The ID of the prepared call to check
18
+ * @returns {Promise<GetCallsStatusResult>} A Promise that resolves to the status information including:
19
+ * - id: The hex ID of the call
20
+ * - chainId: The chain ID in hex format
21
+ * - status: The current status of the batch execution
22
+ * - receipts: Optional array of transaction receipts if the batch has been executed
23
+ *
24
+ * @example
25
+ * // After sending prepared calls
26
+ * const sendResult = await client.sendPreparedCalls({...});
27
+ *
28
+ * // Check the status of the first call ID
29
+ * const status = await client.getCallsStatus(sendResult.preparedCallIds[0]);
30
+ */
12
31
  export async function getCallsStatus<
13
32
  TAccount extends JsonRpcAccount<Address> | undefined =
14
33
  | JsonRpcAccount<Address>
@@ -5,9 +5,11 @@ import {
5
5
  type JsonRpcAccount,
6
6
  toHex,
7
7
  } from "viem";
8
- import type { InnerWalletApiClient } from "../../types";
8
+ import type { InnerWalletApiClient } from "../../types.ts";
9
9
  import type { SmartAccountSigner } from "@aa-sdk/core";
10
- import type { CreateSessionParams } from "../../isomorphic/actions/createSession";
10
+ import type { CreateSessionParams } from "../../isomorphic/actions/createSession.ts";
11
+ import { TypeEip7702AuthExtendedFields } from "../../schemas.js";
12
+ import type { Static } from "@sinclair/typebox";
11
13
 
12
14
  export type GrantPermissionsParams<
13
15
  TAccount extends JsonRpcAccount<Address> | undefined =
@@ -20,8 +22,118 @@ export type GrantPermissionsParams<
20
22
 
21
23
  export type GrantPermissionsResult = {
22
24
  context: Hex;
25
+ signedAuthorization?: Static<typeof TypeEip7702AuthExtendedFields>;
23
26
  };
24
27
 
28
+ /**
29
+ * Grants permissions to a smart account by creating a session.
30
+ * This allows another key to perform operations on behalf of the account.
31
+ *
32
+ * @param {InnerWalletApiClient} client - The wallet API client to use for the request
33
+ * @param {SmartAccountSigner} signer - The signer of the smart account
34
+ * @param {GrantPermissionsParams} params - The parameters for granting permissions
35
+ * @param {Address} [params.account] - The account address (required if client was not initialized with an account)
36
+ * @param {number} params.expiry - Unix timestamp when the permissions expire
37
+ * @param {object} params.key - The session key information
38
+ * @param {string} params.key.publicKey - The public key of the session key
39
+ * @param {string} params.key.type - The type of the key (e.g., "secp256k1")
40
+ * @param {Array} params.permissions - Array of permission objects defining what the session key can do
41
+ * @returns {Promise<GrantPermissionsResult>} A Promise that resolves to the result containing a context identifier
42
+ * @returns {Hex} result.context - A hex identifier for the granted permissions context
43
+ * @returns {Static<typeof TypeEip7702AuthExtendedFields>} result.signedAuthorization - The EIP-7702 authorization fields, if applicable
44
+ *
45
+ * @example
46
+ * // Create a session key and grant root permissions
47
+ * const sessionKey = LocalAccountSigner.generatePrivateKeySigner();
48
+ * const account = await client.requestAccount();
49
+ *
50
+ * const permissions = await client.grantPermissions({
51
+ * account: account.address,
52
+ * expiry: Math.floor(Date.now() / 1000) + 60 * 60, // 1 hour from now
53
+ * key: {
54
+ * publicKey: await sessionKey.getAddress(),
55
+ * type: "secp256k1",
56
+ * },
57
+ * permissions: [{ type: "root" }],
58
+ * });
59
+ *
60
+ * // Use the permissions to prepare a call
61
+ * const preparedCall = await client.prepareCalls({
62
+ * calls: [{ to: zeroAddress, value: "0x0" }],
63
+ * from: account.address,
64
+ * capabilities: {
65
+ * paymasterService: {
66
+ * policyId: "your-paymaster-policy-id",
67
+ * },
68
+ * permissions,
69
+ * },
70
+ * });
71
+ *
72
+ * // Sign with the session key
73
+ * const signature = await signSignatureRequest(
74
+ * sessionKey,
75
+ * preparedCall.signatureRequest,
76
+ * );
77
+ *
78
+ * // Send the prepared call using the session key
79
+ * const result = await client.sendPreparedCalls({
80
+ * ...preparedCall,
81
+ * signature,
82
+ * capabilities: {
83
+ * permissions,
84
+ * },
85
+ * });
86
+ *
87
+ * @example
88
+ * // Create a session key and grant root permissions using a 7702 account
89
+ * const sessionKey = LocalAccountSigner.generatePrivateKeySigner();
90
+ * const account = await client.requestAccount({
91
+ * creationHint: {
92
+ * accountType: "7702",
93
+ * }
94
+ * });
95
+ *
96
+ * const permissions = await client.grantPermissions({
97
+ * account: account.address,
98
+ * expiry: Math.floor(Date.now() / 1000) + 60 * 60, // 1 hour from now
99
+ * key: {
100
+ * publicKey: await sessionKey.getAddress(),
101
+ * type: "secp256k1",
102
+ * },
103
+ * permissions: [{ type: "root" }],
104
+ * });
105
+ *
106
+ * // Use the permissions to prepare a call
107
+ * const preparedCall = await client.prepareCalls({
108
+ * calls: [{ to: zeroAddress, value: "0x0" }],
109
+ * from: account.address,
110
+ * capabilities: {
111
+ * paymasterService: {
112
+ * policyId: "your-paymaster-policy-id",
113
+ * },
114
+ * permissions,
115
+ * },
116
+ * });
117
+ *
118
+ * // Sign with the session key
119
+ * // If the 7702 account delegation is not yet installed, the result
120
+ * // here will include a `signedAuthorization` field that that
121
+ * // must be included when sending the account's first call.
122
+ * const { signedAuthorization, ...signature} = await signSignatureRequest(
123
+ * sessionKey,
124
+ * preparedCall.signatureRequest,
125
+ * );
126
+ *
127
+ * // Send the prepared call using the session key
128
+ * const result = await client.sendPreparedCalls({
129
+ * ...preparedCall,
130
+ * signature,
131
+ * signedAuthorization,
132
+ * capabilities: {
133
+ * permissions,
134
+ * },
135
+ * });
136
+ */
25
137
  export async function grantPermissions<
26
138
  TAccount extends JsonRpcAccount<Address> | undefined =
27
139
  | JsonRpcAccount<Address>
@@ -1,6 +1,6 @@
1
1
  import type { Static } from "@sinclair/typebox";
2
- import type { wallet_listAccounts } from "../../rpc/request";
3
- import type { InnerWalletApiClient } from "../../types";
2
+ import type { wallet_listAccounts } from "../../rpc/request.ts";
3
+ import type { InnerWalletApiClient } from "../../types.ts";
4
4
 
5
5
  export type ListAccountsParams = Static<
6
6
  typeof wallet_listAccounts
@@ -10,6 +10,30 @@ export type ListAccountsResult = Static<
10
10
  typeof wallet_listAccounts
11
11
  >["ReturnType"];
12
12
 
13
+ /**
14
+ * Lists all smart accounts for a given signer using the wallet API client.
15
+ *
16
+ * @param {InnerWalletApiClient} client - The wallet API client to use for the request
17
+ * @param {ListAccountsParams} params - Parameters for listing accounts
18
+ * @param {string} params.signerAddress - The address of the signer to list accounts for
19
+ * @param {number} [params.limit] - Optional maximum number of accounts to return (default: 100, max: 100)
20
+ * @param {string} [params.after] - Optional pagination cursor for fetching subsequent pages
21
+ * @returns {Promise<ListAccountsResult>} A Promise that resolves to the list of accounts and pagination metadata
22
+ *
23
+ * @example
24
+ * // Fetch the first page of accounts
25
+ * const firstPage = await client.listAccounts({
26
+ * signerAddress: "0x123...",
27
+ * limit: 10
28
+ * });
29
+ *
30
+ * // If an 'after' cursor exists, use it to fetch the next page
31
+ * const nextPage = await client.listAccounts({
32
+ * signerAddress: "0x123...",
33
+ * limit: 10,
34
+ * after: firstPage.meta.after
35
+ * });
36
+ */
13
37
  export async function listAccounts(
14
38
  client: InnerWalletApiClient,
15
39
  params: ListAccountsParams,
@@ -7,8 +7,8 @@ import {
7
7
  import type {
8
8
  PrepareCallsParams as IsomorphicPrepareCallsParams,
9
9
  PrepareCallsResult as IsomorphicPrepareCallsResult,
10
- } from "../../isomorphic/actions/prepareCalls";
11
- import type { InnerWalletApiClient } from "../../types";
10
+ } from "../../isomorphic/actions/prepareCalls.ts";
11
+ import type { InnerWalletApiClient } from "../../types.ts";
12
12
 
13
13
  export type GetAccountParam<TAccount> =
14
14
  IsUndefined<TAccount> extends true
@@ -24,6 +24,32 @@ export type PrepareCallsParams<
24
24
 
25
25
  export type PrepareCallsResult = IsomorphicPrepareCallsResult;
26
26
 
27
+ /**
28
+ * Prepares a set of contract calls for execution by building a user operation.
29
+ * Returns the built user operation and a signature request that needs to be signed
30
+ * before submitting to sendPreparedCalls.
31
+ *
32
+ * @param {InnerWalletApiClient<TAccount>} client - The wallet API client to use for the request
33
+ * @param {PrepareCallsParams<TAccount>} params - Parameters for preparing calls
34
+ * @param {Array<{to: Address, data?: Hex, value?: Hex}>} params.calls - Array of contract calls to execute
35
+ * @param {Address} [params.from] - The address to execute the calls from (required if the client wasn't initialized with an account)
36
+ * @param {object} [params.capabilities] - Optional capabilities to include with the request
37
+ * @returns {Promise<PrepareCallsResult>} A Promise that resolves to the prepared calls result containing
38
+ * the user operation data and signature request
39
+ *
40
+ * @example
41
+ * // Prepare a sponosored user operation call
42
+ * const result = await client.prepareCalls({
43
+ * calls: [{
44
+ * to: "0x1234...",
45
+ * data: "0xabcdef...",
46
+ * value: "0x0"
47
+ * }],
48
+ * capabilities: {
49
+ * paymasterService: { policyId: "your-policy-id" }
50
+ * }
51
+ * });
52
+ */
27
53
  export async function prepareCalls<
28
54
  TAccount extends JsonRpcAccount<Address> | undefined =
29
55
  | JsonRpcAccount<Address>
@@ -1,4 +1,7 @@
1
- import type { SmartAccountSigner, SmartContractAccount } from "@aa-sdk/core";
1
+ import {
2
+ type SmartAccountSigner,
3
+ type SmartContractAccount,
4
+ } from "@aa-sdk/core";
2
5
  import type { Static } from "@sinclair/typebox";
3
6
  import { Value } from "@sinclair/typebox/value";
4
7
  import type { Address } from "abitype";
@@ -7,6 +10,7 @@ import { createAccount } from "../../isomorphic/utils/createAccount.js";
7
10
  import type { wallet_requestAccount } from "../../rpc/request.js";
8
11
  import { TypeSerializedInitcode } from "../../schemas.js";
9
12
  import type { InnerWalletApiClient } from "../../types.js";
13
+ import deepEqual from "deep-equal";
10
14
 
11
15
  export type RequestAccountParams<
12
16
  TAccount extends JsonRpcAccount<Address> | undefined =
@@ -20,12 +24,28 @@ export type RequestAccountParams<
20
24
  { signerAddress: Address }
21
25
  >,
22
26
  "signerAddress" | "includeCounterfactualInfo"
23
- >
27
+ > & { accountAddress?: Address }
24
28
  : never;
25
29
 
26
- // TODO: this could be more specific potentially :shrug:
27
30
  export type RequestAccountResult = SmartContractAccount;
28
31
 
32
+ /**
33
+ * Requests an account for the provided signer using the wallet API client.
34
+ * If an account already exists for the signer, it will always return that account unless a new ID is specified.
35
+ * If an account already exists, the creationHint will be ignored.
36
+ *
37
+ * @param {InnerWalletApiClient} client - The wallet API client to use for the request
38
+ * @param {SmartAccountSigner} signer - The signer that will be associated with the account
39
+ * @param {RequestAccountParams} [params] - Optional parameters for requesting a specific account
40
+ * @param {string} [params.id] - Optional identifier for the account. If specified, a new account with this ID will be created even if one already exists for the signer
41
+ * @param {object} [params.creationHint] - Optional hints to guide account creation. These are ignored if an account already exists
42
+ * @returns {Promise<RequestAccountResult>} A Promise that resolves to a SmartContractAccount instance
43
+ *
44
+ * @example
45
+ * // Request an account with default parameters using a local signer
46
+ * const signer = LocalAccountSigner.privateKeyToAccountSigner("0x...");
47
+ * const account = await client.requestAccount(signer);
48
+ */
29
49
  export function requestAccount<
30
50
  TAccount extends JsonRpcAccount<Address> | undefined =
31
51
  | JsonRpcAccount<Address>
@@ -42,9 +62,9 @@ export async function requestAccount(
42
62
  params?: RequestAccountParams,
43
63
  ): Promise<RequestAccountResult> {
44
64
  const args =
45
- client.account && !params
65
+ (client.account && !params) || params?.accountAddress
46
66
  ? {
47
- accountAddress: client.account.address,
67
+ accountAddress: params?.accountAddress ?? client.account!.address,
48
68
  includeCounterfactualInfo: true,
49
69
  }
50
70
  : {
@@ -53,13 +73,23 @@ export async function requestAccount(
53
73
  includeCounterfactualInfo: true,
54
74
  };
55
75
 
76
+ const cachedAccount = client.internal.getAccount();
77
+ if (
78
+ cachedAccount &&
79
+ ((args.accountAddress &&
80
+ cachedAccount.account.address === args.accountAddress) ||
81
+ deepEqual(cachedAccount.requestParams, args, { strict: true }))
82
+ ) {
83
+ return cachedAccount.account;
84
+ }
85
+
56
86
  const { counterfactualInfo, accountAddress } = await client.request({
57
87
  method: "wallet_requestAccount",
58
88
  params: [args],
59
89
  });
60
90
 
61
- return createAccount({
62
- accountAddress: accountAddress,
91
+ const account = await createAccount({
92
+ accountAddress,
63
93
  counterfactualInfo: Value.Parse(
64
94
  TypeSerializedInitcode,
65
95
  counterfactualInfo!,
@@ -68,4 +98,8 @@ export async function requestAccount(
68
98
  transport: custom(client.transport),
69
99
  signer,
70
100
  });
101
+
102
+ client.internal.setAccount({ account, requestParams: args });
103
+
104
+ return account;
71
105
  }
@@ -1,7 +1,7 @@
1
1
  import type { Static, StaticDecode } from "@sinclair/typebox";
2
2
  import { toHex } from "viem";
3
- import type { wallet_sendPreparedCalls } from "../../rpc/request";
4
- import type { InnerWalletApiClient } from "../../types";
3
+ import type { wallet_sendPreparedCalls } from "../../rpc/request.ts";
4
+ import type { InnerWalletApiClient } from "../../types.ts";
5
5
 
6
6
  export type SendPreparedCallsParams = Omit<
7
7
  StaticDecode<typeof wallet_sendPreparedCalls>["Request"]["params"][0],
@@ -12,6 +12,43 @@ export type SendPreparedCallsResult = Static<
12
12
  typeof wallet_sendPreparedCalls
13
13
  >["ReturnType"];
14
14
 
15
+ /**
16
+ * Sends prepared calls by submitting a signed user operation.
17
+ * This method is used after signing the signature request returned from prepareCalls.
18
+ *
19
+ * @param {InnerWalletApiClient} client - The wallet API client to use for the request
20
+ * @param {SendPreparedCallsParams} params - Parameters for sending prepared calls
21
+ * @param {string} params.type - The user operation type ('user-operation-v060' or 'user-operation-v070')
22
+ * @param {object} params.data - The user operation data without signature
23
+ * @param {string} params.chainId - The chain ID in hex format
24
+ * @param {object} params.signature - The signature object
25
+ * @param {string} params.signature.type - The signature type (must be 'ecdsa')
26
+ * @param {string} params.signature.signature - The hex-encoded signature value
27
+ * @param {object} [params.capabilities] - Optional capabilities to include with the request
28
+ * @returns {Promise<SendPreparedCallsResult>} A Promise that resolves to the result containing the prepared call IDs
29
+ *
30
+ * @example
31
+ * // First prepare the calls
32
+ * const preparedCalls = await client.prepareCalls({
33
+ * calls: [{
34
+ * to: "0x1234...",
35
+ * data: "0xabcdef...",
36
+ * value: "0x0"
37
+ * }],
38
+ * capabilities: {
39
+ * paymasterService: { policyId: "your-policy-id" }
40
+ * }
41
+ * });
42
+ *
43
+ * // Sign the signature request using signSignatureRequest with your signer
44
+ * const signedRequest = await client.signSignatureRequest(preparedCalls.signatureRequest);
45
+ *
46
+ * // Then send the prepared calls with the signature
47
+ * const result = await client.sendPreparedCalls({
48
+ * ...preparedCalls,
49
+ * signature: signedRequest.signature,
50
+ * });
51
+ */
15
52
  export async function sendPreparedCalls(
16
53
  client: InnerWalletApiClient,
17
54
  params: SendPreparedCallsParams,
@@ -5,13 +5,30 @@ import {
5
5
  type JsonRpcAccount,
6
6
  type SignableMessage,
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 SignMessageParams = SignableMessage;
11
+ export type SignMessageParams = { message: SignableMessage; account?: Address };
12
12
 
13
13
  export type SignMessageResult = Hex;
14
14
 
15
+ /**
16
+ * Signs a message using the smart account.
17
+ * This method requests the account associated with the signer and uses it to sign the message.
18
+ *
19
+ * @param {InnerWalletApiClient} client - The wallet API client to use for the request
20
+ * @param {SmartAccountSigner} signer - The signer of the smart account
21
+ * @param {SignableMessage} message - The message to sign
22
+ * @returns {Promise<SignMessageResult>} A Promise that resolves to the signed message as a hex string
23
+ *
24
+ * @example
25
+ * // Sign a simple text message
26
+ * const signature = await client.signMessage("Hello, world!");
27
+ *
28
+ * @example
29
+ * // Sign a raw hex message
30
+ * const signature = await client.signMessage({ raw: "0x48656c6c6f2c20776f726c6421" });
31
+ */
15
32
  export async function signMessage<
16
33
  TAccount extends JsonRpcAccount<Address> | undefined =
17
34
  | JsonRpcAccount<Address>
@@ -27,6 +44,9 @@ export async function signMessage(
27
44
  signer: SmartAccountSigner,
28
45
  params: SignMessageParams,
29
46
  ): Promise<SignMessageResult> {
30
- const account = await requestAccount(client, signer);
31
- return account.signMessageWith6492({ message: params });
47
+ const account = await requestAccount(client, signer, {
48
+ accountAddress: params.account ?? client.account?.address,
49
+ });
50
+
51
+ return account.signMessageWith6492({ message: params.message });
32
52
  }
@@ -1,16 +1,50 @@
1
1
  import type { SmartAccountSigner } from "@aa-sdk/core";
2
2
  import type { Static } from "@sinclair/typebox";
3
- import { type Hex } from "viem";
3
+ import { type Hex, toHex } from "viem";
4
4
  import { TypeSignatureRequest } from "../../schemas.js";
5
5
  import { assertNever } from "../../utils.js";
6
+ import type { Eip7702ExtendedFields } from "@aa-sdk/core";
6
7
 
7
8
  export type SignSignatureRequestParams = Static<typeof TypeSignatureRequest>;
8
9
 
9
10
  export type SignSignatureRequestResult = {
10
11
  type: "ecdsa";
11
12
  signature: Hex;
13
+ signedAuthorization?: Eip7702ExtendedFields["eip7702Auth"];
12
14
  };
13
15
 
16
+ /**
17
+ * Signs a signature request using the provided signer.
18
+ * This method handles different types of signature requests including personal_sign and eth_signTypedData_v4.
19
+ *
20
+ * @param {SmartAccountSigner} signer - The signer to use for signing the request
21
+ * @param {SignSignatureRequestParams} params - The signature request parameters
22
+ * @param {string} params.type - The type of signature request ('personal_sign', 'eth_signTypedData_v4', or 'signature_with_authorization')
23
+ * @param {any} params.data - The data to sign, format depends on the signature type
24
+ * @returns {Promise<SignSignatureRequestResult>} A Promise that resolves to the signature result
25
+ * @returns {string} result.type - The signature type (currently only 'ecdsa' is supported)
26
+ * @returns {Hex} result.signature - The hex-encoded signature
27
+ * @returns {Eip7702ExtendedFields["eip7702Auth"]} result.signedAuthorization - The signed EIP-7702 authorization, if applicable
28
+ *
29
+ * @example
30
+ * // Sign a personal message
31
+ * const result = await client.signSignatureRequest({
32
+ * type: 'personal_sign',
33
+ * data: 'Hello, world!'
34
+ * });
35
+ *
36
+ * @example
37
+ * // Sign typed data (EIP-712)
38
+ * const result = await client.signSignatureRequest({
39
+ * type: 'eth_signTypedData_v4',
40
+ * data: {
41
+ * domain: { ... },
42
+ * types: { ... },
43
+ * primaryType: '...',
44
+ * message: { ... }
45
+ * }
46
+ * });
47
+ */
14
48
  export function signSignatureRequest(
15
49
  signer: SmartAccountSigner,
16
50
  params: SignSignatureRequestParams,
@@ -27,8 +61,33 @@ export async function signSignatureRequest(
27
61
  ? await signer.signTypedData(params.data)
28
62
  : assertNever(params, "Unexpected signature request type");
29
63
 
64
+ if (!params.authorizationRequest) {
65
+ return {
66
+ type: "ecdsa" as const,
67
+ signature,
68
+ };
69
+ }
70
+
71
+ if (!signer.signAuthorization) {
72
+ throw new Error("Signer does not implement signAuthorization");
73
+ }
74
+
75
+ const authSig = await signer.signAuthorization(params.authorizationRequest);
76
+ const { r, s } = authSig;
77
+ const yParity = toHex(authSig.yParity ?? authSig.v - 27n);
78
+
79
+ const signedAuthorization = {
80
+ chainId: toHex(params.authorizationRequest.chainId),
81
+ nonce: toHex(params.authorizationRequest.nonce),
82
+ address: params.authorizationRequest.address,
83
+ r,
84
+ s,
85
+ yParity,
86
+ };
87
+
30
88
  return {
31
- type: "ecdsa",
89
+ type: "ecdsa" as const,
32
90
  signature,
91
+ signedAuthorization,
33
92
  };
34
93
  }