payid 0.5.9 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/dist/chunk-AUW7WDAB.js +198 -0
  2. package/dist/{chunk-SSO66YQI.js → chunk-E6VQETBC.js} +13 -0
  3. package/dist/{chunk-AYJYFAXJ.js → chunk-ESTGPUEQ.js} +24 -21
  4. package/dist/{chunk-ROBSNIIZ.js → chunk-EZ3BGZ7G.js} +25 -16
  5. package/dist/chunk-FZNMDGVK.js +24 -0
  6. package/dist/chunk-HKHRYRD6.js +752 -0
  7. package/dist/chunk-X7NYQ47Y.js +27 -0
  8. package/dist/chunk-XMUHMJRD.js +30 -0
  9. package/dist/context/index.d.ts +3 -2
  10. package/dist/context.v1-C1m-tz0o.d.ts +39 -0
  11. package/dist/context.v2-DIzPotmW.d.ts +37 -0
  12. package/dist/core/client/index.d.ts +5 -4
  13. package/dist/core/client/index.js +9 -5
  14. package/dist/core/server/index.d.ts +4 -3
  15. package/dist/core/server/index.js +7 -4
  16. package/dist/{index-2JCvey4-.d.ts → index-CDnE3SGM.d.ts} +18 -3
  17. package/dist/index-CsynGAGv.d.ts +53 -0
  18. package/dist/{index-Dj9IEios.d.ts → index-CubM9whW.d.ts} +4 -17
  19. package/dist/{index-C1DHMQA0.d.ts → index-DSxDlF9J.d.ts} +45 -68
  20. package/dist/{index-BEvnPzzt.d.ts → index-Dm2VdDEB.d.ts} +2 -1
  21. package/dist/index-G_1SiZJo.d.ts +104 -0
  22. package/dist/index.d.ts +407 -72
  23. package/dist/index.js +582 -77
  24. package/dist/issuer/index.d.ts +3 -2
  25. package/dist/issuer/index.js +4 -1
  26. package/dist/rule/index.d.ts +2 -2
  27. package/dist/rule/index.js +4 -3
  28. package/dist/rule-a_5ed-93.d.ts +39 -0
  29. package/dist/sessionPolicy/index.d.ts +3 -3
  30. package/dist/sessionPolicy/index.js +17 -6
  31. package/dist/types-D2o6XS7a.d.ts +66 -0
  32. package/dist/types-i4eTkhWa.d.ts +50 -0
  33. package/package.json +22 -9
  34. package/src/rule/engine/rule_engine.wasm +0 -0
  35. package/dist/chunk-IQNCMOIE.js +0 -47
  36. package/dist/chunk-MXKZJKXE.js +0 -33
  37. package/dist/chunk-PAJYP7JI.js +0 -308
  38. package/dist/chunk-QC24X74O.js +0 -41
  39. package/dist/index-BPJ_oOfy.d.ts +0 -81
  40. package/dist/index-BQQnMG2H.d.ts +0 -114
  41. package/dist/types-B8pJQdMQ.d.ts +0 -26
  42. package/dist/types-BmMf7udp.d.ts +0 -13
