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.
- package/README.md +11 -2
- package/dist/_cjs/abi/{GuardianRecoveryModule.js → GuardianRecoveryValidator.js} +3 -3
- package/dist/_cjs/abi/GuardianRecoveryValidator.js.map +1 -0
- package/dist/_cjs/abi/SsoAccount.js +1288 -0
- package/dist/_cjs/abi/SsoAccount.js.map +1 -0
- package/dist/_cjs/abi/index.js +5 -3
- package/dist/_cjs/abi/index.js.map +1 -1
- package/dist/_cjs/client/ecdsa/decorators/wallet.js +8 -2
- package/dist/_cjs/client/ecdsa/decorators/wallet.js.map +1 -1
- package/dist/_cjs/client/index.js +74 -2
- package/dist/_cjs/client/index.js.map +1 -1
- package/dist/_cjs/client/passkey/account.js +5 -5
- package/dist/_cjs/client/passkey/account.js.map +1 -1
- package/dist/_cjs/client/passkey/actions/account.js +23 -1
- package/dist/_cjs/client/passkey/actions/account.js.map +1 -1
- package/dist/_cjs/client/passkey/actions/passkey.js +10 -7
- package/dist/_cjs/client/passkey/actions/passkey.js.map +1 -1
- package/dist/_cjs/client/passkey/client.js +3 -0
- package/dist/_cjs/client/passkey/client.js.map +1 -1
- package/dist/_cjs/client/passkey/decorators/wallet.js +7 -0
- package/dist/_cjs/client/passkey/decorators/wallet.js.map +1 -1
- package/dist/_cjs/client/recovery/actions/recovery.js +4 -4
- package/dist/_cjs/client/recovery/actions/recovery.js.map +1 -1
- package/dist/_cjs/client/recovery/decorators/wallet.js +7 -0
- package/dist/_cjs/client/recovery/decorators/wallet.js.map +1 -1
- package/dist/_cjs/client/session/actions/session.js +53 -1
- package/dist/_cjs/client/session/actions/session.js.map +1 -1
- package/dist/_cjs/client/session/client.js +19 -0
- package/dist/_cjs/client/session/client.js.map +1 -1
- package/dist/_cjs/client/session/decorators/wallet.js +46 -0
- package/dist/_cjs/client/session/decorators/wallet.js.map +1 -1
- package/dist/_cjs/client/utils/getEip712Domain.js +1 -1
- package/dist/_cjs/client/utils/getEip712Domain.js.map +1 -1
- package/dist/_cjs/client-auth-server/Signer.js +25 -1
- package/dist/_cjs/client-auth-server/Signer.js.map +1 -1
- package/dist/_cjs/client-auth-server/WalletProvider.js +3 -1
- package/dist/_cjs/client-auth-server/WalletProvider.js.map +1 -1
- package/dist/_cjs/utils/helpers.js +26 -0
- package/dist/_cjs/utils/helpers.js.map +1 -1
- package/dist/_cjs/utils/session.js +283 -1
- package/dist/_cjs/utils/session.js.map +1 -1
- package/dist/_esm/abi/{GuardianRecoveryModule.js → GuardianRecoveryValidator.js} +2 -2
- package/dist/_esm/abi/GuardianRecoveryValidator.js.map +1 -0
- package/dist/_esm/abi/SsoAccount.js +1285 -0
- package/dist/_esm/abi/SsoAccount.js.map +1 -0
- package/dist/_esm/abi/index.js +2 -1
- package/dist/_esm/abi/index.js.map +1 -1
- package/dist/_esm/client/ecdsa/decorators/wallet.js +9 -2
- package/dist/_esm/client/ecdsa/decorators/wallet.js.map +1 -1
- package/dist/_esm/client/index.js +74 -2
- package/dist/_esm/client/index.js.map +1 -1
- package/dist/_esm/client/passkey/account.js +5 -5
- package/dist/_esm/client/passkey/account.js.map +1 -1
- package/dist/_esm/client/passkey/actions/account.js +21 -0
- package/dist/_esm/client/passkey/actions/account.js.map +1 -1
- package/dist/_esm/client/passkey/actions/passkey.js +10 -8
- package/dist/_esm/client/passkey/actions/passkey.js.map +1 -1
- package/dist/_esm/client/passkey/client.js +3 -0
- package/dist/_esm/client/passkey/client.js.map +1 -1
- package/dist/_esm/client/passkey/decorators/wallet.js +8 -1
- package/dist/_esm/client/passkey/decorators/wallet.js.map +1 -1
- package/dist/_esm/client/recovery/actions/recovery.js +4 -4
- package/dist/_esm/client/recovery/actions/recovery.js.map +1 -1
- package/dist/_esm/client/recovery/decorators/wallet.js +8 -1
- package/dist/_esm/client/recovery/decorators/wallet.js.map +1 -1
- package/dist/_esm/client/session/actions/session.js +59 -1
- package/dist/_esm/client/session/actions/session.js.map +1 -1
- package/dist/_esm/client/session/client.js +20 -0
- package/dist/_esm/client/session/client.js.map +1 -1
- package/dist/_esm/client/session/decorators/wallet.js +55 -130
- package/dist/_esm/client/session/decorators/wallet.js.map +1 -1
- package/dist/_esm/client/utils/getEip712Domain.js +1 -1
- package/dist/_esm/client/utils/getEip712Domain.js.map +1 -1
- package/dist/_esm/client-auth-server/Signer.js +25 -1
- package/dist/_esm/client-auth-server/Signer.js.map +1 -1
- package/dist/_esm/client-auth-server/WalletProvider.js +3 -1
- package/dist/_esm/client-auth-server/WalletProvider.js.map +1 -1
- package/dist/_esm/utils/helpers.js +24 -0
- package/dist/_esm/utils/helpers.js.map +1 -1
- package/dist/_esm/utils/session.js +296 -1
- package/dist/_esm/utils/session.js.map +1 -1
- package/dist/_types/abi/{GuardianRecoveryModule.d.ts → GuardianRecoveryValidator.d.ts} +2 -2
- package/dist/_types/abi/{GuardianRecoveryModule.d.ts.map → GuardianRecoveryValidator.d.ts.map} +1 -1
- package/dist/_types/abi/SsoAccount.d.ts +992 -0
- package/dist/_types/abi/SsoAccount.d.ts.map +1 -0
- package/dist/_types/abi/index.d.ts +2 -1
- package/dist/_types/abi/index.d.ts.map +1 -1
- package/dist/_types/client/ecdsa/decorators/wallet.d.ts.map +1 -1
- package/dist/_types/client/index.d.ts +28 -2
- package/dist/_types/client/index.d.ts.map +1 -1
- package/dist/_types/client/passkey/account.d.ts +7 -3
- package/dist/_types/client/passkey/account.d.ts.map +1 -1
- package/dist/_types/client/passkey/actions/account.d.ts +7 -0
- package/dist/_types/client/passkey/actions/account.d.ts.map +1 -1
- package/dist/_types/client/passkey/actions/passkey.d.ts +2 -3
- package/dist/_types/client/passkey/actions/passkey.d.ts.map +1 -1
- package/dist/_types/client/passkey/client.d.ts.map +1 -1
- package/dist/_types/client/passkey/decorators/wallet.d.ts.map +1 -1
- package/dist/_types/client/recovery/decorators/wallet.d.ts.map +1 -1
- package/dist/_types/client/session/actions/session.d.ts +26 -1
- package/dist/_types/client/session/actions/session.d.ts.map +1 -1
- package/dist/_types/client/session/client.d.ts +6 -1
- package/dist/_types/client/session/client.d.ts.map +1 -1
- package/dist/_types/client/session/decorators/wallet.d.ts.map +1 -1
- package/dist/_types/client-auth-server/Signer.d.ts +3737 -905
- package/dist/_types/client-auth-server/Signer.d.ts.map +1 -1
- package/dist/_types/client-auth-server/WalletProvider.d.ts +3735 -905
- package/dist/_types/client-auth-server/WalletProvider.d.ts.map +1 -1
- package/dist/_types/utils/helpers.d.ts +7 -0
- package/dist/_types/utils/helpers.d.ts.map +1 -1
- package/dist/_types/utils/session.d.ts +51 -0
- package/dist/_types/utils/session.d.ts.map +1 -1
- package/package.json +4 -5
- package/src/abi/{GuardianRecoveryModule.ts → GuardianRecoveryValidator.ts} +1 -1
- package/src/abi/SsoAccount.ts +1284 -0
- package/src/abi/index.ts +2 -1
- package/src/client/ecdsa/decorators/wallet.ts +10 -3
- package/src/client/index.ts +119 -2
- package/src/client/passkey/account.ts +19 -9
- package/src/client/passkey/actions/account.ts +29 -0
- package/src/client/passkey/actions/passkey.ts +15 -10
- package/src/client/passkey/client.ts +5 -1
- package/src/client/passkey/decorators/wallet.ts +9 -2
- package/src/client/recovery/actions/recovery.ts +4 -4
- package/src/client/recovery/decorators/wallet.ts +9 -2
- package/src/client/session/actions/session.ts +85 -2
- package/src/client/session/client.ts +28 -1
- package/src/client/session/decorators/wallet.ts +68 -133
- package/src/client/utils/getEip712Domain.ts +1 -1
- package/src/client-auth-server/Signer.ts +18 -2
- package/src/client-auth-server/WalletProvider.ts +6 -1
- package/src/utils/helpers.ts +28 -0
- package/src/utils/session.ts +356 -1
- package/dist/_cjs/abi/GuardianRecoveryModule.js.map +0 -1
- 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 {
|
|
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 {
|
|
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
|
-
}
|
|
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
|
}
|
package/src/client/index.ts
CHANGED
|
@@ -1,5 +1,122 @@
|
|
|
1
|
-
export {
|
|
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
|
-
|
|
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 {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
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(
|
|
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.
|
|
108
|
-
credentialId: verification.registrationInfo.
|
|
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
|
|
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
|
-
|
|
139
|
-
|
|
140
|
-
|
|
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 {
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
}
|