zksync-sso 0.1.0 → 0.3.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 (135) hide show
  1. package/README.md +11 -2
  2. package/dist/_cjs/abi/{GuardianRecoveryModule.js → GuardianRecoveryValidator.js} +3 -3
  3. package/dist/_cjs/abi/GuardianRecoveryValidator.js.map +1 -0
  4. package/dist/_cjs/abi/SsoAccount.js +1288 -0
  5. package/dist/_cjs/abi/SsoAccount.js.map +1 -0
  6. package/dist/_cjs/abi/index.js +5 -3
  7. package/dist/_cjs/abi/index.js.map +1 -1
  8. package/dist/_cjs/client/ecdsa/decorators/wallet.js +8 -2
  9. package/dist/_cjs/client/ecdsa/decorators/wallet.js.map +1 -1
  10. package/dist/_cjs/client/index.js +74 -2
  11. package/dist/_cjs/client/index.js.map +1 -1
  12. package/dist/_cjs/client/passkey/account.js +5 -5
  13. package/dist/_cjs/client/passkey/account.js.map +1 -1
  14. package/dist/_cjs/client/passkey/actions/account.js +23 -1
  15. package/dist/_cjs/client/passkey/actions/account.js.map +1 -1
  16. package/dist/_cjs/client/passkey/actions/passkey.js +10 -7
  17. package/dist/_cjs/client/passkey/actions/passkey.js.map +1 -1
  18. package/dist/_cjs/client/passkey/client.js +3 -0
  19. package/dist/_cjs/client/passkey/client.js.map +1 -1
  20. package/dist/_cjs/client/passkey/decorators/wallet.js +7 -0
  21. package/dist/_cjs/client/passkey/decorators/wallet.js.map +1 -1
  22. package/dist/_cjs/client/recovery/actions/recovery.js +4 -4
  23. package/dist/_cjs/client/recovery/actions/recovery.js.map +1 -1
  24. package/dist/_cjs/client/recovery/decorators/wallet.js +7 -0
  25. package/dist/_cjs/client/recovery/decorators/wallet.js.map +1 -1
  26. package/dist/_cjs/client/session/actions/session.js +53 -1
  27. package/dist/_cjs/client/session/actions/session.js.map +1 -1
  28. package/dist/_cjs/client/session/client.js +19 -0
  29. package/dist/_cjs/client/session/client.js.map +1 -1
  30. package/dist/_cjs/client/session/decorators/wallet.js +46 -0
  31. package/dist/_cjs/client/session/decorators/wallet.js.map +1 -1
  32. package/dist/_cjs/client/utils/getEip712Domain.js +1 -1
  33. package/dist/_cjs/client/utils/getEip712Domain.js.map +1 -1
  34. package/dist/_cjs/client-auth-server/Signer.js +25 -1
  35. package/dist/_cjs/client-auth-server/Signer.js.map +1 -1
  36. package/dist/_cjs/client-auth-server/WalletProvider.js +3 -1
  37. package/dist/_cjs/client-auth-server/WalletProvider.js.map +1 -1
  38. package/dist/_cjs/utils/helpers.js +26 -0
  39. package/dist/_cjs/utils/helpers.js.map +1 -1
  40. package/dist/_cjs/utils/session.js +283 -1
  41. package/dist/_cjs/utils/session.js.map +1 -1
  42. package/dist/_esm/abi/{GuardianRecoveryModule.js → GuardianRecoveryValidator.js} +2 -2
  43. package/dist/_esm/abi/GuardianRecoveryValidator.js.map +1 -0
  44. package/dist/_esm/abi/SsoAccount.js +1285 -0
  45. package/dist/_esm/abi/SsoAccount.js.map +1 -0
  46. package/dist/_esm/abi/index.js +2 -1
  47. package/dist/_esm/abi/index.js.map +1 -1
  48. package/dist/_esm/client/ecdsa/decorators/wallet.js +9 -2
  49. package/dist/_esm/client/ecdsa/decorators/wallet.js.map +1 -1
  50. package/dist/_esm/client/index.js +74 -2
  51. package/dist/_esm/client/index.js.map +1 -1
  52. package/dist/_esm/client/passkey/account.js +5 -5
  53. package/dist/_esm/client/passkey/account.js.map +1 -1
  54. package/dist/_esm/client/passkey/actions/account.js +21 -0
  55. package/dist/_esm/client/passkey/actions/account.js.map +1 -1
  56. package/dist/_esm/client/passkey/actions/passkey.js +10 -8
  57. package/dist/_esm/client/passkey/actions/passkey.js.map +1 -1
  58. package/dist/_esm/client/passkey/client.js +3 -0
  59. package/dist/_esm/client/passkey/client.js.map +1 -1
  60. package/dist/_esm/client/passkey/decorators/wallet.js +8 -1
  61. package/dist/_esm/client/passkey/decorators/wallet.js.map +1 -1
  62. package/dist/_esm/client/recovery/actions/recovery.js +4 -4
  63. package/dist/_esm/client/recovery/actions/recovery.js.map +1 -1
  64. package/dist/_esm/client/recovery/decorators/wallet.js +8 -1
  65. package/dist/_esm/client/recovery/decorators/wallet.js.map +1 -1
  66. package/dist/_esm/client/session/actions/session.js +59 -1
  67. package/dist/_esm/client/session/actions/session.js.map +1 -1
  68. package/dist/_esm/client/session/client.js +20 -0
  69. package/dist/_esm/client/session/client.js.map +1 -1
  70. package/dist/_esm/client/session/decorators/wallet.js +55 -130
  71. package/dist/_esm/client/session/decorators/wallet.js.map +1 -1
  72. package/dist/_esm/client/utils/getEip712Domain.js +1 -1
  73. package/dist/_esm/client/utils/getEip712Domain.js.map +1 -1
  74. package/dist/_esm/client-auth-server/Signer.js +25 -1
  75. package/dist/_esm/client-auth-server/Signer.js.map +1 -1
  76. package/dist/_esm/client-auth-server/WalletProvider.js +3 -1
  77. package/dist/_esm/client-auth-server/WalletProvider.js.map +1 -1
  78. package/dist/_esm/utils/helpers.js +24 -0
  79. package/dist/_esm/utils/helpers.js.map +1 -1
  80. package/dist/_esm/utils/session.js +296 -1
  81. package/dist/_esm/utils/session.js.map +1 -1
  82. package/dist/_types/abi/{GuardianRecoveryModule.d.ts → GuardianRecoveryValidator.d.ts} +2 -2
  83. package/dist/_types/abi/{GuardianRecoveryModule.d.ts.map → GuardianRecoveryValidator.d.ts.map} +1 -1
  84. package/dist/_types/abi/SsoAccount.d.ts +992 -0
  85. package/dist/_types/abi/SsoAccount.d.ts.map +1 -0
  86. package/dist/_types/abi/index.d.ts +2 -1
  87. package/dist/_types/abi/index.d.ts.map +1 -1
  88. package/dist/_types/client/ecdsa/decorators/wallet.d.ts.map +1 -1
  89. package/dist/_types/client/index.d.ts +28 -2
  90. package/dist/_types/client/index.d.ts.map +1 -1
  91. package/dist/_types/client/passkey/account.d.ts +7 -3
  92. package/dist/_types/client/passkey/account.d.ts.map +1 -1
  93. package/dist/_types/client/passkey/actions/account.d.ts +7 -0
  94. package/dist/_types/client/passkey/actions/account.d.ts.map +1 -1
  95. package/dist/_types/client/passkey/actions/passkey.d.ts +2 -3
  96. package/dist/_types/client/passkey/actions/passkey.d.ts.map +1 -1
  97. package/dist/_types/client/passkey/client.d.ts.map +1 -1
  98. package/dist/_types/client/passkey/decorators/wallet.d.ts.map +1 -1
  99. package/dist/_types/client/recovery/decorators/wallet.d.ts.map +1 -1
  100. package/dist/_types/client/session/actions/session.d.ts +26 -1
  101. package/dist/_types/client/session/actions/session.d.ts.map +1 -1
  102. package/dist/_types/client/session/client.d.ts +6 -1
  103. package/dist/_types/client/session/client.d.ts.map +1 -1
  104. package/dist/_types/client/session/decorators/wallet.d.ts.map +1 -1
  105. package/dist/_types/client-auth-server/Signer.d.ts +3737 -905
  106. package/dist/_types/client-auth-server/Signer.d.ts.map +1 -1
  107. package/dist/_types/client-auth-server/WalletProvider.d.ts +3735 -905
  108. package/dist/_types/client-auth-server/WalletProvider.d.ts.map +1 -1
  109. package/dist/_types/utils/helpers.d.ts +7 -0
  110. package/dist/_types/utils/helpers.d.ts.map +1 -1
  111. package/dist/_types/utils/session.d.ts +51 -0
  112. package/dist/_types/utils/session.d.ts.map +1 -1
  113. package/package.json +4 -5
  114. package/src/abi/{GuardianRecoveryModule.ts → GuardianRecoveryValidator.ts} +1 -1
  115. package/src/abi/SsoAccount.ts +1284 -0
  116. package/src/abi/index.ts +2 -1
  117. package/src/client/ecdsa/decorators/wallet.ts +10 -3
  118. package/src/client/index.ts +119 -2
  119. package/src/client/passkey/account.ts +19 -9
  120. package/src/client/passkey/actions/account.ts +29 -0
  121. package/src/client/passkey/actions/passkey.ts +15 -10
  122. package/src/client/passkey/client.ts +5 -1
  123. package/src/client/passkey/decorators/wallet.ts +9 -2
  124. package/src/client/recovery/actions/recovery.ts +4 -4
  125. package/src/client/recovery/decorators/wallet.ts +9 -2
  126. package/src/client/session/actions/session.ts +85 -2
  127. package/src/client/session/client.ts +28 -1
  128. package/src/client/session/decorators/wallet.ts +68 -133
  129. package/src/client/utils/getEip712Domain.ts +1 -1
  130. package/src/client-auth-server/Signer.ts +18 -2
  131. package/src/client-auth-server/WalletProvider.ts +6 -1
  132. package/src/utils/helpers.ts +28 -0
  133. package/src/utils/session.ts +356 -1
  134. package/dist/_cjs/abi/GuardianRecoveryModule.js.map +0 -1
  135. package/dist/_esm/abi/GuardianRecoveryModule.js.map +0 -1
