zksync-sso 0.0.0-beta.9 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (223) hide show
  1. package/dist/_cjs/abi/{Factory.js → AAFactory.js} +112 -63
  2. package/dist/_cjs/abi/AAFactory.js.map +1 -0
  3. package/dist/_cjs/abi/GuardianRecoveryModule.js +818 -0
  4. package/dist/_cjs/abi/GuardianRecoveryModule.js.map +1 -0
  5. package/dist/_cjs/abi/{SessionKeyModule.js → SessionKeyValidator.js} +251 -90
  6. package/dist/_cjs/abi/SessionKeyValidator.js.map +1 -0
  7. package/dist/_cjs/abi/WebAuthValidator.js +361 -0
  8. package/dist/_cjs/abi/WebAuthValidator.js.map +1 -0
  9. package/dist/_cjs/abi/index.js +9 -5
  10. package/dist/_cjs/abi/index.js.map +1 -1
  11. package/dist/_cjs/client/ecdsa/account.js +38 -0
  12. package/dist/_cjs/client/ecdsa/account.js.map +1 -0
  13. package/dist/_cjs/client/ecdsa/actions/account.js +83 -0
  14. package/dist/_cjs/client/ecdsa/actions/account.js.map +1 -0
  15. package/dist/_cjs/client/ecdsa/client.js +35 -0
  16. package/dist/_cjs/client/ecdsa/client.js.map +1 -0
  17. package/dist/_cjs/client/ecdsa/decorators/ecdsa.js +22 -0
  18. package/dist/_cjs/client/ecdsa/decorators/ecdsa.js.map +1 -0
  19. package/dist/_cjs/client/ecdsa/decorators/wallet.js +47 -0
  20. package/dist/_cjs/client/ecdsa/decorators/wallet.js.map +1 -0
  21. package/dist/_cjs/client/ecdsa/index.js +23 -0
  22. package/dist/_cjs/client/ecdsa/index.js.map +1 -0
  23. package/dist/_cjs/client/ecdsa/types.js +63 -0
  24. package/dist/_cjs/client/ecdsa/types.js.map +1 -0
  25. package/dist/_cjs/client/index.js +9 -4
  26. package/dist/_cjs/client/index.js.map +1 -1
  27. package/dist/_cjs/client/passkey/actions/account.js +35 -31
  28. package/dist/_cjs/client/passkey/actions/account.js.map +1 -1
  29. package/dist/_cjs/client/passkey/actions/passkey.js +26 -6
  30. package/dist/_cjs/client/passkey/actions/passkey.js.map +1 -1
  31. package/dist/_cjs/client/passkey/client.js +1 -1
  32. package/dist/_cjs/client/passkey/client.js.map +1 -1
  33. package/dist/_cjs/client/passkey/decorators/passkey.js +19 -0
  34. package/dist/_cjs/client/passkey/decorators/passkey.js.map +1 -1
  35. package/dist/_cjs/client/recovery/account.js +46 -0
  36. package/dist/_cjs/client/recovery/account.js.map +1 -0
  37. package/dist/_cjs/client/recovery/actions/recovery.js +114 -0
  38. package/dist/_cjs/client/recovery/actions/recovery.js.map +1 -0
  39. package/dist/_cjs/client/recovery/actions/sendEip712Transaction.js +45 -0
  40. package/dist/_cjs/client/recovery/actions/sendEip712Transaction.js.map +1 -0
  41. package/dist/_cjs/client/recovery/client.js +49 -0
  42. package/dist/_cjs/client/recovery/client.js.map +1 -0
  43. package/dist/_cjs/client/recovery/decorators/publicActionsRewrite.js +33 -0
  44. package/dist/_cjs/client/recovery/decorators/publicActionsRewrite.js.map +1 -0
  45. package/dist/_cjs/client/recovery/decorators/recovery.js +15 -0
  46. package/dist/_cjs/client/recovery/decorators/recovery.js.map +1 -0
  47. package/dist/_cjs/client/recovery/decorators/wallet.js +39 -0
  48. package/dist/_cjs/client/recovery/decorators/wallet.js.map +1 -0
  49. package/dist/_cjs/client/recovery/index.js +19 -0
  50. package/dist/_cjs/client/recovery/index.js.map +1 -0
  51. package/dist/_cjs/client/session/actions/session.js +3 -3
  52. package/dist/_cjs/client/session/actions/session.js.map +1 -1
  53. package/dist/_cjs/client-auth-server/Signer.js +1 -0
  54. package/dist/_cjs/client-auth-server/Signer.js.map +1 -1
  55. package/dist/_cjs/client-auth-server/WalletProvider.js +1 -0
  56. package/dist/_cjs/client-auth-server/WalletProvider.js.map +1 -1
  57. package/dist/_cjs/connector/index.js +1 -0
  58. package/dist/_cjs/connector/index.js.map +1 -1
  59. package/dist/_cjs/utils/encoding.js +6 -3
  60. package/dist/_cjs/utils/encoding.js.map +1 -1
  61. package/dist/_cjs/utils/passkey.js +4 -2
  62. package/dist/_cjs/utils/passkey.js.map +1 -1
  63. package/dist/_esm/abi/{Factory.js → AAFactory.js} +111 -62
  64. package/dist/_esm/abi/AAFactory.js.map +1 -0
  65. package/dist/_esm/abi/GuardianRecoveryModule.js +815 -0
  66. package/dist/_esm/abi/GuardianRecoveryModule.js.map +1 -0
  67. package/dist/_esm/abi/{SessionKeyModule.js → SessionKeyValidator.js} +250 -89
  68. package/dist/_esm/abi/SessionKeyValidator.js.map +1 -0
  69. package/dist/_esm/abi/WebAuthValidator.js +358 -0
  70. package/dist/_esm/abi/WebAuthValidator.js.map +1 -0
  71. package/dist/_esm/abi/index.js +4 -2
  72. package/dist/_esm/abi/index.js.map +1 -1
  73. package/dist/_esm/client/ecdsa/account.js +35 -0
  74. package/dist/_esm/client/ecdsa/account.js.map +1 -0
  75. package/dist/_esm/client/ecdsa/actions/account.js +81 -0
  76. package/dist/_esm/client/ecdsa/actions/account.js.map +1 -0
  77. package/dist/_esm/client/ecdsa/client.js +32 -0
  78. package/dist/_esm/client/ecdsa/client.js.map +1 -0
  79. package/dist/_esm/client/ecdsa/decorators/ecdsa.js +19 -0
  80. package/dist/_esm/client/ecdsa/decorators/ecdsa.js.map +1 -0
  81. package/dist/_esm/client/ecdsa/decorators/wallet.js +47 -0
  82. package/dist/_esm/client/ecdsa/decorators/wallet.js.map +1 -0
  83. package/dist/_esm/client/ecdsa/index.js +7 -0
  84. package/dist/_esm/client/ecdsa/index.js.map +1 -0
  85. package/dist/_esm/client/ecdsa/types.js +61 -0
  86. package/dist/_esm/client/ecdsa/types.js.map +1 -0
  87. package/dist/_esm/client/index.js +3 -0
  88. package/dist/_esm/client/index.js.map +1 -1
  89. package/dist/_esm/client/passkey/actions/account.js +37 -33
  90. package/dist/_esm/client/passkey/actions/account.js.map +1 -1
  91. package/dist/_esm/client/passkey/actions/passkey.js +29 -10
  92. package/dist/_esm/client/passkey/actions/passkey.js.map +1 -1
  93. package/dist/_esm/client/passkey/client.js +1 -1
  94. package/dist/_esm/client/passkey/client.js.map +1 -1
  95. package/dist/_esm/client/passkey/decorators/passkey.js +19 -0
  96. package/dist/_esm/client/passkey/decorators/passkey.js.map +1 -1
  97. package/dist/_esm/client/recovery/account.js +43 -0
  98. package/dist/_esm/client/recovery/account.js.map +1 -0
  99. package/dist/_esm/client/recovery/actions/recovery.js +111 -0
  100. package/dist/_esm/client/recovery/actions/recovery.js.map +1 -0
  101. package/dist/_esm/client/recovery/actions/sendEip712Transaction.js +93 -0
  102. package/dist/_esm/client/recovery/actions/sendEip712Transaction.js.map +1 -0
  103. package/dist/_esm/client/recovery/client.js +45 -0
  104. package/dist/_esm/client/recovery/client.js.map +1 -0
  105. package/dist/_esm/client/recovery/decorators/publicActionsRewrite.js +31 -0
  106. package/dist/_esm/client/recovery/decorators/publicActionsRewrite.js.map +1 -0
  107. package/dist/_esm/client/recovery/decorators/recovery.js +13 -0
  108. package/dist/_esm/client/recovery/decorators/recovery.js.map +1 -0
  109. package/dist/_esm/client/recovery/decorators/wallet.js +38 -0
  110. package/dist/_esm/client/recovery/decorators/wallet.js.map +1 -0
  111. package/dist/_esm/client/recovery/index.js +3 -0
  112. package/dist/_esm/client/recovery/index.js.map +1 -0
  113. package/dist/_esm/client/session/actions/session.js +3 -3
  114. package/dist/_esm/client/session/actions/session.js.map +1 -1
  115. package/dist/_esm/client-auth-server/Signer.js +1 -0
  116. package/dist/_esm/client-auth-server/Signer.js.map +1 -1
  117. package/dist/_esm/client-auth-server/WalletProvider.js +1 -0
  118. package/dist/_esm/client-auth-server/WalletProvider.js.map +1 -1
  119. package/dist/_esm/connector/index.js +1 -0
  120. package/dist/_esm/connector/index.js.map +1 -1
  121. package/dist/_esm/utils/encoding.js +7 -4
  122. package/dist/_esm/utils/encoding.js.map +1 -1
  123. package/dist/_esm/utils/passkey.js +5 -3
  124. package/dist/_esm/utils/passkey.js.map +1 -1
  125. package/dist/_types/abi/{Factory.d.ts → AAFactory.d.ts} +95 -58
  126. package/dist/_types/abi/AAFactory.d.ts.map +1 -0
  127. package/dist/_types/abi/GuardianRecoveryModule.d.ts +630 -0
  128. package/dist/_types/abi/GuardianRecoveryModule.d.ts.map +1 -0
  129. package/dist/_types/abi/{SessionKeyModule.d.ts → SessionKeyValidator.d.ts} +193 -75
  130. package/dist/_types/abi/{SessionKeyModule.d.ts.map → SessionKeyValidator.d.ts.map} +1 -1
  131. package/dist/_types/abi/WebAuthValidator.d.ts +277 -0
  132. package/dist/_types/abi/WebAuthValidator.d.ts.map +1 -0
  133. package/dist/_types/abi/index.d.ts +4 -2
  134. package/dist/_types/abi/index.d.ts.map +1 -1
  135. package/dist/_types/client/ecdsa/account.d.ts +14 -0
  136. package/dist/_types/client/ecdsa/account.d.ts.map +1 -0
  137. package/dist/_types/client/ecdsa/actions/account.d.ts +38 -0
  138. package/dist/_types/client/ecdsa/actions/account.d.ts.map +1 -0
  139. package/dist/_types/client/ecdsa/client.d.ts +25 -0
  140. package/dist/_types/client/ecdsa/client.d.ts.map +1 -0
  141. package/dist/_types/client/ecdsa/decorators/ecdsa.d.ts +16 -0
  142. package/dist/_types/client/ecdsa/decorators/ecdsa.d.ts.map +1 -0
  143. package/dist/_types/client/ecdsa/decorators/wallet.d.ts +5 -0
  144. package/dist/_types/client/ecdsa/decorators/wallet.d.ts.map +1 -0
  145. package/dist/_types/client/ecdsa/index.d.ts +7 -0
  146. package/dist/_types/client/ecdsa/index.d.ts.map +1 -0
  147. package/dist/_types/client/ecdsa/types.d.ts +10 -0
  148. package/dist/_types/client/ecdsa/types.d.ts.map +1 -0
  149. package/dist/_types/client/index.d.ts +3 -0
  150. package/dist/_types/client/index.d.ts.map +1 -1
  151. package/dist/_types/client/passkey/actions/account.d.ts +3 -1
  152. package/dist/_types/client/passkey/actions/account.d.ts.map +1 -1
  153. package/dist/_types/client/passkey/actions/passkey.d.ts +13 -4
  154. package/dist/_types/client/passkey/actions/passkey.d.ts.map +1 -1
  155. package/dist/_types/client/passkey/client.d.ts +1 -0
  156. package/dist/_types/client/passkey/client.d.ts.map +1 -1
  157. package/dist/_types/client/passkey/decorators/passkey.d.ts +4 -0
  158. package/dist/_types/client/passkey/decorators/passkey.d.ts.map +1 -1
  159. package/dist/_types/client/recovery/account.d.ts +14 -0
  160. package/dist/_types/client/recovery/account.d.ts.map +1 -0
  161. package/dist/_types/client/recovery/actions/recovery.d.ts +50 -0
  162. package/dist/_types/client/recovery/actions/recovery.d.ts.map +1 -0
  163. package/dist/_types/client/recovery/actions/sendEip712Transaction.d.ts +60 -0
  164. package/dist/_types/client/recovery/actions/sendEip712Transaction.d.ts.map +1 -0
  165. package/dist/_types/client/recovery/client.d.ts +23 -0
  166. package/dist/_types/client/recovery/client.d.ts.map +1 -0
  167. package/dist/_types/client/recovery/decorators/publicActionsRewrite.d.ts +4 -0
  168. package/dist/_types/client/recovery/decorators/publicActionsRewrite.d.ts.map +1 -0
  169. package/dist/_types/client/recovery/decorators/recovery.d.ts +8 -0
  170. package/dist/_types/client/recovery/decorators/recovery.d.ts.map +1 -0
  171. package/dist/_types/client/recovery/decorators/wallet.d.ts +5 -0
  172. package/dist/_types/client/recovery/decorators/wallet.d.ts.map +1 -0
  173. package/dist/_types/client/recovery/index.d.ts +3 -0
  174. package/dist/_types/client/recovery/index.d.ts.map +1 -0
  175. package/dist/_types/client-auth-server/Signer.d.ts +526 -526
  176. package/dist/_types/client-auth-server/Signer.d.ts.map +1 -1
  177. package/dist/_types/client-auth-server/WalletProvider.d.ts +526 -526
  178. package/dist/_types/client-auth-server/WalletProvider.d.ts.map +1 -1
  179. package/dist/_types/client-auth-server/interface.d.ts +1 -0
  180. package/dist/_types/client-auth-server/interface.d.ts.map +1 -1
  181. package/dist/_types/connector/index.d.ts.map +1 -1
  182. package/dist/_types/utils/encoding.d.ts +1 -0
  183. package/dist/_types/utils/encoding.d.ts.map +1 -1
  184. package/dist/_types/utils/passkey.d.ts +2 -2
  185. package/dist/_types/utils/passkey.d.ts.map +1 -1
  186. package/package.json +11 -1
  187. package/src/abi/{Factory.ts → AAFactory.ts} +110 -61
  188. package/src/abi/GuardianRecoveryModule.ts +814 -0
  189. package/src/abi/{SessionKeyModule.ts → SessionKeyValidator.ts} +249 -88
  190. package/src/abi/WebAuthValidator.ts +357 -0
  191. package/src/abi/index.ts +4 -2
  192. package/src/client/ecdsa/account.ts +56 -0
  193. package/src/client/ecdsa/actions/account.ts +145 -0
  194. package/src/client/ecdsa/client.ts +90 -0
  195. package/src/client/ecdsa/decorators/ecdsa.ts +32 -0
  196. package/src/client/ecdsa/decorators/wallet.ts +73 -0
  197. package/src/client/ecdsa/index.ts +6 -0
  198. package/src/client/ecdsa/types.ts +108 -0
  199. package/src/client/index.ts +3 -0
  200. package/src/client/passkey/actions/account.ts +43 -34
  201. package/src/client/passkey/actions/passkey.ts +46 -15
  202. package/src/client/passkey/client.ts +5 -1
  203. package/src/client/passkey/decorators/passkey.ts +26 -0
  204. package/src/client/recovery/account.ts +61 -0
  205. package/src/client/recovery/actions/recovery.ts +176 -0
  206. package/src/client/recovery/actions/sendEip712Transaction.ts +149 -0
  207. package/src/client/recovery/client.ts +102 -0
  208. package/src/client/recovery/decorators/publicActionsRewrite.ts +38 -0
  209. package/src/client/recovery/decorators/recovery.ts +22 -0
  210. package/src/client/recovery/decorators/wallet.ts +52 -0
  211. package/src/client/recovery/index.ts +2 -0
  212. package/src/client/session/actions/session.ts +3 -3
  213. package/src/client-auth-server/Signer.ts +1 -0
  214. package/src/client-auth-server/WalletProvider.ts +1 -0
  215. package/src/client-auth-server/interface.ts +1 -0
  216. package/src/connector/index.ts +1 -0
  217. package/src/utils/encoding.ts +8 -5
  218. package/src/utils/passkey.ts +6 -3
  219. package/dist/_cjs/abi/Factory.js.map +0 -1
  220. package/dist/_cjs/abi/SessionKeyModule.js.map +0 -1
  221. package/dist/_esm/abi/Factory.js.map +0 -1
  222. package/dist/_esm/abi/SessionKeyModule.js.map +0 -1
  223. package/dist/_types/abi/Factory.d.ts.map +0 -1
