permissionless 0.2.33 → 0.2.35
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/CHANGELOG.md +13 -0
- package/_cjs/accounts/kernel/toKernelSmartAccount.js +3 -3
- package/_cjs/accounts/kernel/toKernelSmartAccount.js.map +1 -1
- package/_cjs/accounts/kernel/utils/signMessage.js +2 -2
- package/_cjs/accounts/kernel/utils/signMessage.js.map +1 -1
- package/_cjs/accounts/safe/toSafeSmartAccount.js +6 -2
- package/_cjs/accounts/safe/toSafeSmartAccount.js.map +1 -1
- package/_cjs/actions/passkeyServer/getCredentials.js +24 -0
- package/_cjs/actions/passkeyServer/getCredentials.js.map +1 -0
- package/_cjs/actions/passkeyServer/startRegistration.js +80 -0
- package/_cjs/actions/passkeyServer/startRegistration.js.map +1 -0
- package/_cjs/actions/passkeyServer/verifyRegistration.js +71 -0
- package/_cjs/actions/passkeyServer/verifyRegistration.js.map +1 -0
- package/_cjs/actions/passkeyServer.js +10 -0
- package/_cjs/actions/passkeyServer.js.map +1 -0
- package/_cjs/clients/decorators/passkeyServer.js +13 -0
- package/_cjs/clients/decorators/passkeyServer.js.map +1 -0
- package/_cjs/clients/passkeyServer.js +15 -0
- package/_cjs/clients/passkeyServer.js.map +1 -0
- package/_cjs/types/passkeyServer.js +3 -0
- package/_cjs/types/passkeyServer.js.map +1 -0
- package/_esm/accounts/kernel/toKernelSmartAccount.js +3 -3
- package/_esm/accounts/kernel/toKernelSmartAccount.js.map +1 -1
- package/_esm/accounts/kernel/utils/signMessage.js +2 -2
- package/_esm/accounts/kernel/utils/signMessage.js.map +1 -1
- package/_esm/accounts/safe/toSafeSmartAccount.js +6 -2
- package/_esm/accounts/safe/toSafeSmartAccount.js.map +1 -1
- package/_esm/actions/passkeyServer/getCredentials.js +20 -0
- package/_esm/actions/passkeyServer/getCredentials.js.map +1 -0
- package/_esm/actions/passkeyServer/startRegistration.js +85 -0
- package/_esm/actions/passkeyServer/startRegistration.js.map +1 -0
- package/_esm/actions/passkeyServer/verifyRegistration.js +67 -0
- package/_esm/actions/passkeyServer/verifyRegistration.js.map +1 -0
- package/_esm/actions/passkeyServer.js +5 -0
- package/_esm/actions/passkeyServer.js.map +1 -0
- package/_esm/clients/decorators/passkeyServer.js +9 -0
- package/_esm/clients/decorators/passkeyServer.js.map +1 -0
- package/_esm/clients/passkeyServer.js +12 -0
- package/_esm/clients/passkeyServer.js.map +1 -0
- package/_esm/types/passkeyServer.js +2 -0
- package/_esm/types/passkeyServer.js.map +1 -0
- package/_types/accounts/kernel/toKernelSmartAccount.d.ts.map +1 -1
- package/_types/accounts/kernel/utils/signMessage.d.ts.map +1 -1
- package/_types/accounts/safe/toSafeSmartAccount.d.ts +2 -1
- package/_types/accounts/safe/toSafeSmartAccount.d.ts.map +1 -1
- package/_types/actions/passkeyServer/getCredentials.d.ts +11 -0
- package/_types/actions/passkeyServer/getCredentials.d.ts.map +1 -0
- package/_types/actions/passkeyServer/startRegistration.d.ts +9 -0
- package/_types/actions/passkeyServer/startRegistration.d.ts.map +1 -0
- package/_types/actions/passkeyServer/verifyRegistration.d.ts +14 -0
- package/_types/actions/passkeyServer/verifyRegistration.d.ts.map +1 -0
- package/_types/actions/passkeyServer.d.ts +5 -0
- package/_types/actions/passkeyServer.d.ts.map +1 -0
- package/_types/clients/decorators/passkeyServer.d.ts +12 -0
- package/_types/clients/decorators/passkeyServer.d.ts.map +1 -0
- package/_types/clients/passkeyServer.d.ts +7 -0
- package/_types/clients/passkeyServer.d.ts.map +1 -0
- package/_types/types/passkeyServer.d.ts +74 -0
- package/_types/types/passkeyServer.d.ts.map +1 -0
- package/accounts/kernel/toKernelSmartAccount.ts +6 -7
- package/accounts/kernel/utils/signMessage.ts +2 -2
- package/accounts/safe/toSafeSmartAccount.ts +11 -2
- package/actions/passkeyServer/getCredentials.ts +47 -0
- package/actions/passkeyServer/startRegistration.ts +125 -0
- package/actions/passkeyServer/verifyRegistration.ts +114 -0
- package/actions/passkeyServer.ts +29 -0
- package/clients/decorators/passkeyServer.ts +42 -0
- package/clients/passkeyServer.ts +69 -0
- package/package.json +18 -3
- package/types/passkeyServer.ts +82 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Account, Chain, Client, Transport } from "viem";
|
|
2
|
+
import { type GetCredentialsParameters, type GetCredentialsReturnType } from "../../actions/passkeyServer/getCredentials.js";
|
|
3
|
+
import { type StartRegistrationParameters, type StartRegistrationReturnType } from "../../actions/passkeyServer/startRegistration.js";
|
|
4
|
+
import { type VerifyRegistrationParameters, type VerifyRegistrationReturnType } from "../../actions/passkeyServer/verifyRegistration.js";
|
|
5
|
+
import type { PasskeyServerRpcSchema } from "../../types/passkeyServer.js";
|
|
6
|
+
export type PasskeyServerActions = {
|
|
7
|
+
startRegistration: (args: StartRegistrationParameters) => Promise<StartRegistrationReturnType>;
|
|
8
|
+
verifyRegistration: (args: VerifyRegistrationParameters) => Promise<VerifyRegistrationReturnType>;
|
|
9
|
+
getCredentials: (args: GetCredentialsParameters) => Promise<GetCredentialsReturnType>;
|
|
10
|
+
};
|
|
11
|
+
export declare const passkeyServerActions: (client: Client<Transport, Chain | undefined, Account | undefined, PasskeyServerRpcSchema>) => PasskeyServerActions;
|
|
12
|
+
//# sourceMappingURL=passkeyServer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"passkeyServer.d.ts","sourceRoot":"","sources":["../../../clients/decorators/passkeyServer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,MAAM,CAAA;AAC7D,OAAO,EACH,KAAK,wBAAwB,EAC7B,KAAK,wBAAwB,EAEhC,MAAM,+CAA+C,CAAA;AACtD,OAAO,EACH,KAAK,2BAA2B,EAChC,KAAK,2BAA2B,EAEnC,MAAM,kDAAkD,CAAA;AACzD,OAAO,EACH,KAAK,4BAA4B,EACjC,KAAK,4BAA4B,EAEpC,MAAM,mDAAmD,CAAA;AAC1D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAA;AAE1E,MAAM,MAAM,oBAAoB,GAAG;IAC/B,iBAAiB,EAAE,CACf,IAAI,EAAE,2BAA2B,KAChC,OAAO,CAAC,2BAA2B,CAAC,CAAA;IACzC,kBAAkB,EAAE,CAChB,IAAI,EAAE,4BAA4B,KACjC,OAAO,CAAC,4BAA4B,CAAC,CAAA;IAC1C,cAAc,EAAE,CACZ,IAAI,EAAE,wBAAwB,KAC7B,OAAO,CAAC,wBAAwB,CAAC,CAAA;CACzC,CAAA;AAED,eAAO,MAAM,oBAAoB,WACrB,MAAM,CACV,SAAS,EACT,KAAK,GAAG,SAAS,EACjB,OAAO,GAAG,SAAS,EACnB,sBAAsB,CACzB,KACF,oBAID,CAAA"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Account, Chain, Client, ClientConfig, Prettify, RpcSchema, Transport } from "viem";
|
|
2
|
+
import type { PasskeyServerRpcSchema } from "../types/passkeyServer.js";
|
|
3
|
+
import { type PasskeyServerActions } from "./decorators/passkeyServer.js";
|
|
4
|
+
export type PasskeyServerClient<rpcSchema extends RpcSchema | undefined = undefined> = Prettify<Client<Transport, Chain | undefined, Account | undefined, rpcSchema extends RpcSchema ? [...PasskeyServerRpcSchema, ...rpcSchema] : [...PasskeyServerRpcSchema], PasskeyServerActions>>;
|
|
5
|
+
export type PasskeyServerClientConfig<rpcSchema extends RpcSchema | undefined = undefined> = Prettify<Pick<ClientConfig<Transport, Chain | undefined, Account | undefined, rpcSchema>, "account" | "cacheTime" | "chain" | "key" | "name" | "pollingInterval" | "rpcSchema" | "transport">>;
|
|
6
|
+
export declare function createPasskeyServerClient<rpcSchema extends RpcSchema | undefined = undefined>(parameters: PasskeyServerClientConfig<rpcSchema>): PasskeyServerClient<rpcSchema>;
|
|
7
|
+
//# sourceMappingURL=passkeyServer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"passkeyServer.d.ts","sourceRoot":"","sources":["../../clients/passkeyServer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACR,OAAO,EACP,KAAK,EACL,MAAM,EACN,YAAY,EACZ,QAAQ,EACR,SAAS,EACT,SAAS,EACZ,MAAM,MAAM,CAAA;AAEb,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAA;AACvE,OAAO,EACH,KAAK,oBAAoB,EAE5B,MAAM,+BAA+B,CAAA;AAEtC,MAAM,MAAM,mBAAmB,CAC3B,SAAS,SAAS,SAAS,GAAG,SAAS,GAAG,SAAS,IACnD,QAAQ,CACR,MAAM,CACF,SAAS,EACT,KAAK,GAAG,SAAS,EACjB,OAAO,GAAG,SAAS,EACnB,SAAS,SAAS,SAAS,GACrB,CAAC,GAAG,sBAAsB,EAAE,GAAG,SAAS,CAAC,GACzC,CAAC,GAAG,sBAAsB,CAAC,EACjC,oBAAoB,CACvB,CACJ,CAAA;AAED,MAAM,MAAM,yBAAyB,CACjC,SAAS,SAAS,SAAS,GAAG,SAAS,GAAG,SAAS,IACnD,QAAQ,CACR,IAAI,CACA,YAAY,CACR,SAAS,EACT,KAAK,GAAG,SAAS,EACjB,OAAO,GAAG,SAAS,EACnB,SAAS,CACZ,EACC,SAAS,GACT,WAAW,GACX,OAAO,GACP,KAAK,GACL,MAAM,GACN,iBAAiB,GACjB,WAAW,GACX,WAAW,CAChB,CACJ,CAAA;AAED,wBAAgB,yBAAyB,CACrC,SAAS,SAAS,SAAS,GAAG,SAAS,GAAG,SAAS,EAEnD,UAAU,EAAE,yBAAyB,CAAC,SAAS,CAAC,GACjD,mBAAmB,CAAC,SAAS,CAAC,CAAA"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { Hex } from "viem";
|
|
2
|
+
export type PasskeyServerRpcSchema = [
|
|
3
|
+
{
|
|
4
|
+
Method: "pks_startRegistration";
|
|
5
|
+
Parameters: [context: unknown];
|
|
6
|
+
ReturnType: {
|
|
7
|
+
rp: {
|
|
8
|
+
id: string;
|
|
9
|
+
name: string;
|
|
10
|
+
};
|
|
11
|
+
user: {
|
|
12
|
+
id: string;
|
|
13
|
+
name: string;
|
|
14
|
+
displayName: string;
|
|
15
|
+
};
|
|
16
|
+
challenge: string;
|
|
17
|
+
timeout?: number;
|
|
18
|
+
authenticatorSelection?: {
|
|
19
|
+
authenticatorAttachment?: "platform" | "cross-platform";
|
|
20
|
+
requireResidentKey?: boolean;
|
|
21
|
+
residentKey?: "required" | "preferred" | "discouraged";
|
|
22
|
+
userVerification?: "required" | "preferred" | "discouraged";
|
|
23
|
+
};
|
|
24
|
+
attestation: "direct" | "enterprise" | "indirect" | "none";
|
|
25
|
+
extensions?: {
|
|
26
|
+
appid?: string;
|
|
27
|
+
credProps?: boolean;
|
|
28
|
+
hmacCreateSecret?: boolean;
|
|
29
|
+
minPinLength?: boolean;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
Method: "pks_verifyRegistration";
|
|
35
|
+
Parameters: [
|
|
36
|
+
{
|
|
37
|
+
id: string;
|
|
38
|
+
rawId: string;
|
|
39
|
+
response: {
|
|
40
|
+
clientDataJSON: string;
|
|
41
|
+
attestationObject: string;
|
|
42
|
+
authenticatorData?: string;
|
|
43
|
+
transports?: ("ble" | "cable" | "hybrid" | "internal" | "nfc" | "smart-card" | "usb")[];
|
|
44
|
+
publicKeyAlgorithm?: number;
|
|
45
|
+
publicKeyType?: string;
|
|
46
|
+
};
|
|
47
|
+
authenticatorAttachment: "cross-platform" | "platform";
|
|
48
|
+
clientExtensionResults: {
|
|
49
|
+
appid?: boolean;
|
|
50
|
+
credProps?: {
|
|
51
|
+
rk?: boolean;
|
|
52
|
+
};
|
|
53
|
+
hmacCreateSecret?: boolean;
|
|
54
|
+
};
|
|
55
|
+
type: "public-key";
|
|
56
|
+
},
|
|
57
|
+
context: unknown
|
|
58
|
+
];
|
|
59
|
+
ReturnType: {
|
|
60
|
+
success: boolean;
|
|
61
|
+
id: string;
|
|
62
|
+
publicKey: Hex;
|
|
63
|
+
};
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
Method: "pks_getCredentials";
|
|
67
|
+
Parameters: [context: unknown];
|
|
68
|
+
ReturnType: {
|
|
69
|
+
id: string;
|
|
70
|
+
publicKey: Hex;
|
|
71
|
+
}[];
|
|
72
|
+
}
|
|
73
|
+
];
|
|
74
|
+
//# sourceMappingURL=passkeyServer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"passkeyServer.d.ts","sourceRoot":"","sources":["../../types/passkeyServer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,MAAM,CAAA;AAE/B,MAAM,MAAM,sBAAsB,GAAG;IACjC;QACI,MAAM,EAAE,uBAAuB,CAAA;QAC/B,UAAU,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;QAC9B,UAAU,EAAE;YACR,EAAE,EAAE;gBACA,EAAE,EAAE,MAAM,CAAA;gBACV,IAAI,EAAE,MAAM,CAAA;aACf,CAAA;YACD,IAAI,EAAE;gBACF,EAAE,EAAE,MAAM,CAAA;gBACV,IAAI,EAAE,MAAM,CAAA;gBACZ,WAAW,EAAE,MAAM,CAAA;aACtB,CAAA;YACD,SAAS,EAAE,MAAM,CAAA;YACjB,OAAO,CAAC,EAAE,MAAM,CAAA;YAChB,sBAAsB,CAAC,EAAE;gBACrB,uBAAuB,CAAC,EAAE,UAAU,GAAG,gBAAgB,CAAA;gBACvD,kBAAkB,CAAC,EAAE,OAAO,CAAA;gBAC5B,WAAW,CAAC,EAAE,UAAU,GAAG,WAAW,GAAG,aAAa,CAAA;gBACtD,gBAAgB,CAAC,EAAE,UAAU,GAAG,WAAW,GAAG,aAAa,CAAA;aAC9D,CAAA;YACD,WAAW,EAAE,QAAQ,GAAG,YAAY,GAAG,UAAU,GAAG,MAAM,CAAA;YAC1D,UAAU,CAAC,EAAE;gBACT,KAAK,CAAC,EAAE,MAAM,CAAA;gBACd,SAAS,CAAC,EAAE,OAAO,CAAA;gBACnB,gBAAgB,CAAC,EAAE,OAAO,CAAA;gBAC1B,YAAY,CAAC,EAAE,OAAO,CAAA;aACzB,CAAA;SACJ,CAAA;KACJ;IACD;QACI,MAAM,EAAE,wBAAwB,CAAA;QAChC,UAAU,EAAE;YACR;gBACI,EAAE,EAAE,MAAM,CAAA;gBACV,KAAK,EAAE,MAAM,CAAA;gBACb,QAAQ,EAAE;oBACN,cAAc,EAAE,MAAM,CAAA;oBACtB,iBAAiB,EAAE,MAAM,CAAA;oBACzB,iBAAiB,CAAC,EAAE,MAAM,CAAA;oBAC1B,UAAU,CAAC,EAAE,CACP,KAAK,GACL,OAAO,GACP,QAAQ,GACR,UAAU,GACV,KAAK,GACL,YAAY,GACZ,KAAK,CACV,EAAE,CAAA;oBACH,kBAAkB,CAAC,EAAE,MAAM,CAAA;oBAC3B,aAAa,CAAC,EAAE,MAAM,CAAA;iBACzB,CAAA;gBACD,uBAAuB,EAAE,gBAAgB,GAAG,UAAU,CAAA;gBACtD,sBAAsB,EAAE;oBACpB,KAAK,CAAC,EAAE,OAAO,CAAA;oBACf,SAAS,CAAC,EAAE;wBACR,EAAE,CAAC,EAAE,OAAO,CAAA;qBACf,CAAA;oBACD,gBAAgB,CAAC,EAAE,OAAO,CAAA;iBAC7B,CAAA;gBACD,IAAI,EAAE,YAAY,CAAA;aACrB;YACD,OAAO,EAAE,OAAO;SACnB,CAAA;QACD,UAAU,EAAE;YACR,OAAO,EAAE,OAAO,CAAA;YAChB,EAAE,EAAE,MAAM,CAAA;YACV,SAAS,EAAE,GAAG,CAAA;SACjB,CAAA;KACJ;IACD;QACI,MAAM,EAAE,oBAAoB,CAAA;QAC5B,UAAU,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;QAC9B,UAAU,EAAE;YACR,EAAE,EAAE,MAAM,CAAA;YACV,SAAS,EAAE,GAAG,CAAA;SACjB,EAAE,CAAA;KACN;CACJ,CAAA"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Base64, Hex, PublicKey } from "ox"
|
|
1
2
|
import type {
|
|
2
3
|
Account,
|
|
3
4
|
Assign,
|
|
@@ -9,7 +10,6 @@ import type {
|
|
|
9
10
|
import {
|
|
10
11
|
type Address,
|
|
11
12
|
type Client,
|
|
12
|
-
type Hex,
|
|
13
13
|
type LocalAccount,
|
|
14
14
|
type TypedDataDefinition,
|
|
15
15
|
concatHex,
|
|
@@ -32,7 +32,6 @@ import {
|
|
|
32
32
|
} from "viem/account-abstraction"
|
|
33
33
|
import { signMessage as _signMessage, getChainId } from "viem/actions"
|
|
34
34
|
import { getAction } from "viem/utils"
|
|
35
|
-
import { base64UrlToBytes, bytesToHex, parsePublicKey } from "webauthn-p256"
|
|
36
35
|
import { getAccountNonce } from "../../actions/public/getAccountNonce.js"
|
|
37
36
|
import { getSenderAddress } from "../../actions/public/getSenderAddress.js"
|
|
38
37
|
import { type EthereumProvider, toOwner } from "../../utils/toOwner.js"
|
|
@@ -225,7 +224,7 @@ const getInitializationData = <entryPointVersion extends "0.6" | "0.7">({
|
|
|
225
224
|
entryPoint: {
|
|
226
225
|
version: entryPointVersion
|
|
227
226
|
}
|
|
228
|
-
validatorData: Hex
|
|
227
|
+
validatorData: Hex.Hex
|
|
229
228
|
validatorAddress: Address
|
|
230
229
|
}) => {
|
|
231
230
|
if (entryPointVersion === "0.6") {
|
|
@@ -268,9 +267,9 @@ const getValidatorData = async (owner: WebAuthnAccount | LocalAccount) => {
|
|
|
268
267
|
}
|
|
269
268
|
|
|
270
269
|
if (isWebAuthnAccount(owner)) {
|
|
271
|
-
const parsedPublicKey =
|
|
270
|
+
const parsedPublicKey = PublicKey.fromHex(owner.publicKey)
|
|
272
271
|
const authenticatorIdHash = keccak256(
|
|
273
|
-
|
|
272
|
+
Hex.fromBytes(Base64.toBytes(owner.id))
|
|
274
273
|
)
|
|
275
274
|
|
|
276
275
|
return encodeAbiParameters(
|
|
@@ -322,13 +321,13 @@ const getAccountInitCode = async <entryPointVersion extends "0.6" | "0.7">({
|
|
|
322
321
|
}: {
|
|
323
322
|
kernelVersion: KernelVersion<entryPointVersion>
|
|
324
323
|
entryPointVersion: entryPointVersion
|
|
325
|
-
validatorData: Hex
|
|
324
|
+
validatorData: Hex.Hex
|
|
326
325
|
index: bigint
|
|
327
326
|
factoryAddress: Address
|
|
328
327
|
accountLogicAddress: Address
|
|
329
328
|
validatorAddress: Address
|
|
330
329
|
useMetaFactory: boolean
|
|
331
|
-
}): Promise<Hex> => {
|
|
330
|
+
}): Promise<Hex.Hex> => {
|
|
332
331
|
// Build the account initialization data
|
|
333
332
|
const initializationData = getInitializationData({
|
|
334
333
|
entryPoint: { version: entryPointVersion },
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Signature } from "ox"
|
|
1
2
|
import {
|
|
2
3
|
type Hash,
|
|
3
4
|
type LocalAccount,
|
|
@@ -8,7 +9,6 @@ import {
|
|
|
8
9
|
} from "viem"
|
|
9
10
|
import type { WebAuthnAccount } from "viem/account-abstraction"
|
|
10
11
|
import { signMessage as _signMessage } from "viem/actions"
|
|
11
|
-
import { parseSignature } from "webauthn-p256"
|
|
12
12
|
import { isWebAuthnAccount } from "./isWebAuthnAccount.js"
|
|
13
13
|
import {
|
|
14
14
|
type WrapMessageHashParams,
|
|
@@ -51,7 +51,7 @@ export async function signMessage({
|
|
|
51
51
|
const { signature: signatureData, webauthn } = await owner.sign({
|
|
52
52
|
hash: messageContent as Hash
|
|
53
53
|
})
|
|
54
|
-
const signature =
|
|
54
|
+
const signature = Signature.fromHex(signatureData)
|
|
55
55
|
|
|
56
56
|
// encode signature
|
|
57
57
|
const encodedSignature = encodeAbiParameters(
|
|
@@ -928,6 +928,7 @@ type GetErc7579Params<TErc7579 extends Address | undefined> =
|
|
|
928
928
|
safeModuleSetupAddress?: Address
|
|
929
929
|
multiSendAddress?: Address
|
|
930
930
|
multiSendCallOnlyAddress?: Address
|
|
931
|
+
// @deprecated This field is deprecated. It is recommended to make any setup transactions in the userOperation's calldata.
|
|
931
932
|
setupTransactions?: {
|
|
932
933
|
to: Address
|
|
933
934
|
data: Address
|
|
@@ -975,6 +976,7 @@ export type ToSafeSmartAccountParameters<
|
|
|
975
976
|
paymentToken?: Address
|
|
976
977
|
payment?: bigint
|
|
977
978
|
paymentReceiver?: Address
|
|
979
|
+
onchainIdentifier?: Hex
|
|
978
980
|
} & GetErc7579Params<TErc7579>
|
|
979
981
|
|
|
980
982
|
function isErc7579Args<entryPointVersion extends "0.6" | "0.7" = "0.7">(
|
|
@@ -1149,7 +1151,8 @@ export async function toSafeSmartAccount<
|
|
|
1149
1151
|
nonceKey,
|
|
1150
1152
|
paymentToken,
|
|
1151
1153
|
payment,
|
|
1152
|
-
paymentReceiver
|
|
1154
|
+
paymentReceiver,
|
|
1155
|
+
onchainIdentifier
|
|
1153
1156
|
} = parameters
|
|
1154
1157
|
|
|
1155
1158
|
const owners = await Promise.all(
|
|
@@ -1421,11 +1424,17 @@ export async function toSafeSmartAccount<
|
|
|
1421
1424
|
value = call.value ?? 0n
|
|
1422
1425
|
}
|
|
1423
1426
|
|
|
1424
|
-
|
|
1427
|
+
const calldata = encodeFunctionData({
|
|
1425
1428
|
abi: executeUserOpWithErrorStringAbi,
|
|
1426
1429
|
functionName: "executeUserOpWithErrorString",
|
|
1427
1430
|
args: [to, value, data, operationType]
|
|
1428
1431
|
})
|
|
1432
|
+
|
|
1433
|
+
if (onchainIdentifier) {
|
|
1434
|
+
return concat([calldata, onchainIdentifier])
|
|
1435
|
+
}
|
|
1436
|
+
|
|
1437
|
+
return calldata
|
|
1429
1438
|
},
|
|
1430
1439
|
async decodeCalls(callData) {
|
|
1431
1440
|
try {
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { Account, Chain, Client, Hex, Transport } from "viem"
|
|
2
|
+
import type { PasskeyServerRpcSchema } from "../../types/passkeyServer.js"
|
|
3
|
+
|
|
4
|
+
export type GetCredentialsParameters = {
|
|
5
|
+
context?: Record<string, unknown>
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export type GetCredentialsReturnType = {
|
|
9
|
+
id: string
|
|
10
|
+
publicKey: Hex
|
|
11
|
+
}[]
|
|
12
|
+
|
|
13
|
+
export const getCredentials = async (
|
|
14
|
+
client: Client<
|
|
15
|
+
Transport,
|
|
16
|
+
Chain | undefined,
|
|
17
|
+
Account | undefined,
|
|
18
|
+
PasskeyServerRpcSchema
|
|
19
|
+
>,
|
|
20
|
+
args?: GetCredentialsParameters
|
|
21
|
+
): Promise<GetCredentialsReturnType> => {
|
|
22
|
+
const response = await client.request({
|
|
23
|
+
method: "pks_getCredentials",
|
|
24
|
+
params: [args?.context]
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
if (!Array.isArray(response)) {
|
|
28
|
+
throw new Error("Invalid response from server - expected array")
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
for (const passkey of response) {
|
|
32
|
+
if (typeof passkey?.id !== "string") {
|
|
33
|
+
throw new Error("Invalid passkey id returned from server")
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (
|
|
37
|
+
typeof passkey?.publicKey !== "string" ||
|
|
38
|
+
!passkey.publicKey.startsWith("0x")
|
|
39
|
+
) {
|
|
40
|
+
throw new Error(
|
|
41
|
+
"Invalid public key returned from server - must be hex string starting with 0x"
|
|
42
|
+
)
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return response
|
|
47
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { Base64 } from "ox"
|
|
2
|
+
import type { Account, Chain, Client, Transport } from "viem"
|
|
3
|
+
import type { CreateWebAuthnCredentialParameters } from "viem/account-abstraction"
|
|
4
|
+
import type { PasskeyServerRpcSchema } from "../../types/passkeyServer.js"
|
|
5
|
+
|
|
6
|
+
const validateAttestation = (attestation: unknown): boolean => {
|
|
7
|
+
return (
|
|
8
|
+
!!attestation &&
|
|
9
|
+
["direct", "enterprise", "indirect", "none"].includes(
|
|
10
|
+
attestation as string
|
|
11
|
+
)
|
|
12
|
+
)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const validateAuthenticatorSelection = (
|
|
16
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
17
|
+
authenticatorSelection: any
|
|
18
|
+
): boolean => {
|
|
19
|
+
if (!authenticatorSelection) return false
|
|
20
|
+
|
|
21
|
+
const validAttachments = ["platform", "cross-platform"]
|
|
22
|
+
const validKeyOptions = ["required", "preferred", "discouraged"]
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
validAttachments.includes(
|
|
26
|
+
authenticatorSelection.authenticatorAttachment
|
|
27
|
+
) &&
|
|
28
|
+
typeof authenticatorSelection.requireResidentKey === "boolean" &&
|
|
29
|
+
validKeyOptions.includes(authenticatorSelection.residentKey) &&
|
|
30
|
+
validKeyOptions.includes(authenticatorSelection.userVerification)
|
|
31
|
+
)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const validateChallenge = (challenge: unknown): boolean => {
|
|
35
|
+
return !!challenge && typeof challenge === "string"
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const validateExtensions = (extensions: unknown): boolean => {
|
|
39
|
+
if (!extensions) return true
|
|
40
|
+
if (typeof extensions !== "object") return false
|
|
41
|
+
|
|
42
|
+
const ext = extensions as Record<string, unknown>
|
|
43
|
+
|
|
44
|
+
// Optional appid must be string if present
|
|
45
|
+
if ("appid" in ext && typeof ext.appid !== "string") return false
|
|
46
|
+
|
|
47
|
+
// Optional credProps must be boolean if present
|
|
48
|
+
if ("credProps" in ext && typeof ext.credProps !== "boolean") return false
|
|
49
|
+
|
|
50
|
+
// Optional hmacCreateSecret must be boolean if present
|
|
51
|
+
if ("hmacCreateSecret" in ext && typeof ext.hmacCreateSecret !== "boolean")
|
|
52
|
+
return false
|
|
53
|
+
|
|
54
|
+
// Optional minPinLength must be boolean if present
|
|
55
|
+
if ("minPinLength" in ext && typeof ext.minPinLength !== "boolean")
|
|
56
|
+
return false
|
|
57
|
+
|
|
58
|
+
return true
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
62
|
+
const validateRp = (rp: any): boolean => {
|
|
63
|
+
return !!rp && typeof rp.id === "string" && typeof rp.name === "string"
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
67
|
+
const validateUser = (user: any): boolean => {
|
|
68
|
+
return (
|
|
69
|
+
!!user &&
|
|
70
|
+
typeof user.id === "string" &&
|
|
71
|
+
typeof user.name === "string" &&
|
|
72
|
+
typeof user.displayName === "string"
|
|
73
|
+
)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export type StartRegistrationParameters = {
|
|
77
|
+
context?: Record<string, unknown>
|
|
78
|
+
}
|
|
79
|
+
export type StartRegistrationReturnType = CreateWebAuthnCredentialParameters
|
|
80
|
+
|
|
81
|
+
export const startRegistration = async (
|
|
82
|
+
client: Client<
|
|
83
|
+
Transport,
|
|
84
|
+
Chain | undefined,
|
|
85
|
+
Account | undefined,
|
|
86
|
+
PasskeyServerRpcSchema
|
|
87
|
+
>,
|
|
88
|
+
args?: StartRegistrationParameters
|
|
89
|
+
): Promise<StartRegistrationReturnType> => {
|
|
90
|
+
const response = await client.request({
|
|
91
|
+
method: "pks_startRegistration",
|
|
92
|
+
params: [args?.context]
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
// Validate the response matches expected schema
|
|
96
|
+
if (
|
|
97
|
+
!validateAttestation(response.attestation) ||
|
|
98
|
+
!validateAuthenticatorSelection(response.authenticatorSelection) ||
|
|
99
|
+
!validateChallenge(response.challenge) ||
|
|
100
|
+
!validateExtensions(response.extensions) ||
|
|
101
|
+
!validateRp(response.rp) ||
|
|
102
|
+
!validateUser(response.user)
|
|
103
|
+
) {
|
|
104
|
+
throw new Error("Invalid response format from passkey server")
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const credentialOptions: StartRegistrationReturnType = {
|
|
108
|
+
attestation: response.attestation,
|
|
109
|
+
authenticatorSelection: response.authenticatorSelection,
|
|
110
|
+
challenge: Base64.toBytes(response.challenge),
|
|
111
|
+
extensions: response.extensions
|
|
112
|
+
? {
|
|
113
|
+
...response.extensions
|
|
114
|
+
}
|
|
115
|
+
: undefined,
|
|
116
|
+
rp: response.rp,
|
|
117
|
+
timeout: response.timeout,
|
|
118
|
+
user: {
|
|
119
|
+
id: Base64.toBytes(response.user.id),
|
|
120
|
+
name: response.user.name,
|
|
121
|
+
displayName: response.user.displayName
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return credentialOptions
|
|
125
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { Base64 } from "ox"
|
|
2
|
+
import type { Account, Chain, Client, Hex, Transport } from "viem"
|
|
3
|
+
import type { CreateWebAuthnCredentialReturnType } from "viem/account-abstraction"
|
|
4
|
+
import type { PasskeyServerRpcSchema } from "../../types/passkeyServer.js"
|
|
5
|
+
|
|
6
|
+
export type VerifyRegistrationParameters = {
|
|
7
|
+
credential: CreateWebAuthnCredentialReturnType
|
|
8
|
+
context: unknown
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export type VerifyRegistrationReturnType = {
|
|
12
|
+
success: boolean
|
|
13
|
+
id: string
|
|
14
|
+
publicKey: Hex
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const verifyRegistration = async (
|
|
18
|
+
client: Client<
|
|
19
|
+
Transport,
|
|
20
|
+
Chain | undefined,
|
|
21
|
+
Account | undefined,
|
|
22
|
+
PasskeyServerRpcSchema
|
|
23
|
+
>,
|
|
24
|
+
args: VerifyRegistrationParameters
|
|
25
|
+
): Promise<VerifyRegistrationReturnType> => {
|
|
26
|
+
const { credential, context } = args
|
|
27
|
+
|
|
28
|
+
const response = credential.raw
|
|
29
|
+
.response as unknown as AuthenticatorAttestationResponse
|
|
30
|
+
|
|
31
|
+
let responsePublicKeyAlgorithm: number | undefined = undefined
|
|
32
|
+
if (typeof response.getPublicKeyAlgorithm === "function") {
|
|
33
|
+
try {
|
|
34
|
+
responsePublicKeyAlgorithm = response.getPublicKeyAlgorithm()
|
|
35
|
+
} catch (error) {
|
|
36
|
+
throw new Error("getPublicKeyAlgorithm() is not supported")
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
let responseAuthenticatorData: string | undefined
|
|
41
|
+
if (typeof response.getAuthenticatorData === "function") {
|
|
42
|
+
try {
|
|
43
|
+
responseAuthenticatorData = Base64.fromBytes(
|
|
44
|
+
new Uint8Array(response.getAuthenticatorData())
|
|
45
|
+
)
|
|
46
|
+
} catch (error) {
|
|
47
|
+
throw new Error("getAuthenticatorData() is not supported")
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const serverResponse = await client.request({
|
|
52
|
+
method: "pks_verifyRegistration",
|
|
53
|
+
params: [
|
|
54
|
+
{
|
|
55
|
+
id: credential.id,
|
|
56
|
+
rawId: Base64.fromBytes(new Uint8Array(credential.raw.rawId), {
|
|
57
|
+
pad: false,
|
|
58
|
+
url: true
|
|
59
|
+
}),
|
|
60
|
+
response: {
|
|
61
|
+
clientDataJSON: Base64.fromBytes(
|
|
62
|
+
new Uint8Array(response.clientDataJSON)
|
|
63
|
+
),
|
|
64
|
+
attestationObject: Base64.fromBytes(
|
|
65
|
+
new Uint8Array(response.attestationObject),
|
|
66
|
+
{
|
|
67
|
+
url: true
|
|
68
|
+
}
|
|
69
|
+
),
|
|
70
|
+
transports:
|
|
71
|
+
typeof response.getTransports === "function"
|
|
72
|
+
? (response.getTransports() as (
|
|
73
|
+
| "ble"
|
|
74
|
+
| "cable"
|
|
75
|
+
| "hybrid"
|
|
76
|
+
| "internal"
|
|
77
|
+
| "nfc"
|
|
78
|
+
| "smart-card"
|
|
79
|
+
| "usb"
|
|
80
|
+
)[])
|
|
81
|
+
: undefined,
|
|
82
|
+
publicKeyAlgorithm: responsePublicKeyAlgorithm,
|
|
83
|
+
authenticatorData: responseAuthenticatorData
|
|
84
|
+
},
|
|
85
|
+
authenticatorAttachment: credential.raw
|
|
86
|
+
.authenticatorAttachment as "cross-platform" | "platform",
|
|
87
|
+
clientExtensionResults:
|
|
88
|
+
credential.raw.getClientExtensionResults(),
|
|
89
|
+
type: credential.raw.type as "public-key"
|
|
90
|
+
},
|
|
91
|
+
context
|
|
92
|
+
]
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
const success = Boolean(serverResponse?.success)
|
|
96
|
+
const id = serverResponse?.id
|
|
97
|
+
const publicKey = serverResponse?.publicKey
|
|
98
|
+
|
|
99
|
+
if (typeof id !== "string") {
|
|
100
|
+
throw new Error("Invalid passkey id returned from server")
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (typeof publicKey !== "string" || !publicKey.startsWith("0x")) {
|
|
104
|
+
throw new Error(
|
|
105
|
+
"Invalid public key returned from server - must be hex string starting with 0x"
|
|
106
|
+
)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return {
|
|
110
|
+
success,
|
|
111
|
+
id,
|
|
112
|
+
publicKey: publicKey as Hex
|
|
113
|
+
}
|
|
114
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type StartRegistrationParameters,
|
|
3
|
+
type StartRegistrationReturnType,
|
|
4
|
+
startRegistration
|
|
5
|
+
} from "./passkeyServer/startRegistration.js"
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
type VerifyRegistrationParameters,
|
|
9
|
+
type VerifyRegistrationReturnType,
|
|
10
|
+
verifyRegistration
|
|
11
|
+
} from "./passkeyServer/verifyRegistration.js"
|
|
12
|
+
|
|
13
|
+
import {
|
|
14
|
+
type GetCredentialsParameters,
|
|
15
|
+
type GetCredentialsReturnType,
|
|
16
|
+
getCredentials
|
|
17
|
+
} from "./passkeyServer/getCredentials.js"
|
|
18
|
+
|
|
19
|
+
export {
|
|
20
|
+
type StartRegistrationParameters,
|
|
21
|
+
type StartRegistrationReturnType,
|
|
22
|
+
type VerifyRegistrationParameters,
|
|
23
|
+
type VerifyRegistrationReturnType,
|
|
24
|
+
type GetCredentialsParameters,
|
|
25
|
+
type GetCredentialsReturnType,
|
|
26
|
+
startRegistration,
|
|
27
|
+
verifyRegistration,
|
|
28
|
+
getCredentials
|
|
29
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { Account, Chain, Client, Transport } from "viem"
|
|
2
|
+
import {
|
|
3
|
+
type GetCredentialsParameters,
|
|
4
|
+
type GetCredentialsReturnType,
|
|
5
|
+
getCredentials
|
|
6
|
+
} from "../../actions/passkeyServer/getCredentials.js"
|
|
7
|
+
import {
|
|
8
|
+
type StartRegistrationParameters,
|
|
9
|
+
type StartRegistrationReturnType,
|
|
10
|
+
startRegistration
|
|
11
|
+
} from "../../actions/passkeyServer/startRegistration.js"
|
|
12
|
+
import {
|
|
13
|
+
type VerifyRegistrationParameters,
|
|
14
|
+
type VerifyRegistrationReturnType,
|
|
15
|
+
verifyRegistration
|
|
16
|
+
} from "../../actions/passkeyServer/verifyRegistration.js"
|
|
17
|
+
import type { PasskeyServerRpcSchema } from "../../types/passkeyServer.js"
|
|
18
|
+
|
|
19
|
+
export type PasskeyServerActions = {
|
|
20
|
+
startRegistration: (
|
|
21
|
+
args: StartRegistrationParameters
|
|
22
|
+
) => Promise<StartRegistrationReturnType>
|
|
23
|
+
verifyRegistration: (
|
|
24
|
+
args: VerifyRegistrationParameters
|
|
25
|
+
) => Promise<VerifyRegistrationReturnType>
|
|
26
|
+
getCredentials: (
|
|
27
|
+
args: GetCredentialsParameters
|
|
28
|
+
) => Promise<GetCredentialsReturnType>
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export const passkeyServerActions = (
|
|
32
|
+
client: Client<
|
|
33
|
+
Transport,
|
|
34
|
+
Chain | undefined,
|
|
35
|
+
Account | undefined,
|
|
36
|
+
PasskeyServerRpcSchema
|
|
37
|
+
>
|
|
38
|
+
): PasskeyServerActions => ({
|
|
39
|
+
startRegistration: (args) => startRegistration(client, args),
|
|
40
|
+
verifyRegistration: (args) => verifyRegistration(client, args),
|
|
41
|
+
getCredentials: (args) => getCredentials(client, args)
|
|
42
|
+
})
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
Account,
|
|
3
|
+
Chain,
|
|
4
|
+
Client,
|
|
5
|
+
ClientConfig,
|
|
6
|
+
Prettify,
|
|
7
|
+
RpcSchema,
|
|
8
|
+
Transport
|
|
9
|
+
} from "viem"
|
|
10
|
+
import { createClient } from "viem"
|
|
11
|
+
import type { PasskeyServerRpcSchema } from "../types/passkeyServer.js"
|
|
12
|
+
import {
|
|
13
|
+
type PasskeyServerActions,
|
|
14
|
+
passkeyServerActions
|
|
15
|
+
} from "./decorators/passkeyServer.js"
|
|
16
|
+
|
|
17
|
+
export type PasskeyServerClient<
|
|
18
|
+
rpcSchema extends RpcSchema | undefined = undefined
|
|
19
|
+
> = Prettify<
|
|
20
|
+
Client<
|
|
21
|
+
Transport,
|
|
22
|
+
Chain | undefined,
|
|
23
|
+
Account | undefined,
|
|
24
|
+
rpcSchema extends RpcSchema
|
|
25
|
+
? [...PasskeyServerRpcSchema, ...rpcSchema]
|
|
26
|
+
: [...PasskeyServerRpcSchema],
|
|
27
|
+
PasskeyServerActions
|
|
28
|
+
>
|
|
29
|
+
>
|
|
30
|
+
|
|
31
|
+
export type PasskeyServerClientConfig<
|
|
32
|
+
rpcSchema extends RpcSchema | undefined = undefined
|
|
33
|
+
> = Prettify<
|
|
34
|
+
Pick<
|
|
35
|
+
ClientConfig<
|
|
36
|
+
Transport,
|
|
37
|
+
Chain | undefined,
|
|
38
|
+
Account | undefined,
|
|
39
|
+
rpcSchema
|
|
40
|
+
>,
|
|
41
|
+
| "account"
|
|
42
|
+
| "cacheTime"
|
|
43
|
+
| "chain"
|
|
44
|
+
| "key"
|
|
45
|
+
| "name"
|
|
46
|
+
| "pollingInterval"
|
|
47
|
+
| "rpcSchema"
|
|
48
|
+
| "transport"
|
|
49
|
+
>
|
|
50
|
+
>
|
|
51
|
+
|
|
52
|
+
export function createPasskeyServerClient<
|
|
53
|
+
rpcSchema extends RpcSchema | undefined = undefined
|
|
54
|
+
>(
|
|
55
|
+
parameters: PasskeyServerClientConfig<rpcSchema>
|
|
56
|
+
): PasskeyServerClient<rpcSchema>
|
|
57
|
+
|
|
58
|
+
export function createPasskeyServerClient(
|
|
59
|
+
parameters: PasskeyServerClientConfig
|
|
60
|
+
): PasskeyServerClient {
|
|
61
|
+
const { key = "public", name = "Passkey Server Client" } = parameters
|
|
62
|
+
|
|
63
|
+
return createClient({
|
|
64
|
+
...parameters,
|
|
65
|
+
key,
|
|
66
|
+
name,
|
|
67
|
+
type: "passkeyServerClient"
|
|
68
|
+
}).extend(passkeyServerActions)
|
|
69
|
+
}
|