package/src/abi/index.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export { AAFactoryAbi } from "./AAFactory.js";
2
- export { GuardianRecoveryModuleAbi } from "./GuardianRecoveryModule.js";
2
+ export { GuardianRecoveryValidatorAbi } from "./GuardianRecoveryValidator.js";
3
3
  export { SessionKeyValidatorAbi } from "./SessionKeyValidator.js";
4
+ export { SsoAccountAbi } from "./SsoAccount.js";
4
5
  export { WebAuthValidatorAbi } from "./WebAuthValidator.js";
@@ -1,6 +1,6 @@
1
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";
2
+ import { deployContract, getAddresses, getCallsStatus, getCapabilities, getChainId, prepareAuthorization, sendCalls, sendRawTransaction, showCallsStatus, signAuthorization, signMessage, signTransaction, signTypedData, waitForCallsStatus, writeContract } from "viem/actions";
3
+ import { type TransactionRequestEIP712, type ZksyncEip712Meta } from "viem/zksync";
4
4
 
5
5
  import { getTransactionWithPaymasterData } from "../../../paymaster/index.js";
6
6
  import { sendEip712Transaction } from "../../session/actions/sendEip712Transaction.js";
@@ -65,9 +65,16 @@ export function zksyncSsoEcdsaWalletActions<
65
65
  return signTransaction(client, {
66
66
  ...args,
67
67
  unformattedTxWithPaymaster,
68
- } as any);
68
+ });
69
69
  },
