zksync-sso 0.0.0-beta.1

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 (300) hide show
  1. package/.gitignore +5 -0
  2. package/.lintstagedrc.js +5 -0
  3. package/.npmignore +10 -0
  4. package/README.md +3 -0
  5. package/dist/_cjs/abi/Factory.js +197 -0
  6. package/dist/_cjs/abi/Factory.js.map +1 -0
  7. package/dist/_cjs/abi/SessionKeyModule.js +1104 -0
  8. package/dist/_cjs/abi/SessionKeyModule.js.map +1 -0
  9. package/dist/_cjs/client/actions/account.js +140 -0
  10. package/dist/_cjs/client/actions/account.js.map +1 -0
  11. package/dist/_cjs/client/actions/index.js +19 -0
  12. package/dist/_cjs/client/actions/index.js.map +1 -0
  13. package/dist/_cjs/client/actions/passkey.js +122 -0
  14. package/dist/_cjs/client/actions/passkey.js.map +1 -0
  15. package/dist/_cjs/client/actions/session.js +40 -0
  16. package/dist/_cjs/client/actions/session.js.map +1 -0
  17. package/dist/_cjs/client/clients/passkey.js +46 -0
  18. package/dist/_cjs/client/clients/passkey.js.map +1 -0
  19. package/dist/_cjs/client/clients/session.js +48 -0
  20. package/dist/_cjs/client/clients/session.js.map +1 -0
  21. package/dist/_cjs/client/decorators/index.js +19 -0
  22. package/dist/_cjs/client/decorators/index.js.map +1 -0
  23. package/dist/_cjs/client/decorators/passkey.js +15 -0
  24. package/dist/_cjs/client/decorators/passkey.js.map +1 -0
  25. package/dist/_cjs/client/decorators/session.js +7 -0
  26. package/dist/_cjs/client/decorators/session.js.map +1 -0
  27. package/dist/_cjs/client/decorators/session_wallet.js +32 -0
  28. package/dist/_cjs/client/decorators/session_wallet.js.map +1 -0
  29. package/dist/_cjs/client/index.js +22 -0
  30. package/dist/_cjs/client/index.js.map +1 -0
  31. package/dist/_cjs/client/passkey.js +20 -0
  32. package/dist/_cjs/client/passkey.js.map +1 -0
  33. package/dist/_cjs/client/smart-account.js +45 -0
  34. package/dist/_cjs/client/smart-account.js.map +1 -0
  35. package/dist/_cjs/client/utils/assertEip712Transaction.js +44 -0
  36. package/dist/_cjs/client/utils/assertEip712Transaction.js.map +1 -0
  37. package/dist/_cjs/client/utils/getEip712Domain.js +57 -0
  38. package/dist/_cjs/client/utils/getEip712Domain.js.map +1 -0
  39. package/dist/_cjs/client/utils/isEip712Transaction.js +16 -0
  40. package/dist/_cjs/client/utils/isEip712Transaction.js.map +1 -0
  41. package/dist/_cjs/client-auth-server/Signer.js +264 -0
  42. package/dist/_cjs/client-auth-server/Signer.js.map +1 -0
  43. package/dist/_cjs/client-auth-server/WalletProvider.js +107 -0
  44. package/dist/_cjs/client-auth-server/WalletProvider.js.map +1 -0
  45. package/dist/_cjs/client-auth-server/index.js +20 -0
  46. package/dist/_cjs/client-auth-server/index.js.map +1 -0
  47. package/dist/_cjs/client-auth-server/interface.js +3 -0
  48. package/dist/_cjs/client-auth-server/interface.js.map +1 -0
  49. package/dist/_cjs/client-auth-server/rpc.js +3 -0
  50. package/dist/_cjs/client-auth-server/rpc.js.map +1 -0
  51. package/dist/_cjs/client-auth-server/session.js +90 -0
  52. package/dist/_cjs/client-auth-server/session.js.map +1 -0
  53. package/dist/_cjs/communicator/PopupCommunicator.js +138 -0
  54. package/dist/_cjs/communicator/PopupCommunicator.js.map +1 -0
  55. package/dist/_cjs/communicator/index.js +6 -0
  56. package/dist/_cjs/communicator/index.js.map +1 -0
  57. package/dist/_cjs/communicator/interface.js +3 -0
  58. package/dist/_cjs/communicator/interface.js.map +1 -0
  59. package/dist/_cjs/connector/index.js +148 -0
  60. package/dist/_cjs/connector/index.js.map +1 -0
  61. package/dist/_cjs/errors/constants.js +97 -0
  62. package/dist/_cjs/errors/constants.js.map +1 -0
  63. package/dist/_cjs/errors/errors.js +122 -0
  64. package/dist/_cjs/errors/errors.js.map +1 -0
  65. package/dist/_cjs/errors/index.js +10 -0
  66. package/dist/_cjs/errors/index.js.map +1 -0
  67. package/dist/_cjs/errors/serialize.js +63 -0
  68. package/dist/_cjs/errors/serialize.js.map +1 -0
  69. package/dist/_cjs/errors/utils.js +95 -0
  70. package/dist/_cjs/errors/utils.js.map +1 -0
  71. package/dist/_cjs/index.js +6 -0
  72. package/dist/_cjs/index.js.map +1 -0
  73. package/dist/_cjs/package.json +1 -0
  74. package/dist/_cjs/utils/encoding.js +32 -0
  75. package/dist/_cjs/utils/encoding.js.map +1 -0
  76. package/dist/_cjs/utils/helpers.js +43 -0
  77. package/dist/_cjs/utils/helpers.js.map +1 -0
  78. package/dist/_cjs/utils/index.js +20 -0
  79. package/dist/_cjs/utils/index.js.map +1 -0
  80. package/dist/_cjs/utils/passkey.js +243 -0
  81. package/dist/_cjs/utils/passkey.js.map +1 -0
  82. package/dist/_cjs/utils/session.js +30 -0
  83. package/dist/_cjs/utils/session.js.map +1 -0
  84. package/dist/_cjs/utils/storage.js +93 -0
  85. package/dist/_cjs/utils/storage.js.map +1 -0
  86. package/dist/_cjs/version.js +5 -0
  87. package/dist/_cjs/version.js.map +1 -0
  88. package/dist/_esm/abi/Factory.js +194 -0
  89. package/dist/_esm/abi/Factory.js.map +1 -0
  90. package/dist/_esm/abi/SessionKeyModule.js +1101 -0
  91. package/dist/_esm/abi/SessionKeyModule.js.map +1 -0
  92. package/dist/_esm/client/actions/account.js +137 -0
  93. package/dist/_esm/client/actions/account.js.map +1 -0
  94. package/dist/_esm/client/actions/index.js +3 -0
  95. package/dist/_esm/client/actions/index.js.map +1 -0
  96. package/dist/_esm/client/actions/passkey.js +121 -0
  97. package/dist/_esm/client/actions/passkey.js.map +1 -0
  98. package/dist/_esm/client/actions/session.js +36 -0
  99. package/dist/_esm/client/actions/session.js.map +1 -0
  100. package/dist/_esm/client/clients/passkey.js +43 -0
  101. package/dist/_esm/client/clients/passkey.js.map +1 -0
  102. package/dist/_esm/client/clients/session.js +45 -0
  103. package/dist/_esm/client/clients/session.js.map +1 -0
  104. package/dist/_esm/client/decorators/index.js +3 -0
  105. package/dist/_esm/client/decorators/index.js.map +1 -0
  106. package/dist/_esm/client/decorators/passkey.js +13 -0
  107. package/dist/_esm/client/decorators/passkey.js.map +1 -0
  108. package/dist/_esm/client/decorators/session.js +5 -0
  109. package/dist/_esm/client/decorators/session.js.map +1 -0
  110. package/dist/_esm/client/decorators/session_wallet.js +171 -0
  111. package/dist/_esm/client/decorators/session_wallet.js.map +1 -0
  112. package/dist/_esm/client/index.js +3 -0
  113. package/dist/_esm/client/index.js.map +1 -0
  114. package/dist/_esm/client/passkey.js +4 -0
  115. package/dist/_esm/client/passkey.js.map +1 -0
  116. package/dist/_esm/client/smart-account.js +46 -0
  117. package/dist/_esm/client/smart-account.js.map +1 -0
  118. package/dist/_esm/client/utils/assertEip712Transaction.js +39 -0
  119. package/dist/_esm/client/utils/assertEip712Transaction.js.map +1 -0
  120. package/dist/_esm/client/utils/getEip712Domain.js +57 -0
  121. package/dist/_esm/client/utils/getEip712Domain.js.map +1 -0
  122. package/dist/_esm/client/utils/isEip712Transaction.js +13 -0
  123. package/dist/_esm/client/utils/isEip712Transaction.js.map +1 -0
  124. package/dist/_esm/client-auth-server/Signer.js +262 -0
  125. package/dist/_esm/client-auth-server/Signer.js.map +1 -0
  126. package/dist/_esm/client-auth-server/WalletProvider.js +104 -0
  127. package/dist/_esm/client-auth-server/WalletProvider.js.map +1 -0
  128. package/dist/_esm/client-auth-server/index.js +4 -0
  129. package/dist/_esm/client-auth-server/index.js.map +1 -0
  130. package/dist/_esm/client-auth-server/interface.js +2 -0
  131. package/dist/_esm/client-auth-server/interface.js.map +1 -0
  132. package/dist/_esm/client-auth-server/rpc.js +2 -0
  133. package/dist/_esm/client-auth-server/rpc.js.map +1 -0
  134. package/dist/_esm/client-auth-server/session.js +91 -0
  135. package/dist/_esm/client-auth-server/session.js.map +1 -0
  136. package/dist/_esm/communicator/PopupCommunicator.js +136 -0
  137. package/dist/_esm/communicator/PopupCommunicator.js.map +1 -0
  138. package/dist/_esm/communicator/index.js +2 -0
  139. package/dist/_esm/communicator/index.js.map +1 -0
  140. package/dist/_esm/communicator/interface.js +2 -0
  141. package/dist/_esm/communicator/interface.js.map +1 -0
  142. package/dist/_esm/connector/index.js +146 -0
  143. package/dist/_esm/connector/index.js.map +1 -0
  144. package/dist/_esm/errors/constants.js +94 -0
  145. package/dist/_esm/errors/constants.js.map +1 -0
  146. package/dist/_esm/errors/errors.js +124 -0
  147. package/dist/_esm/errors/errors.js.map +1 -0
  148. package/dist/_esm/errors/index.js +4 -0
  149. package/dist/_esm/errors/index.js.map +1 -0
  150. package/dist/_esm/errors/serialize.js +69 -0
  151. package/dist/_esm/errors/serialize.js.map +1 -0
  152. package/dist/_esm/errors/utils.js +101 -0
  153. package/dist/_esm/errors/utils.js.map +1 -0
  154. package/dist/_esm/index.js +2 -0
  155. package/dist/_esm/index.js.map +1 -0
  156. package/dist/_esm/package.json +1 -0
  157. package/dist/_esm/utils/encoding.js +26 -0
  158. package/dist/_esm/utils/encoding.js.map +1 -0
  159. package/dist/_esm/utils/helpers.js +40 -0
  160. package/dist/_esm/utils/helpers.js.map +1 -0
  161. package/dist/_esm/utils/index.js +4 -0
  162. package/dist/_esm/utils/index.js.map +1 -0
  163. package/dist/_esm/utils/passkey.js +294 -0
  164. package/dist/_esm/utils/passkey.js.map +1 -0
  165. package/dist/_esm/utils/session.js +31 -0
  166. package/dist/_esm/utils/session.js.map +1 -0
  167. package/dist/_esm/utils/storage.js +89 -0
  168. package/dist/_esm/utils/storage.js.map +1 -0
  169. package/dist/_esm/version.js +2 -0
  170. package/dist/_esm/version.js.map +1 -0
  171. package/dist/_types/abi/Factory.d.ts +149 -0
  172. package/dist/_types/abi/Factory.d.ts.map +1 -0
  173. package/dist/_types/abi/SessionKeyModule.d.ts +846 -0
  174. package/dist/_types/abi/SessionKeyModule.d.ts.map +1 -0
  175. package/dist/_types/client/actions/account.d.ts +38 -0
  176. package/dist/_types/client/actions/account.d.ts.map +1 -0
  177. package/dist/_types/client/actions/index.d.ts +3 -0
  178. package/dist/_types/client/actions/index.d.ts.map +1 -0
  179. package/dist/_types/client/actions/passkey.d.ts +45 -0
  180. package/dist/_types/client/actions/passkey.d.ts.map +1 -0
  181. package/dist/_types/client/actions/session.d.ts +14 -0
  182. package/dist/_types/client/actions/session.d.ts.map +1 -0
  183. package/dist/_types/client/clients/passkey.d.ts +32 -0
  184. package/dist/_types/client/clients/passkey.d.ts.map +1 -0
  185. package/dist/_types/client/clients/session.d.ts +26 -0
  186. package/dist/_types/client/clients/session.d.ts.map +1 -0
  187. package/dist/_types/client/decorators/index.d.ts +3 -0
  188. package/dist/_types/client/decorators/index.d.ts.map +1 -0
  189. package/dist/_types/client/decorators/passkey.d.ts +8 -0
  190. package/dist/_types/client/decorators/passkey.d.ts.map +1 -0
  191. package/dist/_types/client/decorators/session.d.ts +5 -0
  192. package/dist/_types/client/decorators/session.d.ts.map +1 -0
  193. package/dist/_types/client/decorators/session_wallet.d.ts +5 -0
  194. package/dist/_types/client/decorators/session_wallet.d.ts.map +1 -0
  195. package/dist/_types/client/index.d.ts +3 -0
  196. package/dist/_types/client/index.d.ts.map +1 -0
  197. package/dist/_types/client/passkey.d.ts +4 -0
  198. package/dist/_types/client/passkey.d.ts.map +1 -0
  199. package/dist/_types/client/smart-account.d.ts +24 -0
  200. package/dist/_types/client/smart-account.d.ts.map +1 -0
  201. package/dist/_types/client/utils/assertEip712Transaction.d.ts +11 -0
  202. package/dist/_types/client/utils/assertEip712Transaction.d.ts.map +1 -0
  203. package/dist/_types/client/utils/getEip712Domain.d.ts +3 -0
  204. package/dist/_types/client/utils/getEip712Domain.d.ts.map +1 -0
  205. package/dist/_types/client/utils/isEip712Transaction.d.ts +4 -0
  206. package/dist/_types/client/utils/isEip712Transaction.d.ts.map +1 -0
  207. package/dist/_types/client-auth-server/Signer.d.ts +52 -0
  208. package/dist/_types/client-auth-server/Signer.d.ts.map +1 -0
  209. package/dist/_types/client-auth-server/WalletProvider.d.ts +27 -0
  210. package/dist/_types/client-auth-server/WalletProvider.d.ts.map +1 -0
  211. package/dist/_types/client-auth-server/index.d.ts +4 -0
  212. package/dist/_types/client-auth-server/index.d.ts.map +1 -0
  213. package/dist/_types/client-auth-server/interface.d.ts +34 -0
  214. package/dist/_types/client-auth-server/interface.d.ts.map +1 -0
  215. package/dist/_types/client-auth-server/rpc.d.ts +55 -0
  216. package/dist/_types/client-auth-server/rpc.d.ts.map +1 -0
  217. package/dist/_types/client-auth-server/session.d.ts +45 -0
  218. package/dist/_types/client-auth-server/session.d.ts.map +1 -0
  219. package/dist/_types/communicator/PopupCommunicator.d.ts +20 -0
  220. package/dist/_types/communicator/PopupCommunicator.d.ts.map +1 -0
  221. package/dist/_types/communicator/index.d.ts +3 -0
  222. package/dist/_types/communicator/index.d.ts.map +1 -0
  223. package/dist/_types/communicator/interface.d.ts +16 -0
  224. package/dist/_types/communicator/interface.d.ts.map +1 -0
  225. package/dist/_types/connector/index.d.ts +8 -0
  226. package/dist/_types/connector/index.d.ts.map +1 -0
  227. package/dist/_types/errors/constants.d.ts +96 -0
  228. package/dist/_types/errors/constants.d.ts.map +1 -0
  229. package/dist/_types/errors/errors.d.ts +48 -0
  230. package/dist/_types/errors/errors.d.ts.map +1 -0
  231. package/dist/_types/errors/index.d.ts +5 -0
  232. package/dist/_types/errors/index.d.ts.map +1 -0
  233. package/dist/_types/errors/serialize.d.ts +13 -0
  234. package/dist/_types/errors/serialize.d.ts.map +1 -0
  235. package/dist/_types/errors/utils.d.ts +30 -0
  236. package/dist/_types/errors/utils.d.ts.map +1 -0
  237. package/dist/_types/index.d.ts +4 -0
  238. package/dist/_types/index.d.ts.map +1 -0
  239. package/dist/_types/utils/encoding.d.ts +12 -0
  240. package/dist/_types/utils/encoding.d.ts.map +1 -0
  241. package/dist/_types/utils/helpers.d.ts +4 -0
  242. package/dist/_types/utils/helpers.d.ts.map +1 -0
  243. package/dist/_types/utils/index.d.ts +4 -0
  244. package/dist/_types/utils/index.d.ts.map +1 -0
  245. package/dist/_types/utils/passkey.d.ts +47 -0
  246. package/dist/_types/utils/passkey.d.ts.map +1 -0
  247. package/dist/_types/utils/session.d.ts +95 -0
  248. package/dist/_types/utils/session.d.ts.map +1 -0
  249. package/dist/_types/utils/storage.d.ts +30 -0
  250. package/dist/_types/utils/storage.d.ts.map +1 -0
  251. package/dist/_types/version.d.ts +2 -0
  252. package/dist/_types/version.d.ts.map +1 -0
  253. package/eslint.config.js +6 -0
  254. package/package.json +144 -0
  255. package/prepare-package.mjs +39 -0
  256. package/project.json +67 -0
  257. package/src/abi/Factory.ts +193 -0
  258. package/src/abi/SessionKeyModule.ts +1100 -0
  259. package/src/client/actions/account.ts +198 -0
  260. package/src/client/actions/index.ts +2 -0
  261. package/src/client/actions/passkey.ts +165 -0
  262. package/src/client/actions/session.ts +118 -0
  263. package/src/client/clients/passkey.ts +107 -0
  264. package/src/client/clients/session.ts +105 -0
  265. package/src/client/decorators/index.ts +2 -0
  266. package/src/client/decorators/passkey.ts +22 -0
  267. package/src/client/decorators/session.ts +17 -0
  268. package/src/client/decorators/session_wallet.ts +184 -0
  269. package/src/client/index.ts +2 -0
  270. package/src/client/passkey.ts +3 -0
  271. package/src/client/smart-account.ts +68 -0
  272. package/src/client/utils/assertEip712Transaction.ts +49 -0
  273. package/src/client/utils/getEip712Domain.ts +84 -0
  274. package/src/client/utils/isEip712Transaction.ts +18 -0
  275. package/src/client-auth-server/Signer.ts +260 -0
  276. package/src/client-auth-server/WalletProvider.ts +114 -0
  277. package/src/client-auth-server/index.ts +3 -0
  278. package/src/client-auth-server/interface.ts +39 -0
  279. package/src/client-auth-server/rpc.ts +69 -0
  280. package/src/client-auth-server/session.ts +139 -0
  281. package/src/communicator/PopupCommunicator.ts +111 -0
  282. package/src/communicator/index.ts +2 -0
  283. package/src/communicator/interface.ts +15 -0
  284. package/src/connector/index.ts +171 -0
  285. package/src/errors/constants.ts +119 -0
  286. package/src/errors/errors.ts +168 -0
  287. package/src/errors/index.ts +4 -0
  288. package/src/errors/serialize.ts +91 -0
  289. package/src/errors/utils.ts +152 -0
  290. package/src/index.ts +3 -0
  291. package/src/types/index.d.ts +9 -0
  292. package/src/utils/encoding.ts +36 -0
  293. package/src/utils/helpers.ts +43 -0
  294. package/src/utils/index.ts +3 -0
  295. package/src/utils/passkey.ts +344 -0
  296. package/src/utils/session.ts +103 -0
  297. package/src/utils/storage.ts +87 -0
  298. package/src/version.ts +1 -0
  299. package/tsconfig.base.json +44 -0
  300. package/tsconfig.json +11 -0