@@ -0,0 +1,73 @@
1
+ import { type Account, bytesToHex, type Chain, type ExactPartial, formatTransaction, type RpcTransaction, type Transport, type WalletActions } from "viem";
2
+ import { deployContract, getAddresses, getChainId, sendRawTransaction, signMessage, signTypedData, writeContract } from "viem/actions";
3
+ import { signTransaction, type TransactionRequestEIP712, type ZksyncEip712Meta } from "viem/zksync";
4
+
5
+ import { getTransactionWithPaymasterData } from "../../../paymaster/index.js";
6
+ import { sendEip712Transaction } from "../../session/actions/sendEip712Transaction.js";
7
+ import type { ClientWithZksyncSsoEcdsaData } from "../client.js";
8
+
9
+ export type ZksyncSsoEcdsaWalletActions<chain extends Chain, account extends Account> = Omit<
10
+ WalletActions<chain, account>, "addChain" | "getPermissions" | "requestAddresses" | "requestPermissions" | "switchChain" | "watchAsset" | "prepareTransactionRequest"
11
+ >;
12
+
13
+ export function zksyncSsoEcdsaWalletActions<
14
+ transport extends Transport,
15
+ chain extends Chain,
16
+ account extends Account,
17
+ >(client: ClientWithZksyncSsoEcdsaData<transport, chain>): ZksyncSsoEcdsaWalletActions<chain, account> {
18
+ return {
19
+ deployContract: (args) => deployContract(client, args),
20
+ getAddresses: () => getAddresses(client),
21
+ getChainId: () => getChainId(client),
22
+ sendRawTransaction: (args) => sendRawTransaction(client, args),
23
+ sendTransaction: async (args) => {
24
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
25
+ const unformattedTx: any = Object.assign({}, args);
26
+
27
+ if ("eip712Meta" in unformattedTx) {
28
+ const eip712Meta = unformattedTx.eip712Meta as ZksyncEip712Meta;
29
+ unformattedTx.gasPerPubdata = eip712Meta.gasPerPubdata ? BigInt(eip712Meta.gasPerPubdata) : undefined;
30
+ unformattedTx.factoryDeps = eip712Meta.factoryDeps;
31
+ unformattedTx.customSignature = eip712Meta.customSignature;
32
+ unformattedTx.paymaster = eip712Meta.paymasterParams?.paymaster;
33
+ unformattedTx.paymasterInput = eip712Meta.paymasterParams?.paymasterInput ? bytesToHex(new Uint8Array(eip712Meta.paymasterParams?.paymasterInput)) : undefined;
34
+ delete unformattedTx.eip712Meta;
35
+ }
36
+
37
+ /* eslint-disable @typescript-eslint/no-unused-vars */
38
+ const { chainId: _, ...unformattedTxWithPaymaster } = await getTransactionWithPaymasterData(
39
+ client.chain.id,
40
+ client.account.address,
41
+ unformattedTx,
42
+ client.paymasterHandler,
43
+ );
44
+
45
+ const formatters = client.chain?.formatters;
46
+ const format = formatters?.transaction?.format || formatTransaction;
47
+
48
+ const tx = {
49
+ ...format(unformattedTxWithPaymaster as ExactPartial<RpcTransaction>),
50
+ type: "eip712",
51
+ };
52
+
53
+ return await sendEip712Transaction(client, tx);
54
+ },
55
+ signMessage: (args) => signMessage(client, args),
56
+
57
+ signTransaction: async (args) => {
58
+ /* eslint-disable @typescript-eslint/no-unused-vars */
59
+ const { chainId: _, ...unformattedTxWithPaymaster } = await getTransactionWithPaymasterData(
60
+ client.chain.id,
61
+ client.account.address,
62
+ args as TransactionRequestEIP712,
63
+ client.paymasterHandler,
64
+ );
65
+ return signTransaction(client, {
66
+ ...args,
67
+ unformattedTxWithPaymaster,
68
+ } as any);
69
+ },
70
+ signTypedData: (args) => signTypedData(client, args),
71
+ writeContract: (args) => writeContract(client, args),
72
+ };
73
+ }
@@ -0,0 +1,6 @@
1
+ export * from "./account.js";
2
+ export * from "./actions/account.js";
3
+ export * from "./client.js";
4
+ export * from "./decorators/ecdsa.js";
5
+ export * from "./decorators/wallet.js";
6
+ export * from "./types.js";
@@ -0,0 +1,108 @@
1
+ import {
2
+ type Account,
3
+ type Address,
4
+ type Chain,
5
+ createWalletClient, custom,
6
+ type EIP1193Provider,
7
+ hashTypedData,
8
+ type LocalAccount,
9
+ type OneOf,
10
+ type Transport,
11
+ type WalletClient } from "viem";
12
+ import { toAccount } from "viem/accounts";
13
+ import { signTypedData } from "viem/actions";
14
+ import { getAction } from "viem/utils";
15
+ import { serializeTransaction, type ZksyncTransactionSerializableEIP712 } from "viem/zksync";
16
+
17
+ import { getEip712Domain } from "../utils/getEip712Domain.js";
18
+
19
+ export type Signer = OneOf<
20
+ | EIP1193Provider
21
+ | WalletClient<Transport, Chain | undefined, Account>
22
+ | LocalAccount
23
+ >;
24
+
25
+ export type EthereumProvider = OneOf<
26
+ { request(...args: any): Promise<any> } | EIP1193Provider
27
+ >;
28
+
29
+ export async function toOwner<provider extends EthereumProvider>({
30
+ owner,
31
+ address,
32
+ }: {
33
+ owner: OneOf<
34
+ | provider
35
+ | WalletClient<Transport, Chain | undefined, Account>
36
+ | LocalAccount
37
+ >;
38
+ address?: Address;
39
+ }): Promise<LocalAccount> {
40
+ if ("type" in owner && owner.type === "local") {
41
+ return owner as LocalAccount;
42
+ }
43
+
44
+ let walletClient:
45
+ | WalletClient<Transport, Chain | undefined, Account>
46
+ | undefined = undefined;
47
+
48
+ if ("request" in owner) {
49
+ if (!address) {
50
+ try {
51
+ [address] = await (owner as EthereumProvider).request({
52
+ method: "eth_requestAccounts",
53
+ });
54
+ } catch {
55
+ [address] = await (owner as EthereumProvider).request({
56
+ method: "eth_accounts",
57
+ });
58
+ }
59
+ }
60
+ if (!address) {
61
+ // For TS to be happy
62
+ throw new Error("address is required");
63
+ }
64
+ walletClient = createWalletClient({
65
+ account: address,
66
+ transport: custom(owner as EthereumProvider),
67
+ });
68
+ }
69
+
70
+ if (!walletClient) {
71
+ walletClient = owner as WalletClient<
72
+ Transport,
73
+ Chain | undefined,
74
+ Account
75
+ >;
76
+ }
77
+
78
+ return toAccount({
79
+ address: walletClient.account.address,
80
+ async signMessage({ message }) {
81
+ return walletClient.signMessage({ message });
82
+ },
83
+ async signTransaction(transaction) {
84
+ const signableTransaction = {
85
+ ...transaction,
86
+ from: this.address!,
87
+ type: "eip712",
88
+ } as ZksyncTransactionSerializableEIP712;
89
+
90
+ const eip712DomainAndMessage = getEip712Domain(signableTransaction);
91
+ const digest = hashTypedData(eip712DomainAndMessage);
92
+
93
+ const signedMessage = await walletClient.signMessage({ message: digest });
94
+
95
+ return serializeTransaction({
96
+ ...signableTransaction,
97
+ customSignature: signedMessage,
98
+ });
99
+ },
100
+ async signTypedData(typedData) {
101
+ return getAction(
102
+ walletClient,
103
+ signTypedData,
104
+ "signTypedData",
105
+ )(typedData as any);
106
+ },
107
+ });
108
+ }
@@ -1,2 +1,5 @@
1
+ export { deployAccount as deployEcdsaAccount, fetchAccount as fetchEcdsaAccount } from "./ecdsa/actions/account.js";
1
2
  export { deployAccount, fetchAccount } from "./passkey/actions/account.js";