70
70
  signTypedData: (args) => signTypedData(client, args),
71
71
  writeContract: (args) => writeContract(client, args),
72
+ signAuthorization: (args) => signAuthorization(client, args),
73
+ getCallsStatus: (args) => getCallsStatus(client, args),
74
+ getCapabilities: (args) => getCapabilities(client, args),
75
+ prepareAuthorization: (args) => prepareAuthorization(client, args),
76
+ sendCalls: (args) => sendCalls(client, args),
77
+ showCallsStatus: (args) => showCallsStatus(client, args),
78
+ waitForCallsStatus: (args) => waitForCallsStatus(client, args),
72
79
  };
73
80
  }
@@ -1,5 +1,122 @@
1
- export { deployAccount as deployEcdsaAccount, fetchAccount as fetchEcdsaAccount } from "./ecdsa/actions/account.js";
2
- export { deployAccount, fetchAccount } from "./passkey/actions/account.js";
1
+ export { fetchAccount as fetchEcdsaAccount } from "./ecdsa/actions/account.js";
2
+ export { deployAccount, fetchAccount, fetchAccount as fetchPasskeyAccount } from "./passkey/actions/account.js";
3
3
  export * from "./recovery/actions/recovery.js";
4
4
  export * from "./recovery/client.js";
5
5
  export * from "./session/client.js";