@@ -0,0 +1,105 @@
1
+ import { type Account, type Address, type Chain, type Client, createClient, encodeAbiParameters, getAddress, type Hash, type Prettify, publicActions, type PublicRpcSchema, type RpcSchema, type Transport, type WalletClientConfig, type WalletRpcSchema } from "viem";
2
+ import { privateKeyToAccount } from "viem/accounts";
3
+
4
+ import { encodeSession } from "../../utils/encoding.js";
5
+ import type { SessionConfig } from "../../utils/session.js";
6
+ import { type ZksyncSsoSessionActions, zksyncSsoSessionActions } from "../decorators/session.js";
7
+ import { type ZksyncSsoWalletActions, zksyncSsoWalletActions } from "../decorators/session_wallet.js";
8
+ import { toSmartAccount } from "../smart-account.js";
9
+
10
+ export function createZksyncSessionClient<
11
+ transport extends Transport,
12
+ chain extends Chain,
13
+ rpcSchema extends RpcSchema | undefined = undefined,
14
+ >(_parameters: ZksyncSsoSessionClientConfig<transport, chain, rpcSchema>): ZksyncSsoSessionClient<transport, chain, rpcSchema> {
15
+ type WalletClientParameters = typeof _parameters;
16
+ const parameters: WalletClientParameters & {
17
+ key: NonNullable<WalletClientParameters["key"]>;
18
+ name: NonNullable<WalletClientParameters["name"]>;
19
+ } = {
20
+ ..._parameters,
21
+ address: getAddress(_parameters.address),
22
+ key: _parameters.key || "wallet",
23
+ name: _parameters.name || "ZKsync SSO Session Client",
24
+ };
25
+
26
+ const account = toSmartAccount({
27
+ address: parameters.address,
28
+ sign: async ({ hash }) => {
29
+ const sessionKeySigner = privateKeyToAccount(parameters.sessionKey);
30
+ const hashSignature = await sessionKeySigner.sign({ hash });
31
+ return encodeAbiParameters(
32
+ [
33
+ { type: "bytes" },
34
+ { type: "address" },
35
+ { type: "bytes[]" },
36
+ ],
37
+ [
38
+ hashSignature,
39
+ parameters.contracts.session,
40
+ [encodeSession(parameters.sessionConfig)], // FIXME: this is assuming there are no other hooks
41
+ ],
42
+ );
43
+ },
44
+ });
45
+ const client = createClient<transport, chain, Account, rpcSchema>({
46
+ ...parameters,
47
+ account,
48
+ type: "walletClient",
49
+ })
50
+ .extend(() => ({
51
+ sessionKey: parameters.sessionKey,
52
+ sessionConfig: parameters.sessionConfig,
53
+ contracts: parameters.contracts,
54
+ }))
55
+ .extend(publicActions)
56
+ .extend(zksyncSsoWalletActions)
57
+ .extend(zksyncSsoSessionActions);
58
+ return client;
59
+ }
60
+
61
+ export type SessionRequiredContracts = {
62
+ session: Address; // Session, spend limit, etc.
63
+ };
64
+ type ZksyncSsoSessionData = {
65
+ sessionKey: Hash;
66
+ sessionConfig: SessionConfig;
67
+ contracts: SessionRequiredContracts;
68
+ };
69
+
70
+ export type ClientWithZksyncSsoSessionData<
71
+ transport extends Transport = Transport,
72
+ chain extends Chain = Chain,
73
+ account extends Account = Account,
74
+ > = Client<transport, chain, account> & ZksyncSsoSessionData;
75
+
76
+ export type ZksyncSsoSessionClient<
77
+ transport extends Transport = Transport,
78
+ chain extends Chain = Chain,
79
+ rpcSchema extends RpcSchema | undefined = undefined,
80
+ account extends Account = Account,
81
+ > = Prettify<
82
+ Client<
83
+ transport,
84
+ chain,
85
+ account,
86
+ rpcSchema extends RpcSchema
87
+ ? [...PublicRpcSchema, ...WalletRpcSchema, ...rpcSchema]
88
+ : [...PublicRpcSchema, ...WalletRpcSchema],
89
+ ZksyncSsoWalletActions<chain, account> & ZksyncSsoSessionActions
90
+ > & ZksyncSsoSessionData
91
+ >;
92
+
93
+ export interface ZksyncSsoSessionClientConfig<
94
+ transport extends Transport = Transport,
95
+ chain extends Chain = Chain,
96
+ rpcSchema extends RpcSchema | undefined = undefined,
97
+ > extends Omit<WalletClientConfig<transport, chain, Account, rpcSchema>, "account"> {
98
+ chain: NonNullable<chain>;
99
+ address: Address;
100
+ sessionKey: Hash;
101
+ sessionConfig: SessionConfig;
102
+ contracts: SessionRequiredContracts;
103
+ key?: string;
104
+ name?: string;
105
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./session.js";
2
+ export * from "./session_wallet.js";
@@ -0,0 +1,22 @@
1
+ import { type Chain, type Transport } from "viem";
2
+
3
+ import { createSession, type CreateSessionArgs, type CreateSessionReturnType } from "../actions/session.js";
4
+ import type { ClientWithZksyncSsoPasskeyData } from "../clients/passkey.js";
5
+
6
+ export type ZksyncSsoPasskeyActions = {
7
+ createSession: (args: Omit<CreateSessionArgs, "contracts">) => Promise<CreateSessionReturnType>;
8
+ };
9
+
10
+ export function zksyncSsoPasskeyActions<
11
+ transport extends Transport,
12
+ chain extends Chain,
13
+ >(client: ClientWithZksyncSsoPasskeyData<transport, chain>): ZksyncSsoPasskeyActions {
14
+ return {
15
+ createSession: async (args: Omit<CreateSessionArgs, "contracts">) => {
16
+ return await createSession(client, {
17
+ ...args,
18
+ contracts: client.contracts,
19
+ });
20
+ },
21
+ };
22
+ }
@@ -0,0 +1,17 @@
1
+ import { type Account, type Chain, type Transport } from "viem";
2
+
3
+ import type { ClientWithZksyncSsoSessionData } from "../clients/session.js";
4
+
5
+ /* eslint-disable @typescript-eslint/no-empty-object-type */
6
+ export type ZksyncSsoSessionActions = {
7
+ };
8
+
9
+ export function zksyncSsoSessionActions<
10
+ transport extends Transport,
11
+ chain extends Chain,
12
+ account extends Account,
13
+ /* eslint-disable @typescript-eslint/no-unused-vars */
14
+ >(client: ClientWithZksyncSsoSessionData<transport, chain, account>): ZksyncSsoSessionActions {
15
+ return {
16
+ };
17
+ }
@@ -0,0 +1,184 @@
1
+ import { /* decodeFunctionData, erc20Abi, getAddress, */ type Account, type Chain, type Transport, type WalletActions } from "viem";
2
+ import { deployContract, getAddresses, getChainId, prepareTransactionRequest, sendRawTransaction, signMessage, signTypedData, writeContract } from "viem/actions";
3
+ import { getGeneralPaymasterInput, sendEip712Transaction, sendTransaction, signTransaction } from "viem/zksync";
4
+
5
+ import type { ClientWithZksyncSsoSessionData } from "../clients/session.js";
6
+ /* import { getTokenSpendLimit } from '../actions/session.js'; */
7
+
8
+ export type ZksyncSsoWalletActions<chain extends Chain, account extends Account> = Omit<
9
+ WalletActions<chain, account>, "addChain" | "getPermissions" | "requestAddresses" | "requestPermissions" | "switchChain" | "watchAsset"
10
+ >;
11
+
12
+ export function zksyncSsoWalletActions<
13
+ transport extends Transport,
14
+ chain extends Chain,
15
+ account extends Account,
16
+ >(client: ClientWithZksyncSsoSessionData<transport, chain, account>): ZksyncSsoWalletActions<chain, account> {
17
+ return {
18
+ deployContract: (args) => deployContract(client, args),
19
+ getAddresses: () => getAddresses(client),
20
+ getChainId: () => getChainId(client),
21
+ prepareTransactionRequest: (args) =>
22
+ prepareTransactionRequest(client, args),
23
+ sendRawTransaction: (args) => sendRawTransaction(client, args),
24
+ sendTransaction: async (args) => {
25
+ const tx = client.chain.formatters?.transaction?.format(args) || args;
26
+ /* await verifyTransactionData({
27
+ value: tx.value,
28
+ chain: tx.chain || undefined,
29
+ to: tx.to || undefined,
30
+ data: tx.data,
31
+ gas: tx.gas,
32
+ gasPrice: tx.gasPrice,
33
+ maxFeePerGas: tx.maxFeePerGas,
34
+ maxPriorityFeePerGas: tx.maxPriorityFeePerGas,
35
+ }, client); */
36
+ if (tx.eip712Meta) {
37
+ const transaction = {
38
+ ...tx,
39
+ account: client.account,
40
+ paymaster: tx.eip712Meta.paymasterParams.paymaster,
41
+ // TODO: Find permanent fix as this only works for general paymasters with no input
42
+ paymasterInput: getGeneralPaymasterInput({ innerInput: "0x" }),
43
+ };
44
+ return await sendEip712Transaction(client, transaction);
45
+ }
46
+ return await sendTransaction(client, tx);
47
+ },
48
+ signMessage: (args) => signMessage(client, args),
49
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
50
+ signTransaction: (args) => signTransaction(client, args as any),
51
+ signTypedData: (args) => signTypedData(client, args),
52
+ writeContract: (args) => writeContract(client, args),
53
+ };
54
+ }
55
+
56
+ /* export class SpendLimitError extends Error {
57
+ public tokenAddress: Address;
58
+ public spendLimit: bigint;
59
+
60
+ constructor(message: string, info: { tokenAddress: Address, spendLimit: bigint }) {
61
+ super(message);
62
+ this.tokenAddress = info.tokenAddress;
63
+ this.spendLimit = info.spendLimit;
64
+ }
65
+ }
66
+
67
+ const l2BaseTokenAddress = getAddress('0x000000000000000000000000000000000000800a');
68
+
69
+ const blockedMethods = [
70
+ "approve", // do not allow token approvals to prevent indirect token transfer
71
+ ];
72
+ const isBlockedMethod = (method: string) => {
73
+ return blockedMethods.includes(method);
74
+ }
75
+
76
+ const decodeERC20TransactionData = (transactionData: Hash) => {
77
+ try {
78
+ const { functionName, args } = decodeFunctionData({
79
+ abi: erc20Abi,
80
+ data: transactionData,
81
+ });
82
+ return { functionName, args };
83
+ } catch {
84
+ return { functionName: undefined, args: [] };
85
+ }
86
+ }
87
+
88
+ const getTotalFee = (fee: {
89
+ gas?: bigint,
90
+ gasPrice?: bigint,
91
+ maxFeePerGas?: bigint,
92
+ maxPriorityFeePerGas?: bigint,
93
+ }): bigint => {
94
+ if (!fee.gas) return 0n;
95
+
96
+ if (fee.gasPrice) {
97
+ return fee.gas * fee.gasPrice;
98
+ } else if (fee.maxFeePerGas && fee.maxPriorityFeePerGas) {
99
+ return fee.gas * (fee.maxFeePerGas + fee.maxPriorityFeePerGas);
100
+ } else if (fee.maxFeePerGas) {
101
+ return fee.gas * fee.maxFeePerGas;
102
+ } else if (fee.maxPriorityFeePerGas) {
103
+ return fee.gas * fee.maxPriorityFeePerGas;
104
+ }
105
+
106
+ return 0n;
107
+ }
108
+
109
+ const verifyTransactionData = async (
110
+ transaction: {
111
+ value?: bigint;
112
+ chain?: { id: number | undefined };
113
+ to?: Address;
114
+ data?: Hash;
115
+ gas?: bigint,
116
+ gasPrice?: bigint,
117
+ maxFeePerGas?: bigint,
118
+ maxPriorityFeePerGas?: bigint,
119
+ },
120
+ client: ClientWithZksyncSsoSessionData
121
+ ) => {
122
+ const spendLimitCache = new Map<Address, bigint>(); // Prevent multiple calls to getTokenSpendLimit (mostly for ETH)
123
+ const exceedsSpendLimit = async (tokenAddress: Address, amount: bigint): Promise<boolean> => {
124
+ if (!spendLimitCache.has(tokenAddress)) {
125
+ const spendLimit = await getTokenSpendLimit(client, { tokenAddress, sessionKey: client.sessionKey!, contracts: client.contracts });
126
+ spendLimitCache.set(tokenAddress, spendLimit);
127
+ }
128
+
129
+ const tokenSpendLimit = spendLimitCache.get(tokenAddress)!;
130
+ if (tokenSpendLimit < amount) {
131
+ return true;
132
+ }
133
+
134
+ return false;
135
+ }
136
+
137
+ // Verify transaction value
138
+ const value = transaction.value || 0n;
139
+ if (await exceedsSpendLimit(getAddress(l2BaseTokenAddress), value)) {
140
+ throw new SpendLimitError(`Transaction value ${value} exceeds account spend limit`, {
141
+ tokenAddress: getAddress(l2BaseTokenAddress),
142
+ spendLimit: spendLimitCache.get(getAddress(l2BaseTokenAddress))!,
143
+ });
144
+ }
145
+
146
+ // Verify total fee
147
+ const totalFee = getTotalFee({
148
+ gas: transaction.gas,
149
+ gasPrice: transaction.gasPrice,
150
+ maxFeePerGas: transaction.maxFeePerGas,
151
+ maxPriorityFeePerGas: transaction.maxPriorityFeePerGas,
152
+ });
153
+ if (await exceedsSpendLimit(getAddress(l2BaseTokenAddress), totalFee)) {
154
+ throw new SpendLimitError(`Total fee ${totalFee} exceeds account spend limit`, {
155
+ tokenAddress: getAddress(l2BaseTokenAddress),
156
+ spendLimit: spendLimitCache.get(getAddress(l2BaseTokenAddress))!,
157
+ });
158
+ }
159
+
160
+ if (!transaction.data || !transaction.to) return;
161
+
162
+ // Assuming transaction is an erc20 transaction
163
+ const { functionName, args } = decodeERC20TransactionData(transaction.data);
164
+ if (!functionName) return;
165
+
166
+ // Verify if method is not blocked
167
+ if (isBlockedMethod(functionName)) {
168
+ throw new Error(`Method "${functionName}" is not allowed for this account`);
169
+ }
170
+
171
+ const tokenAddress = getAddress(transaction.to.toLowerCase());
172
+
173
+ // Verify transfer amount
174
+ if (functionName === "transfer") {
175
+ const [_to, _amount] = args;
176
+ const amount = _amount ? BigInt(_amount) : 0n;
177
+ if (await exceedsSpendLimit(tokenAddress, amount)) {
178
+ throw new SpendLimitError(`Amount ${amount} exceeds account spend limit`, {
179
+ tokenAddress,
180
+ spendLimit: spendLimitCache.get(tokenAddress)!,
181
+ });
182
+ }
183
+ }
184
+ } */
@@ -0,0 +1,2 @@
1
+ export { deployAccount, fetchAccount } from "./actions/account.js";
2
+ export * from "./clients/session.js";
@@ -0,0 +1,3 @@
1
+ export * from "./actions/passkey.js";
2
+ export * from "./clients/passkey.js";
3
+ export * from "./decorators/passkey.js";
@@ -0,0 +1,68 @@
1
+ import type { Address } from "abitype";
2
+ import { type CustomSource, type Hash, hashMessage, hashTypedData, type Hex, type LocalAccount } from "viem";
3
+ import { toAccount } from "viem/accounts";
4
+ import { serializeTransaction, type ZksyncTransactionSerializableEIP712 } from "viem/zksync";
5
+
6
+ import { getEip712Domain } from "./utils/getEip712Domain.js";
7
+
8
+ export type ToSmartAccountParameters = {
9
+ /** Address of the deployed Account's Contract implementation. */
10
+ address: Address;
11
+ /** Function to sign a hash. */
12
+ sign: (parameters: { hash: Hash }) => Promise<Hex>;
13
+ };
14
+
15
+ export type ZksyncSmartAccount = LocalAccount<"smartAccountZksync"> & {
16
+ sign: NonNullable<CustomSource["sign"]>;
17
+ };
18
+
19
+ type ErrorType<name extends string = "Error"> = Error & { name: name };
20
+ export type ToSmartAccountErrorType = ErrorType;
21
+
22
+ /**
23
+ * Creates a [ZKsync Smart Account](https://docs.zksync.io/build/developer-reference/account-abstraction/building-smart-accounts)
24
+ * from a Contract Address and a custom sign function.
25
+ */
26
+ export function toSmartAccount(
27
+ parameters: ToSmartAccountParameters,
28
+ ): ZksyncSmartAccount {
29
+ const { address, sign } = parameters;
30
+
31
+ const account = toAccount({
32
+ address,
33
+ sign,
34
+ async signMessage({ message }) {
35
+ return sign({
36
+ hash: hashMessage(message),
37
+ });
38
+ },
39
+ async signTransaction(transaction) {
40
+ const signableTransaction = {
41
+ ...transaction,
42
+ from: this.address!,
43
+ type: "eip712",
44
+ gas: 100_000_000n, // TODO remove when gas estimation is fixed
45
+ } as ZksyncTransactionSerializableEIP712;
46
+
47
+ const eip712DomainAndMessage = getEip712Domain(signableTransaction);
48
+ const digest = hashTypedData(eip712DomainAndMessage);
49
+
50
+ return serializeTransaction({
51
+ ...signableTransaction,
52
+ customSignature: await sign({
53
+ hash: digest,
54
+ }),
55
+ });
56
+ },
57
+ async signTypedData(typedData) {
58
+ return sign({
59
+ hash: hashTypedData(typedData),
60
+ });
61
+ },
62
+ });
63
+
64
+ return {
65
+ ...account,
66
+ source: "smartAccountZksync",
67
+ } as ZksyncSmartAccount;
68
+ }
@@ -0,0 +1,49 @@
1
+ import { BaseError, type ExactPartial, InvalidAddressError, InvalidChainIdError, isAddress } from "viem";
2
+ import type { ZksyncTransactionSerializable, ZksyncTransactionSerializableEIP712 } from "viem/zksync";
3
+
4
+ import { isEIP712Transaction } from "./isEip712Transaction.js";
5
+
6
+ export function assertEip712Transaction(
7
+ transaction: ExactPartial<ZksyncTransactionSerializable>,
8
+ ) {
9
+ const { chainId, to, from, paymaster, paymasterInput }
10
+ = transaction as ZksyncTransactionSerializableEIP712;
11
+
12
+ if (!isEIP712Transaction(transaction))
13
+ throw new InvalidEip712TransactionError();
14
+ if (!chainId || chainId <= 0) throw new InvalidChainIdError({ chainId });
15
+ if (to && !isAddress(to)) throw new InvalidAddressError({ address: to });
16
+ if (from && !isAddress(from)) throw new InvalidAddressError({ address: from });
17
+ if (paymaster && !isAddress(paymaster))
18
+ throw new InvalidAddressError({ address: paymaster });
19
+ if (paymaster && !paymasterInput) {
20
+ throw new BaseError(
21
+ "`paymasterInput` must be provided when `paymaster` is defined",
22
+ );
23
+ }
24
+ if (!paymaster && paymasterInput) {
25
+ throw new BaseError(
26
+ "`paymaster` must be provided when `paymasterInput` is defined",
27
+ );
28
+ }
29
+ }
30
+
31
+ export type InvalidEip712TransactionErrorType =
32
+ InvalidEip712TransactionError & {
33
+ name: "InvalidEip712TransactionError";
34
+ };
35
+ export class InvalidEip712TransactionError extends BaseError {
36
+ override name = "InvalidEip712TransactionError";
37
+
38
+ constructor() {
39
+ super(
40
+ [
41
+ "Transaction is not an EIP712 transaction.",
42
+ "",
43
+ "Transaction must:",
44
+ " - include `type: \"eip712\"`",
45
+ " - include one of the following: `customSignature`, `paymaster`, `paymasterInput`, `gasPerPubdata`, `factoryDeps`",
46
+ ].join("\n"),
47
+ );
48
+ }
49
+ }
@@ -0,0 +1,84 @@
1
+ import { toHex } from "viem";
2
+ import { type EIP712DomainFn, hashBytecode, type ZksyncEIP712TransactionSignable, type ZksyncTransactionSerializable, type ZksyncTransactionSerializableEIP712 } from "viem/zksync";
3
+
4
+ import { assertEip712Transaction } from "./assertEip712Transaction.js";
5
+
6
+ const gasPerPubdataDefault = 50000n;
7
+
8
+ /* TODO: This is already available at viem already but not exported (viem also has a mistake in domain name letter casing) */
9
+ export const getEip712Domain: EIP712DomainFn<
10
+ ZksyncTransactionSerializable,
11
+ ZksyncEIP712TransactionSignable
12
+ > = (transaction) => {
13
+ assertEip712Transaction(transaction);
14
+
15
+ const message = transactionToMessage(
16
+ transaction as ZksyncTransactionSerializableEIP712,
17
+ );
18
+
19
+ return {
20
+ domain: {
21
+ // cspell:ignore zkSync
22
+ name: `zkSync`,
23
+ version: "2",
24
+ chainId: transaction.chainId,
25
+ },
26
+ types: {
27
+ Transaction: [
28
+ { name: "txType", type: "uint256" },
29
+ { name: "from", type: "uint256" },
30
+ { name: "to", type: "uint256" },
31
+ { name: "gasLimit", type: "uint256" },
32
+ { name: "gasPerPubdataByteLimit", type: "uint256" },
33
+ { name: "maxFeePerGas", type: "uint256" },
34
+ { name: "maxPriorityFeePerGas", type: "uint256" },
35
+ { name: "paymaster", type: "uint256" },
36
+ { name: "nonce", type: "uint256" },
37
+ { name: "value", type: "uint256" },
38
+ { name: "data", type: "bytes" },
39
+ { name: "factoryDeps", type: "bytes32[]" },
40
+ { name: "paymasterInput", type: "bytes" },
41
+ ],
42
+ },
43
+ primaryType: "Transaction",
44
+ message: message,
45
+ };
46
+ };
47
+
48
+ //////////////////////////////////////////////////////////////////////////////
49
+ // Utilities
50
+
51
+ function transactionToMessage(
52
+ transaction: ZksyncTransactionSerializableEIP712,
53
+ ): ZksyncEIP712TransactionSignable {
54
+ const {
55
+ gas,
56
+ nonce,
57
+ to,
58
+ from,
59
+ value,
60
+ maxFeePerGas,
61
+ maxPriorityFeePerGas,
62
+ factoryDeps,
63
+ paymaster,
64
+ paymasterInput,
65
+ gasPerPubdata,
66
+ data,
67
+ } = transaction;
68
+
69
+ return {
70
+ txType: 113n,
71
+ from: BigInt(from),
72
+ to: to ? BigInt(to) : 0n,
73
+ gasLimit: gas ?? 0n,
74
+ gasPerPubdataByteLimit: gasPerPubdata ?? gasPerPubdataDefault,
75
+ maxFeePerGas: maxFeePerGas ?? 0n,
76
+ maxPriorityFeePerGas: maxPriorityFeePerGas ?? 0n,
77
+ paymaster: paymaster ? BigInt(paymaster) : 0n,
78
+ nonce: nonce ? BigInt(nonce) : 0n,
79
+ value: value ?? 0n,
80
+ data: data ? data : "0x0",
81
+ factoryDeps: factoryDeps?.map((dep) => toHex(hashBytecode(dep))) ?? [],
82
+ paymasterInput: paymasterInput ? paymasterInput : "0x",
83
+ };
84
+ }
@@ -0,0 +1,18 @@
1
+ import type { ExactPartial } from "viem";
2
+ import type { ZksyncTransactionSerializable } from "viem/zksync";
3
+
4
+ export function isEIP712Transaction(
5
+ transaction: ExactPartial<ZksyncTransactionSerializable>,
6
+ ) {
7
+ if (transaction.type === "eip712") return true;
8
+ if (
9
+ ("customSignature" in transaction && transaction.customSignature)
10
+ || ("paymaster" in transaction && transaction.paymaster)
11
+ || ("paymasterInput" in transaction && transaction.paymasterInput)
12
+ || ("gasPerPubdata" in transaction
13
+ && typeof transaction.gasPerPubdata === "bigint")
14
+ || ("factoryDeps" in transaction && transaction.factoryDeps)
15
+ )
16
+ return true;
17
+ return false;
18
+ }