diff --git a/integration-tests/data/default-presentation-tests/equinet-credit-score.json b/integration-tests/data/default-presentation-tests/equinet-credit-score.json
new file mode 100644
index 00000000..ea62e965
--- /dev/null
+++ b/integration-tests/data/default-presentation-tests/equinet-credit-score.json
@@ -0,0 +1,60 @@
+{
+ "@context": [
+ "https://www.w3.org/2018/credentials/v1",
+ "https://ld.truvera.io/credentials/extensions-v1",
+ "https://ld.truvera.io/security/bbs23/v1",
+ {
+ "EquiNetCreditScore": "dk:EquiNetCreditScore",
+ "credit_score": "dk:credit_score",
+ "dk": "https://ld.truvera.io/credentials#"
+ },
+ "https://ld.truvera.io/credentials/prettyvc"
+ ],
+ "credentialStatus": {
+ "id": "accumulator:cheqd:testnet:c0890f1c-c7bb-4ea6-be7a-8c31404743b7:d486206d-a051-4175-9700-40592f14684a",
+ "type": "DockVBAccumulator2022",
+ "revocationCheck": "membership",
+ "revocationId": "1"
+ },
+ "id": "https://creds-staging.truvera.io/ff134a47f7649de2eae4b0ae912b35ba1f00deae565c34b3b2f89444319a7eea",
+ "type": [
+ "VerifiableCredential",
+ "EquiNetCreditScore",
+ "PrettyVerifiableCredential"
+ ],
+ "credentialSubject": {
+ "id": "did:key:z6Mku9R8zdA8LD6hcFXkn47jLnfcKZNGmwaTrDnaCBkSb8Un",
+ "credit_score": 200
+ },
+ "issuanceDate": "2026-03-26T19:10:51.355Z",
+ "issuer": "did:cheqd:testnet:c0890f1c-c7bb-4ea6-be7a-8c31404743b7",
+ "credentialSchema": {
+ "id": "https://schema.truvera.io/EquiNetCreditScore-V2-1738609162316.json",
+ "type": "JsonSchemaValidator2018",
+ "details": "{\"jsonSchema\":{\"$id\":\"https://schema.truvera.io/EquiNetCreditScore-V2-1738609162316.json\",\"$schema\":\"http://json-schema.org/draft-07/schema#\",\"additionalProperties\":true,\"description\":\"This schema represents a Verified Credit Score Credential, issued by EquiNet. It standardizes the presentation of credit scores for reliable and efficient verification processes.\",\"name\":\"EquiNet - Credit Score\",\"properties\":{\"@context\":{\"type\":\"string\"},\"credentialSchema\":{\"properties\":{\"details\":{\"type\":\"string\"},\"id\":{\"type\":\"string\"},\"type\":{\"type\":\"string\"},\"version\":{\"type\":\"string\"}},\"type\":\"object\"},\"credentialStatus\":{\"properties\":{\"id\":{\"type\":\"string\"},\"revocationCheck\":{\"type\":\"string\"},\"revocationId\":{\"type\":\"string\"},\"type\":{\"type\":\"string\"}},\"type\":\"object\"},\"credentialSubject\":{\"properties\":{\"credit_score\":{\"description\":\"This attribute represents the individual's credit score as a numerical value.\",\"title\":\"credit_score\",\"type\":\"number\"},\"id\":{\"description\":\"A unique identifier of the recipient. Example: DID, email address, national ID number, employee ID, student ID etc. If you enter the recipient's DID, the person will automatically receive the credential in their Dock wallet.\",\"title\":\"ID\",\"type\":\"string\"}},\"required\":[\"credit_score\"],\"type\":\"object\"},\"cryptoVersion\":{\"type\":\"string\"},\"id\":{\"type\":\"string\"},\"issuanceDate\":{\"format\":\"date-time\",\"type\":\"string\"},\"issuer\":{\"type\":\"string\"},\"name\":{\"type\":\"string\"},\"prettyVC\":{\"properties\":{\"orientation\":{\"type\":\"string\"},\"proof\":{\"type\":\"string\"},\"size\":{\"type\":\"string\"},\"type\":{\"type\":\"string\"}},\"type\":\"object\"},\"proof\":{\"properties\":{\"@context\":{\"items\":[{\"properties\":{\"proof\":{\"properties\":{\"@container\":{\"type\":\"string\"},\"@id\":{\"type\":\"string\"},\"@type\":{\"type\":\"string\"}},\"type\":\"object\"},\"sec\":{\"type\":\"string\"}},\"type\":\"object\"},{\"type\":\"string\"}],\"type\":\"array\"},\"created\":{\"format\":\"date-time\",\"type\":\"string\"},\"proofPurpose\":{\"type\":\"string\"},\"type\":{\"type\":\"string\"},\"verificationMethod\":{\"type\":\"string\"}},\"type\":\"object\"},\"type\":{\"type\":\"string\"}},\"type\":\"object\"},\"parsingOptions\":{\"defaultDecimalPlaces\":4,\"defaultMinimumDate\":-17592186044415,\"defaultMinimumInteger\":-4294967295,\"useDefaults\":true}}",
+ "version": "0.4.0"
+ },
+ "name": "EquiNet - Credit Score",
+ "prettyVC": {
+ "type": "liquid",
+ "orientation": "landscape",
+ "size": "a4",
+ "proof": "
Issued by: {{issuer.name}}
for completing the {{credential.name}}
Issued on {{credential.issuanceDate | date: \"%B %d, %Y\"}}
"
+ },
+ "cryptoVersion": "0.6.0",
+ "proof": {
+ "@context": [
+ {
+ "sec": "https://w3id.org/security#",
+ "proof": {"@id": "sec:proof", "@type": "@id", "@container": "@graph"}
+ },
+ "https://ld.truvera.io/security/bbs23/v1"
+ ],
+ "type": "Bls12381BBSSignatureDock2023",
+ "created": "2026-03-26T19:11:36Z",
+ "verificationMethod": "did:cheqd:testnet:c0890f1c-c7bb-4ea6-be7a-8c31404743b7#keys-2",
+ "proofPurpose": "assertionMethod",
+ "proofValue": "z2dwGNLsM2XsjsVk78KPB7a8KKpaUkzLrZ1Xxq79cqr2m6gxjtXxQRhug3Y4zdv241SxvmwGk178xAsJwQTDTP2MzuCHFZbFTQX3oktLMFCkMfi"
+ },
+ "$$accum__witness$$": "{\"blockNo\":\"6e1b9610-a0b6-46de-8e20-2f60625e5eae\",\"witness\":\"0x8bc63d0ce34feb8d92c86833b2e6a9b9948ed327756537eecf2b34184f8e5f944a776fbb4c20c2c33a21c4a466d4db8e\"}"
+}
diff --git a/integration-tests/data/default-presentation-tests/university-degree-2.json b/integration-tests/data/default-presentation-tests/university-degree-2.json
new file mode 100644
index 00000000..35af5756
--- /dev/null
+++ b/integration-tests/data/default-presentation-tests/university-degree-2.json
@@ -0,0 +1,67 @@
+{
+ "@context": [
+ "https://www.w3.org/2018/credentials/v1",
+ "https://ld.truvera.io/credentials/extensions-v1",
+ "https://ld.truvera.io/security/bbs23/v1",
+ {
+ "UniversityDegree": "dk:UniversityDegree",
+ "awardedDate": "dk:awardedDate",
+ "dateOfBirth": "dk:dateOfBirth",
+ "degreeName": "dk:degreeName",
+ "degreeType": "dk:degreeType",
+ "dk": "https://ld.truvera.io/credentials#"
+ },
+ "https://ld.truvera.io/credentials/prettyvc"
+ ],
+ "credentialStatus": {
+ "id": "accumulator:cheqd:testnet:c0890f1c-c7bb-4ea6-be7a-8c31404743b7:d486206d-a051-4175-9700-40592f14684a",
+ "type": "DockVBAccumulator2022",
+ "revocationCheck": "membership",
+ "revocationId": "3"
+ },
+ "id": "https://creds-staging.truvera.io/43996053f6bca27d9e6a2cc9e469ad4c39dc61d982366af5d4a27f34277c99c6",
+ "type": [
+ "VerifiableCredential",
+ "UniversityDegree",
+ "PrettyVerifiableCredential"
+ ],
+ "credentialSubject": {
+ "id": "did:key:z6Mku9R8zdA8LD6hcFXkn47jLnfcKZNGmwaTrDnaCBkSb8Un",
+ "degreeName": "University Degree 3",
+ "degreeType": "Degree 3",
+ "awardedDate": "2026-03-19",
+ "name": "Tester",
+ "dateOfBirth": "2012-06-26"
+ },
+ "issuanceDate": "2026-03-26T19:17:34.530Z",
+ "issuer": "did:cheqd:testnet:c0890f1c-c7bb-4ea6-be7a-8c31404743b7",
+ "credentialSchema": {
+ "id": "https://schema.truvera.io/UniversityDegree-V1-1703767509472.json",
+ "type": "JsonSchemaValidator2018",
+ "details": "{\"jsonSchema\":{\"$id\":\"https://schema.truvera.io/UniversityDegree-V1-1703767509472.json\",\"$schema\":\"http://json-schema.org/draft-07/schema#\",\"additionalProperties\":true,\"description\":\"A representation of a university degree issued to a person\",\"name\":\"University Degree\",\"properties\":{\"@context\":{\"type\":\"string\"},\"credentialSchema\":{\"properties\":{\"details\":{\"type\":\"string\"},\"id\":{\"type\":\"string\"},\"type\":{\"type\":\"string\"},\"version\":{\"type\":\"string\"}},\"type\":\"object\"},\"credentialStatus\":{\"properties\":{\"id\":{\"type\":\"string\"},\"revocationCheck\":{\"type\":\"string\"},\"revocationId\":{\"type\":\"string\"},\"type\":{\"type\":\"string\"}},\"type\":\"object\"},\"credentialSubject\":{\"properties\":{\"awardedDate\":{\"description\":\"The date the degree was awarded.\",\"format\":\"date\",\"title\":\"Awarded Date\",\"type\":\"string\"},\"dateOfBirth\":{\"description\":\"The person's date of birth.\",\"format\":\"date\",\"title\":\"Date of Birth\",\"type\":\"string\"},\"degreeName\":{\"description\":\"The full degree name and field.\",\"title\":\"Degree Name\",\"type\":\"string\"},\"degreeType\":{\"description\":\"The type of degree earned.\",\"title\":\"Degree Type\",\"type\":\"string\"},\"id\":{\"description\":\"The recipient’s identifier that will be stored in the credential\",\"title\":\"Recipient ID\",\"type\":\"string\"},\"name\":{\"description\":\"The person's full name.\",\"title\":\"Full Name\",\"type\":\"string\"}},\"required\":[\"name\",\"awardedDate\"],\"type\":\"object\"},\"cryptoVersion\":{\"type\":\"string\"},\"id\":{\"type\":\"string\"},\"issuanceDate\":{\"format\":\"date-time\",\"type\":\"string\"},\"issuer\":{\"type\":\"string\"},\"name\":{\"type\":\"string\"},\"prettyVC\":{\"properties\":{\"orientation\":{\"type\":\"string\"},\"proof\":{\"type\":\"string\"},\"size\":{\"type\":\"string\"},\"type\":{\"type\":\"string\"}},\"type\":\"object\"},\"proof\":{\"properties\":{\"@context\":{\"items\":[{\"properties\":{\"proof\":{\"properties\":{\"@container\":{\"type\":\"string\"},\"@id\":{\"type\":\"string\"},\"@type\":{\"type\":\"string\"}},\"type\":\"object\"},\"sec\":{\"type\":\"string\"}},\"type\":\"object\"},{\"type\":\"string\"}],\"type\":\"array\"},\"created\":{\"format\":\"date-time\",\"type\":\"string\"},\"proofPurpose\":{\"type\":\"string\"},\"type\":{\"type\":\"string\"},\"verificationMethod\":{\"type\":\"string\"}},\"type\":\"object\"},\"type\":{\"type\":\"string\"}},\"type\":\"object\"},\"parsingOptions\":{\"defaultDecimalPlaces\":4,\"defaultMinimumDate\":-17592186044415,\"defaultMinimumInteger\":-4294967295,\"useDefaults\":true}}",
+ "version": "0.4.0"
+ },
+ "name": "University Degree",
+ "prettyVC": {
+ "type": "liquid",
+ "orientation": "landscape",
+ "size": "a4",
+ "proof": "Issued by: {{issuer.name}}
for completing the {{credential.name}}
Issued on {{credential.issuanceDate | date: \"%B %d, %Y\"}}
"
+ },
+ "cryptoVersion": "0.6.0",
+ "proof": {
+ "@context": [
+ {
+ "sec": "https://w3id.org/security#",
+ "proof": {"@id": "sec:proof", "@type": "@id", "@container": "@graph"}
+ },
+ "https://ld.truvera.io/security/bbs23/v1"
+ ],
+ "type": "Bls12381BBSSignatureDock2023",
+ "created": "2026-03-26T19:18:18Z",
+ "verificationMethod": "did:cheqd:testnet:c0890f1c-c7bb-4ea6-be7a-8c31404743b7#keys-2",
+ "proofPurpose": "assertionMethod",
+ "proofValue": "z2fSzqajdYmaizLGHPaQyAfuzRyK8AR8XaXFf6ukkUecZHJtJ8SRNbCc1oj7HVmC1TXgFVuVdLM7LrxwcjAY8Xkk3WrqnjVPiH11hL8rwfbZifa"
+ },
+ "$$accum__witness$$": "{\"blockNo\":\"6e1b9610-a0b6-46de-8e20-2f60625e5eae\",\"witness\":\"0x900cce5b36f88006097221efbcf6ef1a7beca2a8d2009235733ece8e31b2e40e22384bdd7206c3c33844557c63161fff\"}"
+}
diff --git a/integration-tests/data/default-presentation-tests/university-degree.json b/integration-tests/data/default-presentation-tests/university-degree.json
new file mode 100644
index 00000000..3857bba8
--- /dev/null
+++ b/integration-tests/data/default-presentation-tests/university-degree.json
@@ -0,0 +1,69 @@
+{
+ "@context": [
+ "https://www.w3.org/2018/credentials/v1",
+ "https://ld.truvera.io/credentials/extensions-v1",
+ "https://ld.truvera.io/security/bbs23/v1",
+ {
+ "UniversityDegree": "dk:UniversityDegree",
+ "additionalDistinctions": "dk:additionalDistinctions",
+ "awardedDate": "dk:awardedDate",
+ "dateOfBirth": "dk:dateOfBirth",
+ "degreeName": "dk:degreeName",
+ "degreeType": "dk:degreeType",
+ "dk": "https://ld.truvera.io/credentials#"
+ },
+ "https://ld.truvera.io/credentials/prettyvc"
+ ],
+ "credentialStatus": {
+ "id": "accumulator:cheqd:testnet:c0890f1c-c7bb-4ea6-be7a-8c31404743b7:d486206d-a051-4175-9700-40592f14684a",
+ "type": "DockVBAccumulator2022",
+ "revocationCheck": "membership",
+ "revocationId": "2"
+ },
+ "id": "https://creds-staging.truvera.io/f2c3ffa4b226b97278372a0687feb36351c6472c644d44ff3406fcc7e371b7b8",
+ "type": [
+ "VerifiableCredential",
+ "UniversityDegree",
+ "PrettyVerifiableCredential"
+ ],
+ "credentialSubject": {
+ "id": "did:key:z6Mku9R8zdA8LD6hcFXkn47jLnfcKZNGmwaTrDnaCBkSb8Un",
+ "degreeName": "Test",
+ "degreeType": "Test",
+ "awardedDate": "2026-03-26",
+ "name": "Tester",
+ "dateOfBirth": "2014-06-18",
+ "additionalDistinctions": "Test"
+ },
+ "issuanceDate": "2026-03-26T19:14:06.392Z",
+ "issuer": "did:cheqd:testnet:c0890f1c-c7bb-4ea6-be7a-8c31404743b7",
+ "credentialSchema": {
+ "id": "https://schema.truvera.io/UniversityDegree-V1-1703767509472.json",
+ "type": "JsonSchemaValidator2018",
+ "details": "{\"jsonSchema\":{\"$id\":\"https://schema.truvera.io/UniversityDegree-V1-1703767509472.json\",\"$schema\":\"http://json-schema.org/draft-07/schema#\",\"additionalProperties\":true,\"description\":\"A representation of a university degree issued to a person\",\"name\":\"University Degree\",\"properties\":{\"@context\":{\"type\":\"string\"},\"credentialSchema\":{\"properties\":{\"details\":{\"type\":\"string\"},\"id\":{\"type\":\"string\"},\"type\":{\"type\":\"string\"},\"version\":{\"type\":\"string\"}},\"type\":\"object\"},\"credentialStatus\":{\"properties\":{\"id\":{\"type\":\"string\"},\"revocationCheck\":{\"type\":\"string\"},\"revocationId\":{\"type\":\"string\"},\"type\":{\"type\":\"string\"}},\"type\":\"object\"},\"credentialSubject\":{\"properties\":{\"additionalDistinctions\":{\"description\":\"The person's additional distinctions.\",\"title\":\"Additional Distinctions\",\"type\":\"string\"},\"awardedDate\":{\"description\":\"The date the degree was awarded.\",\"format\":\"date\",\"title\":\"Awarded Date\",\"type\":\"string\"},\"dateOfBirth\":{\"description\":\"The person's date of birth.\",\"format\":\"date\",\"title\":\"Date of Birth\",\"type\":\"string\"},\"degreeName\":{\"description\":\"The full degree name and field.\",\"title\":\"Degree Name\",\"type\":\"string\"},\"degreeType\":{\"description\":\"The type of degree earned.\",\"title\":\"Degree Type\",\"type\":\"string\"},\"id\":{\"description\":\"The recipient’s identifier that will be stored in the credential\",\"title\":\"Recipient ID\",\"type\":\"string\"},\"name\":{\"description\":\"The person's full name.\",\"title\":\"Full Name\",\"type\":\"string\"}},\"required\":[\"name\",\"awardedDate\"],\"type\":\"object\"},\"cryptoVersion\":{\"type\":\"string\"},\"id\":{\"type\":\"string\"},\"issuanceDate\":{\"format\":\"date-time\",\"type\":\"string\"},\"issuer\":{\"type\":\"string\"},\"name\":{\"type\":\"string\"},\"prettyVC\":{\"properties\":{\"orientation\":{\"type\":\"string\"},\"proof\":{\"type\":\"string\"},\"size\":{\"type\":\"string\"},\"type\":{\"type\":\"string\"}},\"type\":\"object\"},\"proof\":{\"properties\":{\"@context\":{\"items\":[{\"properties\":{\"proof\":{\"properties\":{\"@container\":{\"type\":\"string\"},\"@id\":{\"type\":\"string\"},\"@type\":{\"type\":\"string\"}},\"type\":\"object\"},\"sec\":{\"type\":\"string\"}},\"type\":\"object\"},{\"type\":\"string\"}],\"type\":\"array\"},\"created\":{\"format\":\"date-time\",\"type\":\"string\"},\"proofPurpose\":{\"type\":\"string\"},\"type\":{\"type\":\"string\"},\"verificationMethod\":{\"type\":\"string\"}},\"type\":\"object\"},\"type\":{\"type\":\"string\"}},\"type\":\"object\"},\"parsingOptions\":{\"defaultDecimalPlaces\":4,\"defaultMinimumDate\":-17592186044415,\"defaultMinimumInteger\":-4294967295,\"useDefaults\":true}}",
+ "version": "0.4.0"
+ },
+ "name": "University Degree",
+ "prettyVC": {
+ "type": "liquid",
+ "orientation": "landscape",
+ "size": "a4",
+ "proof": "Issued by: {{issuer.name}}
for completing the {{credential.name}}
Issued on {{credential.issuanceDate | date: \"%B %d, %Y\"}}
"
+ },
+ "cryptoVersion": "0.6.0",
+ "proof": {
+ "@context": [
+ {
+ "sec": "https://w3id.org/security#",
+ "proof": {"@id": "sec:proof", "@type": "@id", "@container": "@graph"}
+ },
+ "https://ld.truvera.io/security/bbs23/v1"
+ ],
+ "type": "Bls12381BBSSignatureDock2023",
+ "created": "2026-03-26T19:15:07Z",
+ "verificationMethod": "did:cheqd:testnet:c0890f1c-c7bb-4ea6-be7a-8c31404743b7#keys-2",
+ "proofPurpose": "assertionMethod",
+ "proofValue": "z2a6ngYYzpYKWETZYemNJ1U3hVTbZ8nnbwuuzuV6vY3hmV337rL8xaQ2yS48YR2QC9DfRMchs12hoCxeJjxoB9LKqPLPFu59tx4hGNaL45vdPRh"
+ },
+ "$$accum__witness$$": "{\"blockNo\":\"6e1b9610-a0b6-46de-8e20-2f60625e5eae\",\"witness\":\"0xafc625dd441a5b5e9da4460f7734c2d7e163cc6496f5d677121b9b4feb66ad8c1ffddafef641bbd5d0776d54630015fe\"}"
+}
diff --git a/integration-tests/verification-flow/cheqd-revocation.test.ts b/integration-tests/verification-flow/cheqd-revocation.test.ts
index d0c42687..27e677e2 100644
--- a/integration-tests/verification-flow/cheqd-revocation.test.ts
+++ b/integration-tests/verification-flow/cheqd-revocation.test.ts
@@ -9,7 +9,10 @@ import {createVerificationController} from '@docknetwork/wallet-sdk-core/src/ver
import {ProofTemplateIds, createProofRequest} from '../helpers/certs-helpers';
import { cheqdRevocationCredential } from './bbs-plus-revocation-credentials';
-describe('BBS+ revocation cheqd', () => {
+jest.retryTimes(5);
+
+// Skipped: will be handled in https://dock-team.atlassian.net/browse/DCKA-5410
+describe.skip('BBS+ revocation cheqd', () => {
it('should verify a revokable bbs+ credential issued on cheqd', async () => {
const wallet: IWallet = await getWallet();
diff --git a/integration-tests/verification-flow/default-presentation.test.ts b/integration-tests/verification-flow/default-presentation.test.ts
new file mode 100644
index 00000000..d8d2a4c8
--- /dev/null
+++ b/integration-tests/verification-flow/default-presentation.test.ts
@@ -0,0 +1,129 @@
+import {IWallet} from '@docknetwork/wallet-sdk-core/lib/types';
+import {
+ closeWallet,
+ getWallet,
+ getDIDProvider,
+ getCredentialProvider,
+} from '../helpers/wallet-helpers';
+import {createVerificationController} from '@docknetwork/wallet-sdk-core/src/verification-controller';
+import universityDegree from '../data/default-presentation-tests/university-degree.json';
+import universityDegree2 from '../data/default-presentation-tests/university-degree-2.json';
+import equinetCreditScore from '../data/default-presentation-tests/equinet-credit-score.json';
+import {createProofRequest} from '../helpers/certs-helpers';
+
+jest.retryTimes(0);
+
+// Request a university degree and reveal dateOfBirth
+const template1 = '91138d81-1b54-4955-a5bc-4e2d90d8f7b1';
+// 1 range proof credential is requested, creditScore greater than 50
+const template2 = 'a7786f42-03ee-4f49-80b8-ce3027b5a903';
+// Any credential with dateOfBirth is revealed
+const template3 = 'a3e775bb-aaab-4489-b31b-746dc74f76c5';
+// 2 range proofs
+const template4 = '9b434ed1-3b65-4b7c-b678-afc7e218f063';
+
+let wallet: IWallet;
+let didProvider;
+
+describe('Default presentation', () => {
+ beforeAll(async () => {
+ wallet = await getWallet();
+ didProvider = getDIDProvider();
+ const credentialProvider = getCredentialProvider();
+
+ await didProvider.ensureDID();
+ await credentialProvider.addCredential(universityDegree);
+ await credentialProvider.addCredential(universityDegree2);
+ await credentialProvider.addCredential(equinetCreditScore);
+ });
+
+ afterAll(() => closeWallet());
+
+ it('should create a default presentation for university degree', async () => {
+ const proofRequest = await createProofRequest(template1);
+
+ const controller = createVerificationController({
+ wallet,
+ didProvider,
+ });
+
+ await controller.start({
+ template: proofRequest,
+ });
+
+ const presentation = await controller.createDefaultPresentation();
+
+ expect(presentation).toBeDefined();
+ expect(presentation.type).toEqual(['VerifiablePresentation']);
+ expect(presentation.verifiableCredential).toBeDefined();
+ expect(presentation.verifiableCredential.length).toBe(1);
+
+ const result = controller.evaluatePresentation(presentation);
+
+ expect(result.isValid).toBe(true);
+ expect(result.errors).toHaveLength(0);
+ });
+
+ it('should create a default presentation with range proof', async () => {
+ const proofRequest = await createProofRequest(template2);
+
+ const controller = createVerificationController({
+ wallet,
+ didProvider,
+ });
+
+ await controller.start({
+ template: proofRequest,
+ });
+
+ const presentation = await controller.createDefaultPresentation();
+
+ expect(presentation).toBeDefined();
+ expect(presentation.type).toEqual(['VerifiablePresentation']);
+ expect(presentation.verifiableCredential).toBeDefined();
+ expect(presentation.verifiableCredential.length).toBe(1);
+
+ });
+
+ it('should create a default presentation for any credential with dateOfBirth', async () => {
+ const proofRequest = await createProofRequest(template3);
+
+ const controller = createVerificationController({
+ wallet,
+ didProvider,
+ });
+
+ await controller.start({
+ template: proofRequest,
+ });
+
+ const presentation = await controller.createDefaultPresentation();
+
+ expect(presentation).toBeDefined();
+ expect(presentation.type).toEqual(['VerifiablePresentation']);
+ expect(presentation.verifiableCredential).toBeDefined();
+ expect(presentation.verifiableCredential.length).toBe(1);
+
+ });
+
+ it('should create a default presentation with 2 range proofs', async () => {
+ const proofRequest = await createProofRequest(template4);
+
+ const controller = createVerificationController({
+ wallet,
+ didProvider,
+ });
+
+ await controller.start({
+ template: proofRequest,
+ });
+
+ const presentation = await controller.createDefaultPresentation();
+
+ expect(presentation).toBeDefined();
+ expect(presentation.type).toEqual(['VerifiablePresentation']);
+ expect(presentation.verifiableCredential).toBeDefined();
+ expect(presentation.verifiableCredential.length).toBeGreaterThanOrEqual(1);
+
+ });
+});
diff --git a/packages/core/src/verification-controller.test.ts b/packages/core/src/verification-controller.test.ts
index 794f7506..68849639 100644
--- a/packages/core/src/verification-controller.test.ts
+++ b/packages/core/src/verification-controller.test.ts
@@ -90,6 +90,29 @@ describe('Verification provider', () => {
expect(result.isValid).toBe(true);
});
+ it('expect to create a default presentation using filtered credentials', async () => {
+ const controller = createVerificationController({
+ wallet,
+ didProvider,
+ });
+
+ await controller.start({
+ template: anyCredentialProofRequest,
+ });
+
+ const credentials = controller.getFilteredCredentials();
+
+ const presentation = await controller.createDefaultPresentation();
+
+ expect(presentation.credentials[0]).toStrictEqual(credentials[0]);
+ expect(presentation.type).toEqual(['VerifiablePresentation']);
+
+ // validate the presentation
+ const result = await controller.evaluatePresentation(presentation);
+
+ expect(result.isValid).toBe(true);
+ });
+
it('expect to generate presentation iiw credential', async () => {
const controller = createVerificationController({
wallet,
diff --git a/packages/core/src/verification-controller.ts b/packages/core/src/verification-controller.ts
index ef499f14..bdcc959d 100644
--- a/packages/core/src/verification-controller.ts
+++ b/packages/core/src/verification-controller.ts
@@ -52,6 +52,7 @@ export function createVerificationController({
*/
let statusData = null;
let filteredCredentials = [];
+ let filteredMatches = [];
let selectedCredentials: CredentialSelectionMap = new Map();
let selectedDID = null;
@@ -110,6 +111,7 @@ export function createVerificationController({
});
filteredCredentials = result.verifiableCredential;
+ filteredMatches = result.matches || [];
} catch (err) {
console.error(
`Unable to filter credentials using the template: \n ${JSON.stringify(
@@ -171,6 +173,67 @@ export function createVerificationController({
});
}
+ async function createDefaultPresentation() {
+ assert(filteredCredentials.length > 0, 'No filtered credentials available');
+
+ selectedCredentials.clear();
+
+ if (filteredMatches.length > 0) {
+ // Group matches by requirement: matches with distinct `from` values are separate requirements,
+ // matches without `from` sharing the same name/id are alternatives for the same requirement
+ const requirements: Array = [];
+ const groupKey = (match) => match.from ? JSON.stringify(match.from) : (match.name || match.id || '');
+ const seen = new Map();
+
+ for (const match of filteredMatches) {
+ const key = groupKey(match);
+ if (match.from || !seen.has(key)) {
+ // Distinct requirement: new `from` group or first match without `from`
+ seen.set(key, requirements.length);
+ requirements.push([match]);
+ } else {
+ // Alternative for an existing requirement
+ requirements[seen.get(key)].push(match);
+ }
+ }
+
+ // Select one credential per requirement
+ for (const group of requirements) {
+ // Collect all candidate indices from the group
+ const candidates: number[] = [];
+ for (const match of group) {
+ for (const path of match.vc_path || []) {
+ const indexMatch = path.match(/\[(\d+)\]/);
+ if (indexMatch) {
+ candidates.push(parseInt(indexMatch[1], 10));
+ }
+ }
+ }
+
+ // Pick the first candidate not already selected, or fall back to the first
+ const chosen = candidates.find(idx => {
+ const cred = filteredCredentials[idx];
+ return cred && !selectedCredentials.has(cred.id);
+ }) ?? candidates[0];
+
+ if (chosen !== undefined) {
+ const credential = filteredCredentials[chosen];
+ if (credential) {
+ selectedCredentials.set(credential.id, { credential });
+ }
+ }
+ }
+ } else {
+ for (const credential of filteredCredentials) {
+ selectedCredentials.set(credential.id, { credential });
+ }
+ }
+
+ assert(selectedCredentials.size > 0, 'No credentials could be selected for the presentation');
+
+ return createPresentation();
+ }
+
async function createPresentation() {
assert(!!selectedDID, 'No DID selected');
assert(!!selectedCredentials.size, 'No credentials selected');
@@ -209,8 +272,8 @@ export function createVerificationController({
})),
);
- // Pure BBS+/KVAC: use generatePresentationFromPex end-to-end
- if (sdJwtSelections.length === 0 && regularSelections.length === 0) {
+ // Single BBS+/KVAC credential: use generatePresentationFromPex end-to-end
+ if (credentialsWithWitness.length === 1 && sdJwtSelections.length === 0 && regularSelections.length === 0) {
return credentialServiceRPC.generatePresentationFromPex({
credentials: credentialsWithWitness,
pexRequest: templateJSON.request,
@@ -223,16 +286,20 @@ export function createVerificationController({
});
}
- // Mixed: derive BBS+/KVAC, then combine with SD-JWT and regular
- const derivedCredentials =
- await credentialServiceRPC.deriveVCFromPresentation({
- proofRequest: templateJSON,
- credentials: credentialsWithWitness.map(c => ({
- credential: c.credential,
- witness: c.witness,
- attributesToReveal: c.attributesToReveal,
- })),
- });
+ // Multiple BBS+/KVAC or mixed: derive each BBS+/KVAC credential separately, then assemble
+ const derivedResults = await Promise.all(
+ credentialsWithWitness.map(c =>
+ credentialServiceRPC.deriveVCFromPresentation({
+ proofRequest: templateJSON,
+ credentials: [{
+ credential: c.credential,
+ witness: c.witness,
+ attributesToReveal: c.attributesToReveal,
+ }],
+ }),
+ ),
+ );
+ const derivedCredentials = derivedResults.flat();
const nonBbsCredentials = await deriveNonBbsCredentials(sdJwtSelections, regularSelections);
return assembleSignedPresentation(
@@ -272,7 +339,7 @@ export function createVerificationController({
*/
function evaluatePresentation(presentation) {
const definition = getPresentationDefinition();
- const result = credentialServiceRPC.evaluatePresentation({
+ const result = pexService.evaluatePresentation({
presentation,
presentationDefinition: definition,
});
@@ -304,6 +371,7 @@ export function createVerificationController({
isBBSPlusCredential,
loadCredentials,
getFilteredCredentials,
+ createDefaultPresentation,
createPresentation,
evaluatePresentation,
getTemplateJSON() {