3
+ export * from "./recovery/actions/recovery.js";
4
+ export * from "./recovery/client.js";
2
5
  export * from "./session/client.js";
@@ -1,16 +1,18 @@
1
- import { type Account, type Address, type Chain, type Client, getAddress, type Hash, type Hex, parseAbi, type Prettify, toHex, type TransactionReceipt, type Transport } from "viem";
1
+ import { type Account, type Address, type Chain, type Client, getAddress, type Hash, type Hex, keccak256, parseEventLogs, type Prettify, toHex, type TransactionReceipt, type Transport } from "viem";
2
2
  import { readContract, waitForTransactionReceipt, writeContract } from "viem/actions";
3
3
  import { getGeneralPaymasterInput } from "viem/zksync";
4
4
 
5
- import { FactoryAbi } from "../../../abi/Factory.js";
5
+ import { AAFactoryAbi } from "../../../abi/AAFactory.js";
6
+ import { WebAuthValidatorAbi } from "../../../abi/WebAuthValidator.js";
6
7
  import { encodeModuleData, encodePasskeyModuleParameters, encodeSession } from "../../../utils/encoding.js";
7
8
  import { noThrow } from "../../../utils/helpers.js";
8
- import { getPasskeySignatureFromPublicKeyBytes, getPublicKeyBytesFromPasskeySignature } from "../../../utils/passkey.js";
9
+ import { base64UrlToUint8Array, getPasskeySignatureFromPublicKeyBytes, getPublicKeyBytesFromPasskeySignature } from "../../../utils/passkey.js";
9
10
  import type { SessionConfig } from "../../../utils/session.js";
