@tinycloud/sdk-core 3.8.1-beta.2 → 3.9.0-beta.4
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/dist/{credential-admission-DCJhDFFv.d.ts → credential-admission-5iS1yUHN.d.ts} +19 -3
- package/dist/{credential-admission-B7_F6Yb3.d.cts → credential-admission-CB37nOWk.d.cts} +19 -3
- package/dist/held-credentials/index.cjs +286 -116
- package/dist/held-credentials/index.cjs.map +1 -1
- package/dist/held-credentials/index.d.cts +117 -40
- package/dist/held-credentials/index.d.ts +117 -40
- package/dist/held-credentials/index.js +286 -116
- package/dist/held-credentials/index.js.map +1 -1
- package/dist/index.cjs +14 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -5
- package/dist/index.d.ts +8 -5
- package/dist/index.js +14 -6
- package/dist/index.js.map +1 -1
- package/dist/policy/index.d.cts +2 -2
- package/dist/policy/index.d.ts +2 -2
- package/package.json +1 -1
|
@@ -5,6 +5,25 @@ declare class HeldCredentialError extends Error {
|
|
|
5
5
|
constructor(code: HeldCredentialErrorCode, message: string);
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
+
interface PkhDid {
|
|
9
|
+
chainId: string;
|
|
10
|
+
/** Lowercase `0x` + 40 hex. */
|
|
11
|
+
address: string;
|
|
12
|
+
}
|
|
13
|
+
/** EIP-55 checksummed form of a `0x` + 40 hex address. */
|
|
14
|
+
declare function toChecksumAddress(address: string): string;
|
|
15
|
+
/** Parses `did:pkh:eip155:<chainId>:<address>`; null for anything else (no byte fallback). */
|
|
16
|
+
declare function parsePkhDid(did: unknown): PkhDid | null;
|
|
17
|
+
/** Principal equality: the exact eip155 chain id and the same address bytes. Never compares strings. */
|
|
18
|
+
declare function pkhPrincipalsEqual(a: unknown, b: unknown): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* The one key billing, Exo and credentials.org use for a verified subject: the lowercase 20-byte
|
|
21
|
+
* address. It is chain-independent because v1 accepts only externally owned accounts (their control
|
|
22
|
+
* does not depend on the chain). Accepting contract wallets or other chains would require adding
|
|
23
|
+
* the chain here.
|
|
24
|
+
*/
|
|
25
|
+
declare function registryKey(subject: string): string;
|
|
26
|
+
|
|
8
27
|
type Json = null | boolean | number | string | Json[] | {
|
|
9
28
|
[key: string]: Json;
|
|
10
29
|
};
|
|
@@ -96,6 +115,59 @@ interface IssuerSetOptions {
|
|
|
96
115
|
/** Validates a whole issuer set. Any violation makes the whole set invalid. */
|
|
97
116
|
declare function parseIssuerSet(raw: unknown, options: IssuerSetOptions): IssuerSet;
|
|
98
117
|
|
|
118
|
+
interface AcceptedIssuer {
|
|
119
|
+
issuerDid: string;
|
|
120
|
+
kid?: string;
|
|
121
|
+
}
|
|
122
|
+
interface AcceptedProfile {
|
|
123
|
+
profile: string;
|
|
124
|
+
profileVersion: number;
|
|
125
|
+
}
|
|
126
|
+
interface VerifiedHeldCredential {
|
|
127
|
+
issuer: string;
|
|
128
|
+
subject: string;
|
|
129
|
+
/** Lowercase 20-byte address; equals `registryKey(subject)`. */
|
|
130
|
+
subjectAddress: string;
|
|
131
|
+
expiresAt: Date;
|
|
132
|
+
credentialId: string;
|
|
133
|
+
profile: string;
|
|
134
|
+
profileVersion: number;
|
|
135
|
+
vct: string;
|
|
136
|
+
claims: Record<string, Json>;
|
|
137
|
+
}
|
|
138
|
+
/** Base64url of SHA-256 over the ASCII bytes of the whole SD-JWT text (the sd_hash the SIWE resource binds). */
|
|
139
|
+
declare function sdHash(sdJwt: string): string;
|
|
140
|
+
/** `verifyHeldEmailCredential` output: the shared verified shape plus the signed issuance time (`iat`). The presentation verifier's output has no `issuedAt`. */
|
|
141
|
+
interface VerifiedHeldEmailCredential extends VerifiedHeldCredential {
|
|
142
|
+
issuedAt: Date;
|
|
143
|
+
}
|
|
144
|
+
interface HeldEmailCredentialOptions {
|
|
145
|
+
/** Explicit clock. The verifier never reads one. */
|
|
146
|
+
now: Date;
|
|
147
|
+
issuerSet: IssuerSet;
|
|
148
|
+
/** From the owner-signed policy or the caller's allow-list. Empty is refused. */
|
|
149
|
+
acceptedIssuers: readonly AcceptedIssuer[];
|
|
150
|
+
/** Issuer methods the caller enables, e.g. ["web"]. */
|
|
151
|
+
didMethods: {
|
|
152
|
+
issuer: readonly string[];
|
|
153
|
+
};
|
|
154
|
+
/** The authenticated owner (`did:pkh:eip155:...`). The credential subject must be principal-equal to it. */
|
|
155
|
+
owner: string;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Verifies a held email credential on its own. No presentation proof and no nonce: the caller must
|
|
159
|
+
* already hold the SD-JWT and have authenticated `owner`. Refuses an owner mismatch with the same
|
|
160
|
+
* code as the presentation path. Synchronous; the email row is fixed.
|
|
161
|
+
* The code `nonce-account-mismatch` is kept for parity with the presentation path. This path spends no nonce.
|
|
162
|
+
*/
|
|
163
|
+
declare function verifyHeldEmailCredential(sdJwt: unknown, options: HeldEmailCredentialOptions): VerifiedHeldEmailCredential;
|
|
164
|
+
/**
|
|
165
|
+
* Structural selective disclosure: keeps only the disclosures named in `names`, in their original
|
|
166
|
+
* order, and drops any key-binding suffix. It does not verify anything. Verify the full SD-JWT
|
|
167
|
+
* first; this function only re-shapes a verified presentation.
|
|
168
|
+
*/
|
|
169
|
+
declare function selectDisclosures(sdJwt: string, names: readonly string[]): string;
|
|
170
|
+
|
|
99
171
|
/**
|
|
100
172
|
* Single use is a property of the store. `consume` is one atomic compare-and-delete and the only
|
|
101
173
|
* nonce operation a verifier performs: it deletes the entry only where the audience, the nonce and
|
|
@@ -131,14 +203,6 @@ interface HeldPresentation {
|
|
|
131
203
|
signature: string;
|
|
132
204
|
};
|
|
133
205
|
}
|
|
134
|
-
interface AcceptedIssuer {
|
|
135
|
-
issuerDid: string;
|
|
136
|
-
kid?: string;
|
|
137
|
-
}
|
|
138
|
-
interface AcceptedProfile {
|
|
139
|
-
profile: string;
|
|
140
|
-
profileVersion: number;
|
|
141
|
-
}
|
|
142
206
|
interface VerifyHeldPresentationOptions {
|
|
143
207
|
/** Explicit clock. The verifier never reads one. */
|
|
144
208
|
now: Date;
|
|
@@ -162,18 +226,6 @@ interface VerifyHeldPresentationOptions {
|
|
|
162
226
|
/** Defaults to the email row. */
|
|
163
227
|
rows?: readonly ProfileRow[];
|
|
164
228
|
}
|
|
165
|
-
interface VerifiedHeldCredential {
|
|
166
|
-
issuer: string;
|
|
167
|
-
subject: string;
|
|
168
|
-
/** Lowercase 20-byte address; equals `registryKey(subject)`. */
|
|
169
|
-
subjectAddress: string;
|
|
170
|
-
expiresAt: Date;
|
|
171
|
-
credentialId: string;
|
|
172
|
-
profile: string;
|
|
173
|
-
profileVersion: number;
|
|
174
|
-
vct: string;
|
|
175
|
-
claims: Record<string, Json>;
|
|
176
|
-
}
|
|
177
229
|
/**
|
|
178
230
|
* Verifies a held-credential presentation (spec §4.4). Fail closed: the first failed check throws a
|
|
179
231
|
* HeldCredentialError. The caller-bound nonce is spent first, on any outcome. No payload claim is read before the issuer signature has verified.
|
|
@@ -185,25 +237,6 @@ declare const SD_HASH_RESOURCE_PREFIX = "urn:tinycloud:sd-hash:";
|
|
|
185
237
|
/** An audience is a bare RFC 3986 authority: lowercase host[:port], no scheme, userinfo, path, or default port 443. */
|
|
186
238
|
declare function assertValidAudience(audience: string): void;
|
|
187
239
|
|
|
188
|
-
interface PkhDid {
|
|
189
|
-
chainId: string;
|
|
190
|
-
/** Lowercase `0x` + 40 hex. */
|
|
191
|
-
address: string;
|
|
192
|
-
}
|
|
193
|
-
/** EIP-55 checksummed form of a `0x` + 40 hex address. */
|
|
194
|
-
declare function toChecksumAddress(address: string): string;
|
|
195
|
-
/** Parses `did:pkh:eip155:<chainId>:<address>`; null for anything else (no byte fallback). */
|
|
196
|
-
declare function parsePkhDid(did: unknown): PkhDid | null;
|
|
197
|
-
/** Principal equality: the exact eip155 chain id and the same address bytes. Never compares strings. */
|
|
198
|
-
declare function pkhPrincipalsEqual(a: unknown, b: unknown): boolean;
|
|
199
|
-
/**
|
|
200
|
-
* The one key billing, Exo and credentials.org use for a verified subject: the lowercase 20-byte
|
|
201
|
-
* address. It is chain-independent because v1 accepts only externally owned accounts (their control
|
|
202
|
-
* does not depend on the chain). Accepting contract wallets or other chains would require adding
|
|
203
|
-
* the chain here.
|
|
204
|
-
*/
|
|
205
|
-
declare function registryKey(subject: string): string;
|
|
206
|
-
|
|
207
240
|
/**
|
|
208
241
|
* THE single shared email normalisation function (gap G14; the same rules as billing's
|
|
209
242
|
* `src/email-normalise.ts`, TC-1439). The alias rules below are confirmed by Sam on 2026-10-19
|
|
@@ -221,4 +254,48 @@ declare function registryKey(subject: string): string;
|
|
|
221
254
|
*/
|
|
222
255
|
declare function normaliseEmail(email: string): string | null;
|
|
223
256
|
|
|
224
|
-
|
|
257
|
+
/** Signs an EIP-191 `personal_sign` message. Returns `0x` + 130 hex (r, s, v) with low-S. Called once per presentation. */
|
|
258
|
+
type HeldPresentationSigner = (message: string) => Promise<string>;
|
|
259
|
+
interface HeldPresentationSiwe {
|
|
260
|
+
message: string;
|
|
261
|
+
signature: string;
|
|
262
|
+
}
|
|
263
|
+
interface BuildHeldPresentationSiweInput {
|
|
264
|
+
/** The verifier's audience: a bare host[:port] authority. It becomes the SIWE domain and the https origin. */
|
|
265
|
+
audience: string;
|
|
266
|
+
/** Nonce minted by the verifier for `audience`, bound to `account`. At least 22 base62 characters. */
|
|
267
|
+
nonce: string;
|
|
268
|
+
/** Base64url SHA-256 of the presented SD-JWT: `sdHash(selectDisclosures(...))`. */
|
|
269
|
+
sdHash: string;
|
|
270
|
+
/** The holder's `did:pkh:eip155:1:<address>`. */
|
|
271
|
+
account: string;
|
|
272
|
+
/** Whole seconds only, as RFC 3339 `Z`. Sub-second precision is refused, not truncated. */
|
|
273
|
+
issuedAt: Date;
|
|
274
|
+
/** Whole seconds only, as RFC 3339 `Z`. Must be after `issuedAt`. */
|
|
275
|
+
expirationTime?: Date;
|
|
276
|
+
/** Produces the signature. Each call builds a fresh message; nothing is cached. */
|
|
277
|
+
sign: HeldPresentationSigner;
|
|
278
|
+
}
|
|
279
|
+
interface CheckReturnedPresentationOptions {
|
|
280
|
+
/** Explicit clock for the SIWE expiry and not-before windows. */
|
|
281
|
+
now: Date;
|
|
282
|
+
/** The verifier's audience. The SIWE domain and https origin must match it. */
|
|
283
|
+
audience: string;
|
|
284
|
+
/** The holder's `did:pkh:eip155:1:<address>`. The SIWE address must be principal-equal to it. */
|
|
285
|
+
account: string;
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Builds the EIP-4361 message for a held presentation in the layout `parseStrictSiwe` accepts, and
|
|
289
|
+
* signs it with `sign`. The signature must recover to `account`. The verifier, not this builder,
|
|
290
|
+
* decides whether the presentation is accepted.
|
|
291
|
+
*/
|
|
292
|
+
declare function buildHeldPresentationSiwe(input: BuildHeldPresentationSiweInput): Promise<HeldPresentationSiwe>;
|
|
293
|
+
/**
|
|
294
|
+
* Client-side check of a presentation before it is sent on. It is not a verifier: it does not look
|
|
295
|
+
* up issuers, spend a nonce, or check the credential signature. `verifyHeldPresentation` decides acceptance.
|
|
296
|
+
* It refuses a high-S signature, as `buildHeldPresentationSiwe` does. That is stricter than the Rust verifier,
|
|
297
|
+
* which accepts high-S signatures: a presentation this check refuses can still be one the verifier would accept.
|
|
298
|
+
*/
|
|
299
|
+
declare function checkReturnedPresentation(presentation: unknown, options: CheckReturnedPresentationOptions): HeldPresentation;
|
|
300
|
+
|
|
301
|
+
export { ACCOUNT_BINDING_DOMAIN, type AcceptedIssuer, type AcceptedProfile, type BuildHeldPresentationSiweInput, type CheckReturnedPresentationOptions, DEFAULT_ROWS, EMAIL_HELD_ROW, HELD_EMAIL_TTL_SECONDS, HeldCredentialError, type HeldCredentialErrorCode, type HeldEmailCredentialOptions, type HeldPresentation, type HeldPresentationSigner, type HeldPresentationSiwe, ISSUER_SET_FORMAT, InMemoryNonceStore, type IssuerEntry, IssuerSet, type IssuerSetOptions, type NonceStore, ORG_MEMBERSHIP_FREE_ROW, ORG_MEMBERSHIP_ROW, ORG_MEMBERSHIP_ROWS, PRESENTATION_STATEMENT, type ProfileRow, SD_HASH_RESOURCE_PREFIX, type VerifiedHeldCredential, type VerifiedHeldEmailCredential, type VerifyHeldPresentationOptions, assertValidAudience, buildHeldPresentationSiwe, checkReturnedPresentation, normaliseEmail, parseIssuerSet, parsePkhDid, pkhPrincipalsEqual, randomNonce, registryKey, sdHash, selectDisclosures, toChecksumAddress, verifyHeldEmailCredential, verifyHeldPresentation };
|
|
@@ -5,6 +5,25 @@ declare class HeldCredentialError extends Error {
|
|
|
5
5
|
constructor(code: HeldCredentialErrorCode, message: string);
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
+
interface PkhDid {
|
|
9
|
+
chainId: string;
|
|
10
|
+
/** Lowercase `0x` + 40 hex. */
|
|
11
|
+
address: string;
|
|
12
|
+
}
|
|
13
|
+
/** EIP-55 checksummed form of a `0x` + 40 hex address. */
|
|
14
|
+
declare function toChecksumAddress(address: string): string;
|
|
15
|
+
/** Parses `did:pkh:eip155:<chainId>:<address>`; null for anything else (no byte fallback). */
|
|
16
|
+
declare function parsePkhDid(did: unknown): PkhDid | null;
|
|
17
|
+
/** Principal equality: the exact eip155 chain id and the same address bytes. Never compares strings. */
|
|
18
|
+
declare function pkhPrincipalsEqual(a: unknown, b: unknown): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* The one key billing, Exo and credentials.org use for a verified subject: the lowercase 20-byte
|
|
21
|
+
* address. It is chain-independent because v1 accepts only externally owned accounts (their control
|
|
22
|
+
* does not depend on the chain). Accepting contract wallets or other chains would require adding
|
|
23
|
+
* the chain here.
|
|
24
|
+
*/
|
|
25
|
+
declare function registryKey(subject: string): string;
|
|
26
|
+
|
|
8
27
|
type Json = null | boolean | number | string | Json[] | {
|
|
9
28
|
[key: string]: Json;
|
|
10
29
|
};
|
|
@@ -96,6 +115,59 @@ interface IssuerSetOptions {
|
|
|
96
115
|
/** Validates a whole issuer set. Any violation makes the whole set invalid. */
|
|
97
116
|
declare function parseIssuerSet(raw: unknown, options: IssuerSetOptions): IssuerSet;
|
|
98
117
|
|
|
118
|
+
interface AcceptedIssuer {
|
|
119
|
+
issuerDid: string;
|
|
120
|
+
kid?: string;
|
|
121
|
+
}
|
|
122
|
+
interface AcceptedProfile {
|
|
123
|
+
profile: string;
|
|
124
|
+
profileVersion: number;
|
|
125
|
+
}
|
|
126
|
+
interface VerifiedHeldCredential {
|
|
127
|
+
issuer: string;
|
|
128
|
+
subject: string;
|
|
129
|
+
/** Lowercase 20-byte address; equals `registryKey(subject)`. */
|
|
130
|
+
subjectAddress: string;
|
|
131
|
+
expiresAt: Date;
|
|
132
|
+
credentialId: string;
|
|
133
|
+
profile: string;
|
|
134
|
+
profileVersion: number;
|
|
135
|
+
vct: string;
|
|
136
|
+
claims: Record<string, Json>;
|
|
137
|
+
}
|
|
138
|
+
/** Base64url of SHA-256 over the ASCII bytes of the whole SD-JWT text (the sd_hash the SIWE resource binds). */
|
|
139
|
+
declare function sdHash(sdJwt: string): string;
|
|
140
|
+
/** `verifyHeldEmailCredential` output: the shared verified shape plus the signed issuance time (`iat`). The presentation verifier's output has no `issuedAt`. */
|
|
141
|
+
interface VerifiedHeldEmailCredential extends VerifiedHeldCredential {
|
|
142
|
+
issuedAt: Date;
|
|
143
|
+
}
|
|
144
|
+
interface HeldEmailCredentialOptions {
|
|
145
|
+
/** Explicit clock. The verifier never reads one. */
|
|
146
|
+
now: Date;
|
|
147
|
+
issuerSet: IssuerSet;
|
|
148
|
+
/** From the owner-signed policy or the caller's allow-list. Empty is refused. */
|
|
149
|
+
acceptedIssuers: readonly AcceptedIssuer[];
|
|
150
|
+
/** Issuer methods the caller enables, e.g. ["web"]. */
|
|
151
|
+
didMethods: {
|
|
152
|
+
issuer: readonly string[];
|
|
153
|
+
};
|
|
154
|
+
/** The authenticated owner (`did:pkh:eip155:...`). The credential subject must be principal-equal to it. */
|
|
155
|
+
owner: string;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Verifies a held email credential on its own. No presentation proof and no nonce: the caller must
|
|
159
|
+
* already hold the SD-JWT and have authenticated `owner`. Refuses an owner mismatch with the same
|
|
160
|
+
* code as the presentation path. Synchronous; the email row is fixed.
|
|
161
|
+
* The code `nonce-account-mismatch` is kept for parity with the presentation path. This path spends no nonce.
|
|
162
|
+
*/
|
|
163
|
+
declare function verifyHeldEmailCredential(sdJwt: unknown, options: HeldEmailCredentialOptions): VerifiedHeldEmailCredential;
|
|
164
|
+
/**
|
|
165
|
+
* Structural selective disclosure: keeps only the disclosures named in `names`, in their original
|
|
166
|
+
* order, and drops any key-binding suffix. It does not verify anything. Verify the full SD-JWT
|
|
167
|
+
* first; this function only re-shapes a verified presentation.
|
|
168
|
+
*/
|
|
169
|
+
declare function selectDisclosures(sdJwt: string, names: readonly string[]): string;
|
|
170
|
+
|
|
99
171
|
/**
|
|
100
172
|
* Single use is a property of the store. `consume` is one atomic compare-and-delete and the only
|
|
101
173
|
* nonce operation a verifier performs: it deletes the entry only where the audience, the nonce and
|
|
@@ -131,14 +203,6 @@ interface HeldPresentation {
|
|
|
131
203
|
signature: string;
|
|
132
204
|
};
|
|
133
205
|
}
|
|
134
|
-
interface AcceptedIssuer {
|
|
135
|
-
issuerDid: string;
|
|
136
|
-
kid?: string;
|
|
137
|
-
}
|
|
138
|
-
interface AcceptedProfile {
|
|
139
|
-
profile: string;
|
|
140
|
-
profileVersion: number;
|
|
141
|
-
}
|
|
142
206
|
interface VerifyHeldPresentationOptions {
|
|
143
207
|
/** Explicit clock. The verifier never reads one. */
|
|
144
208
|
now: Date;
|
|
@@ -162,18 +226,6 @@ interface VerifyHeldPresentationOptions {
|
|
|
162
226
|
/** Defaults to the email row. */
|
|
163
227
|
rows?: readonly ProfileRow[];
|
|
164
228
|
}
|
|
165
|
-
interface VerifiedHeldCredential {
|
|
166
|
-
issuer: string;
|
|
167
|
-
subject: string;
|
|
168
|
-
/** Lowercase 20-byte address; equals `registryKey(subject)`. */
|
|
169
|
-
subjectAddress: string;
|
|
170
|
-
expiresAt: Date;
|
|
171
|
-
credentialId: string;
|
|
172
|
-
profile: string;
|
|
173
|
-
profileVersion: number;
|
|
174
|
-
vct: string;
|
|
175
|
-
claims: Record<string, Json>;
|
|
176
|
-
}
|
|
177
229
|
/**
|
|
178
230
|
* Verifies a held-credential presentation (spec §4.4). Fail closed: the first failed check throws a
|
|
179
231
|
* HeldCredentialError. The caller-bound nonce is spent first, on any outcome. No payload claim is read before the issuer signature has verified.
|
|
@@ -185,25 +237,6 @@ declare const SD_HASH_RESOURCE_PREFIX = "urn:tinycloud:sd-hash:";
|
|
|
185
237
|
/** An audience is a bare RFC 3986 authority: lowercase host[:port], no scheme, userinfo, path, or default port 443. */
|
|
186
238
|
declare function assertValidAudience(audience: string): void;
|
|
187
239
|
|
|
188
|
-
interface PkhDid {
|
|
189
|
-
chainId: string;
|
|
190
|
-
/** Lowercase `0x` + 40 hex. */
|
|
191
|
-
address: string;
|
|
192
|
-
}
|
|
193
|
-
/** EIP-55 checksummed form of a `0x` + 40 hex address. */
|
|
194
|
-
declare function toChecksumAddress(address: string): string;
|
|
195
|
-
/** Parses `did:pkh:eip155:<chainId>:<address>`; null for anything else (no byte fallback). */
|
|
196
|
-
declare function parsePkhDid(did: unknown): PkhDid | null;
|
|
197
|
-
/** Principal equality: the exact eip155 chain id and the same address bytes. Never compares strings. */
|
|
198
|
-
declare function pkhPrincipalsEqual(a: unknown, b: unknown): boolean;
|
|
199
|
-
/**
|
|
200
|
-
* The one key billing, Exo and credentials.org use for a verified subject: the lowercase 20-byte
|
|
201
|
-
* address. It is chain-independent because v1 accepts only externally owned accounts (their control
|
|
202
|
-
* does not depend on the chain). Accepting contract wallets or other chains would require adding
|
|
203
|
-
* the chain here.
|
|
204
|
-
*/
|
|
205
|
-
declare function registryKey(subject: string): string;
|
|
206
|
-
|
|
207
240
|
/**
|
|
208
241
|
* THE single shared email normalisation function (gap G14; the same rules as billing's
|
|
209
242
|
* `src/email-normalise.ts`, TC-1439). The alias rules below are confirmed by Sam on 2026-10-19
|
|
@@ -221,4 +254,48 @@ declare function registryKey(subject: string): string;
|
|
|
221
254
|
*/
|
|
222
255
|
declare function normaliseEmail(email: string): string | null;
|
|
223
256
|
|
|
224
|
-
|
|
257
|
+
/** Signs an EIP-191 `personal_sign` message. Returns `0x` + 130 hex (r, s, v) with low-S. Called once per presentation. */
|
|
258
|
+
type HeldPresentationSigner = (message: string) => Promise<string>;
|
|
259
|
+
interface HeldPresentationSiwe {
|
|
260
|
+
message: string;
|
|
261
|
+
signature: string;
|
|
262
|
+
}
|
|
263
|
+
interface BuildHeldPresentationSiweInput {
|
|
264
|
+
/** The verifier's audience: a bare host[:port] authority. It becomes the SIWE domain and the https origin. */
|
|
265
|
+
audience: string;
|
|
266
|
+
/** Nonce minted by the verifier for `audience`, bound to `account`. At least 22 base62 characters. */
|
|
267
|
+
nonce: string;
|
|
268
|
+
/** Base64url SHA-256 of the presented SD-JWT: `sdHash(selectDisclosures(...))`. */
|
|
269
|
+
sdHash: string;
|
|
270
|
+
/** The holder's `did:pkh:eip155:1:<address>`. */
|
|
271
|
+
account: string;
|
|
272
|
+
/** Whole seconds only, as RFC 3339 `Z`. Sub-second precision is refused, not truncated. */
|
|
273
|
+
issuedAt: Date;
|
|
274
|
+
/** Whole seconds only, as RFC 3339 `Z`. Must be after `issuedAt`. */
|
|
275
|
+
expirationTime?: Date;
|
|
276
|
+
/** Produces the signature. Each call builds a fresh message; nothing is cached. */
|
|
277
|
+
sign: HeldPresentationSigner;
|
|
278
|
+
}
|
|
279
|
+
interface CheckReturnedPresentationOptions {
|
|
280
|
+
/** Explicit clock for the SIWE expiry and not-before windows. */
|
|
281
|
+
now: Date;
|
|
282
|
+
/** The verifier's audience. The SIWE domain and https origin must match it. */
|
|
283
|
+
audience: string;
|
|
284
|
+
/** The holder's `did:pkh:eip155:1:<address>`. The SIWE address must be principal-equal to it. */
|
|
285
|
+
account: string;
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Builds the EIP-4361 message for a held presentation in the layout `parseStrictSiwe` accepts, and
|
|
289
|
+
* signs it with `sign`. The signature must recover to `account`. The verifier, not this builder,
|
|
290
|
+
* decides whether the presentation is accepted.
|
|
291
|
+
*/
|
|
292
|
+
declare function buildHeldPresentationSiwe(input: BuildHeldPresentationSiweInput): Promise<HeldPresentationSiwe>;
|
|
293
|
+
/**
|
|
294
|
+
* Client-side check of a presentation before it is sent on. It is not a verifier: it does not look
|
|
295
|
+
* up issuers, spend a nonce, or check the credential signature. `verifyHeldPresentation` decides acceptance.
|
|
296
|
+
* It refuses a high-S signature, as `buildHeldPresentationSiwe` does. That is stricter than the Rust verifier,
|
|
297
|
+
* which accepts high-S signatures: a presentation this check refuses can still be one the verifier would accept.
|
|
298
|
+
*/
|
|
299
|
+
declare function checkReturnedPresentation(presentation: unknown, options: CheckReturnedPresentationOptions): HeldPresentation;
|
|
300
|
+
|
|
301
|
+
export { ACCOUNT_BINDING_DOMAIN, type AcceptedIssuer, type AcceptedProfile, type BuildHeldPresentationSiweInput, type CheckReturnedPresentationOptions, DEFAULT_ROWS, EMAIL_HELD_ROW, HELD_EMAIL_TTL_SECONDS, HeldCredentialError, type HeldCredentialErrorCode, type HeldEmailCredentialOptions, type HeldPresentation, type HeldPresentationSigner, type HeldPresentationSiwe, ISSUER_SET_FORMAT, InMemoryNonceStore, type IssuerEntry, IssuerSet, type IssuerSetOptions, type NonceStore, ORG_MEMBERSHIP_FREE_ROW, ORG_MEMBERSHIP_ROW, ORG_MEMBERSHIP_ROWS, PRESENTATION_STATEMENT, type ProfileRow, SD_HASH_RESOURCE_PREFIX, type VerifiedHeldCredential, type VerifiedHeldEmailCredential, type VerifyHeldPresentationOptions, assertValidAudience, buildHeldPresentationSiwe, checkReturnedPresentation, normaliseEmail, parseIssuerSet, parsePkhDid, pkhPrincipalsEqual, randomNonce, registryKey, sdHash, selectDisclosures, toChecksumAddress, verifyHeldEmailCredential, verifyHeldPresentation };
|