@anis-ly/partners 0.0.0-stage → 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.
@@ -0,0 +1,1053 @@
1
+ import { inspect } from 'node:util';
2
+
3
+ /**
4
+ * The narrow key-custody seam: sign exact bytes and return ECDSA P-256 / SHA-256 in IEEE P1363 r‖s form.
5
+ *
6
+ * @remarks Accepting bytes instead of a key object lets a partner keep keys in its own vault or HSM. Exactly 64
7
+ * bytes prevent DER's alternate encoding of a mathematically valid signature from reaching Anis as a request error.
8
+ */
9
+ interface P256Signer {
10
+ /** Signs these bytes and returns exactly 64 bytes; DER has a different wire form and Anis refuses it. */
11
+ sign(data: Uint8Array): Promise<Uint8Array>;
12
+ }
13
+ /** A signer identified by the credential that Anis issued at enrollment. */
14
+ interface RequestSigner extends P256Signer {
15
+ /** The canonical request key ID; treating it as an identifier avoids late authentication failures. */
16
+ readonly keyId: string;
17
+ }
18
+
19
+ /**
20
+ * Associates an external signer with the credential UUID used in request signatures.
21
+ *
22
+ * @remarks Keeping key custody behind the byte-signing seam lets a partner use a vault or HSM without exporting its
23
+ * private key into this process.
24
+ */
25
+ declare class KeyedSigner implements RequestSigner {
26
+ private readonly signer;
27
+ /** The enrolled credential identifier, canonicalized so Anis can resolve it. */
28
+ readonly keyId: string;
29
+ /** Creates a binding; canonical identity avoids a valid signature that names an unknown credential. */
30
+ constructor(signer: P256Signer, keyId: string);
31
+ /** Signs exact bytes through partner-owned key custody without exposing key material. */
32
+ sign(data: Uint8Array): Promise<Uint8Array>;
33
+ }
34
+
35
+ /**
36
+ * One public key published for verifying Partner responses.
37
+ *
38
+ * @remarks Active, next, and retiring versions are published together so a response around a key rotation can still
39
+ * be verified without trusting a key supplied by that response.
40
+ */
41
+ interface PartnerJwk {
42
+ /** Key type; only EC keys can be imported by the response verifier. */ kty?: string;
43
+ /** Curve; only P-256 matches the algorithm Anis uses for response signatures. */ crv?: string;
44
+ /** Base64url X coordinate; it must decode to 32 bytes for a P-256 point. */ x?: string;
45
+ /** Base64url Y coordinate; both coordinates are required to validate the published point. */ y?: string;
46
+ /** Response key version identifier used to find the key named by a response. */ kid?: string;
47
+ /** Intended use when published; retained so the document is represented faithfully. */ use?: string;
48
+ /** Algorithm when published; retained for partner inspection and protocol compatibility. */ alg?: string;
49
+ /** Private scalar; a non-empty value means the whole document has exposed private key material. */ d?: string;
50
+ }
51
+ /** Published response verification key set; rotation versions are needed to verify answers during key changes. */
52
+ interface SigningKeySet {
53
+ /** Active, next, and retiring public key versions published together for safe rotation. */
54
+ keys: readonly PartnerJwk[];
55
+ }
56
+
57
+ /**
58
+ * Signs with a P-256 PKCS#8 key held in this process.
59
+ *
60
+ * @remarks This file-backed option is suitable when the host protects the key file; `P256Signer` remains the seam for
61
+ * a vault or HSM that never releases key material.
62
+ */
63
+ declare class PemP256Signer implements P256Signer {
64
+ #private;
65
+ private readonly publicKey;
66
+ private constructor();
67
+ /** Imports a PKCS#8 PEM key and refuses other curves at load time, before a partner receives an avoidable refusal. */
68
+ static fromPem(pem: string): Promise<PemP256Signer>;
69
+ /** Reads and imports a protected PKCS#8 PEM file so the private key can remain in host-controlled storage. */
70
+ static fromPemFile(path: string): Promise<PemP256Signer>;
71
+ /** Signs bytes in WebCrypto's 64-byte P1363 form; no DER conversion can silently change the wire signature. */
72
+ sign(data: Uint8Array): Promise<Uint8Array>;
73
+ /** Exports only public coordinates for enrollment and verification; the private half is never part of the JWK. */
74
+ publicJwk(): Promise<PartnerJwk>;
75
+ /** Binds this key to the issued credential UUID used by Anis to resolve request signatures. */
76
+ forKey(keyId: string): KeyedSigner;
77
+ }
78
+
79
+ /** Base type for failures raised by this SDK, so applications can handle local faults separately from HTTP refusals. */
80
+ declare class AnisPartnersError extends Error {
81
+ constructor(message: string, options?: ErrorOptions);
82
+ static [Symbol.hasInstance](value: unknown): boolean;
83
+ [inspect.custom](): string;
84
+ }
85
+
86
+ /** Indicates signing failed before a request was sent, so the partner can safely distinguish it from a server outcome. */
87
+ declare class RequestSigningError extends AnisPartnersError {
88
+ /** Preserves the original signer failure as `cause` while keeping sensitive signature material out of the message. */
89
+ constructor(cause: unknown);
90
+ }
91
+
92
+ /**
93
+ * Computes the RFC 7638 fingerprint used to confirm the submitted key.
94
+ *
95
+ * @remarks Computing locally and comparing with Anis's answer catches a changed public key before a partner proves
96
+ * possession of the wrong key.
97
+ */
98
+ declare function keyThumbprint(publicJwk: PartnerJwk): string;
99
+
100
+ /** Converts a locally checked thumbprint into the code read to Anis staff. */
101
+ declare function safetyCodeFromThumbprint(thumbprint: string): string;
102
+
103
+ /**
104
+ * Domain separator checked by Anis when verifying credential possession.
105
+ *
106
+ * @remarks Including a distinct first line prevents a credential proof from being reused as another signature type.
107
+ */
108
+ declare const DOMAIN_SEPARATOR = "anis.partners.v2.credential-proof";
109
+ /** Builds the exact domain-separated UTF-8 proof message so both sides hash the challenge and bind the same credential. */
110
+ declare function proofMessage(keyId: string, challengeGeneration: number, challenge: string, thumbprint: string): Uint8Array;
111
+ /** Signs the proof message and returns unpadded base64url P1363 bytes; DER would be refused at the proof endpoint. */
112
+ declare function proofSignature(message: Uint8Array, signer: P256Signer): Promise<string>;
113
+
114
+ /** Invitation state as reported by the enrollment surface. */
115
+ interface EnrollmentState {
116
+ /** Invitation UUID, when known. */
117
+ invitationId?: string;
118
+ /** Application UUID being enrolled. */
119
+ applicationId?: string;
120
+ /** Current invitation workflow state. */
121
+ state?: string;
122
+ /** Invitation expiry instant. */
123
+ expiresAt?: Date;
124
+ }
125
+ /**
126
+ * Public key and requested validity window submitted during enrollment.
127
+ *
128
+ * @remarks Submit only the public half: sending private key material is refused by Anis and would expose signing
129
+ * credentials outside the partner's key custody.
130
+ */
131
+ interface EnrollmentKeyRequest {
132
+ /** Public P-256 JWK only; private members are refused by Anis. */
133
+ publicJwk: PartnerJwk;
134
+ /** Requested beginning of the validity window. */
135
+ notBefore: Date;
136
+ /** Requested end of the validity window. */
137
+ expiresAt: Date;
138
+ }
139
+ /**
140
+ * Key submission answer containing the challenge that must be signed.
141
+ *
142
+ * @remarks The local thumbprint check ties Anis's challenge and safety code to the key the partner actually submitted;
143
+ * do not trust a safety code copied from an unverified answer.
144
+ */
145
+ interface EnrollmentKeyResult {
146
+ /** Credential UUID that becomes the request key id when active. */
147
+ keyId: string;
148
+ /** Server-computed RFC 7638 thumbprint, compared against the submitted public key. */
149
+ thumbprint?: string;
150
+ /** Safety code derived locally from the verified key thumbprint. */
151
+ safetyCode?: string;
152
+ /** Challenge whose domain-separated message proves possession of the private key. */
153
+ challenge?: string;
154
+ /** Challenge generation, incremented when Anis reissues the challenge. */
155
+ challengeGeneration?: number;
156
+ }
157
+ /** Proof request for the current enrollment challenge generation. */
158
+ interface EnrollmentProofRequest {
159
+ /** Credential UUID whose challenge is being answered. */
160
+ keyId: string;
161
+ /** Generation that Anis currently expects. */
162
+ challengeGeneration: number;
163
+ /** P-256/P1363 signature in unpadded base64url form. */
164
+ signature: string;
165
+ }
166
+ /**
167
+ * Enrollment proof and staff-approval state.
168
+ *
169
+ * @remarks A successful proof can remain pending until Anis staff verify the safety code. That approval is a control
170
+ * on activation, not a state to work around.
171
+ */
172
+ interface EnrollmentStatus {
173
+ /** Credential UUID, when the invitation has accepted a key. */
174
+ keyId?: string;
175
+ /** Current challenge generation. */
176
+ challengeGeneration?: number;
177
+ /** Proof workflow state. */
178
+ proofState?: string;
179
+ /** Staff approval state. */
180
+ approvalState?: string;
181
+ /** Overall enrollment state. */
182
+ state?: string;
183
+ /** Current workflow-step expiry instant. */
184
+ expiresAt?: Date;
185
+ /** Credential validity end instant after activation. */
186
+ keyExpiresAt?: Date;
187
+ }
188
+ /** Facts the signature self-check reports about how the gateway interpreted a request. */
189
+ interface SignatureDiagnostic {
190
+ /** Matched route identifier. */
191
+ routeId?: string;
192
+ /** HTTP method received by the gateway. */
193
+ method?: string;
194
+ /** Authority received by the gateway. */
195
+ authority?: string;
196
+ /** Path received by the gateway. */
197
+ path?: string;
198
+ /** Query without its leading question mark. */
199
+ canonicalQuery?: string;
200
+ /** Kind assigned by the route table. */
201
+ requestKind?: string;
202
+ /** Required permission for the route. */
203
+ requiredScope?: string;
204
+ /** Covered components required by the matched profile. */
205
+ coveredComponents: readonly string[];
206
+ /** Credential UUID named by the request. */
207
+ keyId?: string;
208
+ /** Partner UUID resolved from that credential. */
209
+ partnerId?: string;
210
+ /** Application UUID resolved from that credential. */
211
+ applicationId?: string;
212
+ /** Policy version applied. */
213
+ policyVersion?: number;
214
+ /** Scopes currently in effect. */
215
+ effectiveScopes: readonly string[];
216
+ /** Instant the gateway received the request. */
217
+ receivedAt?: Date;
218
+ }
219
+
220
+ /** Cancellation passed to signing-key retrieval during a caller's API operation. */
221
+ interface SigningKeyRequestOptions {
222
+ /** Stops waiting for or fetching a key document when the owning API call is canceled. */
223
+ signal?: AbortSignal;
224
+ }
225
+ /** Supplies published keys separately from verification so key rotation stays out of signature-check logic. */
226
+ interface SigningKeySource {
227
+ /** Returns the cached key document or fetches it on first use. */
228
+ get(options?: SigningKeyRequestOptions): Promise<SigningKeySet>;
229
+ /** Fetches once after an unknown key so hostile key IDs cannot trigger unbounded requests. */
230
+ refresh(options?: SigningKeyRequestOptions): Promise<SigningKeySet>;
231
+ }
232
+
233
+ /** Optional shared cache for serverless instances that do not retain process memory between requests. */
234
+ interface KeyDocumentCache {
235
+ /** Reads a cached document by stable authority key so another instance can avoid a duplicate fetch. */
236
+ get(key: string): Promise<string | undefined>;
237
+ /** Stores the public document for the requested lifetime. */
238
+ set(key: string, value: string, ttlSeconds: number): Promise<void>;
239
+ }
240
+
241
+ /** Structured partner logger; fields contain stable identifiers and never request secrets. */
242
+ interface PartnerLogger {
243
+ /** Emits a diagnostic event. */
244
+ debug(message: string, fields: Record<string, unknown>): void | Promise<void>;
245
+ /** Emits an informational event. */
246
+ info(message: string, fields: Record<string, unknown>): void | Promise<void>;
247
+ /** Emits a refusal or retry guidance event. */
248
+ warn(message: string, fields: Record<string, unknown>): void | Promise<void>;
249
+ /** Emits a discarded-response or communication error. */
250
+ error(message: string, fields: Record<string, unknown>): void | Promise<void>;
251
+ }
252
+
253
+ /** Settings for an enrollment invitation before an active request key exists. */
254
+ interface AnisEnrollmentClientOptions {
255
+ /** Issued Anis authority. */
256
+ authority: string | URL;
257
+ /** Invitation UUID being enrolled. */
258
+ invitationId: string;
259
+ /** Secret invitation token; it is sent only in Authorization and never logged. */
260
+ enrollmentToken: string;
261
+ /** Injectable fetch for proxies and in-memory API doubles. */
262
+ fetch?: typeof globalThis.fetch | undefined;
263
+ /** Shared key-document cache for short-lived hosts. */
264
+ keyCache?: KeyDocumentCache | undefined;
265
+ /** Optional structured log sink. */
266
+ logger?: Partial<PartnerLogger> | undefined;
267
+ /** Cache lifetime for the unsigned public response-key document. */
268
+ signingKeyCacheSeconds?: number | undefined;
269
+ /** Per-request timeout. */
270
+ timeoutMs?: number | undefined;
271
+ }
272
+ /** Raised when the verified challenge names a different key than the one submitted. */
273
+ declare class EnrollmentKeyMismatchError extends AnisPartnersError {
274
+ /** Thumbprint calculated from the public key submitted by this caller. */
275
+ readonly localThumbprint: string;
276
+ /** Thumbprint returned by Anis, when present. */
277
+ readonly serverThumbprint?: string;
278
+ /** Stops a proof from being made with a challenge bound to another key. */
279
+ constructor(localThumbprint: string, serverThumbprint?: string);
280
+ }
281
+ /** Enrollment flow, authenticated by its one-time token and still verifying every answer. */
282
+ declare class AnisEnrollmentClient {
283
+ #private;
284
+ private readonly transport;
285
+ private readonly invitation;
286
+ private constructor();
287
+ /** Creates an enrollment client over the same mandatory response-verification pipeline. */
288
+ static create(input: AnisEnrollmentClientOptions): AnisEnrollmentClient;
289
+ /** Reads invitation state. */
290
+ get(options?: {
291
+ signal?: AbortSignal;
292
+ }): Promise<EnrollmentState>;
293
+ /** Reads approval and key-expiry state. */
294
+ getStatus(options?: {
295
+ signal?: AbortSignal;
296
+ }): Promise<EnrollmentStatus>;
297
+ /** Submits a public key, then checks the verified answer against its local RFC 7638 thumbprint. */
298
+ submitKey(request: EnrollmentKeyRequest, options?: {
299
+ signal?: AbortSignal;
300
+ }): Promise<EnrollmentKeyResult>;
301
+ /** Builds the possession message, obtains its P-256 signature, and submits the proof. */
302
+ prove(submitted: EnrollmentKeyResult, signer: P256Signer, options?: {
303
+ signal?: AbortSignal;
304
+ }): Promise<EnrollmentStatus>;
305
+ /** Submits a previously prepared proof for the current challenge generation. */
306
+ submitProof(request: EnrollmentProofRequest, options?: {
307
+ signal?: AbortSignal;
308
+ }): Promise<EnrollmentStatus>;
309
+ }
310
+
311
+ /** Every published error code this SDK version recognizes. */
312
+ declare const ERROR_CODES: readonly ["account_inactive", "allowed_debt_consent_required", "binding_not_authorized", "business_subscription_required", "card_not_found", "card_unavailable", "challenge_expired", "currency_not_supported", "daily_limit_exceeded", "dependency_unavailable", "idempotency_conflict", "insufficient_balance", "insufficient_scope", "internal_error", "invalid_content_digest", "invalid_credentials", "invitation_invalid", "invoice_reveal_limit_exceeded", "key_duplicate", "key_proof_invalid", "malformed_signed_request", "operation_processing", "owner_limit_exceeded", "price_changed", "purchase_not_allowed", "quantity_unavailable", "rate_limited", "replay_detected", "request_timeout", "resource_not_found", "reveal_not_allowed", "signature_expired", "source_ip_not_allowed", "validation_failed", "wallet_disabled", "wallet_expired", "wallet_not_granted"];
313
+ /** A published error code, or unknown when Anis adds one this SDK has not seen yet. */
314
+ type ErrorCode = (typeof ERROR_CODES)[number] | 'unknown';
315
+
316
+ /** RFC 9457 problem returned for a verified refusal. Branch on code, never localized title or detail. */
317
+ interface Problem {
318
+ /** Permanent documentation URI for this error. */
319
+ type?: string;
320
+ /** Localized presentation text. */
321
+ title?: string;
322
+ /** HTTP status repeated in the body. */
323
+ status: number;
324
+ /** Localized presentation detail. */
325
+ detail?: string;
326
+ /** Machine code used for stable decisions. */
327
+ code?: string;
328
+ /** Correlation id to quote when asking Anis about this call. */
329
+ requestId?: string;
330
+ /** Documented per-code extensions retained without assuming their shape. */
331
+ extensions?: unknown;
332
+ }
333
+
334
+ /** Whether Anis's refusal means the order is closed or may still complete. */
335
+ type OrderRefusalOutcome = 'notPlaced' | 'unknown';
336
+ /** An Anis API refusal with stable machine fields for partner-side branching. */
337
+ declare class AnisApiError extends AnisPartnersError {
338
+ /** Complete parsed problem returned by Anis. */
339
+ readonly problem: Problem;
340
+ /** Known machine code, or unknown when this SDK has not seen the value. */
341
+ readonly code: ErrorCode;
342
+ /** Exact wire code, including an unknown future value. */
343
+ readonly rawCode?: string;
344
+ /** HTTP status of the verified response. */
345
+ readonly status: number;
346
+ /** Correlation id to quote when asking Anis about the call. */
347
+ readonly requestId?: string;
348
+ /** Permanent documentation link for this code. */
349
+ readonly typeUri?: string;
350
+ /** Signed Retry-After value in seconds, when supplied. */
351
+ readonly retryAfter?: number;
352
+ /** True when Anis returned the recorded refusal for this operation id. */
353
+ readonly isReplayed: boolean;
354
+ /** Whether the catalogue marks this code retryable; this does not decide order recovery. */
355
+ readonly isRetryable: boolean;
356
+ /** Whether the refusal leaves an order open for resume. */
357
+ readonly orderOutcome: OrderRefusalOutcome;
358
+ /**
359
+ * Creates a structured API error from a verified problem.
360
+ *
361
+ * @remarks The code is the stable branching contract. Titles and details change with language and copy updates, so
362
+ * callers that branch on the message can break without any API behavior changing.
363
+ */
364
+ constructor(problem: Problem, status: number, retryAfter?: number, isReplayed?: boolean);
365
+ }
366
+ /** A final refusal because the wallet balance cannot cover the order. */
367
+ declare class InsufficientBalanceError extends AnisApiError {
368
+ }
369
+ /** A final refusal because the catalogue price changed after it was read. */
370
+ declare class PriceChangedError extends AnisApiError {
371
+ }
372
+ /** A final refusal because the card or requested quantity is unavailable. */
373
+ declare class OutOfStockError extends AnisApiError {
374
+ }
375
+ /** A final refusal because an operation id was reused for a different order. */
376
+ declare class IdempotencyConflictError extends AnisApiError {
377
+ }
378
+ /** A request-rate refusal; callers should honor Retry-After when present. */
379
+ declare class RateLimitedError extends AnisApiError {
380
+ }
381
+ /** A final refusal because an owner spending allowance is exhausted. */
382
+ declare class LimitExceededError extends AnisApiError {
383
+ }
384
+ /** A refusal because the signing credentials are not accepted. */
385
+ declare class InvalidCredentialsError extends AnisApiError {
386
+ }
387
+ /** A refusal because the same signed nonce was already received. */
388
+ declare class ReplayDetectedError extends AnisApiError {
389
+ }
390
+ /** A refusal because current application or owner policy does not allow the call. */
391
+ declare class AuthorizationError extends AnisApiError {
392
+ }
393
+ /** A refusal for a resource that is absent or intentionally indistinguishable from absent. */
394
+ declare class ResourceNotFoundError extends AnisApiError {
395
+ }
396
+ /** A refusal because the request does not satisfy the published contract. */
397
+ declare class ValidationFailedError extends AnisApiError {
398
+ }
399
+ /** A refusal where Anis could not reach a decision; an order may still complete. */
400
+ declare class DependencyUnavailableError extends AnisApiError {
401
+ }
402
+ /** A refusal of an invitation, key submission, or enrollment proof step. */
403
+ declare class EnrollmentRefusedError extends AnisApiError {
404
+ }
405
+
406
+ /** Describes a local private-key loading or signing failure without exposing private key material. */
407
+ declare class PrivateKeyError extends AnisPartnersError {
408
+ }
409
+
410
+ /** A signed answer violated a model contract; its content is deliberately absent from the message and cause. */
411
+ declare class MalformedResponseError extends AnisPartnersError {
412
+ readonly model: string;
413
+ constructor(model: string);
414
+ }
415
+
416
+ /** The public signing-key document could not be loaded, so the response has no usable verification key set. */
417
+ declare class SigningKeyDocumentUnavailableError extends AnisPartnersError {
418
+ constructor();
419
+ }
420
+
421
+ /**
422
+ * Closed set of reasons a signed response is discarded.
423
+ *
424
+ * @remarks A response that cannot be verified is never returned for use; stable reasons let a partner handle a
425
+ * refusal without inspecting untrusted response content.
426
+ */
427
+ type ResponseVerificationFailure = 'signature_missing' | 'signature_malformed' | 'signature_invalid' | 'content_digest_mismatch' | 'covered_components_mismatch' | 'unknown_key' | 'key_rejected' | 'algorithm_not_supported' | 'label_unexpected' | 'created_out_of_window';
428
+
429
+ /**
430
+ * Thrown when a response cannot be verified, so its content cannot be used.
431
+ *
432
+ * @remarks This is an exception rather than a flag on a result because callers must not accidentally act on an
433
+ * unverified answer.
434
+ */
435
+ declare class UnverifiableResponseError extends AnisPartnersError {
436
+ /** The contract reason for refusing the response, without requiring callers to parse message text. */
437
+ readonly failure: ResponseVerificationFailure;
438
+ /** Creates a response refusal while keeping its body, signature, base, and key material out of the message. */
439
+ constructor(failure: ResponseVerificationFailure, detail: string);
440
+ }
441
+
442
+ /**
443
+ * An exact currency amount stored as thousandths instead of floating-point units.
444
+ *
445
+ * @remarks The contract sends amounts as decimal strings because a floating-point round trip can change the total
446
+ * checked against unit price multiplied by quantity. Integer thousandths keep that comparison exact.
447
+ */
448
+ declare class Money {
449
+ #private;
450
+ /** ISO currency code associated with this amount. */
451
+ readonly currency: string;
452
+ /** Instant at which the amount was computed, when the wire provides one. */
453
+ readonly asOf?: Date | undefined;
454
+ private constructor();
455
+ static [Symbol.hasInstance](value: unknown): boolean;
456
+ /**
457
+ * Builds an amount from its decimal wire spelling.
458
+ *
459
+ * @remarks A number has already passed through floating-point arithmetic, so accepting one could make an order
460
+ * total differ from the exact unit price the API checks.
461
+ */
462
+ static of(amount: string, currency: string, asOf?: Date): Money;
463
+ /** The amount rendered with exactly three decimal places so Anis receives the contract's decimal-string form. */
464
+ get amount(): string;
465
+ /**
466
+ * Multiplies by a whole quantity without losing fractional currency units.
467
+ *
468
+ * @remarks The source instant describes the unit quote, not the computed order total, so it is cleared on the result.
469
+ */
470
+ multiply(quantity: number): Money;
471
+ /** Uses the familiar decimal and currency spelling when a balance is interpolated into application text. */
472
+ toString(): string;
473
+ [inspect.custom](): string;
474
+ /** Converts to the contract object while retaining its decimal-string amount. */
475
+ toJSON(): {
476
+ amount: string;
477
+ currency: string;
478
+ asOf?: string;
479
+ };
480
+ }
481
+
482
+ /**
483
+ * A wallet this application may act on after current access and owner rules are applied.
484
+ *
485
+ * @remarks The API has already intersected the application's grants with live owner and subscription eligibility;
486
+ * absent subscription and capability fields are not independent permissions for partners to infer.
487
+ */
488
+ interface Wallet {
489
+ /** Wallet identity used by calls on this wallet. */
490
+ id: string;
491
+ /** Display name when the owner supplied one. */
492
+ name?: string;
493
+ /** Currency code used by its balances and orders. */
494
+ currency?: string;
495
+ /** Reserved-adjusted balance and the instant at which it was computed. */
496
+ balance: Money;
497
+ }
498
+ /**
499
+ * The application's identity and the scopes its current policy grants.
500
+ *
501
+ * @remarks Names and environment are omitted because deployments are isolated copies; exposing a single-valued
502
+ * environment would invite branching that cannot change the API surface.
503
+ */
504
+ interface PartnerProfile {
505
+ /** The Partner identity; names are intentionally not part of this surface. */
506
+ partner?: PartnerIdentity;
507
+ /** This application and its effective permissions. */
508
+ application?: ApplicationIdentity;
509
+ /** The owner account behind the wallets, when exposed by the surface. */
510
+ ownerAccount?: OwnerAccount;
511
+ /** Documentation version this deployment is aligned with. */
512
+ documentationVersion?: string;
513
+ }
514
+ /** Partner identity, by canonical UUID. */
515
+ interface PartnerIdentity {
516
+ /** Partner UUID in lower-case hyphenated form. */
517
+ id: string;
518
+ }
519
+ /**
520
+ * Application identity and its effective scopes.
521
+ *
522
+ * @remarks The application id remains stable while signing keys rotate, and scopes should be read from each response
523
+ * because policy can change between calls.
524
+ */
525
+ interface ApplicationIdentity {
526
+ /** Stable application identity; keys can rotate beneath it. */
527
+ id: string;
528
+ /** Scopes in force for calls made now; policy can change between calls. */
529
+ scopes: readonly string[];
530
+ }
531
+ /** Owner account identity behind the wallets. */
532
+ interface OwnerAccount {
533
+ /** Owner account UUID in lower-case hyphenated form. */
534
+ id: string;
535
+ /** Display name when the owner supplied one. */
536
+ displayName?: string;
537
+ }
538
+
539
+ /** Owner-supplied Arabic and English text; either translation can be absent. */
540
+ interface LocalizedText {
541
+ /** Arabic text when supplied. */
542
+ ar?: string;
543
+ /** English text when supplied. */
544
+ en?: string;
545
+ }
546
+ /** Category source. Unknown wire values remain readable if Anis adds a category kind. */
547
+ type CatalogueCategoryType = 'unknown' | 'local' | 'international';
548
+ /** A published catalogue category. */
549
+ interface CatalogueCategory {
550
+ /** Category UUID in canonical lower-case form. */
551
+ id: string;
552
+ /** Display name, which the owner may provide in either language. */
553
+ name?: LocalizedText;
554
+ /** Description, which the owner may provide in either language. */
555
+ description?: LocalizedText;
556
+ /** Logo URL when present. */
557
+ logo?: string;
558
+ /** Local, international, or unknown when the SDK has not seen a new value. */
559
+ type: CatalogueCategoryType;
560
+ /** Whether stock is live under the current owner rules. */
561
+ inStock: boolean;
562
+ /** Position chosen by the owner. */
563
+ displayOrder: number;
564
+ }
565
+ /** A published catalogue subcategory, including buyer-facing terms where present. */
566
+ interface CatalogueSubcategory {
567
+ /** Subcategory UUID. */
568
+ id: string;
569
+ /** Parent category UUID. */
570
+ categoryId: string;
571
+ /** Display name, if supplied. */
572
+ name?: LocalizedText;
573
+ /** Description, if supplied. */
574
+ description?: LocalizedText;
575
+ /** Logo URL when present. */
576
+ logo?: string;
577
+ /** Whether the owner marked this subcategory as a best seller. */
578
+ isBestSelling: boolean;
579
+ /** Position chosen by the owner. */
580
+ displayOrder: number;
581
+ /** Whether it is currently available. */
582
+ available: boolean;
583
+ /** Buyer-facing terms to show before purchase; absent when the owner supplied none. */
584
+ disclaimer?: LocalizedText;
585
+ }
586
+ /** A purchasable card and the price this wallet pays for it. */
587
+ interface CatalogueCard {
588
+ /** Card UUID used in an order. */
589
+ id: string;
590
+ /** Parent subcategory UUID. */
591
+ subcategoryId: string;
592
+ /** Display name, if supplied. */
593
+ name?: LocalizedText;
594
+ /** Printed face value, when the card has one. */
595
+ faceValue?: string;
596
+ /** The current unit price to return as expectedUnitPrice; absent when this wallet cannot buy it. */
597
+ unitPrice?: Money;
598
+ /** Business price for comparison and display; an order at a different value may be refused. */
599
+ businessPrice?: Money;
600
+ /** Retail price for display, present only above business price. */
601
+ personalPrice?: Money;
602
+ /** Whether a special offer applies. */
603
+ hasSpecialOffer: boolean;
604
+ /** Display-only offer price when a special offer applies. */
605
+ specialOfferPrice?: Money;
606
+ /** Whether the card is live under current owner rules. */
607
+ available: boolean;
608
+ /** Lowest quantity accepted in one order, when constrained. */
609
+ minimumQuantity?: number;
610
+ /** Highest quantity accepted in one order, when constrained. */
611
+ maximumQuantity?: number;
612
+ }
613
+ /** One cursor-paged result. Pass nextCursor to continue until it is absent. */
614
+ interface Page<T> {
615
+ /** Values on this page. */
616
+ items: readonly T[];
617
+ /** Cursor for the next page, absent when the list is exhausted. */
618
+ nextCursor?: string;
619
+ }
620
+
621
+ /** A sold card as a masked projection; plaintext is never present here. */
622
+ interface MaskedCard {
623
+ /** Sold-card UUID used by a single-card reveal. */
624
+ id: string;
625
+ /** Order that produced this card, when the API exposes it. */
626
+ orderOperationId?: string;
627
+ /** Owner invoice needed for invoice-level reveal. */
628
+ invoiceId?: string;
629
+ /** Catalogue card summary. */
630
+ card?: MaskedCardProduct;
631
+ /** Masked serial for identification without disclosing the credential. */
632
+ serialNumberMasked?: string;
633
+ /** Whether Anis currently permits the credential to be revealed. */
634
+ credentialAvailable: boolean;
635
+ /** Purchase instant, when supplied. */
636
+ purchasedAt?: Date;
637
+ /** Amount originally charged per card, including after a refund. */
638
+ unitPrice?: Money;
639
+ /** Last calendar day the card can be used. */
640
+ expiryDate?: string;
641
+ /** Number printed on the owner invoice. */
642
+ invoiceNumber?: number;
643
+ /** Printed face value when supplied. */
644
+ faceValue?: string;
645
+ /** Catalogue subcategory summary. */
646
+ subcategory?: MaskedCardSubcategory;
647
+ }
648
+ /** A catalogue subcategory summary attached to a sold card. */
649
+ interface MaskedCardSubcategory {
650
+ /** Subcategory UUID. */
651
+ id: string;
652
+ /** Localized name when supplied. */
653
+ name?: LocalizedText;
654
+ }
655
+ /** A catalogue product summary attached to a sold card or revealed credential. */
656
+ interface MaskedCardProduct {
657
+ /** Card UUID. */
658
+ id: string;
659
+ /** Localized name when supplied. */
660
+ name?: LocalizedText;
661
+ }
662
+ /**
663
+ * Credential plaintext returned only by a protected reveal or first order completion.
664
+ *
665
+ * @remarks This is the only public model that carries a voucher or serial. Redacting its string form prevents a
666
+ * careless log interpolation from disclosing credentials.
667
+ */
668
+ interface RevealedCredential {
669
+ /** Sold-card UUID this credential belongs to. */
670
+ soldCardId: string;
671
+ /** Serial number; keep it out of logs and telemetry. */
672
+ serialNumber?: string;
673
+ /** Voucher code; keep it out of logs and telemetry. */
674
+ voucher?: string;
675
+ /** Reveal instant when supplied. */
676
+ revealedAt?: Date;
677
+ /** Last calendar day the card can be used. */
678
+ expiryDate?: string;
679
+ /** Invoice UUID, present on reveal routes. */
680
+ invoiceId?: string;
681
+ /** Product summary, present on reveal routes. */
682
+ card?: MaskedCardProduct;
683
+ /** Purchase instant, present on reveal routes. */
684
+ purchasedAt?: Date;
685
+ /** Redacted representation for accidental string interpolation. */
686
+ toString(): string;
687
+ /** Redacted representation for Node's recursive native inspection. */
688
+ [inspect.custom](): string;
689
+ }
690
+ /** All credentials released for one invoice, or none when the invoice cannot be revealed. */
691
+ interface RevealedCredentialCollection {
692
+ /** Credentials on this invoice, capped by the public contract. */
693
+ items: readonly RevealedCredential[];
694
+ }
695
+
696
+ /**
697
+ * Order lifecycle state. Unknown future values stay readable as unknown.
698
+ *
699
+ * @remarks The parser maps this wire enum explicitly because serializer defaults differ between runtimes. Order
700
+ * outcomes still depend on the response and replay marker, never on a future status string alone.
701
+ */
702
+ type OrderStatus = 'unknown' | 'processing' | 'recoveryExhausted' | 'completed' | 'failed';
703
+ /**
704
+ * What a partner wants to buy. Prices remain exact decimal strings through Money serialization.
705
+ *
706
+ * @remarks The gateway rejects unknown request members and compares the total to exact unit-price multiplication;
707
+ * floating-point arithmetic can therefore turn an apparently valid order into a refusal.
708
+ */
709
+ interface CreateOrderRequest {
710
+ /** Catalogue card being purchased. */
711
+ cardId: string;
712
+ /** Number of cards, within the live catalogue limits. */
713
+ quantity: number;
714
+ /** Price read from the catalogue, echoed to detect price changes. */
715
+ expectedUnitPrice: Money;
716
+ /** Exact expected unit price multiplied by quantity. */
717
+ expectedTotal: Money;
718
+ /** Partner's own reference, when useful for reconciliation. */
719
+ externalReference?: string | undefined;
720
+ /** Explicit consent to use an allowed owner debt balance. */
721
+ useAllowedDebt?: boolean | undefined;
722
+ }
723
+ /**
724
+ * An order projection returned by create, resume, or lookup.
725
+ *
726
+ * @remarks Credentials appear only on the first completion answer. A replay or lookup is state-only, so use the typed
727
+ * order result for a compile-time distinction before handling credentials.
728
+ */
729
+ interface Order {
730
+ /** Same UUID the caller sent as Idempotency-Key. */
731
+ operationId: string;
732
+ /** Current owner-reported order state. */
733
+ status: OrderStatus;
734
+ /** Owner invoice UUID once one exists. */
735
+ invoiceId?: string;
736
+ /** Wallet UUID the order used. */
737
+ walletId?: string;
738
+ /** Catalogue card UUID. */
739
+ cardId?: string;
740
+ /** Number of cards. */
741
+ quantity?: number;
742
+ /** Total amount charged. */
743
+ total?: Money;
744
+ /** Credentials, only on the first response that reports completion. */
745
+ soldCards?: readonly RevealedCredential[];
746
+ /** Completion instant. */
747
+ completedAt?: Date;
748
+ /** Partner's reference from the create request. */
749
+ externalReference?: string;
750
+ /** Recorded refusal code when a lookup reports a failed order. */
751
+ failureCode?: string;
752
+ /** Whether the completed order's credentials were withheld; absent means the API did not state it. */
753
+ codesWithheld?: boolean;
754
+ }
755
+
756
+ /**
757
+ * Result of creating or resuming an order; callers must handle all five possible outcomes.
758
+ *
759
+ * @remarks Credentials are present only on completion. Keeping the outcomes separate makes that one-time release
760
+ * rule visible to callers and prevents a missed nullable-field check from losing a purchase.
761
+ */
762
+ type OrderResult = OrderCompleted | OrderProcessing | OrderReplayed | OrderNotPlaced | OrderOutcomeUnknown;
763
+ /** The order completed and this response carries its one-time credentials. */
764
+ interface OrderCompleted {
765
+ /** Discriminator for a first completion, including a recovered completion. */
766
+ kind: 'completed';
767
+ /** Caller-owned id that ties the completed response to the idempotency key. */
768
+ operationId: string;
769
+ /** Order state recorded by Anis. */
770
+ order: Order;
771
+ /** Credentials released by this first completion response. */
772
+ credentials: readonly RevealedCredential[];
773
+ /** True when the order completed but no credentials could be released. */
774
+ codesWithheld: boolean;
775
+ }
776
+ /** Anis accepted the order but has not recorded an outcome. */
777
+ interface OrderProcessing {
778
+ /** Discriminator for an accepted order still processing. */
779
+ kind: 'processing';
780
+ /** Caller-owned id to reuse when resuming; a new id could place the cards twice. */
781
+ operationId: string;
782
+ /** Current order projection. */
783
+ order: Order;
784
+ /** Suggested wait before resuming the same operation id. */
785
+ suggestedDelayMs: number;
786
+ /** Location supplied by Anis, when present. */
787
+ location?: string;
788
+ }
789
+ /** This operation id already received a terminal answer. */
790
+ interface OrderReplayed {
791
+ /** Discriminator for an already delivered result. */
792
+ kind: 'replayed';
793
+ /** Caller-owned id whose terminal answer Anis is returning again. */
794
+ operationId: string;
795
+ /** Recorded order state; credentials are not repeated on a replay. */
796
+ order: Order;
797
+ }
798
+ /** Anis made a final decision that nothing was placed or charged. */
799
+ interface OrderNotPlaced {
800
+ /** Discriminator for a closed order refusal. */
801
+ kind: 'notPlaced';
802
+ /** Caller-owned id for the closed attempt. */
803
+ operationId: string;
804
+ /** Typed refusal with the signed problem and response metadata. */
805
+ refusal: AnisApiError;
806
+ }
807
+ /** The call ended before the client could establish whether the order completed. */
808
+ interface OrderOutcomeUnknown {
809
+ /** Discriminator for an unresolved order. */
810
+ kind: 'unknown';
811
+ /** Caller-owned operation id to reuse when resuming. */
812
+ operationId: string;
813
+ /** Suggested delay before resuming the same operation id. */
814
+ suggestedDelayMs: number;
815
+ /** Failure or discarded answer that left the order outcome unresolved. */
816
+ cause: unknown;
817
+ }
818
+
819
+ /** Client settings that select one issued authority and bound signing, caching, and request time. */
820
+ interface ClientOptions {
821
+ /** Issued Anis authority; the host is the only environment selector. */
822
+ authority: string | URL;
823
+ /** Signature lifetime in seconds. Capped at 60 so a request cannot finish after its answer freshness window. */
824
+ signatureLifetimeSeconds?: number | undefined;
825
+ /** Optional Arabic or English presentation preference. */
826
+ acceptLanguage?: 'ar' | 'en' | undefined;
827
+ /** Lifetime of the published response signing-key document cache. */
828
+ signingKeyCacheSeconds?: number | undefined;
829
+ /** Per-request timeout; an order timeout leaves its outcome unknown. */
830
+ timeoutMs?: number | undefined;
831
+ /** Stable host label used for bounded metric dimensions. */
832
+ name?: string | undefined;
833
+ }
834
+ /** Applies SDK defaults and rejects settings that could place orders whose answers are already stale. */
835
+ interface ValidatedClientOptions {
836
+ authority: URL;
837
+ signatureLifetimeSeconds: number;
838
+ signingKeyCacheSeconds: number;
839
+ timeoutMs: number;
840
+ name: string;
841
+ acceptLanguage?: 'ar' | 'en' | undefined;
842
+ }
843
+ /** Rejects invalid authorities and stale signature lifetimes before a call can become unverifiable or leave an order unresolved. */
844
+ declare function validateClientOptions(options: ClientOptions): ValidatedClientOptions;
845
+
846
+ /**
847
+ * The three request shapes accepted by the Partner API.
848
+ *
849
+ * @remarks The route selects a frozen shape; a second configurable map could drift from Anis's route rules and turn
850
+ * a valid signature into an unexplained refusal.
851
+ */
852
+ type SignatureProfile = 'SafeRead' | 'BodylessNonceMutation' | 'OrderMutation';
853
+
854
+ /** Creates the single-use nonce that protects a mutation from replay. */
855
+ interface NonceFactory {
856
+ /** Returns 128 random bits in unpadded base64url; repeated or guessable values are refused as replays. */
857
+ create(): string;
858
+ }
859
+
860
+ /** Frozen request settings used by all route groups. */
861
+ interface TransportOptions extends ValidatedClientOptions {
862
+ /** Route-profile signer. */
863
+ signer?: RequestSigner;
864
+ /** Nonce source retained by the transport so every mutation gets a fresh replay guard. */
865
+ nonceFactory?: NonceFactory;
866
+ /** Injectable fetch implementation. */
867
+ fetcher: typeof globalThis.fetch;
868
+ /** Public response key source. */
869
+ keySource: SigningKeySource;
870
+ /** Optional structured diagnostics. */
871
+ logger?: Partial<PartnerLogger>;
872
+ }
873
+ /** Shared pipeline that signs exact request bytes and verifies a complete response before parsing it. */
874
+ declare class PartnerTransport {
875
+ private readonly settings;
876
+ /** Configured bounded telemetry name for this client instance. */
877
+ get clientName(): string;
878
+ private readonly requestSigner?;
879
+ private readonly verifier;
880
+ private readonly nonceFactory;
881
+ /** Keeps request signing and response verification together so callers cannot return an unverified answer. */
882
+ constructor(settings: TransportOptions);
883
+ /** Sends one API request; response data is not parsed until its signature and digest pass. */
884
+ send(request: {
885
+ method: string;
886
+ route: string;
887
+ path: string;
888
+ profile?: SignatureProfile;
889
+ body?: Uint8Array;
890
+ operationId?: string;
891
+ enrollmentToken?: string;
892
+ signal?: AbortSignal | undefined;
893
+ }): Promise<{
894
+ response: Response;
895
+ body: Uint8Array;
896
+ }>;
897
+ /** Sends and parses a verified non-empty JSON success. */
898
+ json<T>(request: Parameters<PartnerTransport['send']>[0], parse: (value: unknown) => T): Promise<T>;
899
+ /** Records the closed order outcome without attaching credential data to logs. */
900
+ reportOrderOutcome(operationId: string, outcome: string, reason?: string): void;
901
+ }
902
+
903
+ /** Optional caller cancellation applied to one API call. */
904
+ interface CallOptions {
905
+ /** Stops waiting for this request; for orders, its outcome is still recorded as unknown. */
906
+ signal?: AbortSignal | undefined;
907
+ }
908
+ /** Optional continuation cursor and cancellation signal for a single page request. */
909
+ interface PageOptions extends CallOptions {
910
+ /** Cursor returned by the preceding page; omit it to read the first page. */
911
+ cursor?: string | undefined;
912
+ }
913
+ /** Reads the current profile so callers see policy changes. */
914
+ declare class ProfileOperations {
915
+ private readonly transport;
916
+ /** Shares the verified transport so profile reads follow the client's authority and signing policy. */
917
+ constructor(transport: PartnerTransport);
918
+ /** Reads identity and effective scopes from the live policy. */
919
+ get(options?: CallOptions): Promise<PartnerProfile>;
920
+ }
921
+ /** Lists granted wallets and reads one wallet. */
922
+ declare class WalletOperations {
923
+ private readonly transport;
924
+ /** Shares the verified transport so wallet reads follow the client's authority and signing policy. */
925
+ constructor(transport: PartnerTransport);
926
+ /** Walks wallet pages so callers need not manage continuation cursors. */
927
+ list(options?: CallOptions): AsyncIterable<Wallet>;
928
+ /** Reads one page when the caller manages the cursor. */
929
+ listPage(options?: PageOptions): Promise<Page<Wallet>>;
930
+ /** Reads one granted wallet by canonical UUID. */
931
+ get(walletId: string, options?: CallOptions): Promise<Wallet>;
932
+ }
933
+ /** Reads wallet-priced catalogue categories, subcategories, and cards. */
934
+ declare class CatalogueOperations {
935
+ private readonly transport;
936
+ /** Shares the verified transport so catalogue reads use the client's price and signing policy. */
937
+ constructor(transport: PartnerTransport);
938
+ /** Walks category pages for a wallet. */
939
+ listCategories(walletId: string, options?: CallOptions): AsyncIterable<CatalogueCategory>;
940
+ /** Reads one category page. */
941
+ listCategoriesPage(walletId: string, options?: PageOptions): Promise<Page<CatalogueCategory>>;
942
+ /** Walks subcategory pages. */
943
+ listSubcategories(walletId: string, categoryId: string, options?: CallOptions): AsyncIterable<CatalogueSubcategory>;
944
+ /** Reads one subcategory page. */
945
+ listSubcategoriesPage(walletId: string, categoryId: string, options?: PageOptions): Promise<Page<CatalogueSubcategory>>;
946
+ /** Reads one subcategory. */
947
+ getSubcategory(walletId: string, subcategoryId: string, options?: CallOptions): Promise<CatalogueSubcategory>;
948
+ /** Walks card pages for the given wallet and subcategory. */
949
+ listCards(walletId: string, subcategoryId: string, options?: CallOptions): AsyncIterable<CatalogueCard>;
950
+ /** Reads one catalogue card page. */
951
+ listCardsPage(walletId: string, subcategoryId: string, options?: PageOptions): Promise<Page<CatalogueCard>>;
952
+ }
953
+ /** Places, resumes, and reads orders under caller-owned operation ids. */
954
+ declare class OrderOperations {
955
+ private readonly transport;
956
+ /** Shares the verified transport so order recovery uses the same signer and idempotency rules. */
957
+ constructor(transport: PartnerTransport);
958
+ /** Creates an order under an id the caller has persisted, preventing a dropped answer from causing duplicate purchases. */
959
+ create(walletId: string, operationId: string, order: CreateOrderRequest, options?: CallOptions): Promise<OrderResult>;
960
+ /** Repeats the same request and operation id to recover an unknown result. */
961
+ resume(walletId: string, operationId: string, order: CreateOrderRequest, options?: CallOptions): Promise<OrderResult>;
962
+ /** Reads order state without dispatching a new order or returning credentials. */
963
+ get(operationId: string, options?: CallOptions): Promise<Order>;
964
+ private send;
965
+ }
966
+ /** Lists owned cards and reveals credentials only on explicit protected calls. */
967
+ declare class OwnedCardOperations {
968
+ private readonly transport;
969
+ /** Shares the verified transport so card reads and reveals keep the client's response checks. */
970
+ constructor(transport: PartnerTransport);
971
+ /** Walks owned-card pages. */
972
+ list(walletId: string, options?: CallOptions): AsyncIterable<MaskedCard>;
973
+ /** Reads one owned-card page. */
974
+ listPage(walletId: string, options?: PageOptions): Promise<Page<MaskedCard>>;
975
+ /** Reads a masked owned card. */
976
+ get(walletId: string, soldCardId: string, options?: CallOptions): Promise<MaskedCard>;
977
+ /** Reveals one credential using a signed mutation with no body bytes. */
978
+ reveal(walletId: string, soldCardId: string, options?: CallOptions): Promise<RevealedCredential>;
979
+ /** Reveals every credential on an invoice atomically. */
980
+ revealInvoice(walletId: string, invoiceId: string, options?: CallOptions): Promise<RevealedCredentialCollection>;
981
+ }
982
+ /** Runs the signed, side-effect-free signature admission diagnostic. */
983
+ declare class DiagnosticsOperations {
984
+ private readonly transport;
985
+ /** Shares the verified transport so the self-check uses the same request as the partner API. */
986
+ constructor(transport: PartnerTransport);
987
+ /** Sends the exact empty JSON object expected by the self-check route. */
988
+ checkSignature(options?: CallOptions): Promise<SignatureDiagnostic>;
989
+ }
990
+
991
+ /** Dependencies used to create a signed and verified client. */
992
+ interface AnisPartnersClientCreateOptions {
993
+ /** Validated authority and request settings. */
994
+ options: ClientOptions;
995
+ /** Partner key custody; signatures must be 64-byte P-256 P1363. */
996
+ signer: RequestSigner;
997
+ /** Injectable fetch for proxies and in-memory API doubles. */
998
+ fetch?: typeof globalThis.fetch | undefined;
999
+ /** Shared key-document cache for short-lived/serverless hosts. */
1000
+ keyCache?: KeyDocumentCache | undefined;
1001
+ /** Optional structured partner log sink. */
1002
+ logger?: Partial<PartnerLogger> | undefined;
1003
+ }
1004
+ /** Node client whose requests are signed and whose complete responses are verified before parsing. */
1005
+ declare class AnisPartnersClient {
1006
+ /** Reads identity and live scopes. */
1007
+ readonly profile: ProfileOperations;
1008
+ /** Lists wallets available to this application. */
1009
+ readonly wallets: WalletOperations;
1010
+ /** Reads wallet-priced catalogue entries. */
1011
+ readonly catalogue: CatalogueOperations;
1012
+ /** Creates and resumes caller-keyed orders. */
1013
+ readonly orders: OrderOperations;
1014
+ /** Reads owned cards and reveals credentials. */
1015
+ readonly ownedCards: OwnedCardOperations;
1016
+ /** Runs the side-effect-free signature check. */
1017
+ readonly diagnostics: DiagnosticsOperations;
1018
+ private constructor();
1019
+ /** Builds the grouped API client and its unsigned public key-document source. */
1020
+ static create(input: AnisPartnersClientCreateOptions): AnisPartnersClient;
1021
+ }
1022
+
1023
+ /**
1024
+ * Stable OpenTelemetry names for dashboards and host-side instrumentation configuration.
1025
+ *
1026
+ * @remarks These constants keep integrations aligned with the SDK's bounded dimensions so telemetry does not split
1027
+ * into incompatible series after an application upgrade.
1028
+ */
1029
+ declare const AnisPartnersTelemetry: {
1030
+ /** Instrumentation scope used for every SDK span and metric. */
1031
+ readonly scope: "@anis-ly/partners";
1032
+ /** Stable low-cardinality attribute names. */
1033
+ readonly attributes: {
1034
+ readonly client: "anis.client";
1035
+ readonly route: "anis.route";
1036
+ readonly method: "http.request.method";
1037
+ readonly statusCode: "http.response.status_code";
1038
+ readonly errorType: "error.type";
1039
+ readonly errorCode: "anis.error.code";
1040
+ readonly operationId: "anis.operation_id";
1041
+ readonly requestId: "anis.request_id";
1042
+ };
1043
+ /** Metric instrument names emitted by the SDK. */
1044
+ readonly instruments: {
1045
+ readonly requestDuration: "anis.partners.request.duration";
1046
+ readonly signatureDuration: "anis.partners.signature.duration";
1047
+ readonly verificationFailures: "anis.partners.response.verification.failures";
1048
+ readonly orderOutcomes: "anis.partners.order.outcomes";
1049
+ readonly signingKeyFetches: "anis.partners.signing_keys.fetches";
1050
+ };
1051
+ };
1052
+
1053
+ export { AnisApiError, AnisEnrollmentClient, type AnisEnrollmentClientOptions, AnisPartnersClient, type AnisPartnersClientCreateOptions, AnisPartnersError, AnisPartnersTelemetry, type ApplicationIdentity, AuthorizationError, type CallOptions, type CatalogueCard, type CatalogueCategory, type CatalogueCategoryType, CatalogueOperations, type CatalogueSubcategory, type ClientOptions, type CreateOrderRequest, DOMAIN_SEPARATOR, DependencyUnavailableError, DiagnosticsOperations, ERROR_CODES, EnrollmentKeyMismatchError, type EnrollmentKeyRequest, type EnrollmentKeyResult, type EnrollmentProofRequest, EnrollmentRefusedError, type EnrollmentState, type EnrollmentStatus, type ErrorCode, IdempotencyConflictError, InsufficientBalanceError, InvalidCredentialsError, type KeyDocumentCache, KeyedSigner, LimitExceededError, type LocalizedText, MalformedResponseError, type MaskedCard, type MaskedCardProduct, type MaskedCardSubcategory, Money, type Order, type OrderCompleted, type OrderNotPlaced, OrderOperations, type OrderOutcomeUnknown, type OrderProcessing, type OrderRefusalOutcome, type OrderReplayed, type OrderResult, type OrderStatus, OutOfStockError, OwnedCardOperations, type OwnerAccount, type P256Signer, type Page, type PageOptions, type PartnerIdentity, type PartnerJwk, type PartnerLogger, type PartnerProfile, PemP256Signer, PriceChangedError, PrivateKeyError, type Problem, ProfileOperations, RateLimitedError, ReplayDetectedError, type RequestSigner, RequestSigningError, ResourceNotFoundError, type ResponseVerificationFailure, type RevealedCredential, type RevealedCredentialCollection, type SignatureDiagnostic, SigningKeyDocumentUnavailableError, UnverifiableResponseError, type ValidatedClientOptions, ValidationFailedError, type Wallet, WalletOperations, keyThumbprint, proofMessage, proofSignature, safetyCodeFromThumbprint, validateClientOptions };