6
+
7
+ import type { Account, Address, Chain, Client, Hash, Hex, Prettify, TransactionReceipt, Transport } from "viem";
8
+ import { concat, getAddress, keccak256, parseEventLogs, toHex } from "viem";
9
+ import { waitForTransactionReceipt, writeContract } from "viem/actions";
10
+ import { getGeneralPaymasterInput } from "viem/zksync";
11
+
12
+ import { AAFactoryAbi } from "../abi/AAFactory.js";
13
+ import { encodeModuleData, encodeSession } from "../utils/encoding.js";
14
+ import { noThrow } from "../utils/helpers.js";
15
+ import type { SessionConfig } from "../utils/session.js";
16
+ import { type DeployAccountPasskeyArgs, encodePasskeyModuleData } from "./passkey/actions/account.js";
17
+
18
+ export type DeployAccountPaymasterArgs = {
19
+ location: Address; // Paymaster address used to pay the fees of creating accounts
20
+ input?: Hex; // Input for paymaster (if provided)
21
+ };
22
+ export type DeployAccountSessionArgs = {
23
+ location: Address; // module address
24
+ initialSession?: SessionConfig;
25
+ };
26
+
27
+ export type DeployAccountArgs = {
28
+ accountFactory: Address;
29
+ installNoDataModules: Address[];
30
+ owners: Address[]; // ECDSA owners (can be empty)
31
+ sessionModule?: DeployAccountSessionArgs;
32
+ paymaster?: DeployAccountPaymasterArgs;
33
+ passkeyModule?: DeployAccountPasskeyArgs;
34
+ uniqueAccountId?: string; // Unique account ID, can be omitted if you don't need it
35
+ onTransactionSent?: (hash: Hash) => void;
36
+ };
37
+
38
+ export type DeployAccountReturnType = {
39
+ address: Address;
40
+ transactionReceipt: TransactionReceipt;
41
+ };
42
+
43
+ export const deployModularAccount = async <
44
+ transport extends Transport,
45
+ chain extends Chain,
46
+ account extends Account,
47
+ >(
48
+ client: Client<transport, chain, account>, // Account deployer (any viem client)
49
+ args: Prettify<DeployAccountArgs>,
50
+ ): Promise<DeployAccountReturnType> => {
51
+ const uniqueIds: Hex[] = [];
52
+ if (args.uniqueAccountId) {
53
+ uniqueIds.push(toHex(args.uniqueAccountId));
54
+ }
55
+ if (args.owners) {
56
+ uniqueIds.push(...args.owners);
57
+ }
58
+
59
+ const modules = [];
60
+ if (args.sessionModule) {
61
+ modules.push(encodeModuleData({
62
+ address: args.sessionModule.location,
63
+ parameters: args.sessionModule.initialSession ? encodeSession(args.sessionModule.initialSession) : "0x",
64
+ }));
65
+ }
66
+ if (args.passkeyModule) {
67
+ uniqueIds.push(toHex(args.passkeyModule.credentialId));
68
+ modules.push(await encodePasskeyModuleData(args.passkeyModule));
69
+ }
70
+
71
+ if (args.installNoDataModules) {
72
+ args.installNoDataModules.forEach((moduleNoDataInstall) => {
73
+ modules.push(encodeModuleData({
74
+ address: moduleNoDataInstall,
75
+ parameters: "0x",
76
+ }));
77
+ });
78
+ }
79
+
80
+ let deployProxyArgs = {
81
+ account: client.account!,
82
+ chain: client.chain!,
83
+ address: args.accountFactory,
84
+ abi: AAFactoryAbi,
85
+ functionName: "deployProxySsoAccount",
86
+ args: [
87
+ keccak256(toHex(concat(uniqueIds))),
88
+ modules,
89
+ args.owners,
90
+ ],
91
+ } as any;
92
+
93
+ if (args.paymaster) {
94
+ deployProxyArgs = {
95
+ ...deployProxyArgs,
96
+ paymaster: args.paymaster.location,
97
+ paymasterInput: args.paymaster.input ?? getGeneralPaymasterInput({ innerInput: "0x" }),
98
+ };
99
+ }
100
+
101
+ const transactionHash = await writeContract(client, deployProxyArgs);
102
+ if (args.onTransactionSent) {
103
+ noThrow(() => args.onTransactionSent?.(transactionHash));
104
+ }
105
+
106
+ const transactionReceipt = await waitForTransactionReceipt(client, { hash: transactionHash });
107
+ if (transactionReceipt.status !== "success") throw new Error("Account deployment transaction reverted");
108
+
109
+ const accountCreatedEvent = parseEventLogs({ abi: AAFactoryAbi, logs: transactionReceipt.logs })
110
+ .find((log) => log && log.eventName === "AccountCreated");
111
+
112
+ if (!accountCreatedEvent) {
113
+ throw new Error("No contract address in transaction receipt");
114
+ }
115
+
116
+ const { accountAddress } = accountCreatedEvent.args;
117
+
118
+ return {
119
+ address: getAddress(accountAddress),
120
+ transactionReceipt: transactionReceipt,
121
+ };
122
+ };
@@ -1,22 +1,32 @@
1
1
  import type { Address } from "abitype";
2
- import { type CustomSource, type Hash, hashMessage, hashTypedData, type Hex, type LocalAccount } from "viem";
2
+ import { type Chain, type CustomSource, type Hash, hashMessage, hashTypedData, type Hex, type LocalAccount, type Transport } from "viem";
3
3
  import { toAccount } from "viem/accounts";
4
4
  import { serializeTransaction, type ZksyncTransactionSerializableEIP712 } from "viem/zksync";
5
5
 
6
6
  import { getEip712Domain } from "../utils/getEip712Domain.js";
7
+ import type { PasskeyRequiredContracts } from "./client.js";
7
8
 
8
- export type ToPasskeyAccountParameters = {
9
+ export type ToPasskeyAccountParameters<
10
+ transport extends Transport = Transport,
11
+ chain extends Chain = Chain,
12
+ > = {
9
13
  /** Address of the deployed Account's Contract implementation. */
10
14
  address: Address;
11
15
  sign: (parameters: { hash: Hash }) => Promise<Hex>;
16
+ chain: NonNullable<chain>;
17
+ transport: transport;
18
+ contracts: PasskeyRequiredContracts;
12
19
  };
13
20
 
14
21
  export type PasskeyAccount = LocalAccount<"ssoPasskeyAccount"> & {
15
22
  sign: NonNullable<CustomSource["sign"]>;
16
23
  };
17
24
 
18
- export function toPasskeyAccount(
19
- parameters: ToPasskeyAccountParameters,
25
+ export function toPasskeyAccount<
26
+ transport extends Transport = Transport,
27
+ chain extends Chain = Chain,
28
+ >(
29
+ parameters: ToPasskeyAccountParameters<transport, chain>,
20
30
  ): PasskeyAccount {
21
31
  const { address, sign } = parameters;
22
32
 
@@ -28,6 +38,11 @@ export function toPasskeyAccount(
28
38
  hash: hashMessage(message),
29
39
  });
30
40
  },
41
+ async signTypedData(typedData) {
42
+ return sign({
43
+ hash: hashTypedData(typedData),
44
+ });
45
+ },
31
46
  async signTransaction(transaction) {
32
47
  const signableTransaction = {
33
48
  ...transaction,
@@ -45,11 +60,6 @@ export function toPasskeyAccount(
45
60
  }),
46
61
  });
