@tinycloud/node-sdk 3.9.0-beta.3 → 3.9.0-beta.5

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.
@@ -1,4 +1,5 @@
1
1
  import { IssuedCredentialEnvelope, VerifiedCredential, CredentialFlowDescriptor, StoredCredentialRecord, CredentialRequirement } from '@tinycloud/sdk-core';
2
+ import { VerifiedHeldEmailCredential } from '@tinycloud/sdk-core/held-credentials';
2
3
 
3
4
  declare const EMAIL_PROOF_CREDENTIAL_TYPE: {
4
5
  readonly id: "opencredentials.email/v1";
@@ -22,17 +23,18 @@ type EmailProofStep = "request" | "code" | "credential" | "session";
22
23
  * | RATE_LIMITED | witness | witness `recoverable` flag decides (defaults to true); retryAfterMs set |
23
24
  * | ISSUER_UNAVAILABLE | true | transient issuer outage (503); witness flag is honoured |
24
25
  * | NETWORK | true | transport failure or step timeout; pending kept |
25
- * | PROFILE_UNAVAILABLE | false | catalog or descriptor does not match the pinned profile |
26
+ * | PROFILE_UNAVAILABLE | false | catalog or descriptor does not match the pinned profile, or (local, no witness contacted) the profile is not enabled |
26
27
  * | CODE_REJECTED | true | wrong code; witness flag decides whether another attempt is allowed |
27
28
  * | CODE_ATTEMPTS_EXHAUSTED | false | witness proof-attempt budget spent; pending is dead |
28
29
  * | SIGNATURE_REJECTED | true | holder binding rejected; same pending may be retried |
29
30
  * | CREDENTIAL_INVALID | false | issued credential failed local verification |
30
31
  * | SESSION_EXPIRED | false | pending window or server expiry has passed |
31
32
  * | SESSION_INVALID | false | pending does not match holder, descriptor, or requirement |
33
+ * | CLIENT_CLOCK_SKEW | false | device clock more than 5 min behind the witness; no mail sent; fix the clock and start again |
32
34
  * | CANCELED | false | caller aborted; pending is deleted |
33
35
  * | FAILED | false | unclassified failure; pending is deleted |
34
36
  */
35
- type EmailProofErrorCode = "ADDRESS_INVALID" | "HOLDER_INVALID" | "CODE_INVALID" | "RATE_LIMITED" | "ISSUER_UNAVAILABLE" | "NETWORK" | "PROFILE_UNAVAILABLE" | "CODE_REJECTED" | "CODE_ATTEMPTS_EXHAUSTED" | "SIGNATURE_REJECTED" | "CREDENTIAL_INVALID" | "SESSION_EXPIRED" | "SESSION_INVALID" | "CANCELED" | "FAILED";
37
+ type EmailProofErrorCode = "ADDRESS_INVALID" | "HOLDER_INVALID" | "CODE_INVALID" | "RATE_LIMITED" | "ISSUER_UNAVAILABLE" | "NETWORK" | "PROFILE_UNAVAILABLE" | "CODE_REJECTED" | "CODE_ATTEMPTS_EXHAUSTED" | "SIGNATURE_REJECTED" | "CREDENTIAL_INVALID" | "SESSION_EXPIRED" | "SESSION_INVALID" | "CLIENT_CLOCK_SKEW" | "CANCELED" | "FAILED";
36
38
  /** Stable, redaction-safe error. The message never includes the code, verifier, or key material. */
37
39
  declare class EmailProofError extends Error {
38
40
  readonly name = "EmailProofError";
@@ -40,7 +42,8 @@ declare class EmailProofError extends Error {
40
42
  readonly code: EmailProofErrorCode;
41
43
  readonly retryAfterMs: number | undefined;
42
44
  readonly recoverable: boolean;
43
- constructor(step: EmailProofStep, code: EmailProofErrorCode, retryAfterMs?: number, recoverable?: boolean);
45
+ /** `message` overrides the code's text for one refusal whose cause the shared text would misdescribe. It never carries request data. */
46
+ constructor(step: EmailProofStep, code: EmailProofErrorCode, retryAfterMs?: number, recoverable?: boolean, message?: string);
44
47
  }
45
48
  type HolderAlgorithm = "EdDSA" | "EIP191";
46
49
  /**
@@ -63,6 +66,14 @@ interface HolderSigner {
63
66
  declare function createEd25519HolderSigner(did: string, sign: (bytes: Uint8Array) => Promise<Uint8Array>): HolderSigner;
64
67
  /** Options shared by the public steps. Issuer keys are never caller-supplied. */
65
68
  interface EmailProofOptions {
69
+ /**
70
+ * Per-call opt-in for the held profile `tinycloud.email-held/v1`. Only the literal `true` counts, it enables the held
71
+ * profile for this call alone (never stored in a pending, never read from the environment), and it is ignored for any other
72
+ * profile. Without it a held request is refused PROFILE_UNAVAILABLE before any network call. Nothing else can be supplied with
73
+ * it: the origin, issuer key and descriptor digest are compiled pins. The default 60 s step signal spans the wallet prompt in
74
+ * `completeEmailProof` for an account holder: pass a `signal` bounded by the request `expiresAt` if the user may take longer.
75
+ */
76
+ readonly allowHeldProfile?: true;
66
77
  readonly fetch?: typeof fetch;
67
78
  readonly signal?: AbortSignal;
68
79
  readonly now?: () => Date;
@@ -90,6 +101,8 @@ interface EmailProofPending {
90
101
  readonly openerOrigin: string;
91
102
  readonly createdAt: string;
92
103
  readonly expiresAt: string;
104
+ /** Held only: `expiresAt` of the create response (the witness's own deadline). The signed binding must carry it. */
105
+ readonly serverExpiresAt?: string;
93
106
  }
94
107
  /** Holds pending requests keyed by requestId. Implementations must never return an expired request from `findLive`. */
95
108
  interface EmailProofPendingStore {
@@ -104,13 +117,18 @@ interface EmailProofPendingStore {
104
117
  declare function createMemoryEmailProofPendingStore(): EmailProofPendingStore;
105
118
  interface EmailProofResult {
106
119
  readonly envelope: IssuedCredentialEnvelope;
107
- readonly verified: VerifiedCredential;
120
+ /** The ticket verifier's result, or for the held profile (`envelope.profile.id`) the held verifier's. */
121
+ readonly verified: VerifiedCredential | VerifiedHeldEmailCredential;
108
122
  readonly credentialId: string;
109
123
  readonly issuedAt: string;
110
124
  readonly expiresAt: string;
111
125
  /** The descriptor the verifier checked against. Stored alongside the credential for offline re-verification. */
112
126
  readonly descriptor: CredentialFlowDescriptor;
113
127
  }
128
+ /** True for a ticket (did:key) result, whose `verified` is the ticket verifier's output. The held profile's result carries the held verifier's. */
129
+ declare function isTicketEmailProofResult(result: EmailProofResult): result is EmailProofResult & {
130
+ readonly verified: VerifiedCredential;
131
+ };
114
132
  interface EmailProofAcquireInput extends EmailProofRequestInput {
115
133
  /** Supplies the 8-digit code. Omit to only request one; the pending request is returned for a later call. */
116
134
  readonly getCode?: (context: {
@@ -174,4 +192,4 @@ type StoredEmailProofInput = {
174
192
  */
175
193
  declare function verifyStoredEmailProof(input: StoredEmailProofInput): Promise<VerifiedCredential>;
176
194
 
177
- export { DEFAULT_EMAIL_PROOF_PROFILE as D, EMAIL_PROOF_CREDENTIAL_TYPE as E, type HolderAlgorithm as H, type StoredEmailProofInput as S, EMAIL_PROOF_PENDING_MAX_MS as a, type EmailProofAcquireInput as b, type EmailProofAcquisition as c, EmailProofError as d, type EmailProofErrorCode as e, type EmailProofOptions as f, type EmailProofPending as g, type EmailProofPendingStore as h, type EmailProofProfileId as i, type EmailProofRequestInput as j, type EmailProofResult as k, type EmailProofStep as l, type HolderSigner as m, type StoredEmailProofRecord as n, acquireEmailProof as o, completeEmailProof as p, createEd25519HolderSigner as q, createMemoryEmailProofPendingStore as r, emailProofRequirement as s, requestEmailProofCode as t, verifyStoredEmailProof as v };
195
+ export { DEFAULT_EMAIL_PROOF_PROFILE as D, type EmailProofPendingStore as E, type HolderAlgorithm as H, type StoredEmailProofInput as S, type EmailProofPending as a, EMAIL_PROOF_CREDENTIAL_TYPE as b, EMAIL_PROOF_PENDING_MAX_MS as c, type EmailProofAcquireInput as d, type EmailProofAcquisition as e, EmailProofError as f, type EmailProofErrorCode as g, type EmailProofOptions as h, type EmailProofProfileId as i, type EmailProofRequestInput as j, type EmailProofResult as k, type EmailProofStep as l, type HolderSigner as m, type StoredEmailProofRecord as n, acquireEmailProof as o, completeEmailProof as p, createEd25519HolderSigner as q, createMemoryEmailProofPendingStore as r, emailProofRequirement as s, isTicketEmailProofResult as t, requestEmailProofCode as u, verifyStoredEmailProof as v };
@@ -1,4 +1,5 @@
1
1
  import { IssuedCredentialEnvelope, VerifiedCredential, CredentialFlowDescriptor, StoredCredentialRecord, CredentialRequirement } from '@tinycloud/sdk-core';
2
+ import { VerifiedHeldEmailCredential } from '@tinycloud/sdk-core/held-credentials';
2
3
 
3
4
  declare const EMAIL_PROOF_CREDENTIAL_TYPE: {
4
5
  readonly id: "opencredentials.email/v1";
@@ -22,17 +23,18 @@ type EmailProofStep = "request" | "code" | "credential" | "session";
22
23
  * | RATE_LIMITED | witness | witness `recoverable` flag decides (defaults to true); retryAfterMs set |
23
24
  * | ISSUER_UNAVAILABLE | true | transient issuer outage (503); witness flag is honoured |
24
25
  * | NETWORK | true | transport failure or step timeout; pending kept |
25
- * | PROFILE_UNAVAILABLE | false | catalog or descriptor does not match the pinned profile |
26
+ * | PROFILE_UNAVAILABLE | false | catalog or descriptor does not match the pinned profile, or (local, no witness contacted) the profile is not enabled |
26
27
  * | CODE_REJECTED | true | wrong code; witness flag decides whether another attempt is allowed |
27
28
  * | CODE_ATTEMPTS_EXHAUSTED | false | witness proof-attempt budget spent; pending is dead |
28
29
  * | SIGNATURE_REJECTED | true | holder binding rejected; same pending may be retried |
29
30
  * | CREDENTIAL_INVALID | false | issued credential failed local verification |
30
31
  * | SESSION_EXPIRED | false | pending window or server expiry has passed |
31
32
  * | SESSION_INVALID | false | pending does not match holder, descriptor, or requirement |
33
+ * | CLIENT_CLOCK_SKEW | false | device clock more than 5 min behind the witness; no mail sent; fix the clock and start again |
32
34
  * | CANCELED | false | caller aborted; pending is deleted |
33
35
  * | FAILED | false | unclassified failure; pending is deleted |
34
36
  */
35
- type EmailProofErrorCode = "ADDRESS_INVALID" | "HOLDER_INVALID" | "CODE_INVALID" | "RATE_LIMITED" | "ISSUER_UNAVAILABLE" | "NETWORK" | "PROFILE_UNAVAILABLE" | "CODE_REJECTED" | "CODE_ATTEMPTS_EXHAUSTED" | "SIGNATURE_REJECTED" | "CREDENTIAL_INVALID" | "SESSION_EXPIRED" | "SESSION_INVALID" | "CANCELED" | "FAILED";
37
+ type EmailProofErrorCode = "ADDRESS_INVALID" | "HOLDER_INVALID" | "CODE_INVALID" | "RATE_LIMITED" | "ISSUER_UNAVAILABLE" | "NETWORK" | "PROFILE_UNAVAILABLE" | "CODE_REJECTED" | "CODE_ATTEMPTS_EXHAUSTED" | "SIGNATURE_REJECTED" | "CREDENTIAL_INVALID" | "SESSION_EXPIRED" | "SESSION_INVALID" | "CLIENT_CLOCK_SKEW" | "CANCELED" | "FAILED";
36
38
  /** Stable, redaction-safe error. The message never includes the code, verifier, or key material. */
37
39
  declare class EmailProofError extends Error {
38
40
  readonly name = "EmailProofError";
@@ -40,7 +42,8 @@ declare class EmailProofError extends Error {
40
42
  readonly code: EmailProofErrorCode;
41
43
  readonly retryAfterMs: number | undefined;
42
44
  readonly recoverable: boolean;
43
- constructor(step: EmailProofStep, code: EmailProofErrorCode, retryAfterMs?: number, recoverable?: boolean);
45
+ /** `message` overrides the code's text for one refusal whose cause the shared text would misdescribe. It never carries request data. */
46
+ constructor(step: EmailProofStep, code: EmailProofErrorCode, retryAfterMs?: number, recoverable?: boolean, message?: string);
44
47
  }
45
48
  type HolderAlgorithm = "EdDSA" | "EIP191";
46
49
  /**
@@ -63,6 +66,14 @@ interface HolderSigner {
63
66
  declare function createEd25519HolderSigner(did: string, sign: (bytes: Uint8Array) => Promise<Uint8Array>): HolderSigner;
64
67
  /** Options shared by the public steps. Issuer keys are never caller-supplied. */
65
68
  interface EmailProofOptions {
69
+ /**
70
+ * Per-call opt-in for the held profile `tinycloud.email-held/v1`. Only the literal `true` counts, it enables the held
71
+ * profile for this call alone (never stored in a pending, never read from the environment), and it is ignored for any other
72
+ * profile. Without it a held request is refused PROFILE_UNAVAILABLE before any network call. Nothing else can be supplied with
73
+ * it: the origin, issuer key and descriptor digest are compiled pins. The default 60 s step signal spans the wallet prompt in
74
+ * `completeEmailProof` for an account holder: pass a `signal` bounded by the request `expiresAt` if the user may take longer.
75
+ */
76
+ readonly allowHeldProfile?: true;
66
77
  readonly fetch?: typeof fetch;
67
78
  readonly signal?: AbortSignal;
68
79
  readonly now?: () => Date;
@@ -90,6 +101,8 @@ interface EmailProofPending {
90
101
  readonly openerOrigin: string;
91
102
  readonly createdAt: string;
92
103
  readonly expiresAt: string;
104
+ /** Held only: `expiresAt` of the create response (the witness's own deadline). The signed binding must carry it. */
105
+ readonly serverExpiresAt?: string;
93
106
  }
94
107
  /** Holds pending requests keyed by requestId. Implementations must never return an expired request from `findLive`. */
95
108
  interface EmailProofPendingStore {
@@ -104,13 +117,18 @@ interface EmailProofPendingStore {
104
117
  declare function createMemoryEmailProofPendingStore(): EmailProofPendingStore;
105
118
  interface EmailProofResult {
106
119
  readonly envelope: IssuedCredentialEnvelope;
107
- readonly verified: VerifiedCredential;
120
+ /** The ticket verifier's result, or for the held profile (`envelope.profile.id`) the held verifier's. */
121
+ readonly verified: VerifiedCredential | VerifiedHeldEmailCredential;
108
122
  readonly credentialId: string;
109
123
  readonly issuedAt: string;
110
124
  readonly expiresAt: string;
111
125
  /** The descriptor the verifier checked against. Stored alongside the credential for offline re-verification. */
112
126
  readonly descriptor: CredentialFlowDescriptor;
113
127
  }
128
+ /** True for a ticket (did:key) result, whose `verified` is the ticket verifier's output. The held profile's result carries the held verifier's. */
129
+ declare function isTicketEmailProofResult(result: EmailProofResult): result is EmailProofResult & {
130
+ readonly verified: VerifiedCredential;
131
+ };
114
132
  interface EmailProofAcquireInput extends EmailProofRequestInput {
115
133
  /** Supplies the 8-digit code. Omit to only request one; the pending request is returned for a later call. */
116
134
  readonly getCode?: (context: {
@@ -174,4 +192,4 @@ type StoredEmailProofInput = {
174
192
  */
175
193
  declare function verifyStoredEmailProof(input: StoredEmailProofInput): Promise<VerifiedCredential>;
176
194
 
177
- export { DEFAULT_EMAIL_PROOF_PROFILE as D, EMAIL_PROOF_CREDENTIAL_TYPE as E, type HolderAlgorithm as H, type StoredEmailProofInput as S, EMAIL_PROOF_PENDING_MAX_MS as a, type EmailProofAcquireInput as b, type EmailProofAcquisition as c, EmailProofError as d, type EmailProofErrorCode as e, type EmailProofOptions as f, type EmailProofPending as g, type EmailProofPendingStore as h, type EmailProofProfileId as i, type EmailProofRequestInput as j, type EmailProofResult as k, type EmailProofStep as l, type HolderSigner as m, type StoredEmailProofRecord as n, acquireEmailProof as o, completeEmailProof as p, createEd25519HolderSigner as q, createMemoryEmailProofPendingStore as r, emailProofRequirement as s, requestEmailProofCode as t, verifyStoredEmailProof as v };
195
+ export { DEFAULT_EMAIL_PROOF_PROFILE as D, type EmailProofPendingStore as E, type HolderAlgorithm as H, type StoredEmailProofInput as S, type EmailProofPending as a, EMAIL_PROOF_CREDENTIAL_TYPE as b, EMAIL_PROOF_PENDING_MAX_MS as c, type EmailProofAcquireInput as d, type EmailProofAcquisition as e, EmailProofError as f, type EmailProofErrorCode as g, type EmailProofOptions as h, type EmailProofProfileId as i, type EmailProofRequestInput as j, type EmailProofResult as k, type EmailProofStep as l, type HolderSigner as m, type StoredEmailProofRecord as n, acquireEmailProof as o, completeEmailProof as p, createEd25519HolderSigner as q, createMemoryEmailProofPendingStore as r, emailProofRequirement as s, isTicketEmailProofResult as t, requestEmailProofCode as u, verifyStoredEmailProof as v };