From 440a9834cff3e9b5cd3c66c2c89d295d1e71aee7 Mon Sep 17 00:00:00 2001 From: Adam Burdett Date: Tue, 14 Nov 2023 10:41:10 -0700 Subject: [PATCH] feat: more bugs with mt tests Signed-off-by: Adam Burdett --- oid4vci/demo/frontend/src/FormPage.js | 36 +- .../runner/sphereon_wrapper/__init__.py | 0 .../sphereon_wrapper/test_client_issuer.py | 350 +++++++++++++++ oid4vci/int/sphereon/.dockerignore | 3 + oid4vci/int/sphereon/.gitignore | 144 ++++++ oid4vci/int/sphereon/.prettierrc | 11 + oid4vci/int/sphereon/Dockerfile | 43 ++ oid4vci/int/sphereon/package-lock.json | 415 ++++++++++++++++++ oid4vci/int/sphereon/package.json | 24 + oid4vci/int/sphereon/src/app.ts | 0 oid4vci/int/sphereon/tsconfig.json | 109 +++++ oid4vci/oid4vci/v1_0/models/supported_cred.py | 43 +- oid4vci/oid4vci/v1_0/public_routes.py | 8 +- oid4vci/oid4vci/v1_0/routes.py | 12 +- 14 files changed, 1167 insertions(+), 31 deletions(-) create mode 100644 oid4vci/int/runner/runner/sphereon_wrapper/__init__.py create mode 100644 oid4vci/int/runner/runner/sphereon_wrapper/test_client_issuer.py create mode 100644 oid4vci/int/sphereon/.dockerignore create mode 100644 oid4vci/int/sphereon/.gitignore create mode 100644 oid4vci/int/sphereon/.prettierrc create mode 100644 oid4vci/int/sphereon/Dockerfile create mode 100644 oid4vci/int/sphereon/package-lock.json create mode 100644 oid4vci/int/sphereon/package.json create mode 100644 oid4vci/int/sphereon/src/app.ts create mode 100644 oid4vci/int/sphereon/tsconfig.json diff --git a/oid4vci/demo/frontend/src/FormPage.js b/oid4vci/demo/frontend/src/FormPage.js index 99b4cdac5..0c2b72461 100644 --- a/oid4vci/demo/frontend/src/FormPage.js +++ b/oid4vci/demo/frontend/src/FormPage.js @@ -18,7 +18,8 @@ const FormPage = () => { const handleSubmit = () => { // Set the Axios configuration for CORS and credentials axios.defaults.withCredentials = true; // Enable credentials (cookies, etc.) - axios.defaults.headers.common['Access-Control-Allow-Origin'] = 'http://localhost:3001'; // Adjust the origin as needed + axios.defaults.headers.common["Access-Control-Allow-Origin"] = + "http://localhost:3001"; // Adjust the origin as needed // api call to controller, `POST /exchange/submit` axios @@ -32,22 +33,31 @@ const FormPage = () => { }) .then((response) => { console.log(response.data); - const {exchange_id} = response.data - // TODO: call offer endpoint + const { exchange_id } = response.data; + // TODO: call offer endpoint - const queryParams = { - credentials: [selectedCredential], - user_pin_required: false, - exchange_id: exchange_id, - }; - axios.get("http://localhost:3001/oid4vci/draft-11/credential-offer", { params: queryParams }) + const queryParams = { + credentials: selectedCredential, + user_pin_required: false, + exchange_id: exchange_id, + }; + console.log("get offer params:"); + console.log(queryParams); + axios + .get("http://localhost:3001/oid4vci/draft-11/credential-offer", { + params: queryParams, + headers: { + accept: "application/json", + }, + }) .then((response) => { console.log(response.data); const credentialOffer = response.data; - const {exchange_id} = response.data; - navigate(`/qr-code`, { state: { credentialOffer, exchange_id: exchange_id } }); - }) - }) + navigate(`/qr-code`, { + state: { credentialOffer, exchange_id: exchange_id }, + }); + }); + }) .catch((error) => { console.error(error); }); diff --git a/oid4vci/int/runner/runner/sphereon_wrapper/__init__.py b/oid4vci/int/runner/runner/sphereon_wrapper/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/oid4vci/int/runner/runner/sphereon_wrapper/test_client_issuer.py b/oid4vci/int/runner/runner/sphereon_wrapper/test_client_issuer.py new file mode 100644 index 000000000..a7a1b3e16 --- /dev/null +++ b/oid4vci/int/runner/runner/sphereon_wrapper/test_client_issuer.py @@ -0,0 +1,350 @@ +import pytest +import asyncio +from cryptography.hazmat.primitives import serialization +from cryptography.hazmat.primitives.asymmetric import ec +from cryptography.hazmat.backends import default_backend +from jose import JWTError +from jose.constants import ALGORITHMS +from jose.backends import RSAKey +from ssi import ExpressBuilder +from oid4vci import ( + VcIssuerBuilder, + OID4VCIServer, + AccessTokenResponse, + CredentialOfferSession, + CredentialSupportedBuilderV1_11, + OpenId4VCIClient, +) +from oid4vci_common import ( + Alg, + IssuerCredentialSubjectDisplay, + CredentialSupported, + Jwt, + JWTHeader, + JWTPayload, + OpenId4VCIVersion, +) +from oid4vci_issuer import MemoryStates +from did_resolver import DIDDocument +from did_key.driver import driver as didKeyDriver +from did_key.key import KeyObject +import jose + + +@pytest.fixture +async def subject_did_key(): + did_kd = didKeyDriver() + return await did_kd.generate() + + +@pytest.fixture +async def subject_keypair(): + private_key = ec.generate_private_key(ec.SECP256R1(), default_backend()) + public_key = private_key.public_key() + return KeyPair(public_key, private_key) + + +class KeyPair: + def __init__(self, public_key, private_key): + self.public_key = public_key + self.private_key = private_key + + +@pytest.fixture +def express_support(): + return ExpressBuilder.from_server_opts(port=3456, hostname="localhost").build( + start_listening=False + ) + + +@pytest.fixture +async def vc_issuer(express_support, subject_keypair, subject_did_key): + issuer_url = "http://localhost:3456/test" + state_manager = MemoryStates() + credential_supported = ( + CredentialSupportedBuilderV1_11() + .with_cryptographic_suites_supported("ES256K") + .with_cryptographic_binding_method("did") + .with_types("VerifiableCredential") + .with_format("jwt_vc_json") + .with_id("UniversityDegree_JWT") + .with_credential_supported_display( + IssuerCredentialSubjectDisplay( + name="University Credential", + locale="en-US", + logo={ + "url": "https://exampleuniversity.com/public/logo.png", + "alt_text": "a square logo of a university", + }, + background_color="#12107c", + text_color="#FFFFFF", + ) + ) + .add_credential_subject_property_display( + "given_name", + IssuerCredentialSubjectDisplay(name="given name", locale="en-US"), + ) + .build() + ) + + credential = { + "@context": ["https://www.w3.org/2018/credentials/v1"], + "type": ["VerifiableCredential"], + "issuer": "did:key:test", + "issuanceDate": "2023-01-01T00:00:00Z", + "credentialSubject": {}, + } + + vc_issuer = ( + VcIssuerBuilder() + .with_credential_endpoint("http://localhost:3456/test/credential-endpoint") + .with_default_credential_offer_base_uri("http://localhost:3456/test") + .with_credential_issuer(issuer_url) + .with_issuer_display(name="example issuer", locale="en-US") + .with_credentials_supported(credential_supported) + .with_credential_offer_state_manager(state_manager) + .with_in_memory_c_nonce_state() + .with_in_memory_credential_offer_uri_state() + .with_credential_data_supplier( + lambda: asyncio.ensure_future( + { + "format": "ldp_vc", + "credential": credential, + } + ) + ) + .with_credential_signer_callback( + lambda: asyncio.ensure_future( + { + **credential, + "proof": { + "type": "JwtProof2020", + "jwt": "ye.ye.ye", + "created": "2023-01-01T00:00:00Z", + "proofPurpose": "assertionMethod", + "verificationMethod": "sdfsdfasdfasdfasdfasdfassdfasdf", + }, + } + ) + ) + .with_jwt_verify_callback(lambda args: asyncio.ensure_future(verify_jwt(args))) + .build() + ) + + return vc_issuer + + +async def verify_jwt(args): + header = jose.decode_protected_header(args["jwt"]) + payload = jose.decode_jwt(args["jwt"]) + + kid = header.get("kid") or args.get("kid") + did = kid.split("#")[0] + did_document = DIDDocument("@context=https://www.w3.org/ns/did/v1", id=did) + alg = header.get("alg", "ES256k") + return { + "alg": alg, + "kid": kid, + "did": did, + "didDocument": did_document, + "jwt": { + "header": header, + "payload": payload, + }, + } + + +@pytest.fixture +async def server(express_support, vc_issuer): + server = OID4VCIServer( + express_support, + issuer=vc_issuer, + base_url="http://localhost:3456/test", + endpoint_opts={ + "token_endpoint_opts": { + "accessTokenSignerCallback": lambda jwt, kid=None: asyncio.ensure_future( + sign_access_token(jwt, kid) + ), + "tokenPath": "/test/token", + }, + }, + ) + await express_support.start() + return server + + +async def sign_access_token(jwt, kid=None): + private_key = ec.generate_private_key(ec.SECP256R1(), default_backend()) + return ( + jose.SignJWT(jwt["payload"]) + .set_protected_header(jwt["header"]) + .sign(private_key) + ) + + +@pytest.mark.asyncio +async def test_vc_issuer( + server, vc_issuer, express_support, subject_keypair, subject_did_key +): + issuer_state = "previously-created-state" + pre_authorized_code = "test_code" + + async with OpenId4VCIClient.from_uri( + uri=await vc_issuer.create_credential_offer_uri( + grants={ + "authorization_code": { + "issuer_state": issuer_state, + }, + "urn:ietf:params:oauth:grant-type:pre-authorized_code": { + "pre-authorized_code": pre_authorized_code, + "user_pin_required": True, + }, + }, + credentials=["UniversityDegree_JWT"], + scheme="http", + ), + kid=subject_did_key["didDocument"]["authentication"][0], + alg="ES256", + ) as client: + assert server.issuer is not None + assert client.credential_offer == { + "baseUrl": "http://localhost:3456/test", + "credential_offer": { + "credential_issuer": "http://localhost:3456/test", + "credentials": ["UniversityDegree_JWT"], + "grants": { + "authorization_code": { + "issuer_state": "previously-created-state", + }, + "urn:ietf:params:oauth:grant-type:pre-authorized_code": { + "pre-authorized_code": "test_code", + "user_pin_required": True, + }, + }, + }, + "issuerState": "previously-created-state", + "original_credential_offer": { + "credential_issuer": "http://localhost:3456/test", + "credentials": ["UniversityDegree_JWT"], + "grants": { + "authorization_code": { + "issuer_state": "previously-created-state", + }, + "urn:ietf:params:oauth:grant-type:pre-authorized_code": { + "pre-authorized_code": "test_code", + "user_pin_required": True, + }, + }, + }, + "preAuthorizedCode": "test_code", + "scheme": "http", + "supportedFlows": ["Authorization Code Flow", "Pre-Authorized Code Flow"], + "userPinRequired": True, + "version": 1011, + } + assert client.get_issuer() == "http://localhost:3456/test" + assert client.version() == OpenId4VCIVersion.VER_1_0_11 + + metadata = await client.retrieve_server_metadata() + assert metadata == { + "authorizationServerType": "OID4VCI", + "authorization_server": "http://localhost:3456/test", + "credentialIssuerMetadata": { + "credential_endpoint": "http://localhost:3456/test/credential-endpoint", + "credential_issuer": "http://localhost:3456/test", + "credentials_supported": [ + { + "credentialSubject": { + "given_name": { + "locale": "en-US", + "name": "given name", + }, + }, + "cryptographic_binding_methods_supported": ["did"], + "cryptographic_suites_supported": ["ES256K"], + "display": [ + { + "background_color": "#12107c", + "locale": "en-US", + "logo": { + "alt_text": "a square logo of a university", + "url": "https://exampleuniversity.com/public/logo.png", + }, + "name": "University Credential", + "text_color": "#FFFFFF", + }, + ], + "format": "jwt_vc_json", + "id": "UniversityDegree_JWT", + "types": ["VerifiableCredential"], + }, + ], + "display": [ + { + "locale": "en-US", + "name": "example issuer", + }, + ], + }, + "credential_endpoint": "http://localhost:3456/test/credential-endpoint", + "issuer": "http://localhost:3456/test", + "token_endpoint": "http://localhost:3456/test/token", + } + + pre_auth_code = ( + client.credential_offer["credential_offer"]["grants"] + .get("urn:ietf:params:oauth:grant-type:pre-authorized_code", {}) + .get("pre-authorized_code") + ) + assert pre_auth_code is not None + + cred_offer_session = await vc_issuer.credential_offer_sessions.get_asserted( + pre_auth_code + ) + assert cred_offer_session is not None + + access_token = await client.acquire_access_token( + pin=cred_offer_session["userPin"] + ) + assert access_token is not None + + async def proof_of_possession_callback_function(args): + return ( + await jose.SignJWT(args["payload"]) + .set_protected_header(args["header"]) + .set_issued_at(int(datetime.datetime.utcnow().timestamp())) + .set_issuer(args["kid"]) + .set_audience(args["payload"]["aud"]) + .set_expiration_time(2 * 3600) + .sign(subject_keypair.private_key) + ) + + credential_response = await client.acquire_credentials( + credential_types=["VerifiableCredential"], + format="jwt_vc_json", + proof_callbacks={"signCallback": proof_of_possession_callback_function}, + ) + + assert credential_response == { + "c_nonce_expires_in": 300000, + "credential": { + "@context": ["https://www.w3.org/2018/credentials/v1"], + "credentialSubject": {}, + "issuer": "did:key:test", + "proof": { + "jwt": "ye.ye.ye", + "proofPurpose": "assertionMethod", + "type": "JwtProof2020", + "verificationMethod": "sdfsdfasdfasdfasdfasdfassdfasdf", + }, + "type": ["VerifiableCredential"], + }, + "format": "jwt_vc_json", + } + + +@pytest.fixture +def event_loop(): + loop = asyncio.get_event_loop_policy().new_event_loop() + yield loop + loop.close() diff --git a/oid4vci/int/sphereon/.dockerignore b/oid4vci/int/sphereon/.dockerignore new file mode 100644 index 000000000..b763d8235 --- /dev/null +++ b/oid4vci/int/sphereon/.dockerignore @@ -0,0 +1,3 @@ +node_modules +dist +Dockerfile diff --git a/oid4vci/int/sphereon/.gitignore b/oid4vci/int/sphereon/.gitignore new file mode 100644 index 000000000..3502ef7fa --- /dev/null +++ b/oid4vci/int/sphereon/.gitignore @@ -0,0 +1,144 @@ +# Created by https://www.toptal.com/developers/gitignore/api/node +# Edit at https://www.toptal.com/developers/gitignore?templates=node + +### Node ### +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) +web_modules/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional stylelint cache +.stylelintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) +.cache +.parcel-cache + +# Next.js build output +.next +out + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and not Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# vuepress v2.x temp and cache directory +.temp + +# Docusaurus cache and generated files +.docusaurus + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# yarn v2 +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* + +### Node Patch ### +# Serverless Webpack directories +.webpack/ + +# Optional stylelint cache + +# SvelteKit build / generate output +.svelte-kit + +# End of https://www.toptal.com/developers/gitignore/api/node diff --git a/oid4vci/int/sphereon/.prettierrc b/oid4vci/int/sphereon/.prettierrc new file mode 100644 index 000000000..74984fed7 --- /dev/null +++ b/oid4vci/int/sphereon/.prettierrc @@ -0,0 +1,11 @@ +{ + "semi": true, + "trailingComma": "es5", + "singleQuote": true, + "printWidth": 90, + "tabWidth": 2, + "useTabs": false, + "bracketSpacing": true, + "arrowParens": "avoid", + "endOfLine": "lf" +} diff --git a/oid4vci/int/sphereon/Dockerfile b/oid4vci/int/sphereon/Dockerfile new file mode 100644 index 000000000..c6fffc1bd --- /dev/null +++ b/oid4vci/int/sphereon/Dockerfile @@ -0,0 +1,43 @@ +# ---- Base Stage ---- +FROM node:18 AS base + +# Set the working directory +WORKDIR /usr/src/app + +# Copy package.json and package-lock.json (if available) +COPY package*.json ./ + +# ---- Dependencies Stage ---- +FROM base AS dependencies + +# Install node modules, including 'devDependencies' for building the TypeScript source +RUN npm install + +# Copy the rest of the application source code +COPY . . + +# Build the TypeScript source +RUN npm run build + +# ---- Release Stage ---- +FROM node:18 AS release + +# Set the working directory for the release stage +WORKDIR /usr/src/app + +RUN apt-get update && apt-get install ncat -y && apt-get clean + +# Copy package.json and package-lock.json for the production installation +COPY package*.json ./ + +# Install production node_modules (skip 'devDependencies') +RUN npm ci --only=production + +# Copy built node modules and build directory from the 'dependencies' stage +COPY --from=dependencies /usr/src/app/dist ./dist + +# Your app binds to port 3000 so you'll use the EXPOSE instruction to have it mapped by the docker daemon +EXPOSE 3000 + +# Define the command to run your app using CMD which defines your runtime +CMD [ "node", "dist/app.js" ] diff --git a/oid4vci/int/sphereon/package-lock.json b/oid4vci/int/sphereon/package-lock.json new file mode 100644 index 000000000..7904921ee --- /dev/null +++ b/oid4vci/int/sphereon/package-lock.json @@ -0,0 +1,415 @@ +{ + "name": "sphereon-json-rpc", + "version": "0.1.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "sphereon-json-rpc", + "version": "0.1.0", + "license": "Apache-2.0", + "dependencies": { + "json-rpc-api-proxy": "github:Indicio-tech/json-rpc-api-proxy#cced6a17455c4d3e249604b10acd7530e04466d7" + }, + "devDependencies": { + "prettier": "^3.0.3", + "ts-node": "^10.9.1", + "typescript": "^5.2.2" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true + }, + "node_modules/@types/node": { + "version": "20.9.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.9.0.tgz", + "integrity": "sha512-nekiGu2NDb1BcVofVcEKMIwzlx4NjHlcjhoxxKBNLtz15Y1z7MYf549DFvkHSId02Ax6kGwWntIBPC3l/JZcmw==", + "dev": true, + "peer": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/acorn": { + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", + "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.0.tgz", + "integrity": "sha512-FS7hV565M5l1R08MXqo8odwMTB02C2UqzB17RVgu9EyuYFBqJZ3/ZY97sQD5FewVu1UyDFc1yztUDrAwT0EypA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/json-rpc-2.0": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/json-rpc-2.0/-/json-rpc-2.0-1.7.0.tgz", + "integrity": "sha512-asnLgC1qD5ytP+fvBP8uL0rvj+l8P6iYICbzZ8dVxCpESffVjzA7KkYkbKCIbavs7cllwH1ZUaNtJwphdeRqpg==" + }, + "node_modules/json-rpc-api-proxy": { + "version": "0.1.0", + "resolved": "git+ssh://git@github.com/Indicio-tech/json-rpc-api-proxy.git#cced6a17455c4d3e249604b10acd7530e04466d7", + "integrity": "sha512-7wxBwjvKn3i7YJxB7GqWjbPesZsy60PmtG3d/BH/8qqryItsVheW/A3X7Yzq0wEfv/GPEEG7QF5s2gej1ZVsfQ==", + "license": "Apache-2.0", + "dependencies": { + "json-rpc-2.0": "^1.7.0" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/prettier": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.1.0.tgz", + "integrity": "sha512-TQLvXjq5IAibjh8EpBIkNKxO749UEWABoiIZehEPiY4GNpVdhaFKqSTu+QrlU6D2dPAfubRmtJTi4K4YkQ5eXw==", + "dev": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/typescript": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true, + "peer": true + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + } + }, + "dependencies": { + "@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "0.3.9" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "dev": true + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true + }, + "@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true + }, + "@types/node": { + "version": "20.9.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.9.0.tgz", + "integrity": "sha512-nekiGu2NDb1BcVofVcEKMIwzlx4NjHlcjhoxxKBNLtz15Y1z7MYf549DFvkHSId02Ax6kGwWntIBPC3l/JZcmw==", + "dev": true, + "peer": true, + "requires": { + "undici-types": "~5.26.4" + } + }, + "acorn": { + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", + "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", + "dev": true + }, + "acorn-walk": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.0.tgz", + "integrity": "sha512-FS7hV565M5l1R08MXqo8odwMTB02C2UqzB17RVgu9EyuYFBqJZ3/ZY97sQD5FewVu1UyDFc1yztUDrAwT0EypA==", + "dev": true + }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, + "json-rpc-2.0": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/json-rpc-2.0/-/json-rpc-2.0-1.7.0.tgz", + "integrity": "sha512-asnLgC1qD5ytP+fvBP8uL0rvj+l8P6iYICbzZ8dVxCpESffVjzA7KkYkbKCIbavs7cllwH1ZUaNtJwphdeRqpg==" + }, + "json-rpc-api-proxy": { + "version": "git+ssh://git@github.com/Indicio-tech/json-rpc-api-proxy.git#cced6a17455c4d3e249604b10acd7530e04466d7", + "integrity": "sha512-7wxBwjvKn3i7YJxB7GqWjbPesZsy60PmtG3d/BH/8qqryItsVheW/A3X7Yzq0wEfv/GPEEG7QF5s2gej1ZVsfQ==", + "from": "json-rpc-api-proxy@github:Indicio-tech/json-rpc-api-proxy#cced6a17455c4d3e249604b10acd7530e04466d7", + "requires": { + "json-rpc-2.0": "^1.7.0" + } + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "prettier": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.1.0.tgz", + "integrity": "sha512-TQLvXjq5IAibjh8EpBIkNKxO749UEWABoiIZehEPiY4GNpVdhaFKqSTu+QrlU6D2dPAfubRmtJTi4K4YkQ5eXw==", + "dev": true + }, + "ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "dev": true, + "requires": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + } + }, + "typescript": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", + "dev": true + }, + "undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true, + "peer": true + }, + "v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true + } + } +} diff --git a/oid4vci/int/sphereon/package.json b/oid4vci/int/sphereon/package.json new file mode 100644 index 000000000..c3e987816 --- /dev/null +++ b/oid4vci/int/sphereon/package.json @@ -0,0 +1,24 @@ +{ + "name": "sphereon-json-rpc", + "version": "0.1.0", + "description": "JSON-RPC interface to sphereon", + "main": "index.ts", + "scripts": { + "build": "tsc", + "start": "node dist/app.js", + "format": "prettier --write ." + }, + "author": "Daniel Bluhm ", + "license": "Apache-2.0", + "devDependencies": { + "prettier": "^3.0.3", + "ts-node": "^10.9.1", + "typescript": "^5.2.2" + }, + "dependencies": { + "json-rpc-api-proxy": "github:Indicio-tech/json-rpc-api-proxy#cced6a17455c4d3e249604b10acd7530e04466d7" + }, + "overrides": { + "ref-napi": "npm:@2060.io/ref-napi" + } +} diff --git a/oid4vci/int/sphereon/src/app.ts b/oid4vci/int/sphereon/src/app.ts new file mode 100644 index 000000000..e69de29bb diff --git a/oid4vci/int/sphereon/tsconfig.json b/oid4vci/int/sphereon/tsconfig.json new file mode 100644 index 000000000..2d706d939 --- /dev/null +++ b/oid4vci/int/sphereon/tsconfig.json @@ -0,0 +1,109 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig to read more about this file */ + + /* Projects */ + // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + + /* Language and Environment */ + "target": "es2020" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, + // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + // "jsx": "preserve", /* Specify what JSX code is generated. */ + // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ + // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ + // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ + + /* Modules */ + "module": "nodenext" /* Specify what module code is generated. */, + // "rootDir": "./", /* Specify the root folder within your source files. */ + "moduleResolution": "nodenext" /* Specify how TypeScript looks up a file from a given module specifier. */, + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ + // "types": [], /* Specify type package names to be included without being referenced in a source file. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ + // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ + // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ + "resolveJsonModule": true /* Enable importing .json files. */, + // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ + // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ + + /* JavaScript Support */ + // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ + + /* Emit */ + // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + // "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ + "outDir": "./dist" /* Specify an output folder for all emitted files. */, + // "removeComments": true, /* Disable emitting comments. */ + // "noEmit": true, /* Disable emitting files from a compilation. */ + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ + + /* Interop Constraints */ + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ + // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */, + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, + + /* Type Checking */ + "strict": true /* Enable all strict type-checking options. */, + // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ + // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ + // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ + // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + } +} diff --git a/oid4vci/oid4vci/v1_0/models/supported_cred.py b/oid4vci/oid4vci/v1_0/models/supported_cred.py index f37b6dd77..d1780dc51 100644 --- a/oid4vci/oid4vci/v1_0/models/supported_cred.py +++ b/oid4vci/oid4vci/v1_0/models/supported_cred.py @@ -16,7 +16,7 @@ class Meta: EVENT_NAMESPACE = "oid4vci" RECORD_ID_NAME = "supported_cred_id" RECORD_TYPE = "supported_cred" - TAG_NAMES = {"supported_cred_id", "types", "scope"} + TAG_NAMES = {"scope"} def __init__( self, @@ -24,25 +24,27 @@ def __init__( supported_cred_id: Optional[str] = None, state: Optional[str] = None, format: Optional[str] = None, - types: Optional[List[str]] = None, + scope=None, cryptographic_binding_methods_supported: Optional[List[str]] = None, cryptographic_suites_supported: Optional[List[str]] = None, + proof_types_supported: Optional[List[str]] = None, display: Optional[List[Dict]] = None, - credential_subject: Optional[Dict] = None, - scope=None, + credential_subject: Optional[Dict] = None, # v11 + credential_definition: Optional[Dict] = None, # v13 **kwargs, ): """Initialize a new SupportedCredential Record.""" super().__init__(supported_cred_id, state or "init", **kwargs) self.format = format - self.types = types + self.scope = scope self.cryptographic_binding_methods_supported = ( cryptographic_binding_methods_supported ) self.cryptographic_suites_supported = cryptographic_suites_supported + self.proof_types_supported = proof_types_supported self.display = display self.credential_subject = credential_subject - self.scope = scope + self.credential_definition = credential_definition def web_serialize(self) -> dict: """Serialize record for web.""" @@ -53,6 +55,22 @@ def supported_cred_id(self): """Accessor for the ID associated with this record.""" return self._id + @property + def record_value(self) -> dict: + """Return dict representation of the exchange record for storage.""" + return { + prop: getattr(self, prop) + for prop in ( + "format", + "scope", + "cryptographic_binding_methods_supported", + "cryptographic_suites_supported", + "display", + "credential_subject", + "credential_definition", + ) + } + class SupportedCredentialSchema(BaseRecordSchema): """Schema for SupportedCredential.""" @@ -62,10 +80,10 @@ class Meta: model_class = SupportedCredential + format = fields.Str(required=True, metadata={"example": "jwt_vc_json"}) scope = fields.Str( required=True, metadata={"example": "UniversityDegreeCredential"} ) - format = fields.Str(required=True, metadata={"example": "jwt_vc_json"}) cryptographic_binding_methods_supported = fields.List( fields.Str(), metadata={"example": []} ) @@ -100,3 +118,14 @@ class Meta: "gpa": {"display": [{"name": "GPA"}]}, } ) + credential_definition = fields.Dict( + metadata={ + "type": ["VerifiableCredential", "UniversityDegreeCredential"], + "credentialSubject": { + "given_name": {"display": [{"name": "Given Name", "locale": "en-US"}]}, + "family_name": {"display": [{"name": "Surname", "locale": "en-US"}]}, + "degree": {}, + "gpa": {"display": [{"name": "GPA"}]}, + }, + }, + ) diff --git a/oid4vci/oid4vci/v1_0/public_routes.py b/oid4vci/oid4vci/v1_0/public_routes.py index db6ac2200..20bddf148 100644 --- a/oid4vci/oid4vci/v1_0/public_routes.py +++ b/oid4vci/oid4vci/v1_0/public_routes.py @@ -63,16 +63,16 @@ async def oid_cred_issuer(request: web.Request): public_url = OID4VCI_ENDPOINT # TODO: check for flag first # Wallet query to retrieve credential definitions - tag_filter = {"type": {"$in": ["sd_jwt", "jwt_vc_json"]}} + tag_filter = {} # {"type": {"$in": ["sd_jwt", "jwt_vc_json"]}} async with profile.session() as session: credentials_supported = await SupportedCredential.query(session, tag_filter) metadata = { "credential_issuer": f"{public_url}/", # TODO: update path with wallet id "credential_endpoint": f"{public_url}/credential", - "credentials_supported": [cred.serialize() for cred in credentials_supported], - "authorization_server": f"{public_url}/auth-server", - "batch_credential_endpoint": f"{public_url}/batch_credential", + "credentials_supported": [vars(cred) for cred in credentials_supported], + # "authorization_server": f"{public_url}/auth-server", + # "batch_credential_endpoint": f"{public_url}/batch_credential", } return web.json_response(metadata) diff --git a/oid4vci/oid4vci/v1_0/routes.py b/oid4vci/oid4vci/v1_0/routes.py index e23f2fe71..ee82e0139 100644 --- a/oid4vci/oid4vci/v1_0/routes.py +++ b/oid4vci/oid4vci/v1_0/routes.py @@ -235,7 +235,7 @@ async def get_cred_offer(request: web.BaseRequest): For example, can be used in QR-Code presented to a compliant wallet. """ # Access the query parameters in your view function - creds = request.query.get("credentials") + cred = request.query.get("credentials") # TODO: lists is not working # TODO: store with input form and retrieve from record issuer_url = getenv("OID4VCI_ENDPOINT") # issuer_url = request.query.get('credential_issuer') @@ -264,7 +264,7 @@ async def get_cred_offer(request: web.BaseRequest): # Create offer object offer = { "credential_issuer": issuer_url, - "credentials": creds, + "credentials": [cred], "grants": { "urn:ietf:params:oauth:grant-type:pre-authorized_code": { "pre-authorized_code": code, @@ -287,8 +287,7 @@ async def credential_supported_create(request: web.BaseRequest): body = await request.json() credential_definition_id = body.get("credential_definition_id") - format = body.get("format") - types = body.get("types") + _format = body.get("format") cryptographic_binding_methods_supported = body.get( "cryptographic_binding_methods_supported" ) @@ -299,13 +298,12 @@ async def credential_supported_create(request: web.BaseRequest): record = SupportedCredential( supported_cred_id=credential_definition_id, - format=format, - types=types, + format=_format, + scope=scope, cryptographic_binding_methods_supported=cryptographic_binding_methods_supported, cryptographic_suites_supported=cryptographic_suites_supported, display=display, credential_subject=credential_subject, - scope=scope, ) async with profile.session() as session: