From 88afb9804ed29bc7c76978749193d6da1de23e7c Mon Sep 17 00:00:00 2001 From: Maycon Date: Wed, 28 Aug 2024 12:07:17 -0300 Subject: [PATCH] DCKM-582: OID4VP integration --- packages/core/src/credentials/oidvc.ts | 80 ++++++++++++++++++- packages/wasm/src/services/pex/config.ts | 6 ++ packages/wasm/src/services/pex/service-rpc.js | 5 ++ packages/wasm/src/services/pex/service.ts | 15 +++- yarn.lock | 7 ++ 5 files changed, 111 insertions(+), 2 deletions(-) diff --git a/packages/core/src/credentials/oidvc.ts b/packages/core/src/credentials/oidvc.ts index 99baac75..9638b104 100644 --- a/packages/core/src/credentials/oidvc.ts +++ b/packages/core/src/credentials/oidvc.ts @@ -1,7 +1,10 @@ - import {IWallet} from '../types'; import {IDIDProvider} from '../did-provider'; import {credentialServiceRPC} from '@docknetwork/wallet-sdk-wasm/src/services/credential'; +import {MetadataClient} from '@sphereon/oid4vci-client'; +import jwtDecode from 'jwt-decode'; +import axios from 'axios'; +import {pexService} from '@docknetwork/wallet-sdk-wasm/src/services/pex'; export async function acquireOpenIDCredentialFromURI({ didProvider, @@ -30,3 +33,78 @@ export async function acquireOpenIDCredentialFromURI({ return response.credential; } + +export async function getAuthURL( + uri: string, + walletClientId: string = 'dock-wallet', + requestedRedirectURI: string = 'dockwallet://vp', +) { + function buildOID4VPRequestURL(params, prefix = 'dockwallet://') { + return `${prefix}?${Object.keys(params) + .map( + key => + `${encodeURIComponent(key)}=${encodeURIComponent( + typeof params[key] === 'object' + ? JSON.stringify(params[key]) + : params[key], + )}`, + ) + .join('&')}`; + } + + const searchParams = new URL(uri).searchParams; + const params = new URLSearchParams(searchParams); + const clientId = params.get('client_id'); + const metadata = await MetadataClient.retrieveAllMetadata(clientId); + const requestedAlg = + metadata?.authorizationServerMetadata + ?.request_object_signing_alg_values_supported[0]; + const requestParams = { + scope: 'openid vp_token', + redirect_uri: requestedRedirectURI, + client_metadata: + requestedAlg && requestedAlg !== 'EdDSA' + ? JSON.stringify({ + vp_formats_supported: { + vc_json: { + alg_values_supported: [requestedAlg], + }, + }, + }) + : ['EdDSA'], + }; + + return buildOID4VPRequestURL( + { + ...requestParams, + client_id: walletClientId, + }, + metadata.authorization_endpoint, + ); +} + +export async function decodeRequestJWT(uri: string) { + const searchParams = new URL(uri).searchParams; + const params = new URLSearchParams(searchParams); + const requestUri = params.get('request_uri'); + const jwt = await axios.get(requestUri).then(res => res.data); + const decoded = jwtDecode(jwt); + + return decoded; +} + +export async function getPresentationSubmision({ + credentials, + presentationDefinition, + holderDID, +}) { + const presentation = await pexService.presentationFrom({ + presentationDefinition, + credentials, + holderDID, + }); + + return presentation.presentation_submission; +} + +pexService.evaluatePresentation; diff --git a/packages/wasm/src/services/pex/config.ts b/packages/wasm/src/services/pex/config.ts index b5f7af90..8bf064d1 100644 --- a/packages/wasm/src/services/pex/config.ts +++ b/packages/wasm/src/services/pex/config.ts @@ -19,6 +19,12 @@ export type FilterCredentialsParams = { holderDIDs: string[]; }; +export type CreatePresentationParams = { + credentials: any[]; + presentationDefinition: any; + holderDID: string; +}; + export type EvaluatePresentationParams = { presentation: any; presentationDefinition: any; diff --git a/packages/wasm/src/services/pex/service-rpc.js b/packages/wasm/src/services/pex/service-rpc.js index d735d567..e80a3c0a 100644 --- a/packages/wasm/src/services/pex/service-rpc.js +++ b/packages/wasm/src/services/pex/service-rpc.js @@ -4,6 +4,7 @@ import { FilterCredentialsParams, validation, EvaluatePresentationParams, + CreatePresentationParams, } from './config'; export class PEXServiceRPC extends RpcService { @@ -19,4 +20,8 @@ export class PEXServiceRPC extends RpcService { validation.evaluatePresentation(params); return this.call('evaluatePresentation', params); } + + async presentationFrom(params: CreatePresentationParams) { + return this.call('presentationFrom', params); + } } diff --git a/packages/wasm/src/services/pex/service.ts b/packages/wasm/src/services/pex/service.ts index 222f0d7d..cc3046b0 100644 --- a/packages/wasm/src/services/pex/service.ts +++ b/packages/wasm/src/services/pex/service.ts @@ -4,8 +4,9 @@ import { validation, EvaluatePresentationParams, FilterCredentialsParams, + CreatePresentationParams, } from './config'; -import {PEX} from '@sphereon/pex'; +import {IPresentationDefinition, PEX} from '@sphereon/pex'; const pex: PEX = new PEX(); @@ -65,6 +66,7 @@ class PEXService { rpcMethods = [ PEXService.prototype.filterCredentials, PEXService.prototype.evaluatePresentation, + PEXService.prototype.presentationFrom, ]; filterCredentials(params: FilterCredentialsParams) { @@ -89,6 +91,17 @@ class PEXService { return result; } + + presentationFrom(params: CreatePresentationParams) { + const {credentials, presentationDefinition, holderDID} = params; + const result: IPresentation = pex.presentationFrom( + removeOptionalAttribute(presentationDefinition), + credentials, + holderDID, + ); + + return result; + } } export const pexService = new PEXService(); diff --git a/yarn.lock b/yarn.lock index 5d63b2c8..b31f2759 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4775,6 +4775,13 @@ available-typed-arrays@^1.0.5: resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== +available-typed-arrays@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz#a5cc375d6a03c2efc87a553f3e0b1522def14846" + integrity sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ== + dependencies: + possible-typed-array-names "^1.0.0" + axe-core@^4.6.2: version "4.8.1" resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.8.1.tgz#6948854183ee7e7eae336b9877c5bafa027998ea"