10
11
 
11
12
  /* TODO: try to get rid of most of the contract params like passkey, session */
12
13
  /* it should come from factory, not passed manually each time */
13
14
  export type DeployAccountArgs = {
15
+ credentialId: string; // Unique id of the passkey public key (base64)
14
16
  credentialPublicKey: Uint8Array; // Public key of the previously registered
15
17
  paymasterAddress?: Address; // Paymaster used to pay the fees of creating accounts
16
18
  paymasterInput?: Hex; // Input for paymaster (if provided)
@@ -20,9 +22,9 @@ export type DeployAccountArgs = {
20
22
  accountFactory: Address;
21
23
  passkey: Address;
22
24
  session: Address;
25
+ recovery: Address;
23
26
  };
24
27
  initialSession?: SessionConfig;
25
- salt?: Uint8Array; // Random 32 bytes
26
28
  onTransactionSent?: (hash: Hash) => void;
27
29
  };
28
30
  export type DeployAccountReturnType = {
@@ -36,6 +38,7 @@ export type FetchAccountArgs = {
36
38
  accountFactory: Address;
37
39
  passkey: Address;
38
40
  session: Address;
41
+ recovery: Address;
39
42
  };
40
43
  };
41
44
  export type FetchAccountReturnType = {
@@ -54,10 +57,6 @@ export const deployAccount = async <
54
57
  client: Client<transport, chain, account>, // Account deployer (any viem client)
55
58
  args: Prettify<DeployAccountArgs>,
56
59
  ): Promise<DeployAccountReturnType> => {
57
- if (!args.salt) {
58
- args.salt = crypto.getRandomValues(new Uint8Array(32));
59
- }
60
-
61
60
  let origin: string | undefined = args.expectedOrigin;
62
61
  if (!origin) {
63
62
  try {
@@ -69,6 +68,7 @@ export const deployAccount = async <
69
68
 
70
69
  const passkeyPublicKey = getPublicKeyBytesFromPasskeySignature(args.credentialPublicKey);
71
70
  const encodedPasskeyParameters = encodePasskeyModuleParameters({
71
+ credentialId: args.credentialId,
72
72
  passkeyPublicKey,
73
73
  expectedOrigin: origin,
74
74
  });
@@ -83,16 +83,20 @@ export const deployAccount = async <
83
83
  parameters: args.initialSession ? encodeSession(args.initialSession) : "0x",
84
84
  });
85
85
 
86
+ const encodedGuardianRecoveryModuleData = encodeModuleData({
87
+ address: args.contracts.recovery,
88
+ parameters: "0x",
89
+ });
90
+
86
91
  let deployProxyArgs = {
87
92
  account: client.account!,
88
93
  chain: client.chain!,
89
94
  address: args.contracts.accountFactory,
90
- abi: FactoryAbi,
95
+ abi: AAFactoryAbi,
91
96
  functionName: "deployProxySsoAccount",
92
97
  args: [
93
- toHex(args.salt),
94
- accountId,
95
- [encodedPasskeyModuleData, encodedSessionKeyModuleData],
98
+ keccak256(toHex(accountId)),
99
+ [encodedPasskeyModuleData, encodedSessionKeyModuleData, encodedGuardianRecoveryModuleData],
96
100
  [],
97
101
  ],
98
102
  } as any;
@@ -112,14 +116,25 @@ export const deployAccount = async <
112
116
 
113
117
  const transactionReceipt = await waitForTransactionReceipt(client, { hash: transactionHash });
114
118
  if (transactionReceipt.status !== "success") throw new Error("Account deployment transaction reverted");
119
+ const getAccountId = () => {
120
+ if (transactionReceipt.contractAddress) {
121
+ return transactionReceipt.contractAddress;
122
+ }
123
+ const accountCreatedEvent = parseEventLogs({ abi: AAFactoryAbi, logs: transactionReceipt.logs })
124
+ .find((log) => log && log.eventName === "AccountCreated");
115
125
 
116
- const proxyAccountAddress = transactionReceipt.contractAddress;
117
- if (!proxyAccountAddress) {
118
- throw new Error("No contract address in transaction receipt");
119
- }
126
+ if (!accountCreatedEvent) {
127
+ throw new Error("No contract address in transaction receipt");
128
+ }
129
+
130
+ const { accountAddress } = accountCreatedEvent.args;
131
+ return accountAddress;
132
+ };
133
+
134
+ const accountAddress = getAccountId();
120
135
 
121
136
  return {
122
- address: getAddress(proxyAccountAddress),
137
+ address: getAddress(accountAddress),
123
138
  transactionReceipt: transactionReceipt,
124
139
  };
125
140
  };