@@ -1,308 +0,0 @@
1
- import {
2
- randomHex
3
- } from "./chunk-KDC67LIN.js";
4
-
5
- // src/evaluate.ts
6
- import { executeRule, preprocessContextV2 } from "payid-rule-engine";
7
-
8
- // src/normalize.ts
9
- function normalizeContext(ctx) {
10
- return {
11
- ...ctx,
12
- tx: {
13
- ...ctx.tx,
14
- sender: ctx.tx.sender?.toLowerCase(),
15
- receiver: ctx.tx.receiver?.toLowerCase(),
16
- asset: ctx.tx.asset.toUpperCase()
17
- }
18
- };
19
- }
20
-
21
- // src/core/dicisionTrace.ts
22
- function toBigIntSafe(v) {
23
- try {
24
- if (typeof v === "bigint") return v;
25
- if (typeof v === "number" && Number.isFinite(v)) return BigInt(Math.trunc(v));
26
- if (typeof v === "string" && v !== "") return BigInt(v);
27
- return null;
28
- } catch {
29
- return null;
30
- }
31
- }
32
- function resolveField(obj, fieldExpr) {
33
- const [path, ...transforms] = fieldExpr.split("|");
34
- let value = path?.split(".").reduce((o, k) => o?.[k], obj);
35
- for (const t of transforms) {
36
- if (value === void 0 || value === null) break;
37
- if (t.startsWith("div:")) {
38
- const n = Number(t.slice(4));
39
- value = Number(value) / n;
40
- } else if (t.startsWith("mod:")) {
41
- const n = BigInt(t.slice(4));
42
- value = BigInt(value) % n;
43
- } else if (t === "abs") {
44
- value = Math.abs(Number(value));
45
- } else if (t === "hour") {
46
- value = new Date(Number(value) * 1e3).getUTCHours();
47
- } else if (t === "day") {
48
- value = new Date(Number(value) * 1e3).getUTCDay();
49
- } else if (t === "date") {
50
- value = new Date(Number(value) * 1e3).getUTCDate();
51
- } else if (t === "month") {
52
- value = new Date(Number(value) * 1e3).getUTCMonth() + 1;
53
- } else if (t === "len") {
54
- value = String(value).length;
55
- } else if (t === "lower") {
56
- value = String(value).toLowerCase();
57
- } else if (t === "upper") {
58
- value = String(value).toUpperCase();
59
- }
60
- }
61
- return value;
62
- }
63
- function resolveValue(context, value) {
64
- if (typeof value === "string" && value.startsWith("$")) {
65
- return resolveField(context, value.slice(1));
66
- }
67
- return value;
68
- }
69
- function evaluateCondition(actual, op, expected) {
70
- switch (op) {
71
- case ">=":
72
- case "<=":
73
- case ">":
74
- case "<": {
75
- const a = toBigIntSafe(actual);
76
- const b = toBigIntSafe(expected);
77
- if (a === null || b === null) return false;
78
- if (op === ">=") return a >= b;
79
- if (op === "<=") return a <= b;
80
- if (op === ">") return a > b;
81
- if (op === "<") return a < b;
82
- return false;
83
- }
84
- case "==":
85
- return actual == expected;
86
- case "!=":
87
- return actual != expected;
88
- case "in":
89
- return Array.isArray(expected) && expected.includes(actual);
90
- case "not_in":
91
- return Array.isArray(expected) && !expected.includes(actual);
92
- case "between":
93
- return Array.isArray(expected) && actual >= expected[0] && actual <= expected[1];
94
- case "not_between":
95
- return Array.isArray(expected) && !(actual >= expected[0] && actual <= expected[1]);
96
- case "exists":
97
- return actual !== void 0 && actual !== null;
98
- case "not_exists":
99
- return actual === void 0 || actual === null;
100
- default:
101
- return false;
102
- }
103
- }
104
- function traceCondition(context, ruleId, cond) {
105
- const actual = resolveField(context, cond.field);
106
- const expected = resolveValue(context, cond.value);
107
- const pass = evaluateCondition(actual, cond.op, expected);
108
- return {
109
- ruleId,
110
- field: cond.field,
111
- op: cond.op,
112
- expected: cond.value,
113
- actual,
114
- result: actual === void 0 ? "FAIL" : pass ? "PASS" : "FAIL"
115
- };
116
- }
117
- function traceRule(context, rule) {
118
- if ("if" in rule) {
119
- return [traceCondition(context, rule.id, rule.if)];
120
- }
121
- if ("conditions" in rule) {
122
- return rule.conditions.map((cond) => traceCondition(context, rule.id, cond));
123
- }
124
- if ("rules" in rule) {
125
- return rule.rules.flatMap((child) => traceRule(context, child));
126
- }
127
- return [];
128
- }
129
- function buildDecisionTrace(context, ruleConfig) {
130
- return ruleConfig.rules.flatMap((rule) => traceRule(context, rule));
131
- }
132
-
133
- // src/evaluate.ts
134
- async function evaluate(context, ruleConfig, options, wasmBinary) {
135
- if (!context || typeof context !== "object") {
136
- throw new Error("evaluate(): context is required");
137
- }
138
- if (!context.tx) {
139
- throw new Error("evaluate(): context.tx is required");
140
- }
141
- if (!ruleConfig || typeof ruleConfig !== "object") {
142
- throw new Error("evaluate(): ruleConfig is required");
143
- }
144
- let result;
145
- try {
146
- const preparedContext = options?.trustedIssuers ? preprocessContextV2(context, ruleConfig, options.trustedIssuers) : context;
147
- const normalized = normalizeContext(preparedContext);
148
- result = await executeRule(normalized, ruleConfig, wasmBinary);
149
- } catch (err) {
150
- return {
151
- decision: "REJECT",
152
- code: "CONTEXT_OR_ENGINE_ERROR",
153
- reason: err?.message ?? "rule evaluation failed"
154
- };
155
- }
156
- if (result.decision !== "ALLOW" && result.decision !== "REJECT") {
157
- return {
158
- decision: "REJECT",
159
- code: "INVALID_ENGINE_OUTPUT",
160
- reason: "invalid decision value"
161
- };
162
- }
163
- const baseResult = {
164
- decision: result.decision,
165
- code: result.code || "UNKNOWN",
166
- reason: result.reason
167
- };
168
- if (options?.debug) {
169
- return {
170
- ...baseResult,
171
- debug: {
172
- trace: buildDecisionTrace(context, ruleConfig)
173
- }
174
- };
175
- }
176
- return baseResult;
177
- }
178
-
179
- // src/utils/subtle.ts
180
- var subtleCrypto = globalThis.crypto.subtle;
181
-
182
- // src/utils/fetchJson.ts
183
- async function fetchJsonWithHashCheck(url, expectedHash) {
184
- const res = await fetch(url);
185
- if (!res.ok) {
186
- throw new Error("RULE_FETCH_FAILED");
187
- }
188
- const buffer = await res.arrayBuffer();
189
- if (expectedHash) {
190
- const digest = await subtleCrypto.digest(
191
- "SHA-256",
192
- buffer
193
- );
194
- const actualHash = bufferToHex(digest);
195
- if (actualHash !== expectedHash) {
196
- throw new Error("RULE_HASH_MISMATCH");
197
- }
198
- }
199
- return JSON.parse(new TextDecoder().decode(buffer));
200
- }
201
- function bufferToHex(buffer) {
202
- return [...new Uint8Array(buffer)].map((b) => b.toString(16).padStart(2, "0")).join("");
203
- }
204
-
205
- // src/resolver/resolver.ts
206
- async function resolveRule(source) {
207
- const { uri, hash: hash2 } = source;
208
- if (uri.startsWith("inline://")) {
209
- const encoded = uri.replace("inline://", "");
210
- const json = JSON.parse(atob(encoded));
211
- return { config: json, source };
212
- }
213
- if (uri.startsWith("ipfs://")) {
214
- const cid = uri.replace("ipfs://", "");
215
- const url = `https://ipfs.io/ipfs/${cid}`;
216
- const config = await fetchJsonWithHashCheck(url, hash2);
217
- return { config, source };
218
- }
219
- if (uri.startsWith("http://") || uri.startsWith("https://")) {
220
- const config = await fetchJsonWithHashCheck(uri, hash2);
221
- return { config, source };
222
- }
223
- throw new Error("UNSUPPORTED_RULE_URI");
224
- }
225
-
226
- // src/decision-proof/hash.ts
227
- import { keccak256 } from "ethers";
228
- function stableStringify(obj) {
229
- if (Array.isArray(obj)) {
230
- return `[${obj.map(stableStringify).join(",")}]`;
231
- }
232
- if (obj && typeof obj === "object") {
233
- return `{${Object.keys(obj).sort().map(
234
- (k) => `"${k}":${stableStringify(obj[k])}`
235
- ).join(",")}}`;
236
- }
237
- return JSON.stringify(obj);
238
- }
239
- function toUtf8Bytes(str) {
240
- return new TextEncoder().encode(str);
241
- }
242
- function hashContext(context) {
243
- return keccak256(toUtf8Bytes(stableStringify(context)));
244
- }
245
- function hashRuleSet(ruleConfig) {
246
- return keccak256(toUtf8Bytes(stableStringify(ruleConfig)));
247
- }
248
-
249
- // src/decision-proof/generate.ts
250
- import { ethers, ZeroAddress } from "ethers";
251
- var hash = (v) => ethers.keccak256(ethers.toUtf8Bytes(v));
252
- async function generateDecisionProof(params) {
253
- const now = params.blockTimestamp ?? Math.floor(Date.now() / 1e3);
254
- const issuedAt = now - 30;
255
- const expiresAt = now + (params.ttlSeconds ?? 300);
256
- const chainId = params.chainId ?? Number((await params.signer.provider.getNetwork()).chainId);
257
- const requiresAttestation = Array.isArray(params.ruleConfig?.requires) && params.ruleConfig.requires.length > 0;
258
- const payload = {
259
- version: hash("2"),
260
- payId: hash(params.payId),
261
- payer: params.payer,
262
- receiver: params.receiver,
263
- asset: params.asset,
264
- amount: params.amount,
265
- contextHash: hashContext(params.context),
266
- ruleSetHash: params.ruleSetHashOverride ?? hashRuleSet(params.ruleConfig),
267
- ruleAuthority: params.ruleAuthority ?? ZeroAddress,
268
- issuedAt: BigInt(issuedAt),
269
- expiresAt: BigInt(expiresAt),
270
- nonce: randomHex(32),
271
- requiresAttestation
272
- };
273
- const domain = {
274
- name: "PAY.ID Decision",
275
- version: "2",
276
- chainId,
277
- verifyingContract: params.verifyingContract
278
- };
279
- const types = {
280
- Decision: [
281
- { name: "version", type: "bytes32" },
282
- { name: "payId", type: "bytes32" },
283
- { name: "payer", type: "address" },
284
- { name: "receiver", type: "address" },
285
- { name: "asset", type: "address" },
286
- { name: "amount", type: "uint256" },
287
- { name: "contextHash", type: "bytes32" },
288
- { name: "ruleSetHash", type: "bytes32" },
289
- { name: "ruleAuthority", type: "address" },
290
- { name: "issuedAt", type: "uint64" },
291
- { name: "expiresAt", type: "uint64" },
292
- { name: "nonce", type: "bytes32" },
293
- { name: "requiresAttestation", type: "bool" }
294
- ]
295
- };
296
- const signature = await params.signer.signTypedData(domain, types, payload);
297
- const recovered = ethers.verifyTypedData(domain, types, payload, signature);
298
- if (recovered.toLowerCase() !== params.payer.toLowerCase()) {
299
- throw new Error("SIGNATURE_MISMATCH");
300
- }
301
- return { payload, signature };
302
- }
303
-
304
- export {
305
- evaluate,
306
- resolveRule,
307
- generateDecisionProof
308
- };
@@ -1,41 +0,0 @@
1
- import {
2
- combineRules
3
- } from "./chunk-GG34PNTF.js";
4
- import {
5
- canonicalizeRuleSet
6
- } from "./chunk-6VPSJFO4.js";
7
- import {
8
- __export
9
- } from "./chunk-MLKGABMK.js";
10
-
11
- // src/rule/index.ts
12
- var rule_exports = {};
13
- __export(rule_exports, {
14
- canonicalizeRuleSet: () => canonicalizeRuleSet,
15
- combineRules: () => combineRules,
16
- hashRuleSet: () => hashRuleSet
17
- });
18
-
19
- // src/rule/hash.ts
20
- import { keccak256, toUtf8Bytes } from "ethers";
21
- function stableStringify(obj) {
22
- if (Array.isArray(obj)) {
23
- return `[${obj.map(stableStringify).join(",")}]`;
24
- }
25
- if (obj && typeof obj === "object") {
26
- return `{${Object.keys(obj).sort().map(
27
- (k) => `"${k}":${stableStringify(obj[k])}`
28
- ).join(",")}}`;
29
- }
30
- return JSON.stringify(obj);
31
- }
32
- function hashRuleSet(ruleSet) {
33
- return keccak256(
34
- toUtf8Bytes(stableStringify(ruleSet))
35
- );
36
- }
37
-
38
- export {
39
- hashRuleSet,
40
- rule_exports
41
- };
@@ -1,81 +0,0 @@
1
- import { RuleContext, RuleConfig, RuleResult } from 'payid-types';
2
- import { ethers } from 'ethers';
3
- import { R as RuleSource, D as DecisionProof } from './types-B8pJQdMQ.js';
4
- import { P as PayIDSessionPolicyPayloadV1 } from './types-BmMf7udp.js';
5
-
6
- declare class PayIDClient {
7
- private readonly debugTrace?;
8
- private readonly wasm?;
9
- private readonly _ready;
10
- constructor(debugTrace?: boolean | undefined, wasm?: Uint8Array | undefined);
11
- ready(): Promise<void>;
12
- evaluate(context: RuleContext, rule: RuleConfig | RuleSource): Promise<RuleResult>;
13
- evaluateAndProve(params: {
14
- context: RuleContext;
15
- authorityRule: RuleConfig | RuleSource;
16
- evaluationRule?: RuleConfig;
17
- sessionPolicy?: PayIDSessionPolicyPayloadV1;
18
- payId: string;
19
- payer: string;
20
- receiver: string;
21
- asset: string;
22
- amount: bigint;
23
- signer: ethers.Signer;
24
- verifyingContract: string;
25
- ruleAuthority: string;
26
- ruleSetHashOverride?: string;
27
- ttlSeconds?: number;
28
- chainId: number;
29
- blockTimestamp: number;
30
- }): Promise<{
31
- result: RuleResult;
32
- proof: DecisionProof | null;
33
- }>;
34
- }
35
-
36
- /**
37
- * Create a PayID policy engine instance backed by a WASM rule evaluator.
38
- *
39
- * ## Responsibility
40
- *
41
- * - Holds the WASM binary used for rule execution
42
- * - Defines the trust boundary for context attestation verification
43
- * - Acts as the primary entry point for PayID rule evaluation
44
- *
45
- * ## Trust model
46
- *
47
- * - If `trustedIssuers` is provided, Context V2 attestation
48
- * verification is ENFORCED.
49
- * - If `trustedIssuers` is omitted, the engine runs in
50
- * legacy (Context V1) mode without cryptographic verification.
51
- *
52
- * ## Environment
53
- *
54
- * This class is safe to instantiate in:
55
- * - Browsers
56
- * - Mobile apps
57
- * - Edge runtimes
58
- * - Backend services
59
- *
60
- * @param wasm
61
- * Compiled PayID WASM rule engine binary.
62
- *
63
- * @param debugTrace
64
- * Optional flag to enable decision trace generation for debugging.
65
- * @example
66
- * ```ts
67
- *
68
- * const payid = new PayID(wasmBinary, debugTrace);
69
- * ```
70
- */
71
- declare function createPayID(params: {
72
- wasm?: Uint8Array;
73
- debugTrace?: boolean;
74
- }): PayIDClient;
75
-
76
- declare const index_createPayID: typeof createPayID;
77
- declare namespace index {
78
- export { index_createPayID as createPayID };
79
- }
80
-
81
- export { createPayID as c, index as i };
@@ -1,114 +0,0 @@
1
- import { ethers } from 'ethers';
2
- import { RuleConfig } from 'payid-types';
3
- import { P as PayIDSessionPolicyPayloadV1 } from './types-BmMf7udp.js';
4
-
5
- /**
6
- * Create and sign an ephemeral PayID session policy payload.
7
- *
8
- * A session policy represents a **temporary, off-chain consent**
9
- * granted by the receiver to apply additional rule constraints
10
- * during rule evaluation (e.g. session limits, QR payments,
11
- * intent-scoped conditions).
12
- *
13
- * ## Security model
14
- *
15
- * - The session policy is signed by the receiver.
16
- * - The signature proves **explicit consent** for the included rule.
17
- * - This policy does NOT establish on-chain authority and MUST NOT
18
- * be registered or referenced in any on-chain rule registry.
19
- *
20
- * ## Canonicalization
21
- *
22
- * - The rule set is canonicalized BEFORE signing to ensure
23
- * deterministic hashing and signature verification.
24
- * - The exact payload signed here MUST be used verbatim during
25
- * policy verification.
26
- *
27
- * ## Lifecycle
28
- *
29
- * - Session policies are valid only until `expiresAt`.
30
- * - Expired policies MUST be rejected by the verifier.
31
- *
32
- * @param params
33
- * @param params.receiver
34
- * Address of the receiver granting the session policy.
35
- *
36
- * @param params.rule
37
- * Rule configuration to be applied as an **off-chain evaluation
38
- * override** during the session.
39
- *
40
- * @param params.expiresAt
41
- * UNIX timestamp (seconds) indicating when the session policy
42
- * becomes invalid.
43
- *
44
- * @param params.signer
45
- * Signer controlling the receiver address, used to sign the
46
- * session policy payload.
47
- *
48
- * @returns
49
- * A signed `PayIDSessionPolicyPayloadV1` that may be transmitted
50
- * to clients and verified using `decodeSessionPolicy`.
51
- *
52
- * @throws
53
- * May throw if signing fails or the signer is misconfigured.
54
- */
55
- declare function createSessionPolicyPayload(params: {
56
- receiver: string;
57
- rule: RuleConfig;
58
- expiresAt: number;
59
- signer: ethers.Signer;
60
- }): Promise<PayIDSessionPolicyPayloadV1>;
61
-
62
- /**
63
- * Decode and verify an ephemeral PayID session policy.
64
- *
65
- * This function validates that a session policy:
66
- * - Uses a supported policy version
67
- * - Has not expired
68
- * - Was cryptographically signed by the declared receiver
69
- *
70
- * If all checks pass, the embedded rule configuration is returned
71
- * and may be used as an **off-chain evaluation override**
72
- * (e.g. combined with an authoritative on-chain rule).
73
- *
74
- * ## Security model
75
- *
76
- * - The session policy signature represents **explicit consent**
77
- * from the receiver for temporary rule constraints.
78
- * - This policy does NOT establish on-chain authority and MUST NOT
79
- * be used to derive `ruleSetHash` or interact with rule registries.
80
- *
81
- * ## Invariants
82
- *
83
- * - The payload verified here MUST match exactly the payload that was signed.
84
- * - No canonicalization or mutation is performed during verification.
85
- * - Expired or invalidly signed policies are rejected immediately.
86
- *
87
- * @export
88
- *
89
- * @param sessionPolicy
90
- * A signed session policy payload created by
91
- * `createSessionPolicyPayload`.
92
- *
93
- * @param now
94
- * Current UNIX timestamp (seconds) used to validate policy expiry.
95
- *
96
- * @returns
97
- * A `RuleConfig` representing the session's evaluation rule.
98
- *
99
- * @throws
100
- * Throws if:
101
- * - The policy version is unsupported
102
- * - The policy has expired
103
- * - The signature does not match the receiver
104
- */
105
- declare function decodeSessionPolicy(sessionPolicy: PayIDSessionPolicyPayloadV1, now: number): RuleConfig;
106
-
107
- declare const index_PayIDSessionPolicyPayloadV1: typeof PayIDSessionPolicyPayloadV1;
108
- declare const index_createSessionPolicyPayload: typeof createSessionPolicyPayload;
109
- declare const index_decodeSessionPolicy: typeof decodeSessionPolicy;
110
- declare namespace index {
111
- export { index_PayIDSessionPolicyPayloadV1 as PayIDSessionPolicyPayloadV1, index_createSessionPolicyPayload as createSessionPolicyPayload, index_decodeSessionPolicy as decodeSessionPolicy };
112
- }
113
-
114
- export { createSessionPolicyPayload as c, decodeSessionPolicy as d, index as i };
@@ -1,26 +0,0 @@
1
- interface RuleSource {
2
- uri: string;
3
- hash?: string;
4
- }
5
-
6
- interface DecisionPayload {
7
- version: string;
8
- payId: string;
9
- payer: string;
10
- receiver: string;
11
- asset: string;
12
- amount: bigint;
13
- contextHash: string;
14
- ruleSetHash: string;
15
- ruleAuthority: string;
16
- issuedAt: bigint;
17
- expiresAt: bigint;
18
- nonce: string;
19
- requiresAttestation: boolean;
20
- }
21
- interface DecisionProof {
22
- payload: DecisionPayload;
23
- signature: string;
24
- }
25
-
26
- export type { DecisionProof as D, RuleSource as R };
@@ -1,13 +0,0 @@
1
- import { RuleConfig } from 'payid-types';
2
-
3
- interface PayIDSessionPolicyPayloadV1 {
4
- version: "payid.session.policy.v1" | string;
5
- receiver: string;
6
- rule: RuleConfig;
7
- expiresAt: number;
8
- nonce: string;
9
- issuedAt: number;
10
- signature: string;
11
- }
12
-
13
- export type { PayIDSessionPolicyPayloadV1 as P };