@zerodev/permissions 5.2.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/_cjs/constants.js +18 -0
- package/_cjs/constants.js.map +1 -0
- package/_cjs/deserializePermissionAccount.js +99 -0
- package/_cjs/deserializePermissionAccount.js.map +1 -0
- package/_cjs/index.js +12 -0
- package/_cjs/index.js.map +1 -0
- package/_cjs/package.json +1 -0
- package/_cjs/policies/callPolicyUtils.js +87 -0
- package/_cjs/policies/callPolicyUtils.js.map +1 -0
- package/_cjs/policies/index.js +21 -0
- package/_cjs/policies/index.js.map +1 -0
- package/_cjs/policies/toCallPolicy.js +42 -0
- package/_cjs/policies/toCallPolicy.js.map +1 -0
- package/_cjs/policies/toGasPolicy.js +30 -0
- package/_cjs/policies/toGasPolicy.js.map +1 -0
- package/_cjs/policies/toRateLimitPolicy.js +30 -0
- package/_cjs/policies/toRateLimitPolicy.js.map +1 -0
- package/_cjs/policies/toSignatureCallerPolicy.js +24 -0
- package/_cjs/policies/toSignatureCallerPolicy.js.map +1 -0
- package/_cjs/policies/toSudoPolicy.js +22 -0
- package/_cjs/policies/toSudoPolicy.js.map +1 -0
- package/_cjs/policies/toTimestampPolicy.js +27 -0
- package/_cjs/policies/toTimestampPolicy.js.map +1 -0
- package/_cjs/policies/types.js +19 -0
- package/_cjs/policies/types.js.map +1 -0
- package/_cjs/policies/utils/toPolicyId.js +11 -0
- package/_cjs/policies/utils/toPolicyId.js.map +1 -0
- package/_cjs/serializePermissionAccount.js +27 -0
- package/_cjs/serializePermissionAccount.js.map +1 -0
- package/_cjs/signers/index.js +14 -0
- package/_cjs/signers/index.js.map +1 -0
- package/_cjs/signers/toECDSASigner.js +39 -0
- package/_cjs/signers/toECDSASigner.js.map +1 -0
- package/_cjs/signers/toEmptyECDSASigner.js +30 -0
- package/_cjs/signers/toEmptyECDSASigner.js.map +1 -0
- package/_cjs/signers/toWebAuthnPubKey.js +98 -0
- package/_cjs/signers/toWebAuthnPubKey.js.map +1 -0
- package/_cjs/signers/toWebAuthnSigner.js +154 -0
- package/_cjs/signers/toWebAuthnSigner.js.map +1 -0
- package/_cjs/signers/utils/toSignerId.js +9 -0
- package/_cjs/signers/utils/toSignerId.js.map +1 -0
- package/_cjs/signers/webAuthnUtils.js +45 -0
- package/_cjs/signers/webAuthnUtils.js.map +1 -0
- package/_cjs/toPermissionValidator.js +98 -0
- package/_cjs/toPermissionValidator.js.map +1 -0
- package/_cjs/types.js +3 -0
- package/_cjs/types.js.map +1 -0
- package/_cjs/utils.js +37 -0
- package/_cjs/utils.js.map +1 -0
- package/_esm/constants.js +15 -0
- package/_esm/constants.js.map +1 -0
- package/_esm/deserializePermissionAccount.js +94 -0
- package/_esm/deserializePermissionAccount.js.map +1 -0
- package/_esm/index.js +5 -0
- package/_esm/index.js.map +1 -0
- package/_esm/package.json +1 -0
- package/_esm/policies/callPolicyUtils.js +82 -0
- package/_esm/policies/callPolicyUtils.js.map +1 -0
- package/_esm/policies/index.js +9 -0
- package/_esm/policies/index.js.map +1 -0
- package/_esm/policies/toCallPolicy.js +38 -0
- package/_esm/policies/toCallPolicy.js.map +1 -0
- package/_esm/policies/toGasPolicy.js +26 -0
- package/_esm/policies/toGasPolicy.js.map +1 -0
- package/_esm/policies/toRateLimitPolicy.js +26 -0
- package/_esm/policies/toRateLimitPolicy.js.map +1 -0
- package/_esm/policies/toSignatureCallerPolicy.js +20 -0
- package/_esm/policies/toSignatureCallerPolicy.js.map +1 -0
- package/_esm/policies/toSudoPolicy.js +18 -0
- package/_esm/policies/toSudoPolicy.js.map +1 -0
- package/_esm/policies/toTimestampPolicy.js +23 -0
- package/_esm/policies/toTimestampPolicy.js.map +1 -0
- package/_esm/policies/types.js +17 -0
- package/_esm/policies/types.js.map +1 -0
- package/_esm/policies/utils/toPolicyId.js +7 -0
- package/_esm/policies/utils/toPolicyId.js.map +1 -0
- package/_esm/serializePermissionAccount.js +23 -0
- package/_esm/serializePermissionAccount.js.map +1 -0
- package/_esm/signers/index.js +6 -0
- package/_esm/signers/index.js.map +1 -0
- package/_esm/signers/toECDSASigner.js +36 -0
- package/_esm/signers/toECDSASigner.js.map +1 -0
- package/_esm/signers/toEmptyECDSASigner.js +27 -0
- package/_esm/signers/toEmptyECDSASigner.js.map +1 -0
- package/_esm/signers/toWebAuthnPubKey.js +108 -0
- package/_esm/signers/toWebAuthnPubKey.js.map +1 -0
- package/_esm/signers/toWebAuthnSigner.js +164 -0
- package/_esm/signers/toWebAuthnSigner.js.map +1 -0
- package/_esm/signers/utils/toSignerId.js +5 -0
- package/_esm/signers/utils/toSignerId.js.map +1 -0
- package/_esm/signers/webAuthnUtils.js +41 -0
- package/_esm/signers/webAuthnUtils.js.map +1 -0
- package/_esm/toPermissionValidator.js +94 -0
- package/_esm/toPermissionValidator.js.map +1 -0
- package/_esm/types.js +3 -0
- package/_esm/types.js.map +1 -0
- package/_esm/utils.js +32 -0
- package/_esm/utils.js.map +1 -0
- package/_types/constants.d.ts +14 -0
- package/_types/constants.d.ts.map +1 -0
- package/_types/deserializePermissionAccount.d.ts +13 -0
- package/_types/deserializePermissionAccount.d.ts.map +1 -0
- package/_types/index.d.ts +6 -0
- package/_types/index.d.ts.map +1 -0
- package/_types/policies/callPolicyUtils.d.ts +5 -0
- package/_types/policies/callPolicyUtils.d.ts.map +1 -0
- package/_types/policies/index.d.ts +9 -0
- package/_types/policies/index.d.ts.map +1 -0
- package/_types/policies/toCallPolicy.d.ts +8 -0
- package/_types/policies/toCallPolicy.d.ts.map +1 -0
- package/_types/policies/toGasPolicy.d.ts +9 -0
- package/_types/policies/toGasPolicy.d.ts.map +1 -0
- package/_types/policies/toRateLimitPolicy.d.ts +8 -0
- package/_types/policies/toRateLimitPolicy.d.ts.map +1 -0
- package/_types/policies/toSignatureCallerPolicy.d.ts +7 -0
- package/_types/policies/toSignatureCallerPolicy.d.ts.map +1 -0
- package/_types/policies/toSudoPolicy.d.ts +4 -0
- package/_types/policies/toSudoPolicy.d.ts.map +1 -0
- package/_types/policies/toTimestampPolicy.d.ts +7 -0
- package/_types/policies/toTimestampPolicy.d.ts.map +1 -0
- package/_types/policies/types.d.ts +56 -0
- package/_types/policies/types.d.ts.map +1 -0
- package/_types/policies/utils/toPolicyId.d.ts +4 -0
- package/_types/policies/utils/toPolicyId.d.ts.map +1 -0
- package/_types/serializePermissionAccount.d.ts +5 -0
- package/_types/serializePermissionAccount.d.ts.map +1 -0
- package/_types/signers/index.d.ts +6 -0
- package/_types/signers/index.d.ts.map +1 -0
- package/_types/signers/toECDSASigner.d.ts +8 -0
- package/_types/signers/toECDSASigner.d.ts.map +1 -0
- package/_types/signers/toEmptyECDSASigner.d.ts +4 -0
- package/_types/signers/toEmptyECDSASigner.d.ts.map +1 -0
- package/_types/signers/toWebAuthnPubKey.d.ts +11 -0
- package/_types/signers/toWebAuthnPubKey.d.ts.map +1 -0
- package/_types/signers/toWebAuthnSigner.d.ts +16 -0
- package/_types/signers/toWebAuthnSigner.d.ts.map +1 -0
- package/_types/signers/utils/toSignerId.d.ts +4 -0
- package/_types/signers/utils/toSignerId.d.ts.map +1 -0
- package/_types/signers/webAuthnUtils.d.ts +13 -0
- package/_types/signers/webAuthnUtils.d.ts.map +1 -0
- package/_types/toPermissionValidator.d.ts +5 -0
- package/_types/toPermissionValidator.d.ts.map +1 -0
- package/_types/types.d.ts +61 -0
- package/_types/types.d.ts.map +1 -0
- package/_types/utils.d.ts +8 -0
- package/_types/utils.d.ts.map +1 -0
- package/constants.ts +19 -0
- package/deserializePermissionAccount.ts +130 -0
- package/index.ts +5 -0
- package/package.json +63 -0
- package/policies/callPolicyUtils.ts +122 -0
- package/policies/index.ts +17 -0
- package/policies/toCallPolicy.ts +65 -0
- package/policies/toGasPolicy.ts +42 -0
- package/policies/toRateLimitPolicy.ts +41 -0
- package/policies/toSignatureCallerPolicy.ts +32 -0
- package/policies/toSudoPolicy.ts +24 -0
- package/policies/toTimestampPolicy.ts +37 -0
- package/policies/types.ts +118 -0
- package/policies/utils/toPolicyId.ts +13 -0
- package/serializePermissionAccount.ts +38 -0
- package/signers/index.ts +11 -0
- package/signers/toECDSASigner.ts +61 -0
- package/signers/toEmptyECDSASigner.ts +34 -0
- package/signers/toWebAuthnPubKey.ts +153 -0
- package/signers/toWebAuthnSigner.ts +246 -0
- package/signers/utils/toSignerId.ts +9 -0
- package/signers/webAuthnUtils.ts +54 -0
- package/toPermissionValidator.ts +151 -0
- package/types.ts +75 -0
- package/utils.ts +42 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { type Address, concatHex, encodeAbiParameters, zeroAddress } from "viem"
|
|
2
|
+
import { PolicyFlags } from "../constants.js"
|
|
3
|
+
import { GAS_POLICY_CONTRACT } from "../constants.js"
|
|
4
|
+
import type { Policy, PolicyParams } from "../types.js"
|
|
5
|
+
|
|
6
|
+
export type GasPolicyParams = PolicyParams & {
|
|
7
|
+
allowed?: bigint
|
|
8
|
+
enforcePaymaster?: boolean
|
|
9
|
+
allowedPaymaster?: Address
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function toGasPolicy({
|
|
13
|
+
policyAddress = GAS_POLICY_CONTRACT,
|
|
14
|
+
policyFlag = PolicyFlags.FOR_ALL_VALIDATION,
|
|
15
|
+
allowed = 0n,
|
|
16
|
+
enforcePaymaster = false,
|
|
17
|
+
allowedPaymaster = zeroAddress
|
|
18
|
+
}: GasPolicyParams): Policy {
|
|
19
|
+
return {
|
|
20
|
+
getPolicyData: () => {
|
|
21
|
+
return encodeAbiParameters(
|
|
22
|
+
[
|
|
23
|
+
{ name: "allowed", type: "uint128" },
|
|
24
|
+
{ name: "enforcePaymaster", type: "bool" },
|
|
25
|
+
{ name: "allowedPaymaster", type: "address" }
|
|
26
|
+
],
|
|
27
|
+
[allowed, enforcePaymaster, allowedPaymaster]
|
|
28
|
+
)
|
|
29
|
+
},
|
|
30
|
+
getPolicyInfoInBytes: () => {
|
|
31
|
+
return concatHex([policyFlag, policyAddress])
|
|
32
|
+
},
|
|
33
|
+
policyParams: {
|
|
34
|
+
type: "gas",
|
|
35
|
+
policyAddress,
|
|
36
|
+
policyFlag,
|
|
37
|
+
allowed,
|
|
38
|
+
enforcePaymaster,
|
|
39
|
+
allowedPaymaster
|
|
40
|
+
} as GasPolicyParams & { type: "gas" }
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { concatHex } from "viem"
|
|
2
|
+
import { PolicyFlags } from "../constants.js"
|
|
3
|
+
import { RATE_LIMIT_POLICY_CONTRACT } from "../constants.js"
|
|
4
|
+
import type { Policy, PolicyParams } from "../types.js"
|
|
5
|
+
|
|
6
|
+
export type RateLimitPolicyParams = PolicyParams & {
|
|
7
|
+
interval?: number
|
|
8
|
+
count: number
|
|
9
|
+
startAt?: number
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function toRateLimitPolicy({
|
|
13
|
+
policyAddress = RATE_LIMIT_POLICY_CONTRACT,
|
|
14
|
+
policyFlag = PolicyFlags.FOR_ALL_VALIDATION,
|
|
15
|
+
interval = 0,
|
|
16
|
+
count,
|
|
17
|
+
startAt = 0
|
|
18
|
+
}: RateLimitPolicyParams): Policy {
|
|
19
|
+
return {
|
|
20
|
+
getPolicyData: () => {
|
|
21
|
+
const intervalHex = interval.toString(16).padStart(12, "0")
|
|
22
|
+
const countHex = count.toString(16).padStart(12, "0")
|
|
23
|
+
const startAtHex = startAt.toString(16).padStart(12, "0")
|
|
24
|
+
|
|
25
|
+
const data = intervalHex + countHex + startAtHex
|
|
26
|
+
|
|
27
|
+
return `0x${data}`
|
|
28
|
+
},
|
|
29
|
+
getPolicyInfoInBytes: () => {
|
|
30
|
+
return concatHex([policyFlag, policyAddress])
|
|
31
|
+
},
|
|
32
|
+
policyParams: {
|
|
33
|
+
type: "rate-limit",
|
|
34
|
+
policyAddress,
|
|
35
|
+
policyFlag,
|
|
36
|
+
interval,
|
|
37
|
+
count,
|
|
38
|
+
startAt
|
|
39
|
+
} as RateLimitPolicyParams & { type: "rate-limit" }
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type Address, concatHex, encodeAbiParameters } from "viem"
|
|
2
|
+
import { PolicyFlags } from "../constants.js"
|
|
3
|
+
import { SIGNATURE_POLICY_CONTRACT } from "../constants.js"
|
|
4
|
+
import type { Policy, PolicyParams } from "../types.js"
|
|
5
|
+
|
|
6
|
+
export type SignatureCallerPolicyParams = PolicyParams & {
|
|
7
|
+
allowedCallers: Address[]
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function toSignatureCallerPolicy({
|
|
11
|
+
policyAddress = SIGNATURE_POLICY_CONTRACT,
|
|
12
|
+
policyFlag = PolicyFlags.FOR_ALL_VALIDATION,
|
|
13
|
+
allowedCallers
|
|
14
|
+
}: SignatureCallerPolicyParams): Policy {
|
|
15
|
+
return {
|
|
16
|
+
getPolicyData: () => {
|
|
17
|
+
return encodeAbiParameters(
|
|
18
|
+
[{ name: "allowedCallers", type: "address[]" }],
|
|
19
|
+
[allowedCallers]
|
|
20
|
+
)
|
|
21
|
+
},
|
|
22
|
+
getPolicyInfoInBytes: () => {
|
|
23
|
+
return concatHex([policyFlag, policyAddress])
|
|
24
|
+
},
|
|
25
|
+
policyParams: {
|
|
26
|
+
type: "signature-caller",
|
|
27
|
+
policyAddress,
|
|
28
|
+
policyFlag,
|
|
29
|
+
allowedCallers
|
|
30
|
+
} as SignatureCallerPolicyParams & { type: "signature-caller" }
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { concatHex } from "viem"
|
|
2
|
+
import { PolicyFlags, SUDO_POLICY_CONTRACT } from "../constants.js"
|
|
3
|
+
import type { Policy, PolicyParams } from "../types.js"
|
|
4
|
+
|
|
5
|
+
export type SudoPolicyParams = PolicyParams
|
|
6
|
+
|
|
7
|
+
export function toSudoPolicy({
|
|
8
|
+
policyAddress = SUDO_POLICY_CONTRACT,
|
|
9
|
+
policyFlag = PolicyFlags.FOR_ALL_VALIDATION
|
|
10
|
+
}: SudoPolicyParams): Policy {
|
|
11
|
+
return {
|
|
12
|
+
getPolicyData: () => {
|
|
13
|
+
return "0x"
|
|
14
|
+
},
|
|
15
|
+
getPolicyInfoInBytes: () => {
|
|
16
|
+
return concatHex([policyFlag, policyAddress])
|
|
17
|
+
},
|
|
18
|
+
policyParams: {
|
|
19
|
+
type: "sudo",
|
|
20
|
+
policyAddress,
|
|
21
|
+
policyFlag
|
|
22
|
+
} as SudoPolicyParams & { type: "sudo" }
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { concatHex, encodeAbiParameters } from "viem"
|
|
2
|
+
import { PolicyFlags, TIMESTAMP_POLICY_CONTRACT } from "../constants.js"
|
|
3
|
+
import type { Policy, PolicyParams } from "../types.js"
|
|
4
|
+
|
|
5
|
+
export type TimestampPolicyParams = PolicyParams & {
|
|
6
|
+
validAfter?: number
|
|
7
|
+
validUntil?: number
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function toTimestampPolicy({
|
|
11
|
+
policyAddress = TIMESTAMP_POLICY_CONTRACT,
|
|
12
|
+
policyFlag = PolicyFlags.FOR_ALL_VALIDATION,
|
|
13
|
+
validAfter = 0,
|
|
14
|
+
validUntil = 0
|
|
15
|
+
}: TimestampPolicyParams): Policy {
|
|
16
|
+
return {
|
|
17
|
+
getPolicyData: () => {
|
|
18
|
+
return encodeAbiParameters(
|
|
19
|
+
[
|
|
20
|
+
{ name: "validAfter", type: "uint48" },
|
|
21
|
+
{ name: "validUntil", type: "uint48" }
|
|
22
|
+
],
|
|
23
|
+
[validAfter, validUntil]
|
|
24
|
+
)
|
|
25
|
+
},
|
|
26
|
+
getPolicyInfoInBytes: () => {
|
|
27
|
+
return concatHex([policyFlag, policyAddress])
|
|
28
|
+
},
|
|
29
|
+
policyParams: {
|
|
30
|
+
type: "timestamp",
|
|
31
|
+
policyAddress,
|
|
32
|
+
policyFlag,
|
|
33
|
+
validAfter,
|
|
34
|
+
validUntil
|
|
35
|
+
} as TimestampPolicyParams & { type: "timestamp" }
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { type ExtractAbiFunction, type ExtractAbiFunctionNames } from "abitype"
|
|
2
|
+
import type {
|
|
3
|
+
Abi,
|
|
4
|
+
AbiFunction,
|
|
5
|
+
AbiParameter,
|
|
6
|
+
AbiParameterKind,
|
|
7
|
+
AbiParameterToPrimitiveType,
|
|
8
|
+
AbiStateMutability,
|
|
9
|
+
Address,
|
|
10
|
+
Hex,
|
|
11
|
+
Narrow
|
|
12
|
+
} from "viem"
|
|
13
|
+
|
|
14
|
+
export enum CallType {
|
|
15
|
+
CALL = "0x00",
|
|
16
|
+
BATCH_CALL = "0x01",
|
|
17
|
+
DELEGATE_CALL = "0xff"
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export enum ParamCondition {
|
|
21
|
+
EQUAL = 0,
|
|
22
|
+
GREATER_THAN = 1,
|
|
23
|
+
LESS_THAN = 2,
|
|
24
|
+
GREATER_THAN_OR_EQUAL = 3,
|
|
25
|
+
LESS_THAN_OR_EQUAL = 4,
|
|
26
|
+
NOT_EQUAL = 5
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface ParamRule {
|
|
30
|
+
condition: ParamCondition
|
|
31
|
+
offset: number
|
|
32
|
+
param: Hex
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export type PermissionCore = {
|
|
36
|
+
callType?: CallType
|
|
37
|
+
target: Address
|
|
38
|
+
selector?: Hex
|
|
39
|
+
valueLimit?: bigint
|
|
40
|
+
rules?: ParamRule[]
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export type InferFunctionName<
|
|
44
|
+
TAbi extends Abi | readonly unknown[] = Abi,
|
|
45
|
+
TFunctionName extends string | undefined = string,
|
|
46
|
+
TAbiStateMutability extends AbiStateMutability = AbiStateMutability
|
|
47
|
+
> = TAbi extends Abi
|
|
48
|
+
? ExtractAbiFunctionNames<
|
|
49
|
+
TAbi,
|
|
50
|
+
TAbiStateMutability
|
|
51
|
+
> extends infer AbiFunctionNames
|
|
52
|
+
?
|
|
53
|
+
| AbiFunctionNames
|
|
54
|
+
| (TFunctionName extends AbiFunctionNames ? TFunctionName : never)
|
|
55
|
+
| (Abi extends TAbi ? string : never)
|
|
56
|
+
: never
|
|
57
|
+
: TFunctionName
|
|
58
|
+
|
|
59
|
+
export type GetFunctionArgs<
|
|
60
|
+
TAbi extends Abi | readonly unknown[],
|
|
61
|
+
TFunctionName extends string,
|
|
62
|
+
TAbiFunction extends AbiFunction = TAbi extends Abi
|
|
63
|
+
? ExtractAbiFunction<TAbi, TFunctionName>
|
|
64
|
+
: AbiFunction,
|
|
65
|
+
TArgs = CombinedArgs<TAbiFunction["inputs"]>,
|
|
66
|
+
FailedToParseArgs =
|
|
67
|
+
| ([TArgs] extends [never] ? true : false)
|
|
68
|
+
| (readonly unknown[] extends TArgs ? true : false)
|
|
69
|
+
> = true extends FailedToParseArgs
|
|
70
|
+
? {
|
|
71
|
+
args?: readonly unknown[]
|
|
72
|
+
}
|
|
73
|
+
: TArgs extends readonly []
|
|
74
|
+
? { args?: never }
|
|
75
|
+
: {
|
|
76
|
+
args?: TArgs
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export type Permission<
|
|
80
|
+
TAbi extends Abi | readonly unknown[],
|
|
81
|
+
TFunctionName extends string | undefined = string,
|
|
82
|
+
_FunctionName = TAbi extends Abi
|
|
83
|
+
? InferFunctionName<TAbi, TFunctionName>
|
|
84
|
+
: never
|
|
85
|
+
> = PermissionCore & {
|
|
86
|
+
functionName?: _FunctionName
|
|
87
|
+
} & (TFunctionName extends string
|
|
88
|
+
? { abi?: Narrow<TAbi> } & GetFunctionArgs<TAbi, TFunctionName>
|
|
89
|
+
: _FunctionName extends string
|
|
90
|
+
? { abi?: [Narrow<TAbi[number]>] } & GetFunctionArgs<
|
|
91
|
+
TAbi,
|
|
92
|
+
_FunctionName
|
|
93
|
+
>
|
|
94
|
+
: never)
|
|
95
|
+
|
|
96
|
+
export type CombinedArgs<
|
|
97
|
+
TAbiParameters extends readonly AbiParameter[],
|
|
98
|
+
TAbiParameterKind extends AbiParameterKind = AbiParameterKind
|
|
99
|
+
> = {
|
|
100
|
+
[K in keyof TAbiParameters]: {
|
|
101
|
+
condition: ParamCondition
|
|
102
|
+
value: AbiParameterToPrimitiveType<TAbiParameters[K], TAbiParameterKind>
|
|
103
|
+
} | null
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export type GeneratePermissionFromArgsParameters<
|
|
107
|
+
TAbi extends Abi | readonly unknown[],
|
|
108
|
+
TFunctionName extends string | undefined = string,
|
|
109
|
+
_FunctionName = TAbi extends Abi
|
|
110
|
+
? InferFunctionName<TAbi, TFunctionName>
|
|
111
|
+
: never
|
|
112
|
+
> = {
|
|
113
|
+
functionName?: _FunctionName
|
|
114
|
+
} & (TFunctionName extends string
|
|
115
|
+
? { abi: Narrow<TAbi> } & GetFunctionArgs<TAbi, TFunctionName>
|
|
116
|
+
: _FunctionName extends string
|
|
117
|
+
? { abi: [Narrow<TAbi[number]>] } & GetFunctionArgs<TAbi, _FunctionName>
|
|
118
|
+
: never)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type Hex, concat, encodeAbiParameters } from "viem"
|
|
2
|
+
import type { Policy } from "../../types.js"
|
|
3
|
+
|
|
4
|
+
export const toPolicyId = (policies: Policy[]): Hex => {
|
|
5
|
+
return encodeAbiParameters(
|
|
6
|
+
[{ name: "policiesData", type: "bytes[]" }],
|
|
7
|
+
[
|
|
8
|
+
policies.map((policy) =>
|
|
9
|
+
concat([policy.getPolicyInfoInBytes(), policy.getPolicyData()])
|
|
10
|
+
)
|
|
11
|
+
]
|
|
12
|
+
)
|
|
13
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { KernelSmartAccount } from "@zerodev/sdk"
|
|
2
|
+
import type { EntryPoint } from "permissionless/types"
|
|
3
|
+
import type { Hex } from "viem"
|
|
4
|
+
import {
|
|
5
|
+
isPermissionValidatorPlugin,
|
|
6
|
+
serializePermissionAccountParams
|
|
7
|
+
} from "./utils.js"
|
|
8
|
+
|
|
9
|
+
export const serializePermissionAccount = async <entryPoint extends EntryPoint>(
|
|
10
|
+
account: KernelSmartAccount<entryPoint>,
|
|
11
|
+
privateKey?: Hex
|
|
12
|
+
): Promise<string> => {
|
|
13
|
+
if (!isPermissionValidatorPlugin(account.kernelPluginManager))
|
|
14
|
+
throw new Error("Account plugin is not a permission validator")
|
|
15
|
+
const permissionParams =
|
|
16
|
+
account.kernelPluginManager.getPluginSerializationParams()
|
|
17
|
+
const action = account.kernelPluginManager.getAction()
|
|
18
|
+
const validityData = account.kernelPluginManager.getValidityData()
|
|
19
|
+
const enableSignature =
|
|
20
|
+
await account.kernelPluginManager.getPluginEnableSignature(
|
|
21
|
+
account.address
|
|
22
|
+
)
|
|
23
|
+
const accountParams = {
|
|
24
|
+
initCode: await account.generateInitCode(),
|
|
25
|
+
accountAddress: account.address
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const paramsToBeSerialized = {
|
|
29
|
+
permissionParams,
|
|
30
|
+
action,
|
|
31
|
+
validityData,
|
|
32
|
+
accountParams,
|
|
33
|
+
enableSignature,
|
|
34
|
+
privateKey
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return serializePermissionAccountParams(paramsToBeSerialized)
|
|
38
|
+
}
|
package/signers/index.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export {
|
|
2
|
+
toECDSASigner,
|
|
3
|
+
type ECDSAModularSignerParams
|
|
4
|
+
} from "./toECDSASigner.js"
|
|
5
|
+
export {
|
|
6
|
+
toWebAuthnSigner,
|
|
7
|
+
type WebAuthnModularSignerParams
|
|
8
|
+
} from "./toWebAuthnSigner.js"
|
|
9
|
+
export { WebAuthnMode } from "./toWebAuthnPubKey.js"
|
|
10
|
+
export { toSignerId } from "./utils/toSignerId.js"
|
|
11
|
+
export { toEmptyECDSASigner } from "./toEmptyECDSASigner.js"
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { constants, fixSignedData } from "@zerodev/sdk"
|
|
2
|
+
import type { TypedData } from "abitype"
|
|
3
|
+
import {
|
|
4
|
+
SignTransactionNotSupportedBySmartAccount,
|
|
5
|
+
type SmartAccountSigner
|
|
6
|
+
} from "permissionless/accounts"
|
|
7
|
+
import { type Address, type LocalAccount, type TypedDataDefinition } from "viem"
|
|
8
|
+
import { toAccount } from "viem/accounts"
|
|
9
|
+
import { ECDSA_SIGNER_CONTRACT } from "../constants.js"
|
|
10
|
+
import type { ModularSigner, ModularSignerParams } from "../types.js"
|
|
11
|
+
|
|
12
|
+
export type ECDSAModularSignerParams<
|
|
13
|
+
TSource extends string = "custom",
|
|
14
|
+
TAddress extends Address = Address
|
|
15
|
+
> = ModularSignerParams & {
|
|
16
|
+
signer: SmartAccountSigner<TSource, TAddress>
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function toECDSASigner<
|
|
20
|
+
TSource extends string = "custom",
|
|
21
|
+
TAddress extends Address = Address
|
|
22
|
+
>({
|
|
23
|
+
signer,
|
|
24
|
+
signerContractAddress = ECDSA_SIGNER_CONTRACT
|
|
25
|
+
}: ECDSAModularSignerParams<TSource, TAddress>): ModularSigner {
|
|
26
|
+
const viemSigner: LocalAccount = {
|
|
27
|
+
...signer,
|
|
28
|
+
signTransaction: (_, __) => {
|
|
29
|
+
throw new SignTransactionNotSupportedBySmartAccount()
|
|
30
|
+
}
|
|
31
|
+
} as LocalAccount
|
|
32
|
+
const account = toAccount({
|
|
33
|
+
address: viemSigner.address,
|
|
34
|
+
async signMessage({ message }) {
|
|
35
|
+
return fixSignedData(await viemSigner.signMessage({ message }))
|
|
36
|
+
},
|
|
37
|
+
async signTransaction(_, __) {
|
|
38
|
+
throw new SignTransactionNotSupportedBySmartAccount()
|
|
39
|
+
},
|
|
40
|
+
async signTypedData<
|
|
41
|
+
const TTypedData extends TypedData | Record<string, unknown>,
|
|
42
|
+
TPrimaryType extends
|
|
43
|
+
| keyof TTypedData
|
|
44
|
+
| "EIP712Domain" = keyof TTypedData
|
|
45
|
+
>(typedData: TypedDataDefinition<TTypedData, TPrimaryType>) {
|
|
46
|
+
return fixSignedData(
|
|
47
|
+
await viemSigner.signTypedData<TTypedData, TPrimaryType>({
|
|
48
|
+
...typedData
|
|
49
|
+
})
|
|
50
|
+
)
|
|
51
|
+
}
|
|
52
|
+
})
|
|
53
|
+
return {
|
|
54
|
+
account,
|
|
55
|
+
signerContractAddress,
|
|
56
|
+
getSignerData: () => {
|
|
57
|
+
return viemSigner.address
|
|
58
|
+
},
|
|
59
|
+
getDummySignature: () => constants.DUMMY_ECDSA_SIG
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { constants } from "@zerodev/sdk"
|
|
2
|
+
import type { TypedData } from "abitype"
|
|
3
|
+
import { type Address, type TypedDataDefinition } from "viem"
|
|
4
|
+
import { toAccount } from "viem/accounts"
|
|
5
|
+
import { ECDSA_SIGNER_CONTRACT } from "../constants.js"
|
|
6
|
+
import type { ModularSigner } from "../types.js"
|
|
7
|
+
|
|
8
|
+
export function toEmptyECDSASigner(address: Address): ModularSigner {
|
|
9
|
+
const account = toAccount({
|
|
10
|
+
address,
|
|
11
|
+
async signMessage() {
|
|
12
|
+
throw new Error("Method not supported")
|
|
13
|
+
},
|
|
14
|
+
async signTransaction(_, __) {
|
|
15
|
+
throw new Error("Method not supported")
|
|
16
|
+
},
|
|
17
|
+
async signTypedData<
|
|
18
|
+
const TTypedData extends TypedData | Record<string, unknown>,
|
|
19
|
+
TPrimaryType extends
|
|
20
|
+
| keyof TTypedData
|
|
21
|
+
| "EIP712Domain" = keyof TTypedData
|
|
22
|
+
>(_typedData: TypedDataDefinition<TTypedData, TPrimaryType>) {
|
|
23
|
+
throw new Error("Method not supported")
|
|
24
|
+
}
|
|
25
|
+
})
|
|
26
|
+
return {
|
|
27
|
+
account,
|
|
28
|
+
signerContractAddress: ECDSA_SIGNER_CONTRACT,
|
|
29
|
+
getSignerData: () => {
|
|
30
|
+
return address
|
|
31
|
+
},
|
|
32
|
+
getDummySignature: () => constants.DUMMY_ECDSA_SIG
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { Buffer } from "buffer"
|
|
2
|
+
import { type Hex, keccak256 } from "viem"
|
|
3
|
+
import { type WebAuthnKey } from "./toWebAuthnSigner.js"
|
|
4
|
+
import { b64ToBytes, uint8ArrayToHexString } from "./webAuthnUtils.js"
|
|
5
|
+
|
|
6
|
+
export enum WebAuthnMode {
|
|
7
|
+
Register = "register",
|
|
8
|
+
Login = "login"
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const toWebAuthnPubKey = async ({
|
|
12
|
+
passkeyName,
|
|
13
|
+
passkeyServerUrl,
|
|
14
|
+
mode = WebAuthnMode.Login
|
|
15
|
+
}: {
|
|
16
|
+
passkeyName: string
|
|
17
|
+
passkeyServerUrl: string
|
|
18
|
+
mode: WebAuthnMode
|
|
19
|
+
}): Promise<WebAuthnKey> => {
|
|
20
|
+
let pubKey: string | undefined
|
|
21
|
+
let authenticatorIdHash: Hex
|
|
22
|
+
if (mode === WebAuthnMode.Login) {
|
|
23
|
+
// Get login options
|
|
24
|
+
const loginOptionsResponse = await fetch(
|
|
25
|
+
`${passkeyServerUrl}/login/options`,
|
|
26
|
+
{
|
|
27
|
+
method: "POST",
|
|
28
|
+
headers: { "Content-Type": "application/json" },
|
|
29
|
+
credentials: "include"
|
|
30
|
+
}
|
|
31
|
+
)
|
|
32
|
+
const loginOptions = await loginOptionsResponse.json()
|
|
33
|
+
|
|
34
|
+
// Start authentication (login)
|
|
35
|
+
const { startAuthentication } = await import("@simplewebauthn/browser")
|
|
36
|
+
const loginCred = await startAuthentication(loginOptions)
|
|
37
|
+
|
|
38
|
+
// get authenticatorIdHash
|
|
39
|
+
authenticatorIdHash = keccak256(
|
|
40
|
+
uint8ArrayToHexString(b64ToBytes(loginCred.id))
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
// Verify authentication
|
|
44
|
+
const loginVerifyResponse = await fetch(
|
|
45
|
+
`${passkeyServerUrl}/login/verify`,
|
|
46
|
+
{
|
|
47
|
+
method: "POST",
|
|
48
|
+
headers: { "Content-Type": "application/json" },
|
|
49
|
+
body: JSON.stringify({ cred: loginCred }),
|
|
50
|
+
credentials: "include"
|
|
51
|
+
}
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
const loginVerifyResult = await loginVerifyResponse.json()
|
|
55
|
+
|
|
56
|
+
if (window.sessionStorage === undefined) {
|
|
57
|
+
throw new Error("sessionStorage is not available")
|
|
58
|
+
}
|
|
59
|
+
sessionStorage.setItem("userId", loginVerifyResult.userId)
|
|
60
|
+
|
|
61
|
+
if (!loginVerifyResult.verification.verified) {
|
|
62
|
+
throw new Error("Login not verified")
|
|
63
|
+
}
|
|
64
|
+
// Import the key
|
|
65
|
+
pubKey = loginVerifyResult.pubkey // Uint8Array pubkey
|
|
66
|
+
} else {
|
|
67
|
+
if (!passkeyName) {
|
|
68
|
+
throw new Error("No passkey name provided")
|
|
69
|
+
}
|
|
70
|
+
// Get registration options
|
|
71
|
+
const registerOptionsResponse = await fetch(
|
|
72
|
+
`${passkeyServerUrl}/register/options`,
|
|
73
|
+
{
|
|
74
|
+
method: "POST",
|
|
75
|
+
headers: {
|
|
76
|
+
"Content-Type": "application/json"
|
|
77
|
+
},
|
|
78
|
+
body: JSON.stringify({ username: passkeyName }),
|
|
79
|
+
credentials: "include"
|
|
80
|
+
}
|
|
81
|
+
)
|
|
82
|
+
const registerOptions = await registerOptionsResponse.json()
|
|
83
|
+
|
|
84
|
+
// save userId to sessionStorage
|
|
85
|
+
if (window.sessionStorage === undefined) {
|
|
86
|
+
throw new Error("sessionStorage is not available")
|
|
87
|
+
}
|
|
88
|
+
sessionStorage.setItem("userId", registerOptions.userId)
|
|
89
|
+
|
|
90
|
+
// Start registration
|
|
91
|
+
const { startRegistration } = await import("@simplewebauthn/browser")
|
|
92
|
+
const registerCred = await startRegistration(registerOptions.options)
|
|
93
|
+
|
|
94
|
+
// get authenticatorIdHash
|
|
95
|
+
authenticatorIdHash = keccak256(
|
|
96
|
+
uint8ArrayToHexString(b64ToBytes(registerCred.id))
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
// Verify registration
|
|
100
|
+
const registerVerifyResponse = await fetch(
|
|
101
|
+
`${passkeyServerUrl}/register/verify`,
|
|
102
|
+
{
|
|
103
|
+
method: "POST",
|
|
104
|
+
headers: {
|
|
105
|
+
"Content-Type": "application/json"
|
|
106
|
+
},
|
|
107
|
+
body: JSON.stringify({
|
|
108
|
+
userId: registerOptions.userId,
|
|
109
|
+
username: passkeyName,
|
|
110
|
+
cred: registerCred
|
|
111
|
+
}),
|
|
112
|
+
credentials: "include"
|
|
113
|
+
}
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
const registerVerifyResult = await registerVerifyResponse.json()
|
|
117
|
+
if (!registerVerifyResult.verified) {
|
|
118
|
+
throw new Error("Registration not verified")
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Import the key
|
|
122
|
+
pubKey = registerCred.response.publicKey
|
|
123
|
+
}
|
|
124
|
+
if (!pubKey) {
|
|
125
|
+
throw new Error("No public key returned from registration credential")
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const spkiDer = Buffer.from(pubKey, "base64")
|
|
129
|
+
const key = await crypto.subtle.importKey(
|
|
130
|
+
"spki",
|
|
131
|
+
spkiDer,
|
|
132
|
+
{
|
|
133
|
+
name: "ECDSA",
|
|
134
|
+
namedCurve: "P-256"
|
|
135
|
+
},
|
|
136
|
+
true,
|
|
137
|
+
["verify"]
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
// Export the key to the raw format
|
|
141
|
+
const rawKey = await crypto.subtle.exportKey("raw", key)
|
|
142
|
+
const rawKeyBuffer = Buffer.from(rawKey)
|
|
143
|
+
|
|
144
|
+
// The first byte is 0x04 (uncompressed), followed by x and y coordinates (32 bytes each for P-256)
|
|
145
|
+
const pubKeyX = rawKeyBuffer.subarray(1, 33).toString("hex")
|
|
146
|
+
const pubKeyY = rawKeyBuffer.subarray(33).toString("hex")
|
|
147
|
+
|
|
148
|
+
return {
|
|
149
|
+
pubX: BigInt(`0x${pubKeyX}`),
|
|
150
|
+
pubY: BigInt(`0x${pubKeyY}`),
|
|
151
|
+
authenticatorIdHash
|
|
152
|
+
}
|
|
153
|
+
}
|