@@ -141,7 +156,6 @@ export const fetchAccount = async <
141
156
  }
142
157
  }
143
158
 
144
- if (!args.contracts.accountFactory) throw new Error("Account factory address is not set");
145
159
  if (!args.contracts.passkey) throw new Error("Passkey module address is not set");
146
160
 
147
161
  let username: string | undefined = args.uniqueAccountId;
@@ -163,31 +177,26 @@ export const fetchAccount = async <
163
177
 
164
178
  if (!username) throw new Error("No account found");
165
179
 
180
+ const credentialId = toHex(base64UrlToUint8Array(username));
166
181
  const accountAddress = await readContract(client, {
167
- abi: parseAbi(["function accountMappings(string) view returns (address)"]),
168
- address: args.contracts.accountFactory,
169
- functionName: "accountMappings",
170
- args: [username],
182
+ abi: WebAuthValidatorAbi,
183
+ address: args.contracts.passkey,
184
+ functionName: "registeredAddress",
185
+ args: [origin, credentialId],
171
186
  });
172
187
 
173
188
  if (!accountAddress || accountAddress == NULL_ADDRESS) throw new Error(`No account found for username: ${username}`);
174
189
 
175
- const lowerKeyHalfBytes = await readContract(client, {
176
- abi: parseAbi(["function lowerKeyHalf(string,address) view returns (bytes32)"]),
177
- address: args.contracts.passkey,
178
- functionName: "lowerKeyHalf",
179
- args: [origin, accountAddress],
180
- });
181
- const upperKeyHalfBytes = await readContract(client, {
182
- abi: parseAbi(["function upperKeyHalf(string,address) view returns (bytes32)"]),
190
+ const publicKey = await readContract(client, {
191
+ abi: WebAuthValidatorAbi,
183
192
  address: args.contracts.passkey,
184
- functionName: "upperKeyHalf",
185
- args: [origin, accountAddress],
193
+ functionName: "getAccountKey",
194
+ args: [origin, credentialId, accountAddress],
186
195
  });
187
196
 
188
- if (!lowerKeyHalfBytes || !upperKeyHalfBytes) throw new Error(`Passkey credentials not found in on-chain module for passkey ${username}`);
197
+ if (!publicKey || !publicKey[0] || !publicKey[1]) throw new Error(`Passkey credentials not found in on-chain module for passkey ${username}`);
189
198
 
190
- const passkeyPublicKey = getPasskeySignatureFromPublicKeyBytes([lowerKeyHalfBytes, upperKeyHalfBytes]);
199
+ const passkeyPublicKey = getPasskeySignatureFromPublicKeyBytes(publicKey);
191
200
 
192
201
  return {
193
202
  username,
@@ -1,8 +1,13 @@
1
1
  import { startAuthentication, startRegistration } from "@simplewebauthn/browser";
2
2
  import { generateAuthenticationOptions, type GenerateAuthenticationOptionsOpts, generateRegistrationOptions, type GenerateRegistrationOptionsOpts, type VerifiedRegistrationResponse, verifyAuthenticationResponse, verifyRegistrationResponse } from "@simplewebauthn/server";
3
3
  import { type AuthenticationResponseJSON, type PublicKeyCredentialCreationOptionsJSON, type PublicKeyCredentialRequestOptionsJSON, type RegistrationResponseJSON } from "@simplewebauthn/types";
4
- import { type Account, type Address, type Chain, type Client, type Hash, toBytes, type Transport } from "viem";
5
- import { writeContract } from "viem/actions";
4
+ import { type Account, type Address, type Chain, type Client, encodeFunctionData, type Hash, type Hex, toBytes, toHex, type TransactionReceipt, type Transport } from "viem";
5
+ import { waitForTransactionReceipt } from "viem/actions";
6
+ import { getGeneralPaymasterInput, sendTransaction } from "viem/zksync";
7
+
8
+ import { WebAuthValidatorAbi } from "../../../abi/WebAuthValidator.js";
9
+ import { noThrow } from "../../../utils/helpers.js";
10
+ import { base64UrlToUint8Array } from "../../../utils/passkey.js";
6
11
 
7
12
  const identifyPasskeyParams = () => {
8
13
  let rpName: string | undefined;
@@ -19,7 +24,6 @@ const identifyPasskeyParams = () => {
19
24
  return { rpName, rpID, origin };
20
25
  };
21
26
 
22
- // let pubKey: Uint8Array = new Uint8Array();
23
27
  export type GeneratePasskeyRegistrationOptionsArgs = Partial<GenerateRegistrationOptionsOpts> & { userName: string; userDisplayName: string };
24
28
  export type GeneratePasskeyRegistrationOptionsReturnType = PublicKeyCredentialCreationOptionsJSON;
25
29
  export const generatePasskeyRegistrationOptions = async (args: GeneratePasskeyRegistrationOptionsArgs): Promise<GeneratePasskeyRegistrationOptionsReturnType> => {
@@ -146,22 +150,49 @@ export const requestPasskeyAuthentication = async (args: RequestPasskeyAuthentic
146
150
  };
147
151
 
148
152
  export type AddAccountOwnerPasskeyArgs = {
149
- passkeyPublicKey: Uint8Array;
150
- contracts: { session: Address };
153
+ credentialId: string;
154
+ rawPublicKey: readonly [Hex, Hex];
155
+ origin: string;
156
+ contracts: { passkey: Address };
157
+ paymaster?: {
158
+ address: Address;
159
+ paymasterInput?: Hex;
160
+ };
161
+ onTransactionSent?: (hash: Hash) => void;
162
+ };
163
+ export type AddAccountOwnerPasskeyReturnType = {
164
+ transactionReceipt: TransactionReceipt;
151
165
  };
152
- export type AddAccountOwnerPasskeyReturnType = Hash;
153
166
  export const addAccountOwnerPasskey = async <
154
167
  transport extends Transport,
155
168
  chain extends Chain,
156
169
  account extends Account,
157
170
  >(client: Client<transport, chain, account>, args: AddAccountOwnerPasskeyArgs): Promise<AddAccountOwnerPasskeyReturnType> => {
158
- /* TODO: Implement set owner passkey */
159
- const transactionHash = await writeContract(client, {
160
- address: args.contracts.session,
161
- args: [args.passkeyPublicKey],
162
- abi: [] as const,
163
- functionName: "USE_ACTUAL_METHOD_HERE",
164
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
165
- } as any);
166
- return transactionHash;
171
+ const callData = encodeFunctionData({
172
+ abi: WebAuthValidatorAbi,
173
+ functionName: "addValidationKey",
174
+ args: [toHex(base64UrlToUint8Array(args.credentialId)), args.rawPublicKey, args.origin],
175
+ });
176
+
177
+ const sendTransactionArgs = {
178
+ account: client.account,
179
+ to: args.contracts.passkey,
180
+ paymaster: args.paymaster?.address,
181
+ paymasterInput: args.paymaster?.address ? (args.paymaster?.paymasterInput || getGeneralPaymasterInput({ innerInput: "0x" })) : undefined,
182
+ data: callData,
183
+ gas: 10_000_000n, // TODO: Remove when gas estimation is fixed
184
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
185
+ } as any;
186
+
187
+ const transactionHash = await sendTransaction(client, sendTransactionArgs);
188
+ if (args.onTransactionSent) {
189
+ noThrow(() => args.onTransactionSent?.(transactionHash));
190
+ }
191
+
192
+ const transactionReceipt = await waitForTransactionReceipt(client, { hash: transactionHash });
193
+ if (transactionReceipt.status !== "success") throw new Error("addValidationKey transaction reverted");
194
+
195
+ return {
196
+ transactionReceipt,
197
+ };
167
198
  };
@@ -32,7 +32,10 @@ export function createZksyncPasskeyClient<
32
32
  credentialPublicKey: parameters.credentialPublicKey,
33
33
  });
34
34
 
35
- return passkeyHashSignatureResponseFormat(passkeySignature.passkeyAuthenticationResponse.response, parameters.contracts);
35
+ return passkeyHashSignatureResponseFormat(
36
+ passkeySignature.passkeyAuthenticationResponse.id,
37
+ passkeySignature.passkeyAuthenticationResponse.response,
38
+ parameters.contracts);
36
39
  },
37
40
  });
