UNPKG

@sphereon/oid4vci-client

Version:

OpenID for Verifiable Credential Issuance (OpenID4VCI) client

183 lines (160 loc) 6.42 kB
import { AccessTokenResponse, CredentialIssuerMetadataV1_0_13, CredentialOfferPayloadV1_0_13, CredentialOfferRequestWithBaseUrl, determineSpecVersionFromOffer, EndpointMetadata, ExperimentalSubjectIssuance, getIssuerFromCredentialOfferPayload, OID4VCICredentialFormat, OpenId4VCIVersion, UniformCredentialOfferRequest, } from '@sphereon/oid4vci-common'; import { CredentialFormat } from '@sphereon/ssi-types'; import { CredentialOfferClient } from './CredentialOfferClient'; import { CredentialRequestClient } from './CredentialRequestClient'; export class CredentialRequestClientBuilderV1_0_13 { credentialEndpoint?: string; deferredCredentialEndpoint?: string; deferredCredentialAwait = false; deferredCredentialIntervalInMS = 5000; credentialIdentifier?: string; credentialTypes?: string[] = []; format?: CredentialFormat | OID4VCICredentialFormat; token?: string; version?: OpenId4VCIVersion; subjectIssuance?: ExperimentalSubjectIssuance; issuerState?: string; public static fromCredentialIssuer({ credentialIssuer, metadata, version, credentialIdentifier, credentialTypes, }: { credentialIssuer: string; metadata?: EndpointMetadata; version?: OpenId4VCIVersion; credentialIdentifier?: string; credentialTypes?: string | string[]; }): CredentialRequestClientBuilderV1_0_13 { const issuer = credentialIssuer; const builder = new CredentialRequestClientBuilderV1_0_13(); builder.withVersion(version ?? OpenId4VCIVersion.VER_1_0_13); builder.withCredentialEndpoint(metadata?.credential_endpoint ?? (issuer.endsWith('/') ? `${issuer}credential` : `${issuer}/credential`)); if (metadata?.deferred_credential_endpoint) { builder.withDeferredCredentialEndpoint(metadata.deferred_credential_endpoint); } if (credentialIdentifier) { builder.withCredentialIdentifier(credentialIdentifier); } if (credentialTypes) { builder.withCredentialType(credentialTypes); } return builder; } public static async fromURI({ uri, metadata }: { uri: string; metadata?: EndpointMetadata }): Promise<CredentialRequestClientBuilderV1_0_13> { const offer = await CredentialOfferClient.fromURI(uri); return CredentialRequestClientBuilderV1_0_13.fromCredentialOfferRequest({ request: offer, ...offer, metadata, version: offer.version }); } public static fromCredentialOfferRequest(opts: { request: UniformCredentialOfferRequest; scheme?: string; baseUrl?: string; version?: OpenId4VCIVersion; metadata?: EndpointMetadata; }): CredentialRequestClientBuilderV1_0_13 { const { request, metadata } = opts; const version = opts.version ?? request.version ?? determineSpecVersionFromOffer(request.original_credential_offer); if (version < OpenId4VCIVersion.VER_1_0_13) { throw new Error('Versions below v1.0.13 (draft 13) are not supported.'); } const builder = new CredentialRequestClientBuilderV1_0_13(); const issuer = getIssuerFromCredentialOfferPayload(request.credential_offer) ?? (metadata?.issuer as string); builder.withVersion(version); builder.withCredentialEndpoint(metadata?.credential_endpoint ?? (issuer.endsWith('/') ? `${issuer}credential` : `${issuer}/credential`)); if (metadata?.deferred_credential_endpoint) { builder.withDeferredCredentialEndpoint(metadata.deferred_credential_endpoint); } const ids: string[] = (request.credential_offer as CredentialOfferPayloadV1_0_13).credential_configuration_ids; // if there's only one in the offer, we pre-select it. if not, you should provide the credentialType if (ids.length && ids.length === 1) { builder.withCredentialIdentifier(ids[0]); } return builder; } public static fromCredentialOffer({ credentialOffer, metadata, }: { credentialOffer: CredentialOfferRequestWithBaseUrl; metadata?: EndpointMetadata; }): CredentialRequestClientBuilderV1_0_13 { const builder = CredentialRequestClientBuilderV1_0_13.fromCredentialOfferRequest({ request: credentialOffer, metadata, version: credentialOffer.version, }); return builder; } public withCredentialEndpointFromMetadata(metadata: CredentialIssuerMetadataV1_0_13): this { this.credentialEndpoint = metadata.credential_endpoint; return this; } public withCredentialEndpoint(credentialEndpoint: string): this { this.credentialEndpoint = credentialEndpoint; return this; } public withIssuerState(issuerState?: string): this { this.issuerState = issuerState; return this; } public withDeferredCredentialEndpointFromMetadata(metadata: CredentialIssuerMetadataV1_0_13): this { this.deferredCredentialEndpoint = metadata.deferred_credential_endpoint; return this; } public withDeferredCredentialEndpoint(deferredCredentialEndpoint: string): this { this.deferredCredentialEndpoint = deferredCredentialEndpoint; return this; } public withDeferredCredentialAwait(deferredCredentialAwait: boolean, deferredCredentialIntervalInMS?: number): this { this.deferredCredentialAwait = deferredCredentialAwait; this.deferredCredentialIntervalInMS = deferredCredentialIntervalInMS ?? 5000; return this; } public withCredentialIdentifier(credentialIdentifier: string): this { this.credentialIdentifier = credentialIdentifier; return this; } public withCredentialType(credentialTypes: string | string[]): this { this.credentialTypes = Array.isArray(credentialTypes) ? credentialTypes : [credentialTypes]; return this; } public withFormat(format: CredentialFormat | OID4VCICredentialFormat): this { this.format = format; return this; } public withSubjectIssuance(subjectIssuance: ExperimentalSubjectIssuance): this { this.subjectIssuance = subjectIssuance; return this; } public withToken(accessToken: string): this { this.token = accessToken; return this; } public withTokenFromResponse(response: AccessTokenResponse): this { this.token = response.access_token; return this; } public withVersion(version: OpenId4VCIVersion): this { this.version = version; return this; } public build(): CredentialRequestClient { if (!this.version) { this.withVersion(OpenId4VCIVersion.VER_1_0_11); } return new CredentialRequestClient(this); } }