Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
acc1f1e
add witness cache for accumulator resolution with tests
maycon-mello Mar 31, 2026
ff55b99
unify createPresentation API in web SDK with auto-select support
maycon-mello Mar 31, 2026
1286c33
Add e2e tests with performance reporting and fix witness cache to sto…
maycon-mello Mar 31, 2026
61c0f0f
Prefetch witness cache on credential add and increase TTL to 2 minutes
maycon-mello Mar 31, 2026
5073f2e
Add perf-report.json to gitignore
maycon-mello Mar 31, 2026
ba64c1a
Add removeCredential method to web SDK
maycon-mello Mar 31, 2026
27d9cde
Add compound presentation tests for integration and web e2e
maycon-mello Mar 31, 2026
9f95689
Make witness cache TTL injectable and delete stale entries on expiry
maycon-mello Apr 1, 2026
23c1831
Remove platform-specific rollup dependency breaking CI
maycon-mello Apr 1, 2026
2fc491e
Fix prettier formatting
maycon-mello Apr 1, 2026
aaf4caf
Fix credential-to-descriptor mapping in getPexRequiredAttributes
maycon-mello Apr 1, 2026
a8d6e2e
Fix credential-to-descriptor mapping in compound presentations
maycon-mello Apr 1, 2026
1ca9424
Fix switchCredential test to create presentation after switching
maycon-mello Apr 1, 2026
2124e6b
Add retry with exponential backoff to submitPresentation
maycon-mello Apr 1, 2026
c7e4560
Only retry submitPresentation on server errors and network failures
maycon-mello Apr 1, 2026
d47aa9c
Fix linting issues in verification controller
maycon-mello Apr 1, 2026
8f39197
Disable witness cache in integration tests
maycon-mello Apr 2, 2026
0b1b2cc
Disable witness cache by default
maycon-mello Apr 2, 2026
88b77ed
Enable witness cache in unit tests since default is now disabled
maycon-mello Apr 2, 2026
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
195 changes: 195 additions & 0 deletions integration-tests/verification-flow/compound-presentation.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
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 {setWitnessCacheTTL} from '@docknetwork/wallet-sdk-wasm/src/services/credential/bbs-revocation';