38
41
  const client = createClient<transport, chain, Account, rpcSchema>({
@@ -57,6 +60,7 @@ export function createZksyncPasskeyClient<
57
60
  export type PasskeyRequiredContracts = {
58
61
  session: Address; // Session, spend limit, etc.
59
62
  passkey: Address; // Validator for passkey signature
63
+ recovery: Address; // Validator for account recovery
60
64
  accountFactory?: Address; // For account creation
61
65
  };
62
66
  type ZksyncSsoPasskeyData = {
@@ -1,5 +1,10 @@
1
1
  import { type Chain, type Transport } from "viem";
2
2
 
3
+ import {
4
+ confirmGuardian, type ConfirmGuardianArgs, type ConfirmGuardianReturnType,
5
+ proposeGuardian, type ProposeGuardianArgs, type ProposeGuardianReturnType,
6
+ removeGuardian, type RemoveGuardianArgs, type RemoveGuardianReturnType,
7
+ } from "../../recovery/actions/recovery.js";
3
8
  import {
4
9
  createSession, type CreateSessionArgs, type CreateSessionReturnType,
5
10
  revokeSession, type RevokeSessionArgs, type RevokeSessionReturnType,
@@ -9,6 +14,9 @@ import type { ClientWithZksyncSsoPasskeyData } from "../client.js";
9
14
  export type ZksyncSsoPasskeyActions = {
10
15
  createSession: (args: Omit<CreateSessionArgs, "contracts">) => Promise<CreateSessionReturnType>;
11
16
  revokeSession: (args: Omit<RevokeSessionArgs, "contracts">) => Promise<RevokeSessionReturnType>;
17
+ proposeGuardian: (args: Omit<ProposeGuardianArgs, "contracts">) => Promise<ProposeGuardianReturnType>;
18
+ confirmGuardian: (args: Omit<ConfirmGuardianArgs, "contracts">) => Promise<ConfirmGuardianReturnType>;
19
+ removeGuardian: (args: Omit<RemoveGuardianArgs, "contracts">) => Promise<RemoveGuardianReturnType>;
12
20
  };
13
21
 
14
22
  export function zksyncSsoPasskeyActions<
@@ -28,5 +36,23 @@ export function zksyncSsoPasskeyActions<
28
36
  contracts: client.contracts,
29
37
  });
30
38
  },
39
+ proposeGuardian: async (args: Omit<ProposeGuardianArgs, "contracts">) => {
40
+ return await proposeGuardian(client, {
41
+ ...args,
42
+ contracts: client.contracts,
43
+ });
44
+ },
45
+ confirmGuardian: async (args: Omit<ConfirmGuardianArgs, "contracts">) => {
46
+ return await confirmGuardian(client, {
47
+ ...args,
48
+ contracts: client.contracts,
49
+ });
50
+ },
51
+ removeGuardian: async (args: Omit<RemoveGuardianArgs, "contracts">) => {
52
+ return await removeGuardian(client, {
53
+ ...args,
54
+ contracts: client.contracts,
55
+ });
56
+ },
31
57
  };