47
62
  },
48
- async signTypedData(typedData) {
49
- return sign({
50
- hash: hashTypedData(typedData),
51
- });
52
- },
53
63
  });
54
64
 
55
65
  return {
@@ -9,6 +9,35 @@ import { noThrow } from "../../../utils/helpers.js";
9
9
  import { base64UrlToUint8Array, getPasskeySignatureFromPublicKeyBytes, getPublicKeyBytesFromPasskeySignature } from "../../../utils/passkey.js";
10
10
  import type { SessionConfig } from "../../../utils/session.js";
11
11
 
12
+ export type DeployAccountPasskeyArgs = {
13
+ location: Address; // module address
14
+ credentialId: string; // Unique id of the passkey public key (base64)
15
+ credentialPublicKey: Uint8Array; // Public key of the previously registered
16
+ expectedOrigin?: string; // Expected origin of the passkey
17
+ };
18
+ export const encodePasskeyModuleData = async (
19
+ args: DeployAccountPasskeyArgs,
20
+ ): Promise<Hash> => {
21
+ let origin: string | undefined = args.expectedOrigin;
22
+ if (!origin) {
23
+ try {
24
+ origin = window.location.origin;
25
+ } catch {
26
+ throw new Error("Can't identify expectedOrigin, please provide it manually");
27
+ }
28
+ }
29
+ const passkeyPublicKey = getPublicKeyBytesFromPasskeySignature(args.credentialPublicKey);
30
+ const encodedPasskeyParameters = encodePasskeyModuleParameters({
31
+ credentialId: args.credentialId,
32
+ passkeyPublicKey,
33
+ expectedOrigin: origin,
34
+ });
35
+ return encodeModuleData({
36
+ address: args.location,
37
+ parameters: encodedPasskeyParameters,
38
+ });
39
+ };
40
+
12
41
  /* TODO: try to get rid of most of the contract params like passkey, session */
13
42
  /* it should come from factory, not passed manually each time */
14
43
  export type DeployAccountArgs = {
@@ -1,7 +1,8 @@
1
1
  import { startAuthentication, startRegistration } from "@simplewebauthn/browser";
2
- import { generateAuthenticationOptions, type GenerateAuthenticationOptionsOpts, generateRegistrationOptions, type GenerateRegistrationOptionsOpts, type VerifiedRegistrationResponse, verifyAuthenticationResponse, verifyRegistrationResponse } from "@simplewebauthn/server";
3
- import { type AuthenticationResponseJSON, type PublicKeyCredentialCreationOptionsJSON, type PublicKeyCredentialRequestOptionsJSON, type RegistrationResponseJSON } from "@simplewebauthn/types";
4
- import { type Account, type Address, type Chain, type Client, encodeFunctionData, type Hash, type Hex, toBytes, toHex, type TransactionReceipt, type Transport } from "viem";
2
+ import type { AuthenticationResponseJSON, GenerateAuthenticationOptionsOpts, GenerateRegistrationOptionsOpts, PublicKeyCredentialCreationOptionsJSON, PublicKeyCredentialRequestOptionsJSON, RegistrationResponseJSON, VerifiedRegistrationResponse } from "@simplewebauthn/server";
3
+ import { generateAuthenticationOptions, generateRegistrationOptions, verifyAuthenticationResponse, verifyRegistrationResponse } from "@simplewebauthn/server";
4
+ import type { Account, Address, Chain, Client, Hash, Hex, TransactionReceipt, Transport } from "viem";
5
+ import { encodeFunctionData, toBytes, toHex } from "viem";
5
6
  import { waitForTransactionReceipt } from "viem/actions";
6
7
  import { getGeneralPaymasterInput, sendTransaction } from "viem/zksync";
7
8
 
@@ -92,7 +93,9 @@ export const registerNewPasskey = async (args: RegisterNewPasskeyArgs): Promise<
92
93
  if (!origin) throw new Error("Can't set origin automatically, please provide it manually in the arguments");
93
94
 
94
95
  const passkeyRegistrationOptions = "passkeyRegistrationOptions" in args ? args.passkeyRegistrationOptions : await generatePasskeyRegistrationOptions(args);
95
- const registrationResponse: RegistrationResponseJSON = await startRegistration(passkeyRegistrationOptions);
96
+ const registrationResponse: RegistrationResponseJSON = await startRegistration({
97
+ optionsJSON: passkeyRegistrationOptions,
98
+ });
96
99
  const verification = await verifyRegistrationResponse({
97
100
  response: registrationResponse,
98
101
  expectedChallenge: passkeyRegistrationOptions.challenge,
@@ -104,8 +107,8 @@ export const registerNewPasskey = async (args: RegisterNewPasskeyArgs): Promise<
104
107
  passkeyRegistrationOptions,
105
108
  passkeyRegistrationResponse: registrationResponse,
106
109
  verificationResponse: verification,
107
- credentialPublicKey: verification.registrationInfo.credentialPublicKey,
108
- credentialId: verification.registrationInfo.credentialID,
110
+ credentialPublicKey: verification.registrationInfo.credential.publicKey,
111
+ credentialId: verification.registrationInfo.credential.id,
109
112
  };
110
113
  };
111
114
 
@@ -123,7 +126,8 @@ export const requestPasskeyAuthentication = async (args: RequestPasskeyAuthentic
123
126
  const passkeyAuthenticationOptions = await generatePasskeyAuthenticationOptions({
124
127
  challenge: toBytes(args.challenge),
125
128
  });
126
- const authenticationResponse: AuthenticationResponseJSON = await startAuthentication(passkeyAuthenticationOptions);
129
+ const optionsJSON: PublicKeyCredentialRequestOptionsJSON = { ...passkeyAuthenticationOptions };
130
+ const authenticationResponse: AuthenticationResponseJSON = await startAuthentication({ optionsJSON: optionsJSON });
127
131
 
128
132
  let { rpID, origin } = identifyPasskeyParams();
129
133
  rpID = args.rpID || passkeyAuthenticationOptions.rpId || rpID;
@@ -135,10 +139,11 @@ export const requestPasskeyAuthentication = async (args: RequestPasskeyAuthentic
135
139
  expectedChallenge: passkeyAuthenticationOptions.challenge,
136
140
  expectedOrigin: origin,
137
141
  expectedRPID: rpID,
138
- authenticator: {
139
- credentialPublicKey: args.credentialPublicKey,
140
- credentialID: authenticationResponse.id,
142
+ credential: {
143
+ id: authenticationResponse.id,
144
+ publicKey: args.credentialPublicKey,
141
145
  counter: 0, // TODO: figure out if this has to be dynamic
146
+
142
147
  },
143
148
  });
144
149
  if (!verification.verified || !verification.authenticationInfo) throw new Error("Passkey validation failed");
@@ -26,6 +26,9 @@ export function createZksyncPasskeyClient<
26
26
 
27
27
  const account = toPasskeyAccount({
28
28
  address: parameters.address,
29
+ chain: parameters.chain,
30
+ contracts: parameters.contracts,
31
+ transport: parameters.transport,
29
32
  sign: async ({ hash }) => {
30
33
  const passkeySignature = await requestPasskeyAuthentication({
31
34
  challenge: hash,
@@ -35,7 +38,8 @@ export function createZksyncPasskeyClient<
35
38
  return passkeyHashSignatureResponseFormat(
36
39
  passkeySignature.passkeyAuthenticationResponse.id,
37
40
  passkeySignature.passkeyAuthenticationResponse.response,
38
- parameters.contracts);
41
+ parameters.contracts,
42
+ );
39
43
  },
40
44
  });
41
45
  const client = createClient<transport, chain, Account, rpcSchema>({
@@ -1,5 +1,5 @@
1
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";
2
+ import { deployContract, getAddresses, getCallsStatus, getCapabilities, getChainId, prepareAuthorization, sendCalls, sendRawTransaction, showCallsStatus, signAuthorization, signMessage, signTypedData, waitForCallsStatus, writeContract } from "viem/actions";
3
3
  import { signTransaction, type TransactionRequestEIP712, type ZksyncEip712Meta } from "viem/zksync";
4
4
 
5
5
  import { getTransactionWithPaymasterData } from "../../../paymaster/index.js";
@@ -65,9 +65,16 @@ export function zksyncSsoPasskeyWalletActions<
65
65
  return signTransaction(client, {
66
66
  ...args,
67
67
  unformattedTxWithPaymaster,
68
- } as any);
68
+ } as any) as any;
69
69
  },
70
70
  signTypedData: (args) => signTypedData(client, args),
71
71
  writeContract: (args) => writeContract(client, args),
72
+ signAuthorization: (args) => signAuthorization(client, args),
73
+ getCallsStatus: (args) => getCallsStatus(client, args),
74
+ getCapabilities: (args) => getCapabilities(client, args),
75
+ prepareAuthorization: (args) => prepareAuthorization(client, args),
76
+ sendCalls: (args) => sendCalls(client, args),
77
+ showCallsStatus: (args) => showCallsStatus(client, args),
78
+ waitForCallsStatus: (args) => waitForCallsStatus(client, args),
72
79
  };
73
80
  }
@@ -2,7 +2,7 @@ import { type Account, type Address, type Chain, type Client, encodeFunctionData
2
2
  import { waitForTransactionReceipt } from "viem/actions";
3
3
  import { getGeneralPaymasterInput, sendTransaction } from "viem/zksync";
4
4
 
5
- import { GuardianRecoveryModuleAbi } from "../../../abi/GuardianRecoveryModule.js";
5
+ import { GuardianRecoveryValidatorAbi } from "../../../abi/GuardianRecoveryValidator.js";
6
6
  import { noThrow } from "../../../utils/helpers.js";
7
7
 
8
8
  export type ProposeGuardianArgs = {
@@ -35,7 +35,7 @@ export const proposeGuardian = async <
35
35
  }
36
36
 
37
37
  const callData = encodeFunctionData({
38
- abi: GuardianRecoveryModuleAbi,
38
+ abi: GuardianRecoveryValidatorAbi,
39
39
  functionName: "proposeGuardian",
40
40
  args: [keccak256(toHex(origin)), args.newGuardian],
41
41
  });
@@ -91,7 +91,7 @@ export const confirmGuardian = async <
91
91
  }
92
92
  }
