Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 70 additions & 42 deletions integration-tests/verification-flow/bbs-plus-valid.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,54 +72,51 @@ const credential = {
},
};

const proofRequest = {
qr: 'https://creds-example.dock.io/proof/d3c0c23e-efb5-41fc-a8a9-6213507f419a',
id: 'd3c0c23e-efb5-41fc-a8a9-6213507f419a',
name: 'BasicCredential Template',
nonce: '08ec5ca2e2446b50b25a55e1b6b21f2b',
created: '2023-10-02T21:30:55.851Z',
updated: '2023-10-02T21:30:55.851Z',
verified: false,
response_url: `/proof-requests/d3c0c23e-efb5-41fc-a8a9-6213507f419a/send-presentation`,
request: {
id: '1cf6a349-f1d3-42f7-b751-8de7fb5fde6c',
input_descriptors: [
{
id: 'Credential 1',
name: 'Basic Credential (Biometrics)',
purpose: 'Basic Credential with proof of biometrics',
constraints: {
fields: [
{
path: ['$.type'],
},
{
path: [
'$.issuer.id',
'$.issuer',
'$.vc.issuer.id',
'$.vc.issuer',
'$.iss',
],
},
],
},
},
],
},
type: 'proof-request',
};

describe('BBS+ presentations', () => {
it('should verify valid bbs+ credential', async () => {
it('should verify valid bbs+ credential with explicit attributesToReveal', async () => {
const wallet: IWallet = await getWallet();
const controller = await createVerificationController({
wallet,
});

const proofRequest = {
qr: 'https://creds-example.dock.io/proof/d3c0c23e-efb5-41fc-a8a9-6213507f419a',
id: 'd3c0c23e-efb5-41fc-a8a9-6213507f419a',
name: 'BasicCredential Template',
nonce: '08ec5ca2e2446b50b25a55e1b6b21f2b',
created: '2023-10-02T21:30:55.851Z',
updated: '2023-10-02T21:30:55.851Z',
verified: false,
response_url: `/proof-requests/d3c0c23e-efb5-41fc-a8a9-6213507f419a/send-presentation`,
request: {
id: '1cf6a349-f1d3-42f7-b751-8de7fb5fde6c',
input_descriptors: [
{
id: 'Credential 1',
name: 'Basic Credential (Biometrics)',
purpose: 'Basic Credential with proof of biometrics',
constraints: {
fields: [
{
path: ['$.expirationDate'],
},
{
path: ['$.type'],
},
{
path: [
'$.issuer.id',
'$.issuer',
'$.vc.issuer.id',
'$.vc.issuer',
'$.iss',
],
},
],
},
},
],
},
type: 'proof-request',
};

await controller.start({
template: proofRequest,
});
Expand Down Expand Up @@ -147,5 +144,36 @@ describe('BBS+ presentations', () => {
expect(verificationResults.verified).toBe(true);
});

it('should generate presentation without explicit attributesToReveal', async () => {
const wallet: IWallet = await getWallet();
const controller = await createVerificationController({
wallet,
});

await controller.start({
template: proofRequest,
});

// No attributesToReveal specified - let PEX template handle it
controller.selectedCredentials.set(credential.id, {
credential: credential,
});

const presentation = await controller.createPresentation();

const verificationResults = await credentialService.verifyPresentation({
presentation,
options: {
compactProof: true,
resolver: blockchainService.resolver,
challenge: proofRequest.nonce,
unsignedPresentation: true,
domain: 'dock.io',
},
});

expect(verificationResults.verified).toBe(true);
});

afterAll(() => closeWallet());
});
13 changes: 11 additions & 2 deletions packages/core/src/verification-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ export enum VerificationStatus {
type CredentialId = string;
type CredentialSelection = {
credential: any;
/**
* Optional list of credential attributes to reveal in the presentation.
* When omitted, the credential-sdk automatically determines which attributes
* to reveal based on the PEX (Presentation Exchange) template requirements.
* This allows generating a default presentation without manual attribute selection.
*/
attributesToReveal?: string[];
};
type CredentialSelectionMap = Map<CredentialId, CredentialSelection>;
Expand Down Expand Up @@ -192,11 +198,14 @@ export function createVerificationController({
}

if (bbsKvacSelections.length > 0) {
// When attributesToReveal is undefined, the credential-sdk will automatically
// determine which attributes to reveal based on the PEX template requirements.
// This enables generating a default presentation without manual attribute selection.
const credentialsWithWitness = await Promise.all(
bbsKvacSelections.map(async sel => ({
credential: sel.credential,
witness: await credentialProvider.getMembershipWitness(sel.credential.id),
attributesToReveal: sel.attributesToReveal || [],
attributesToReveal: sel.attributesToReveal,
})),
);

Expand All @@ -221,7 +230,7 @@ export function createVerificationController({
credentials: credentialsWithWitness.map(c => ({
credential: c.credential,
witness: c.witness,
attributesToReveal: [...(c.attributesToReveal || []), 'id'],
attributesToReveal: c.attributesToReveal,
})),
});

Expand Down
4 changes: 3 additions & 1 deletion packages/wasm/src/services/credential/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -766,7 +766,9 @@ class CredentialService {
const attributesToSkip = descriptorBounds[idx]
? descriptorBounds[idx].map(bound => bound.attributeName)
: [];
const filteredAttributes = attributesToReveal.filter(
// attributesToReveal may be undefined when using default presentation generation,
// in which case only PEX-required attributes will be revealed
const filteredAttributes = (attributesToReveal || []).filter(
attribute => !attributesToSkip.includes(attribute) && !shouldSkipAttribute(attribute),
);
const _pexRequiredAttributes = pexRequiredAttributes[idx] || [];
Expand Down
Loading