32
58
  }
@@ -0,0 +1,61 @@
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 ToRecoveryAccountParameters = {
9
+ /** Address of the deployed Account's Contract implementation. */
10
+ address: Address;
11
+ signTransaction: (parameters: { hash: Hash }) => Promise<Hex>;
12
+ };
13
+
14
+ export type RecoveryAccount = LocalAccount<"ssoRecoveryAccount"> & {
15
+ sign: NonNullable<CustomSource["sign"]>;
16
+ };
17
+
18
+ export function toRecoveryAccount(
19
+ parameters: ToRecoveryAccountParameters,
20
+ ): RecoveryAccount {
21
+ const { address, signTransaction } = parameters;
22
+
23
+ const account = toAccount({
24
+ address,
25
+ async signTransaction(transaction) {
26
+ const signableTransaction = {
27
+ ...transaction,
28
+ from: this.address!,
29
+ type: "eip712",
30
+ } as ZksyncTransactionSerializableEIP712;
31
+
32
+ const eip712DomainAndMessage = getEip712Domain(signableTransaction);
33
+ const digest = hashTypedData(eip712DomainAndMessage);
34
+
35
+ return serializeTransaction({
36
+ ...signableTransaction,
37
+ customSignature: await signTransaction({
38
+ hash: digest,
39
+ }),
40
+ });
41
+ },
42
+ async sign({ hash }) {
43
+ return signTransaction({ hash });
44
+ },
45
+ async signMessage({ message }) {
46
+ return signTransaction({
47
+ hash: hashMessage(message),
48
+ });
49
+ },
50
+ async signTypedData(typedData) {
51
+ return signTransaction({
52
+ hash: hashTypedData(typedData),
53
+ });
54
+ },
55
+ });
56
+
57
+ return {
58
+ ...account,
59
+ source: "ssoRecoveryAccount",
60
+ } as RecoveryAccount;
61
+ }