93
93
  const callData = encodeFunctionData({
94
- abi: GuardianRecoveryModuleAbi,
94
+ abi: GuardianRecoveryValidatorAbi,
95
95
  functionName: "addGuardian",
96
96
  args: [keccak256(toHex(origin)), args.accountToGuard],
97
97
  });
@@ -147,7 +147,7 @@ export const removeGuardian = async <
147
147
  }
148
148
  }
149
149
  const callData = encodeFunctionData({
150
- abi: GuardianRecoveryModuleAbi,
150
+ abi: GuardianRecoveryValidatorAbi,
151
151
  functionName: "removeGuardian",
152
152
  args: [keccak256(toHex(origin)), args.guardian],
153
153
  });
@@ -1,5 +1,5 @@
1
1
  import { type Account, bytesToHex, type Chain, formatTransaction, type Transport, type WalletActions } from "viem";
2
- import { deployContract, getAddresses, getChainId, sendRawTransaction, signMessage, signTypedData, writeContract } from "viem/actions";
2
+ import { deployContract, getAddresses, getCallsStatus, getCapabilities, getChainId, prepareAuthorization, sendCalls, sendRawTransaction, showCallsStatus, signAuthorization, signMessage, signTypedData, waitForCallsStatus, writeContract } from "viem/actions";
3
3
  import { signTransaction, type ZksyncEip712Meta } from "viem/zksync";