const allCredentials = [
{
'@context': [
'https://www.w3.org/2018/credentials/v1',
'https://ld.truvera.io/credentials/extensions-v1',
'https://ld.truvera.io/security/bbs23/v1',
{
QuotientCustomerIdentity: 'dk:QuotientCustomerIdentity',
address: 'dk:address',
age: 'dk:age',
customerID: 'dk:customerID',
dateOfBirth: 'dk:dateOfBirth',
dk: 'https://ld.truvera.io/credentials#',
fullName: 'dk:fullName',
phoneNumber: 'dk:phoneNumber',
},
],
credentialStatus: {
id: 'accumulator:cheqd:testnet:59459883-4e4d-40a0-bb4f-2b7c42405dd3:aac15524-4aff-43bd-b132-1779eb7dcf36',
type: 'DockVBAccumulator2022',
revocationCheck: 'membership',
revocationId: '79',
},
id: 'https://creds-testnet.truvera.io/76dd0f26a04b4253ac29faf08555e43a5d6329bdc6659dc35a35ee6645750b91',
type: ['VerifiableCredential', 'QuotientCustomerIdentity'],
credentialSubject: {
id: 'did:key:z6MkqEFT8w27x18qRqf7SBnd882pNWsBZPLnk5hVZfVP9AqG',
age: 51,
address: '654 Cedar Ln, Austin, TX 78701',
fullName: 'Grace Lee',
customerID: 'CIDT2CQ0E',
dateOfBirth: '1974-10-17',
phoneNumber: '+14519037960',
},
issuanceDate: '2026-03-31T13:05:53.563Z',
issuer: {
name: 'Quotient',
logo: 'https://img.truvera.io/d689827d822056c6da742080ac6c80ba',
id: 'did:cheqd:testnet:59459883-4e4d-40a0-bb4f-2b7c42405dd3',
},
credentialSchema: {
id: 'https://schema.truvera.io/QuotientCustomerIdentity-V1-1768398916249.json',
type: 'JsonSchemaValidator2018',
details:
'{"jsonSchema":{"$id":"https://schema.truvera.io/QuotientCustomerIdentity-V1-1768398916249.json","$schema":"http://json-schema.org/draft-07/schema#","additionalProperties":true,"description":"Schema to issue identity credentials for Quotient customers","name":"Quotient Customer Identity","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":{"address":{"title":"Address","type":"string"},"age":{"title":"Age","type":"number"},"customerID":{"title":"Customer ID","type":"string"},"dateOfBirth":{"format":"date","title":"Date of birth","type":"string"},"fullName":{"description":"","title":"Full Name","type":"string"},"id":{"description":"A unique identifier of the recipient. Example: DID, email address, national ID number, employee ID, student ID etc.","title":"ID","type":"string"},"phoneNumber":{"title":"Phone number","type":"string"}},"required":["fullName","age","phoneNumber","customerID"],"type":"object"},"cryptoVersion":{"type":"string"},"id":{"type":"string"},"issuanceDate":{"format":"date-time","type":"string"},"issuer":{"properties":{"id":{"type":"string"},"logo":{"type":"string"},"name":{"type":"string"}},"type":"object"},"name":{"type":"string"},"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: 'Quotient Customer Identity',
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-31T13:05:55Z',
verificationMethod:
'did:cheqd:testnet:59459883-4e4d-40a0-bb4f-2b7c42405dd3#keys-2',
proofPurpose: 'assertionMethod',
proofValue:
'z2mhJL8VK9cvvRuBqEkscjqUtXG2nCQ2oLH1NvuUT6uejKMha61Zz7ux61nui1X3cYsjc8nTmQLMgH7T5y4L8PH29eEVykbGtAT5rnxQAUjoxra',
},
'$$accum__witness$$': '{"blockNo":"d10f73a8-8aed-4e5c-be8d-24105cb494ac","witness":"0xb8ff9c2afe1753a7b455315127e402ec7357110dfda15460f8df55b474220ec5f29de9177dd60dc409751ede1d1f66fb"}',
},
{
'@context': [
'https://www.w3.org/2018/credentials/v1',
'https://ld.truvera.io/credentials/extensions-v1',
'https://ld.truvera.io/security/bbs23/v1',
{
QuotientLoyaltyCard: 'dk:QuotientLoyaltyCard',
customerID: 'dk:customerID',
customerName: 'dk:customerName',
dk: 'https://ld.truvera.io/credentials#',
loyaltyCardNumber: 'dk:loyaltyCardNumber',
},
],
credentialStatus: {
id: 'accumulator:cheqd:testnet:59459883-4e4d-40a0-bb4f-2b7c42405dd3:aac15524-4aff-43bd-b132-1779eb7dcf36',
type: 'DockVBAccumulator2022',
revocationCheck: 'membership',
revocationId: '80',
},
id: 'https://creds-testnet.truvera.io/e66ee7ff343b74248d80da9a56e32fb38b6956cdee5534fe738ef6fe44a6913a',
type: ['VerifiableCredential', 'QuotientLoyaltyCard'],
credentialSubject: {
id: 'did:key:z6MkqEFT8w27x18qRqf7SBnd882pNWsBZPLnk5hVZfVP9AqG',
customerID: 'CIDT2CQ0E',
customerName: 'Grace Lee',
loyaltyCardNumber: '6048443734212353276',
},
issuanceDate: '2026-03-31T13:05:53.563Z',
issuer: {
name: 'Quotient',
logo: 'https://img.truvera.io/d689827d822056c6da742080ac6c80ba',
id: 'did:cheqd:testnet:59459883-4e4d-40a0-bb4f-2b7c42405dd3',
},
credentialSchema: {
id: 'https://schema.truvera.io/QuotientLoyaltyCard-V1-1768398982554.json',
type: 'JsonSchemaValidator2018',
details:
'{"jsonSchema":{"$id":"https://schema.truvera.io/QuotientLoyaltyCard-V1-1768398982554.json","$schema":"http://json-schema.org/draft-07/schema#","additionalProperties":true,"description":"Schema to issue loyalty card credentials to Quotient customers","name":"Quotient Loyalty Card","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":{"customerID":{"description":"","title":"Customer ID","type":"string"},"customerName":{"title":"Customer Name","type":"string"},"id":{"description":"A unique identifier of the recipient. Example: DID, email address, national ID number, employee ID, student ID etc.","title":"ID","type":"string"},"loyaltyCardNumber":{"title":"Loyalty card number","type":"string"}},"required":["loyaltyCardNumber","customerID","customerName"],"type":"object"},"cryptoVersion":{"type":"string"},"id":{"type":"string"},"issuanceDate":{"format":"date-time","type":"string"},"issuer":{"properties":{"id":{"type":"string"},"logo":{"type":"string"},"name":{"type":"string"}},"type":"object"},"name":{"type":"string"},"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: 'Quotient Loyalty Card',
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-31T13:05:57Z',
verificationMethod:
'did:cheqd:testnet:59459883-4e4d-40a0-bb4f-2b7c42405dd3#keys-2',
proofPurpose: 'assertionMethod',
proofValue:
'z2TZXgpEqiRkAmoB8XRvZZj8KJBpgFv5M9vVj4Nm5uYAj5nw5XwDRN2gYwyVyWtyrwyBtWHbbfhfahWWZN49RwHeedJ7kEuzCrxoSU5HQAKxHPG',
},
'$$accum__witness$$': '{"blockNo":"d10f73a8-8aed-4e5c-be8d-24105cb494ac","witness":"0x935dd2dcf49a488a9aafda317abc477a8cd8c0edcfdf7f79a6fe4f51b0b352cf4d050822e8d44ecb001a8d98c7a618f2"}',
}
];

