zksync-sso 0.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.gitignore +5 -0
- package/.lintstagedrc.js +5 -0
- package/.npmignore +10 -0
- package/README.md +3 -0
- package/dist/_cjs/abi/Factory.js +197 -0
- package/dist/_cjs/abi/Factory.js.map +1 -0
- package/dist/_cjs/abi/SessionKeyModule.js +1104 -0
- package/dist/_cjs/abi/SessionKeyModule.js.map +1 -0
- package/dist/_cjs/client/actions/account.js +140 -0
- package/dist/_cjs/client/actions/account.js.map +1 -0
- package/dist/_cjs/client/actions/index.js +19 -0
- package/dist/_cjs/client/actions/index.js.map +1 -0
- package/dist/_cjs/client/actions/passkey.js +122 -0
- package/dist/_cjs/client/actions/passkey.js.map +1 -0
- package/dist/_cjs/client/actions/session.js +40 -0
- package/dist/_cjs/client/actions/session.js.map +1 -0
- package/dist/_cjs/client/clients/passkey.js +46 -0
- package/dist/_cjs/client/clients/passkey.js.map +1 -0
- package/dist/_cjs/client/clients/session.js +48 -0
- package/dist/_cjs/client/clients/session.js.map +1 -0
- package/dist/_cjs/client/decorators/index.js +19 -0
- package/dist/_cjs/client/decorators/index.js.map +1 -0
- package/dist/_cjs/client/decorators/passkey.js +15 -0
- package/dist/_cjs/client/decorators/passkey.js.map +1 -0
- package/dist/_cjs/client/decorators/session.js +7 -0
- package/dist/_cjs/client/decorators/session.js.map +1 -0
- package/dist/_cjs/client/decorators/session_wallet.js +32 -0
- package/dist/_cjs/client/decorators/session_wallet.js.map +1 -0
- package/dist/_cjs/client/index.js +22 -0
- package/dist/_cjs/client/index.js.map +1 -0
- package/dist/_cjs/client/passkey.js +20 -0
- package/dist/_cjs/client/passkey.js.map +1 -0
- package/dist/_cjs/client/smart-account.js +45 -0
- package/dist/_cjs/client/smart-account.js.map +1 -0
- package/dist/_cjs/client/utils/assertEip712Transaction.js +44 -0
- package/dist/_cjs/client/utils/assertEip712Transaction.js.map +1 -0
- package/dist/_cjs/client/utils/getEip712Domain.js +57 -0
- package/dist/_cjs/client/utils/getEip712Domain.js.map +1 -0
- package/dist/_cjs/client/utils/isEip712Transaction.js +16 -0
- package/dist/_cjs/client/utils/isEip712Transaction.js.map +1 -0
- package/dist/_cjs/client-auth-server/Signer.js +264 -0
- package/dist/_cjs/client-auth-server/Signer.js.map +1 -0
- package/dist/_cjs/client-auth-server/WalletProvider.js +107 -0
- package/dist/_cjs/client-auth-server/WalletProvider.js.map +1 -0
- package/dist/_cjs/client-auth-server/index.js +20 -0
- package/dist/_cjs/client-auth-server/index.js.map +1 -0
- package/dist/_cjs/client-auth-server/interface.js +3 -0
- package/dist/_cjs/client-auth-server/interface.js.map +1 -0
- package/dist/_cjs/client-auth-server/rpc.js +3 -0
- package/dist/_cjs/client-auth-server/rpc.js.map +1 -0
- package/dist/_cjs/client-auth-server/session.js +90 -0
- package/dist/_cjs/client-auth-server/session.js.map +1 -0
- package/dist/_cjs/communicator/PopupCommunicator.js +138 -0
- package/dist/_cjs/communicator/PopupCommunicator.js.map +1 -0
- package/dist/_cjs/communicator/index.js +6 -0
- package/dist/_cjs/communicator/index.js.map +1 -0
- package/dist/_cjs/communicator/interface.js +3 -0
- package/dist/_cjs/communicator/interface.js.map +1 -0
- package/dist/_cjs/connector/index.js +148 -0
- package/dist/_cjs/connector/index.js.map +1 -0
- package/dist/_cjs/errors/constants.js +97 -0
- package/dist/_cjs/errors/constants.js.map +1 -0
- package/dist/_cjs/errors/errors.js +122 -0
- package/dist/_cjs/errors/errors.js.map +1 -0
- package/dist/_cjs/errors/index.js +10 -0
- package/dist/_cjs/errors/index.js.map +1 -0
- package/dist/_cjs/errors/serialize.js +63 -0
- package/dist/_cjs/errors/serialize.js.map +1 -0
- package/dist/_cjs/errors/utils.js +95 -0
- package/dist/_cjs/errors/utils.js.map +1 -0
- package/dist/_cjs/index.js +6 -0
- package/dist/_cjs/index.js.map +1 -0
- package/dist/_cjs/package.json +1 -0
- package/dist/_cjs/utils/encoding.js +32 -0
- package/dist/_cjs/utils/encoding.js.map +1 -0
- package/dist/_cjs/utils/helpers.js +43 -0
- package/dist/_cjs/utils/helpers.js.map +1 -0
- package/dist/_cjs/utils/index.js +20 -0
- package/dist/_cjs/utils/index.js.map +1 -0
- package/dist/_cjs/utils/passkey.js +243 -0
- package/dist/_cjs/utils/passkey.js.map +1 -0
- package/dist/_cjs/utils/session.js +30 -0
- package/dist/_cjs/utils/session.js.map +1 -0
- package/dist/_cjs/utils/storage.js +93 -0
- package/dist/_cjs/utils/storage.js.map +1 -0
- package/dist/_cjs/version.js +5 -0
- package/dist/_cjs/version.js.map +1 -0
- package/dist/_esm/abi/Factory.js +194 -0
- package/dist/_esm/abi/Factory.js.map +1 -0
- package/dist/_esm/abi/SessionKeyModule.js +1101 -0
- package/dist/_esm/abi/SessionKeyModule.js.map +1 -0
- package/dist/_esm/client/actions/account.js +137 -0
- package/dist/_esm/client/actions/account.js.map +1 -0
- package/dist/_esm/client/actions/index.js +3 -0
- package/dist/_esm/client/actions/index.js.map +1 -0
- package/dist/_esm/client/actions/passkey.js +121 -0
- package/dist/_esm/client/actions/passkey.js.map +1 -0
- package/dist/_esm/client/actions/session.js +36 -0
- package/dist/_esm/client/actions/session.js.map +1 -0
- package/dist/_esm/client/clients/passkey.js +43 -0
- package/dist/_esm/client/clients/passkey.js.map +1 -0
- package/dist/_esm/client/clients/session.js +45 -0
- package/dist/_esm/client/clients/session.js.map +1 -0
- package/dist/_esm/client/decorators/index.js +3 -0
- package/dist/_esm/client/decorators/index.js.map +1 -0
- package/dist/_esm/client/decorators/passkey.js +13 -0
- package/dist/_esm/client/decorators/passkey.js.map +1 -0
- package/dist/_esm/client/decorators/session.js +5 -0
- package/dist/_esm/client/decorators/session.js.map +1 -0
- package/dist/_esm/client/decorators/session_wallet.js +171 -0
- package/dist/_esm/client/decorators/session_wallet.js.map +1 -0
- package/dist/_esm/client/index.js +3 -0
- package/dist/_esm/client/index.js.map +1 -0
- package/dist/_esm/client/passkey.js +4 -0
- package/dist/_esm/client/passkey.js.map +1 -0
- package/dist/_esm/client/smart-account.js +46 -0
- package/dist/_esm/client/smart-account.js.map +1 -0
- package/dist/_esm/client/utils/assertEip712Transaction.js +39 -0
- package/dist/_esm/client/utils/assertEip712Transaction.js.map +1 -0
- package/dist/_esm/client/utils/getEip712Domain.js +57 -0
- package/dist/_esm/client/utils/getEip712Domain.js.map +1 -0
- package/dist/_esm/client/utils/isEip712Transaction.js +13 -0
- package/dist/_esm/client/utils/isEip712Transaction.js.map +1 -0
- package/dist/_esm/client-auth-server/Signer.js +262 -0
- package/dist/_esm/client-auth-server/Signer.js.map +1 -0
- package/dist/_esm/client-auth-server/WalletProvider.js +104 -0
- package/dist/_esm/client-auth-server/WalletProvider.js.map +1 -0
- package/dist/_esm/client-auth-server/index.js +4 -0
- package/dist/_esm/client-auth-server/index.js.map +1 -0
- package/dist/_esm/client-auth-server/interface.js +2 -0
- package/dist/_esm/client-auth-server/interface.js.map +1 -0
- package/dist/_esm/client-auth-server/rpc.js +2 -0
- package/dist/_esm/client-auth-server/rpc.js.map +1 -0
- package/dist/_esm/client-auth-server/session.js +91 -0
- package/dist/_esm/client-auth-server/session.js.map +1 -0
- package/dist/_esm/communicator/PopupCommunicator.js +136 -0
- package/dist/_esm/communicator/PopupCommunicator.js.map +1 -0
- package/dist/_esm/communicator/index.js +2 -0
- package/dist/_esm/communicator/index.js.map +1 -0
- package/dist/_esm/communicator/interface.js +2 -0
- package/dist/_esm/communicator/interface.js.map +1 -0
- package/dist/_esm/connector/index.js +146 -0
- package/dist/_esm/connector/index.js.map +1 -0
- package/dist/_esm/errors/constants.js +94 -0
- package/dist/_esm/errors/constants.js.map +1 -0
- package/dist/_esm/errors/errors.js +124 -0
- package/dist/_esm/errors/errors.js.map +1 -0
- package/dist/_esm/errors/index.js +4 -0
- package/dist/_esm/errors/index.js.map +1 -0
- package/dist/_esm/errors/serialize.js +69 -0
- package/dist/_esm/errors/serialize.js.map +1 -0
- package/dist/_esm/errors/utils.js +101 -0
- package/dist/_esm/errors/utils.js.map +1 -0
- package/dist/_esm/index.js +2 -0
- package/dist/_esm/index.js.map +1 -0
- package/dist/_esm/package.json +1 -0
- package/dist/_esm/utils/encoding.js +26 -0
- package/dist/_esm/utils/encoding.js.map +1 -0
- package/dist/_esm/utils/helpers.js +40 -0
- package/dist/_esm/utils/helpers.js.map +1 -0
- package/dist/_esm/utils/index.js +4 -0
- package/dist/_esm/utils/index.js.map +1 -0
- package/dist/_esm/utils/passkey.js +294 -0
- package/dist/_esm/utils/passkey.js.map +1 -0
- package/dist/_esm/utils/session.js +31 -0
- package/dist/_esm/utils/session.js.map +1 -0
- package/dist/_esm/utils/storage.js +89 -0
- package/dist/_esm/utils/storage.js.map +1 -0
- package/dist/_esm/version.js +2 -0
- package/dist/_esm/version.js.map +1 -0
- package/dist/_types/abi/Factory.d.ts +149 -0
- package/dist/_types/abi/Factory.d.ts.map +1 -0
- package/dist/_types/abi/SessionKeyModule.d.ts +846 -0
- package/dist/_types/abi/SessionKeyModule.d.ts.map +1 -0
- package/dist/_types/client/actions/account.d.ts +38 -0
- package/dist/_types/client/actions/account.d.ts.map +1 -0
- package/dist/_types/client/actions/index.d.ts +3 -0
- package/dist/_types/client/actions/index.d.ts.map +1 -0
- package/dist/_types/client/actions/passkey.d.ts +45 -0
- package/dist/_types/client/actions/passkey.d.ts.map +1 -0
- package/dist/_types/client/actions/session.d.ts +14 -0
- package/dist/_types/client/actions/session.d.ts.map +1 -0
- package/dist/_types/client/clients/passkey.d.ts +32 -0
- package/dist/_types/client/clients/passkey.d.ts.map +1 -0
- package/dist/_types/client/clients/session.d.ts +26 -0
- package/dist/_types/client/clients/session.d.ts.map +1 -0
- package/dist/_types/client/decorators/index.d.ts +3 -0
- package/dist/_types/client/decorators/index.d.ts.map +1 -0
- package/dist/_types/client/decorators/passkey.d.ts +8 -0
- package/dist/_types/client/decorators/passkey.d.ts.map +1 -0
- package/dist/_types/client/decorators/session.d.ts +5 -0
- package/dist/_types/client/decorators/session.d.ts.map +1 -0
- package/dist/_types/client/decorators/session_wallet.d.ts +5 -0
- package/dist/_types/client/decorators/session_wallet.d.ts.map +1 -0
- package/dist/_types/client/index.d.ts +3 -0
- package/dist/_types/client/index.d.ts.map +1 -0
- package/dist/_types/client/passkey.d.ts +4 -0
- package/dist/_types/client/passkey.d.ts.map +1 -0
- package/dist/_types/client/smart-account.d.ts +24 -0
- package/dist/_types/client/smart-account.d.ts.map +1 -0
- package/dist/_types/client/utils/assertEip712Transaction.d.ts +11 -0
- package/dist/_types/client/utils/assertEip712Transaction.d.ts.map +1 -0
- package/dist/_types/client/utils/getEip712Domain.d.ts +3 -0
- package/dist/_types/client/utils/getEip712Domain.d.ts.map +1 -0
- package/dist/_types/client/utils/isEip712Transaction.d.ts +4 -0
- package/dist/_types/client/utils/isEip712Transaction.d.ts.map +1 -0
- package/dist/_types/client-auth-server/Signer.d.ts +52 -0
- package/dist/_types/client-auth-server/Signer.d.ts.map +1 -0
- package/dist/_types/client-auth-server/WalletProvider.d.ts +27 -0
- package/dist/_types/client-auth-server/WalletProvider.d.ts.map +1 -0
- package/dist/_types/client-auth-server/index.d.ts +4 -0
- package/dist/_types/client-auth-server/index.d.ts.map +1 -0
- package/dist/_types/client-auth-server/interface.d.ts +34 -0
- package/dist/_types/client-auth-server/interface.d.ts.map +1 -0
- package/dist/_types/client-auth-server/rpc.d.ts +55 -0
- package/dist/_types/client-auth-server/rpc.d.ts.map +1 -0
- package/dist/_types/client-auth-server/session.d.ts +45 -0
- package/dist/_types/client-auth-server/session.d.ts.map +1 -0
- package/dist/_types/communicator/PopupCommunicator.d.ts +20 -0
- package/dist/_types/communicator/PopupCommunicator.d.ts.map +1 -0
- package/dist/_types/communicator/index.d.ts +3 -0
- package/dist/_types/communicator/index.d.ts.map +1 -0
- package/dist/_types/communicator/interface.d.ts +16 -0
- package/dist/_types/communicator/interface.d.ts.map +1 -0
- package/dist/_types/connector/index.d.ts +8 -0
- package/dist/_types/connector/index.d.ts.map +1 -0
- package/dist/_types/errors/constants.d.ts +96 -0
- package/dist/_types/errors/constants.d.ts.map +1 -0
- package/dist/_types/errors/errors.d.ts +48 -0
- package/dist/_types/errors/errors.d.ts.map +1 -0
- package/dist/_types/errors/index.d.ts +5 -0
- package/dist/_types/errors/index.d.ts.map +1 -0
- package/dist/_types/errors/serialize.d.ts +13 -0
- package/dist/_types/errors/serialize.d.ts.map +1 -0
- package/dist/_types/errors/utils.d.ts +30 -0
- package/dist/_types/errors/utils.d.ts.map +1 -0
- package/dist/_types/index.d.ts +4 -0
- package/dist/_types/index.d.ts.map +1 -0
- package/dist/_types/utils/encoding.d.ts +12 -0
- package/dist/_types/utils/encoding.d.ts.map +1 -0
- package/dist/_types/utils/helpers.d.ts +4 -0
- package/dist/_types/utils/helpers.d.ts.map +1 -0
- package/dist/_types/utils/index.d.ts +4 -0
- package/dist/_types/utils/index.d.ts.map +1 -0
- package/dist/_types/utils/passkey.d.ts +47 -0
- package/dist/_types/utils/passkey.d.ts.map +1 -0
- package/dist/_types/utils/session.d.ts +95 -0
- package/dist/_types/utils/session.d.ts.map +1 -0
- package/dist/_types/utils/storage.d.ts +30 -0
- package/dist/_types/utils/storage.d.ts.map +1 -0
- package/dist/_types/version.d.ts +2 -0
- package/dist/_types/version.d.ts.map +1 -0
- package/eslint.config.js +6 -0
- package/package.json +144 -0
- package/prepare-package.mjs +39 -0
- package/project.json +67 -0
- package/src/abi/Factory.ts +193 -0
- package/src/abi/SessionKeyModule.ts +1100 -0
- package/src/client/actions/account.ts +198 -0
- package/src/client/actions/index.ts +2 -0
- package/src/client/actions/passkey.ts +165 -0
- package/src/client/actions/session.ts +118 -0
- package/src/client/clients/passkey.ts +107 -0
- package/src/client/clients/session.ts +105 -0
- package/src/client/decorators/index.ts +2 -0
- package/src/client/decorators/passkey.ts +22 -0
- package/src/client/decorators/session.ts +17 -0
- package/src/client/decorators/session_wallet.ts +184 -0
- package/src/client/index.ts +2 -0
- package/src/client/passkey.ts +3 -0
- package/src/client/smart-account.ts +68 -0
- package/src/client/utils/assertEip712Transaction.ts +49 -0
- package/src/client/utils/getEip712Domain.ts +84 -0
- package/src/client/utils/isEip712Transaction.ts +18 -0
- package/src/client-auth-server/Signer.ts +260 -0
- package/src/client-auth-server/WalletProvider.ts +114 -0
- package/src/client-auth-server/index.ts +3 -0
- package/src/client-auth-server/interface.ts +39 -0
- package/src/client-auth-server/rpc.ts +69 -0
- package/src/client-auth-server/session.ts +139 -0
- package/src/communicator/PopupCommunicator.ts +111 -0
- package/src/communicator/index.ts +2 -0
- package/src/communicator/interface.ts +15 -0
- package/src/connector/index.ts +171 -0
- package/src/errors/constants.ts +119 -0
- package/src/errors/errors.ts +168 -0
- package/src/errors/index.ts +4 -0
- package/src/errors/serialize.ts +91 -0
- package/src/errors/utils.ts +152 -0
- package/src/index.ts +3 -0
- package/src/types/index.d.ts +9 -0
- package/src/utils/encoding.ts +36 -0
- package/src/utils/helpers.ts +43 -0
- package/src/utils/index.ts +3 -0
- package/src/utils/passkey.ts +344 -0
- package/src/utils/session.ts +103 -0
- package/src/utils/storage.ts +87 -0
- package/src/version.ts +1 -0
- package/tsconfig.base.json +44 -0
- package/tsconfig.json +11 -0
|
@@ -0,0 +1,198 @@
|
|
|
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";
|
|
2
|
+
import { readContract, waitForTransactionReceipt, writeContract } from "viem/actions";
|
|
3
|
+
import { getGeneralPaymasterInput } from "viem/zksync";
|
|
4
|
+
|
|
5
|
+
import { FactoryAbi } from "../../abi/Factory.js";
|
|
6
|
+
import { encodeModuleData, encodePasskeyModuleParameters, encodeSession } from "../../utils/encoding.js";
|
|
7
|
+
import { noThrow } from "../../utils/helpers.js";
|
|
8
|
+
import { getPasskeySignatureFromPublicKeyBytes, getPublicKeyBytesFromPasskeySignature } from "../../utils/passkey.js";
|
|
9
|
+
import type { SessionConfig } from "../../utils/session.js";
|
|
10
|
+
|
|
11
|
+
/* TODO: try to get rid of most of the contract params like passkey, session */
|
|
12
|
+
/* it should come from factory, not passed manually each time */
|
|
13
|
+
export type DeployAccountArgs = {
|
|
14
|
+
credentialPublicKey: Uint8Array; // Public key of the previously registered
|
|
15
|
+
paymasterAddress?: Address; // Paymaster used to pay the fees of creating accounts
|
|
16
|
+
paymasterInput?: Hex; // Input for paymaster (if provided)
|
|
17
|
+
expectedOrigin?: string; // Expected origin of the passkey
|
|
18
|
+
uniqueAccountId?: string; // Unique account ID, can be omitted if you don't need it
|
|
19
|
+
contracts: {
|
|
20
|
+
accountFactory: Address;
|
|
21
|
+
passkey: Address;
|
|
22
|
+
session: Address;
|
|
23
|
+
};
|
|
24
|
+
initialSession?: SessionConfig;
|
|
25
|
+
salt?: Uint8Array; // Random 32 bytes
|
|
26
|
+
onTransactionSent?: (hash: Hash) => void;
|
|
27
|
+
};
|
|
28
|
+
export type DeployAccountReturnType = {
|
|
29
|
+
address: Address;
|
|
30
|
+
transactionReceipt: TransactionReceipt;
|
|
31
|
+
};
|
|
32
|
+
export type FetchAccountArgs = {
|
|
33
|
+
uniqueAccountId?: string; // Unique account ID, can be omitted if you don't need it
|
|
34
|
+
expectedOrigin?: string; // Expected origin of the passkey
|
|
35
|
+
contracts: {
|
|
36
|
+
accountFactory: Address;
|
|
37
|
+
passkey: Address;
|
|
38
|
+
session: Address;
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
export type FetchAccountReturnType = {
|
|
42
|
+
username: string;
|
|
43
|
+
address: Address;
|
|
44
|
+
passkeyPublicKey: Uint8Array;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const NULL_ADDRESS = "0x0000000000000000000000000000000000000000";
|
|
48
|
+
|
|
49
|
+
export const deployAccount = async <
|
|
50
|
+
transport extends Transport,
|
|
51
|
+
chain extends Chain,
|
|
52
|
+
account extends Account,
|
|
53
|
+
>(
|
|
54
|
+
client: Client<transport, chain, account>, // Account deployer (any viem client)
|
|
55
|
+
args: Prettify<DeployAccountArgs>,
|
|
56
|
+
): Promise<DeployAccountReturnType> => {
|
|
57
|
+
if (!args.salt) {
|
|
58
|
+
args.salt = crypto.getRandomValues(new Uint8Array(32));
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
let origin: string | undefined = args.expectedOrigin;
|
|
62
|
+
if (!origin) {
|
|
63
|
+
try {
|
|
64
|
+
origin = window.location.origin;
|
|
65
|
+
} catch {
|
|
66
|
+
throw new Error("Can't identify expectedOrigin, please provide it manually");
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const passkeyPublicKey = getPublicKeyBytesFromPasskeySignature(args.credentialPublicKey);
|
|
71
|
+
const encodedPasskeyParameters = encodePasskeyModuleParameters({
|
|
72
|
+
passkeyPublicKey,
|
|
73
|
+
expectedOrigin: origin,
|
|
74
|
+
});
|
|
75
|
+
const encodedPasskeyModuleData = encodeModuleData({
|
|
76
|
+
address: args.contracts.passkey,
|
|
77
|
+
parameters: encodedPasskeyParameters,
|
|
78
|
+
});
|
|
79
|
+
const accountId = args.uniqueAccountId || encodedPasskeyParameters;
|
|
80
|
+
|
|
81
|
+
const encodedSessionKeyModuleData = encodeModuleData({
|
|
82
|
+
address: args.contracts.session,
|
|
83
|
+
parameters: args.initialSession == null ? "0x" : encodeSession(args.initialSession),
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
let deployProxyArgs = {
|
|
87
|
+
account: client.account!,
|
|
88
|
+
chain: client.chain!,
|
|
89
|
+
address: args.contracts.accountFactory,
|
|
90
|
+
abi: FactoryAbi,
|
|
91
|
+
functionName: "deployProxy7579Account",
|
|
92
|
+
args: [
|
|
93
|
+
toHex(args.salt),
|
|
94
|
+
accountId,
|
|
95
|
+
[encodedPasskeyModuleData],
|
|
96
|
+
[encodedSessionKeyModuleData],
|
|
97
|
+
[],
|
|
98
|
+
],
|
|
99
|
+
} as any;
|
|
100
|
+
|
|
101
|
+
if (args.paymasterAddress) {
|
|
102
|
+
deployProxyArgs = {
|
|
103
|
+
...deployProxyArgs,
|
|
104
|
+
paymaster: args.paymasterAddress,
|
|
105
|
+
paymasterInput: args.paymasterInput ?? getGeneralPaymasterInput({ innerInput: "0x" }),
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const transactionHash = await writeContract(client, deployProxyArgs);
|
|
110
|
+
if (args.onTransactionSent) {
|
|
111
|
+
noThrow(() => args.onTransactionSent?.(transactionHash));
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const transactionReceipt = await waitForTransactionReceipt(client, { hash: transactionHash });
|
|
115
|
+
if (transactionReceipt.status !== "success") throw new Error("Account deployment transaction reverted");
|
|
116
|
+
|
|
117
|
+
const proxyAccountAddress = transactionReceipt.contractAddress;
|
|
118
|
+
if (!proxyAccountAddress) {
|
|
119
|
+
throw new Error("No contract address in transaction receipt");
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return {
|
|
123
|
+
address: getAddress(proxyAccountAddress),
|
|
124
|
+
transactionReceipt: transactionReceipt,
|
|
125
|
+
};
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
export const fetchAccount = async <
|
|
129
|
+
transport extends Transport,
|
|
130
|
+
chain extends Chain,
|
|
131
|
+
account extends Account,
|
|
132
|
+
>(
|
|
133
|
+
client: Client<transport, chain, account>, // Account deployer (any viem client)
|
|
134
|
+
args: Prettify<FetchAccountArgs>,
|
|
135
|
+
): Promise<FetchAccountReturnType> => {
|
|
136
|
+
let origin: string | undefined = args.expectedOrigin;
|
|
137
|
+
if (!origin) {
|
|
138
|
+
try {
|
|
139
|
+
origin = window.location.origin;
|
|
140
|
+
} catch {
|
|
141
|
+
throw new Error("Can't identify expectedOrigin, please provide it manually");
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (!args.contracts.accountFactory) throw new Error("Account factory address is not set");
|
|
146
|
+
if (!args.contracts.passkey) throw new Error("Passkey module address is not set");
|
|
147
|
+
|
|
148
|
+
let username: string | undefined = args.uniqueAccountId;
|
|
149
|
+
if (!username) {
|
|
150
|
+
try {
|
|
151
|
+
const credential = await navigator.credentials.get({
|
|
152
|
+
publicKey: {
|
|
153
|
+
challenge: new Uint8Array(32),
|
|
154
|
+
userVerification: "discouraged",
|
|
155
|
+
},
|
|
156
|
+
}) as PublicKeyCredential | null;
|
|
157
|
+
|
|
158
|
+
if (!credential) throw new Error("No registered passkeys");
|
|
159
|
+
username = credential.id;
|
|
160
|
+
} catch {
|
|
161
|
+
throw new Error("Unable to retrieve passkey");
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
if (!username) throw new Error("No account found");
|
|
166
|
+
|
|
167
|
+
const accountAddress = await readContract(client, {
|
|
168
|
+
abi: parseAbi(["function accountMappings(string) view returns (address)"]),
|
|
169
|
+
address: args.contracts.accountFactory,
|
|
170
|
+
functionName: "accountMappings",
|
|
171
|
+
args: [username],
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
if (!accountAddress || accountAddress == NULL_ADDRESS) throw new Error(`No account found for username: ${username}`);
|
|
175
|
+
|
|
176
|
+
const lowerKeyHalfBytes = await readContract(client, {
|
|
177
|
+
abi: parseAbi(["function lowerKeyHalf(string,address) view returns (bytes32)"]),
|
|
178
|
+
address: args.contracts.passkey,
|
|
179
|
+
functionName: "lowerKeyHalf",
|
|
180
|
+
args: [origin, accountAddress],
|
|
181
|
+
});
|
|
182
|
+
const upperKeyHalfBytes = await readContract(client, {
|
|
183
|
+
abi: parseAbi(["function upperKeyHalf(string,address) view returns (bytes32)"]),
|
|
184
|
+
address: args.contracts.passkey,
|
|
185
|
+
functionName: "upperKeyHalf",
|
|
186
|
+
args: [origin, accountAddress],
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
if (!lowerKeyHalfBytes || !upperKeyHalfBytes) throw new Error(`Passkey credentials not found in on-chain module for passkey ${username}`);
|
|
190
|
+
|
|
191
|
+
const passkeyPublicKey = getPasskeySignatureFromPublicKeyBytes([lowerKeyHalfBytes, upperKeyHalfBytes]);
|
|
192
|
+
|
|
193
|
+
return {
|
|
194
|
+
username,
|
|
195
|
+
address: accountAddress,
|
|
196
|
+
passkeyPublicKey,
|
|
197
|
+
};
|
|
198
|
+
};
|
|
@@ -0,0 +1,165 @@
|
|
|
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, type Hash, toBytes, type Transport } from "viem";
|
|
5
|
+
import { writeContract } from "viem/actions";
|
|
6
|
+
|
|
7
|
+
const identifyPasskeyParams = () => {
|
|
8
|
+
let rpName: string | undefined;
|
|
9
|
+
let rpID: string | undefined;
|
|
10
|
+
let origin: string | undefined;
|
|
11
|
+
try {
|
|
12
|
+
rpName = window.location.hostname;
|
|
13
|
+
rpID = window.location.hostname;
|
|
14
|
+
origin = window.location.origin;
|
|
15
|
+
} catch {
|
|
16
|
+
// ignore
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return { rpName, rpID, origin };
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
// let pubKey: Uint8Array = new Uint8Array();
|
|
23
|
+
export type GeneratePasskeyRegistrationOptionsArgs = Partial<GenerateRegistrationOptionsOpts> & { userName: string; userDisplayName: string };
|
|
24
|
+
export type GeneratePasskeyRegistrationOptionsReturnType = PublicKeyCredentialCreationOptionsJSON;
|
|
25
|
+
export const generatePasskeyRegistrationOptions = async (args: GeneratePasskeyRegistrationOptionsArgs): Promise<GeneratePasskeyRegistrationOptionsReturnType> => {
|
|
26
|
+
let { rpName, rpID } = identifyPasskeyParams();
|
|
27
|
+
rpName = args.rpName || rpName;
|
|
28
|
+
rpID = args.rpID || rpID;
|
|
29
|
+
if (!rpName || !rpID) throw new Error("Can't set rpName and rpID automatically, please provide them manually in the arguments");
|
|
30
|
+
|
|
31
|
+
const defaultOptions: GenerateRegistrationOptionsOpts = {
|
|
32
|
+
rpName,
|
|
33
|
+
rpID,
|
|
34
|
+
userName: args.userName,
|
|
35
|
+
userDisplayName: args.userDisplayName,
|
|
36
|
+
// We want a stable id for the passkey
|
|
37
|
+
attestationType: "direct",
|
|
38
|
+
// Not preventing users from re-registering existing authenticators
|
|
39
|
+
excludeCredentials: [],
|
|
40
|
+
// See "Guiding use of authenticators via authenticatorSelection" below
|
|
41
|
+
authenticatorSelection: {
|
|
42
|
+
residentKey: "required",
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
const params: GenerateRegistrationOptionsOpts = Object.assign({}, defaultOptions, args);
|
|
46
|
+
const options = await generateRegistrationOptions(params);
|
|
47
|
+
options.pubKeyCredParams = options.pubKeyCredParams.filter(
|
|
48
|
+
(creds) => creds.alg == 1,
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
return options;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export type GeneratePasskeyAuthenticationOptionsArgs = Partial<GenerateAuthenticationOptionsOpts>;
|
|
55
|
+
export type GeneratePasskeyAuthenticationOptionsReturnType = PublicKeyCredentialRequestOptionsJSON;
|
|
56
|
+
export const generatePasskeyAuthenticationOptions = async (args: GeneratePasskeyAuthenticationOptionsArgs): Promise<GeneratePasskeyAuthenticationOptionsReturnType> => {
|
|
57
|
+
let { rpID } = identifyPasskeyParams();
|
|
58
|
+
rpID = args.rpID || rpID;
|
|
59
|
+
if (!rpID) throw new Error("Can't set rpID automatically, please provide them manually in the arguments");
|
|
60
|
+
|
|
61
|
+
const defaultOptions: GenerateAuthenticationOptionsOpts = {
|
|
62
|
+
rpID: rpID,
|
|
63
|
+
};
|
|
64
|
+
const params: GenerateAuthenticationOptionsOpts = Object.assign({}, defaultOptions, args);
|
|
65
|
+
const options = await generateAuthenticationOptions(params);
|
|
66
|
+
if ("pubKeyCredParams" in options) {
|
|
67
|
+
options.pubKeyCredParams = (
|
|
68
|
+
options.pubKeyCredParams as Array<{ alg: number; type: string }>
|
|
69
|
+
).filter((creds) => creds.alg == -7);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return options;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
export type RegisterNewPasskeyArgs = ({ passkeyRegistrationOptions: PublicKeyCredentialCreationOptionsJSON } | GeneratePasskeyRegistrationOptionsArgs) & { origin?: string };
|
|
76
|
+
export type RegisterNewPasskeyReturnType = {
|
|
77
|
+
passkeyRegistrationOptions: PublicKeyCredentialCreationOptionsJSON;
|
|
78
|
+
passkeyRegistrationResponse: RegistrationResponseJSON;
|
|
79
|
+
verificationResponse: VerifiedRegistrationResponse;
|
|
80
|
+
credentialPublicKey: Uint8Array;
|
|
81
|
+
credentialId: string;
|
|
82
|
+
};
|
|
83
|
+
export const registerNewPasskey = async (args: RegisterNewPasskeyArgs): Promise<RegisterNewPasskeyReturnType> => {
|
|
84
|
+
let { origin } = identifyPasskeyParams();
|
|
85
|
+
origin = args.origin || origin;
|
|
86
|
+
if (!origin) throw new Error("Can't set origin automatically, please provide it manually in the arguments");
|
|
87
|
+
|
|
88
|
+
const passkeyRegistrationOptions = "passkeyRegistrationOptions" in args ? args.passkeyRegistrationOptions : await generatePasskeyRegistrationOptions(args);
|
|
89
|
+
const registrationResponse: RegistrationResponseJSON = await startRegistration(passkeyRegistrationOptions);
|
|
90
|
+
const verification = await verifyRegistrationResponse({
|
|
91
|
+
response: registrationResponse,
|
|
92
|
+
expectedChallenge: passkeyRegistrationOptions.challenge,
|
|
93
|
+
expectedOrigin: origin,
|
|
94
|
+
});
|
|
95
|
+
if (!verification.verified || !verification.registrationInfo) throw new Error("Passkey validation failed");
|
|
96
|
+
|
|
97
|
+
return {
|
|
98
|
+
passkeyRegistrationOptions,
|
|
99
|
+
passkeyRegistrationResponse: registrationResponse,
|
|
100
|
+
verificationResponse: verification,
|
|
101
|
+
credentialPublicKey: verification.registrationInfo.credentialPublicKey,
|
|
102
|
+
credentialId: verification.registrationInfo.credentialID,
|
|
103
|
+
};
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
export type RequestPasskeyAuthenticationArgs = {
|
|
107
|
+
challenge: Hash; // Transaction hash to sign
|
|
108
|
+
credentialPublicKey: Uint8Array;
|
|
109
|
+
rpID?: string;
|
|
110
|
+
origin?: string;
|
|
111
|
+
};
|
|
112
|
+
export type RequestPasskeyAuthenticationReturnType = {
|
|
113
|
+
passkeyAuthenticationResponse: AuthenticationResponseJSON;
|
|
114
|
+
passkeyAuthenticationOptions: PublicKeyCredentialRequestOptionsJSON;
|
|
115
|
+
};
|
|
116
|
+
export const requestPasskeyAuthentication = async (args: RequestPasskeyAuthenticationArgs): Promise<RequestPasskeyAuthenticationReturnType> => {
|
|
117
|
+
const passkeyAuthenticationOptions = await generatePasskeyAuthenticationOptions({
|
|
118
|
+
challenge: toBytes(args.challenge),
|
|
119
|
+
});
|
|
120
|
+
const authenticationResponse: AuthenticationResponseJSON = await startAuthentication(passkeyAuthenticationOptions);
|
|
121
|
+
|
|
122
|
+
let { rpID, origin } = identifyPasskeyParams();
|
|
123
|
+
rpID = args.rpID || passkeyAuthenticationOptions.rpId || rpID;
|
|
124
|
+
origin = args.origin || origin;
|
|
125
|
+
if (!rpID || !origin) throw new Error("Can't set rpID and origin automatically, please provide them manually in the arguments");
|
|
126
|
+
|
|
127
|
+
const verification = await verifyAuthenticationResponse({
|
|
128
|
+
response: authenticationResponse,
|
|
129
|
+
expectedChallenge: passkeyAuthenticationOptions.challenge,
|
|
130
|
+
expectedOrigin: origin,
|
|
131
|
+
expectedRPID: rpID,
|
|
132
|
+
authenticator: {
|
|
133
|
+
credentialPublicKey: args.credentialPublicKey,
|
|
134
|
+
credentialID: authenticationResponse.id,
|
|
135
|
+
counter: 0, // TODO: figure out if this has to be dynamic
|
|
136
|
+
},
|
|
137
|
+
});
|
|
138
|
+
if (!verification.verified || !verification.authenticationInfo) throw new Error("Passkey validation failed");
|
|
139
|
+
|
|
140
|
+
return {
|
|
141
|
+
passkeyAuthenticationResponse: authenticationResponse,
|
|
142
|
+
passkeyAuthenticationOptions,
|
|
143
|
+
};
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
export type AddAccountOwnerPasskeyArgs = {
|
|
147
|
+
passkeyPublicKey: Uint8Array;
|
|
148
|
+
contracts: { session: Address };
|
|
149
|
+
};
|
|
150
|
+
export type AddAccountOwnerPasskeyReturnType = Hash;
|
|
151
|
+
export const addAccountOwnerPasskey = async <
|
|
152
|
+
transport extends Transport,
|
|
153
|
+
chain extends Chain,
|
|
154
|
+
account extends Account,
|
|
155
|
+
>(client: Client<transport, chain, account>, args: AddAccountOwnerPasskeyArgs): Promise<AddAccountOwnerPasskeyReturnType> => {
|
|
156
|
+
/* TODO: Implement set owner passkey */
|
|
157
|
+
const transactionHash = await writeContract(client, {
|
|
158
|
+
address: args.contracts.session,
|
|
159
|
+
args: [args.passkeyPublicKey],
|
|
160
|
+
abi: [] as const,
|
|
161
|
+
functionName: "USE_ACTUAL_METHOD_HERE",
|
|
162
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
163
|
+
} as any);
|
|
164
|
+
return transactionHash;
|
|
165
|
+
};
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { type Account, type Address, type Chain, type Client, encodeFunctionData, type Hash, type Prettify, type TransactionReceipt, type Transport } from "viem";
|
|
2
|
+
import { waitForTransactionReceipt } from "viem/actions";
|
|
3
|
+
import { getGeneralPaymasterInput, sendTransaction } from "viem/zksync";
|
|
4
|
+
|
|
5
|
+
import { SessionKeyModuleAbi } from "../../abi/SessionKeyModule.js";
|
|
6
|
+
import { noThrow } from "../../utils/helpers.js";
|
|
7
|
+
import type { SessionConfig } from "../../utils/session.js";
|
|
8
|
+
|
|
9
|
+
/* DO NOT USE THIS. USE FUNCTION FROM PASSKEY ACTIONS INSTEAD */
|
|
10
|
+
/* TODO: Remove */
|
|
11
|
+
/* export type RequestSessionArgs = Prettify<SessionPreferences & {
|
|
12
|
+
sessionKey?: Hash;
|
|
13
|
+
contracts: {
|
|
14
|
+
session: Address
|
|
15
|
+
}
|
|
16
|
+
}> & ({ passkeyRegistrationResponse: RegistrationResponseJSON } | { passkeyRegistrationOptions: GeneratePasskeyRegistrationOptionsArgs });
|
|
17
|
+
export type RequestSessionReturnType<chain extends Chain> = {
|
|
18
|
+
transactionReceipt: ExtractChainFormatterReturnType<chain, "transactionReceipt", TransactionReceipt>;
|
|
19
|
+
sessionKey: Hash;
|
|
20
|
+
}
|
|
21
|
+
export const requestSession = async <
|
|
22
|
+
transport extends Transport,
|
|
23
|
+
chain extends Chain,
|
|
24
|
+
account extends Account
|
|
25
|
+
>(client: Client<transport, chain, account>, args: RequestSessionArgs): Promise<RequestSessionReturnType<chain>> => {
|
|
26
|
+
const passkeyRegistrationResponse: RegistrationResponseJSON =
|
|
27
|
+
'passkeyRegistrationResponse' in args
|
|
28
|
+
? args.passkeyRegistrationResponse
|
|
29
|
+
: (await requestPasskeySignature(args.passkeyRegistrationOptions)).passkeyRegistrationResponse;
|
|
30
|
+
|
|
31
|
+
const sessionKey = args.sessionKey || generatePrivateKey();
|
|
32
|
+
const sessionKeyPublicAddress = publicKeyToAddress(sessionKey);
|
|
33
|
+
const transactionHash = await createSessionWithPasskey(client, {
|
|
34
|
+
sessionKeyPublicAddress,
|
|
35
|
+
passkeyRegistrationResponse,
|
|
36
|
+
contracts: args.contracts,
|
|
37
|
+
spendLimit: args.spendLimit,
|
|
38
|
+
validUntil: args.validUntil,
|
|
39
|
+
});
|
|
40
|
+
const receipt = await waitForTransactionReceipt(client, { hash: transactionHash });
|
|
41
|
+
if (receipt.status === "reverted") throw new Error("Transaction reverted");
|
|
42
|
+
return {
|
|
43
|
+
transactionReceipt: receipt,
|
|
44
|
+
sessionKey,
|
|
45
|
+
};
|
|
46
|
+
} */
|
|
47
|
+
|
|
48
|
+
/* DO NOT USE THIS. USE FUNCTION FROM PASSKEY ACTIONS INSTEAD */
|
|
49
|
+
/* TODO: Remove */
|
|
50
|
+
/* export type CreateSessionWithPasskeyArgs = Prettify<SessionPreferences & {
|
|
51
|
+
sessionKeyPublicAddress: Address;
|
|
52
|
+
passkeyRegistrationResponse: RegistrationResponseJSON;
|
|
53
|
+
contracts: { session: Address };
|
|
54
|
+
}>
|
|
55
|
+
export type CreateSessionWithPasskeyReturnType = Hash;
|
|
56
|
+
export const createSessionWithPasskey = async <
|
|
57
|
+
transport extends Transport,
|
|
58
|
+
chain extends Chain,
|
|
59
|
+
account extends Account,
|
|
60
|
+
>(client: Client<transport, chain, account>, args: CreateSessionWithPasskeyArgs): Promise<CreateSessionWithPasskeyReturnType> => {
|
|
61
|
+
// TODO: Implement set session
|
|
62
|
+
const transactionHash = await writeContract(client, {
|
|
63
|
+
address: args.contracts.session,
|
|
64
|
+
args: [args.sessionKeyPublicAddress, args.passkeyRegistrationResponse, args.spendLimit, args.validUntil],
|
|
65
|
+
abi: [] as const,
|
|
66
|
+
functionName: "USE_ACTUAL_METHOD_HERE2222",
|
|
67
|
+
} as any);
|
|
68
|
+
return transactionHash;
|
|
69
|
+
} */
|
|
70
|
+
|
|
71
|
+
export type CreateSessionArgs = {
|
|
72
|
+
sessionConfig: SessionConfig;
|
|
73
|
+
contracts: {
|
|
74
|
+
session: Address; // session module
|
|
75
|
+
};
|
|
76
|
+
onTransactionSent?: (hash: Hash) => void;
|
|
77
|
+
};
|
|
78
|
+
export type CreateSessionReturnType = {
|
|
79
|
+
transactionReceipt: TransactionReceipt;
|
|
80
|
+
};
|
|
81
|
+
export const createSession = async <
|
|
82
|
+
transport extends Transport,
|
|
83
|
+
chain extends Chain,
|
|
84
|
+
account extends Account,
|
|
85
|
+
>(client: Client<transport, chain, account>, args: Prettify<CreateSessionArgs>): Promise<Prettify<CreateSessionReturnType>> => {
|
|
86
|
+
const callData = encodeFunctionData({
|
|
87
|
+
abi: SessionKeyModuleAbi,
|
|
88
|
+
functionName: "createSession",
|
|
89
|
+
args: [args.sessionConfig],
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
let sendTransactionArgs = {
|
|
93
|
+
to: args.contracts.session,
|
|
94
|
+
data: callData,
|
|
95
|
+
gas: 10_000_000n, // TODO: Remove when gas estimation is fixed
|
|
96
|
+
} as any;
|
|
97
|
+
|
|
98
|
+
if ((client as any).paymasterAddress) {
|
|
99
|
+
sendTransactionArgs = {
|
|
100
|
+
...sendTransactionArgs,
|
|
101
|
+
account: client.account,
|
|
102
|
+
paymaster: (client as any).paymasterAddress,
|
|
103
|
+
paymasterInput: (client as any).paymasterInput ?? getGeneralPaymasterInput({ innerInput: "0x" }),
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const transactionHash = await sendTransaction(client, sendTransactionArgs);
|
|
108
|
+
if (args.onTransactionSent) {
|
|
109
|
+
noThrow(() => args.onTransactionSent?.(transactionHash));
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const transactionReceipt = await waitForTransactionReceipt(client, { hash: transactionHash });
|
|
113
|
+
if (transactionReceipt.status !== "success") throw new Error("createSession transaction reverted");
|
|
114
|
+
|
|
115
|
+
return {
|
|
116
|
+
transactionReceipt,
|
|
117
|
+
};
|
|
118
|
+
};
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { type Account, type Address, type Chain, type Client, createClient, getAddress, type Hex, type Prettify, type PublicActions, publicActions, type PublicRpcSchema, type RpcSchema, type Transport, type WalletActions, walletActions, type WalletClientConfig, type WalletRpcSchema } from "viem";
|
|
2
|
+
import { eip712WalletActions } from "viem/zksync";
|
|
3
|
+
|
|
4
|
+
import { passkeyHashSignatureResponseFormat } from "../../utils/passkey.js";
|
|
5
|
+
import { requestPasskeyAuthentication } from "../actions/passkey.js";
|
|
6
|
+
import { type ZksyncSsoPasskeyActions, zksyncSsoPasskeyActions } from "../decorators/passkey.js";
|
|
7
|
+
import { toSmartAccount } from "../smart-account.js";
|
|
8
|
+
|
|
9
|
+
export function createZksyncPasskeyClient<
|
|
10
|
+
transport extends Transport,
|
|
11
|
+
chain extends Chain,
|
|
12
|
+
rpcSchema extends RpcSchema | undefined = undefined,
|
|
13
|
+
>(_parameters: ZksyncSsoPasskeyClientConfig<transport, chain, rpcSchema>): ZksyncSsoPasskeyClient<transport, chain, rpcSchema> {
|
|
14
|
+
type WalletClientParameters = typeof _parameters;
|
|
15
|
+
const parameters: WalletClientParameters & {
|
|
16
|
+
key: NonNullable<WalletClientParameters["key"]>;
|
|
17
|
+
name: NonNullable<WalletClientParameters["name"]>;
|
|
18
|
+
} = {
|
|
19
|
+
..._parameters,
|
|
20
|
+
address: getAddress(_parameters.address),
|
|
21
|
+
key: _parameters.key || "wallet",
|
|
22
|
+
name: _parameters.name || "ZKsync SSO Passkey Client",
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const account = toSmartAccount({
|
|
26
|
+
address: parameters.address,
|
|
27
|
+
sign: async ({ hash }) => {
|
|
28
|
+
const passkeySignature = await requestPasskeyAuthentication({
|
|
29
|
+
challenge: hash,
|
|
30
|
+
credentialPublicKey: parameters.credentialPublicKey,
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
return passkeyHashSignatureResponseFormat(passkeySignature.passkeyAuthenticationResponse.response, parameters.contracts);
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
const client = createClient<transport, chain, Account, rpcSchema>({
|
|
37
|
+
...parameters,
|
|
38
|
+
account,
|
|
39
|
+
type: "walletClient",
|
|
40
|
+
})
|
|
41
|
+
.extend(() => ({
|
|
42
|
+
credentialPublicKey: parameters.credentialPublicKey,
|
|
43
|
+
userName: parameters.userName,
|
|
44
|
+
userDisplayName: parameters.userDisplayName,
|
|
45
|
+
contracts: parameters.contracts,
|
|
46
|
+
paymasterAddress: parameters.paymasterAddress,
|
|
47
|
+
paymasterInput: parameters.paymasterInput,
|
|
48
|
+
}))
|
|
49
|
+
.extend(publicActions)
|
|
50
|
+
.extend(walletActions)
|
|
51
|
+
.extend(eip712WalletActions())
|
|
52
|
+
.extend(zksyncSsoPasskeyActions);
|
|
53
|
+
return client;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export type PasskeyRequiredContracts = {
|
|
57
|
+
session: Address; // Session, spend limit, etc.
|
|
58
|
+
passkey: Address; // Validator for passkey signature
|
|
59
|
+
accountFactory?: Address; // For account creation
|
|
60
|
+
};
|
|
61
|
+
type ZksyncSsoPasskeyData = {
|
|
62
|
+
credentialPublicKey: Uint8Array; // Public key of the passkey
|
|
63
|
+
userName: string; // Basically unique user id (which is called `userName` in webauthn)
|
|
64
|
+
userDisplayName: string; // Also option required for webauthn
|
|
65
|
+
contracts: PasskeyRequiredContracts;
|
|
66
|
+
paymasterAddress?: Address;
|
|
67
|
+
paymasterInput?: Hex;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export type ClientWithZksyncSsoPasskeyData<
|
|
71
|
+
transport extends Transport = Transport,
|
|
72
|
+
chain extends Chain = Chain,
|
|
73
|
+
> = Client<transport, chain, Account> & ZksyncSsoPasskeyData;
|
|
74
|
+
|
|
75
|
+
export type ZksyncSsoPasskeyClient<
|
|
76
|
+
transport extends Transport = Transport,
|
|
77
|
+
chain extends Chain = Chain,
|
|
78
|
+
rpcSchema extends RpcSchema | undefined = undefined,
|
|
79
|
+
account extends Account = Account,
|
|
80
|
+
> = Prettify<
|
|
81
|
+
Client<
|
|
82
|
+
transport,
|
|
83
|
+
chain,
|
|
84
|
+
account,
|
|
85
|
+
rpcSchema extends RpcSchema
|
|
86
|
+
? [...PublicRpcSchema, ...WalletRpcSchema, ...rpcSchema]
|
|
87
|
+
: [...PublicRpcSchema, ...WalletRpcSchema],
|
|
88
|
+
PublicActions<transport, chain, account> & WalletActions<chain, account> & ZksyncSsoPasskeyActions
|
|
89
|
+
> & ZksyncSsoPasskeyData
|
|
90
|
+
>;
|
|
91
|
+
|
|
92
|
+
export interface ZksyncSsoPasskeyClientConfig<
|
|
93
|
+
transport extends Transport = Transport,
|
|
94
|
+
chain extends Chain = Chain,
|
|
95
|
+
rpcSchema extends RpcSchema | undefined = undefined,
|
|
96
|
+
> extends Omit<WalletClientConfig<transport, chain, Account, rpcSchema>, "account"> {
|
|
97
|
+
chain: NonNullable<chain>;
|
|
98
|
+
address: Address;
|
|
99
|
+
credentialPublicKey: Uint8Array;
|
|
100
|
+
userName: string;
|
|
101
|
+
userDisplayName: string;
|
|
102
|
+
contracts: PasskeyRequiredContracts;
|
|
103
|
+
paymasterAddress?: Address;
|
|
104
|
+
paymasterInput?: Hex;
|
|
105
|
+
key?: string;
|
|
106
|
+
name?: string;
|
|
107
|
+
}
|