4
4
 
5
5
  import { sendEip712Transaction } from "../actions/sendEip712Transaction.js";
@@ -45,8 +45,15 @@ export function zksyncSsoWalletActions<
45
45
  },
46
46
  signMessage: (args) => signMessage(client, args),
47
47
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
48
- signTransaction: (args) => signTransaction(client, args as any),
48
+ signTransaction: (args) => signTransaction(client, args as any) as any,
49
49
  signTypedData: (args) => signTypedData(client, args),
50
50
  writeContract: (args) => writeContract(client, args),
51
+ signAuthorization: (args) => signAuthorization(client, args),
52
+ getCallsStatus: (args) => getCallsStatus(client, args),
53
+ getCapabilities: (args) => getCapabilities(client, args),
54
+ prepareAuthorization: (args) => prepareAuthorization(client, args),
55
+ sendCalls: (args) => sendCalls(client, args),
56
+ showCallsStatus: (args) => showCallsStatus(client, args),
57
+ waitForCallsStatus: (args) => waitForCallsStatus(client, args),
51
58
  };
52
59
  }
@@ -1,11 +1,12 @@
1
1
  import { type Account, type Address, type Chain, type Client, encodeFunctionData, type Hash, type Hex, type Prettify, type TransactionReceipt, type Transport } from "viem";
2
- import { waitForTransactionReceipt } from "viem/actions";
2
+ import { readContract, waitForTransactionReceipt } from "viem/actions";
3
3
  import { getGeneralPaymasterInput, sendTransaction } from "viem/zksync";
4
4
 
5
5
  import { SessionKeyValidatorAbi } from "../../../abi/SessionKeyValidator.js";
6
6
  import { type CustomPaymasterHandler, getTransactionWithPaymasterData } from "../../../paymaster/index.js";
7
7
  import { noThrow } from "../../../utils/helpers.js";
8
- import type { SessionConfig } from "../../../utils/session.js";
8
+ import type { SessionConfig, SessionState, SessionStateEventCallback } from "../../../utils/session.js";
9
+ import { SessionEventType, SessionStatus } from "../../../utils/session.js";
9
10
 
10
11
  export type CreateSessionArgs = {
11
12
  sessionConfig: SessionConfig;
@@ -119,3 +120,85 @@ export const revokeSession = async <
119
120
  transactionReceipt,
120
121
  };
121
122
  };