let wallet: IWallet;
let didProvider;
let credentialProvider;

describe('Default presentation', () => {
beforeAll(async () => {
setWitnessCacheTTL(0); // Disable witness cache for testing
wallet = await getWallet();
didProvider = getDIDProvider();
credentialProvider = getCredentialProvider();

await didProvider.ensureDID();
for (const credential of allCredentials) {
await credentialProvider.addCredential(credential);
}
});

afterAll(() => closeWallet());

it('should create a compound presentation with 2 credentials', async () => {
const controller = createVerificationController({
wallet,
didProvider,
credentialProvider,
});

await controller.start({
template: 'https://creds-testnet.truvera.io/proof/62f832bd-d7af-4da9-9e4f-bc7288a77d69',
});

controller.selectedCredentials.set(allCredentials[0].id, {
credential: allCredentials[0],
attributesToReveal: ['credentialSubject.age', 'credentialSubject.address'],
});

controller.selectedCredentials.set(allCredentials[1].id, {
credential: allCredentials[1],
attributesToReveal: ['credentialSubject.loyaltyCardNumber'],
});

const presentation = await controller.createPresentation();

expect(presentation).toBeDefined();
expect(presentation.type).toEqual(['VerifiablePresentation']);
expect(presentation.verifiableCredential).toBeDefined();
expect(presentation.verifiableCredential.length).toBe(2);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import universityDegree from '../data/default-presentation-tests/university-degr
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';
import {setWitnessCacheTTL} from '@docknetwork/wallet-sdk-wasm/src/services/credential/bbs-revocation';

jest.retryTimes(0);

Expand All @@ -27,6 +28,7 @@ let didProvider;

describe('Default presentation', () => {
beforeAll(async () => {
setWitnessCacheTTL(0); // Disable witness cache for testing
wallet = await getWallet();
didProvider = getDIDProvider();
const credentialProvider = getCredentialProvider();
Expand Down Expand Up @@ -207,11 +209,12 @@ describe('Default presentation', () => {
const originalCredentialId = descriptors[0].selected.id;
const replacementCredentialId = descriptors[0].alternatives[0].id;

const newPresentation = await controller.switchCredential(
await controller.switchCredential(
originalCredentialId,
replacementCredentialId,
);

const newPresentation = await controller.createPresentation();
expect(newPresentation).toBeDefined();
expect(newPresentation.type).toEqual(['VerifiablePresentation']);

Expand Down
30 changes: 15 additions & 15 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions packages/core/src/credential-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/

import {credentialServiceRPC} from '@docknetwork/wallet-sdk-wasm/src/services/credential';
import {prefetchWitnessCache} from '@docknetwork/wallet-sdk-wasm/src/services/credential/bbs-revocation';
import {IWallet, ICredentialProvider} from './types';
export type {ICredentialProvider};
import assert from 'assert';
Expand Down Expand Up @@ -203,6 +204,9 @@ export async function addCredential({wallet, credential}) {
value: acummWitness,
initialWitness: acummWitness,
});

// Pre-fetch and cache the witness blockchain data in the background
prefetchWitnessCache(credential, acummWitness);
}

syncCredentialStatus({wallet, credentialIds: [credential.id]});
Expand Down
Loading
Loading