123
+
124
+ export type GetSessionStateArgs = {
125
+ account: Address;
126
+ sessionConfig: SessionConfig;
127
+ contracts: {
128
+ session: Address; // session module
129
+ };
130
+ };
131
+ export type GetSessionStateReturnType = {
132
+ sessionState: SessionState;
133
+ };
134
+ export const getSessionState = async <
135
+ transport extends Transport,
136
+ chain extends Chain,
137
+ >(client: Client<transport, chain>, args: Prettify<GetSessionStateArgs>): Promise<Prettify<GetSessionStateReturnType>> => {
138
+ const sessionState = await readContract(client, {
139
+ address: args.contracts.session,
140
+ abi: SessionKeyValidatorAbi,
141
+ functionName: "sessionState",
142
+ args: [args.account, args.sessionConfig],
143
+ });
144
+
145
+ return {
146
+ sessionState: sessionState as SessionState,
147
+ };
148
+ };
149
+
150
+ export type CheckSessionStateArgs = {
151
+ sessionConfig: SessionConfig;
152
+ sessionState: SessionState;
153
+ onSessionStateChange: SessionStateEventCallback;
154
+ sessionNotifyTimeout?: NodeJS.Timeout;
155
+ };
156
+ export type CheckSessionStateReturnType = {
157
+ newTimeout?: NodeJS.Timeout;
158
+ };
159
+
160
+ /**
161
+ * Checks the current session state and sets up expiry notification.
162
+ * This function will trigger the callback with the session state.
163
+ */
164
+ export const sessionStateNotify = (args: Prettify<CheckSessionStateArgs>): CheckSessionStateReturnType => {
165
+ // Generate a session ID for tracking timeouts
166
+ const { sessionState } = args;
167
+ const now = BigInt(Math.floor(Date.now() / 1000));
168
+
169
+ // Check session status
170
+ if (sessionState.status === SessionStatus.NotInitialized) { // Not initialized
171
+ args.onSessionStateChange({
172
+ type: SessionEventType.Inactive,
173
+ message: "Session is not initialized",
174
+ });
175
+ } else if (sessionState.status === SessionStatus.Closed) { // Closed/Revoked
176
+ args.onSessionStateChange({
177
+ type: SessionEventType.Revoked,
178
+ message: "Session has been revoked",
179
+ });
180
+ } else if (args.sessionConfig.expiresAt <= now) {
181
+ // Session has expired
182
+ args.onSessionStateChange({
183
+ type: SessionEventType.Expired,
184
+ message: "Session has expired",
185
+ });
186
+ } else {
187
+ // Session is active, set up expiry notification
188
+ const timeToExpiry = Number(args.sessionConfig.expiresAt - now) * 1000;
189
+ if (args.sessionNotifyTimeout) {
190
+ clearTimeout(args.sessionNotifyTimeout);
191
+ }
192
+ const newTimeout = setTimeout(() => {
193
+ args.onSessionStateChange({
194
+ type: SessionEventType.Expired,
195
+ message: "Session has expired",
196
+ });
197
+ }, timeToExpiry);
198
+ return {
199
+ newTimeout,
200
+ };
201
+ }
202
+
203
+ return {};
204
+ };
@@ -4,8 +4,9 @@ import { zksyncInMemoryNode } from "viem/chains";
4
4
 
5
5
  import type { CustomPaymasterHandler } from "../../paymaster/index.js";
6
6
  import { encodeSessionTx } from "../../utils/encoding.js";
7
- import type { SessionConfig } from "../../utils/session.js";
7
+ import type { SessionConfig, SessionStateEventCallback } from "../../utils/session.js";
8
8
  import { toSessionAccount } from "./account.js";
9
+ import { getSessionState, sessionStateNotify } from "./actions/session.js";
9
10
  import { publicActionsRewrite } from "./decorators/publicActionsRewrite.js";
10
11
  import { type ZksyncSsoWalletActions, zksyncSsoWalletActions } from "./decorators/wallet.js";
11
12
 
@@ -90,10 +91,31 @@ export function createZksyncSessionClient<
90
91
  sessionConfig: parameters.sessionConfig,
91
92
  contracts: parameters.contracts,
92
93
  paymasterHandler: parameters.paymasterHandler,
94
+ onSessionStateChange: parameters.onSessionStateChange,
95
+ _sessionNotifyTimeout: undefined as NodeJS.Timeout | undefined,
93
96
  }))
94
97
  .extend(publicActions)
95
98
  .extend(publicActionsRewrite)
96
99
  .extend(zksyncSsoWalletActions);
100
+
101
+ // Check session state on initialization if callback is provided
102
+ if (client.onSessionStateChange) {
103
+ getSessionState(client, {
104
+ account: client.account.address,
105
+ sessionConfig: client.sessionConfig,
106
+ contracts: client.contracts,
107
+ }).then(({ sessionState }) => {
108
+ sessionStateNotify({
109
+ sessionConfig: client.sessionConfig,
110
+ sessionState,
111
+ onSessionStateChange: client.onSessionStateChange!,
112
+ sessionNotifyTimeout: client._sessionNotifyTimeout,
113
+ });
114
+ }).catch((error) => {
115
+ console.error("Failed to get session state on initialization:", error);
116
+ });
117
+ }
118
+
97
119
  return client;
98
120
  }
99
121
 
@@ -105,6 +127,9 @@ type ZksyncSsoSessionData = {
105
127
  sessionConfig: SessionConfig;
106
128
  contracts: SessionRequiredContracts;
107
129
  paymasterHandler?: CustomPaymasterHandler;
130
+ onSessionStateChange?: SessionStateEventCallback;
131
+ skipPreTransactionStateValidation?: boolean;
132
+ _sessionNotifyTimeout?: NodeJS.Timeout;
108
133
  };
109
134
 
110
135
  export type ClientWithZksyncSsoSessionData<
@@ -143,4 +168,6 @@ export interface ZksyncSsoSessionClientConfig<
143
168
  key?: string;
144
169
  name?: string;
145
170
  paymasterHandler?: CustomPaymasterHandler;
171
+ onSessionStateChange?: SessionStateEventCallback;
172
+ skipPreTransactionStateValidation?: boolean; // Useful if you want to send session transactions really fast
146
173
  }