Skip to content
Open
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
3 changes: 3 additions & 0 deletions lib/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,5 +135,8 @@ config.wallet = {
// only derived proof is allowed in presentation
proofValuePrefix: 'u2V0Dh'
}]
},
debug: {
queryByExample: false // Default to false, let debug.js handle detection
}
};
28 changes: 28 additions & 0 deletions lib/debug.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import {config} from '@bedrock/web';

const isDebugEnabled = () => {
// Check config first
if(config.wallet?.debug?.queryByExample) {
return true;
}

// Node.js environment
if(typeof process !== 'undefined' &&
process.env?.DEBUG_QUERY_BY_EXAMPLE === 'true') {
return true;
}

// Browser environment
if(typeof window !== 'undefined' &&
window.DEBUG_QUERY_BY_EXAMPLE === true) {
return true;
}

return false;
};

export function debugLog(...args) {
if(isDebugEnabled()) {
console.log('[QBE DEBUG]', ...args);
}
}
3 changes: 2 additions & 1 deletion lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,13 @@ import * as exchanges from './exchanges/index.js';
import * as helpers from './helpers.js';
import * as inbox from './inbox.js';
import * as presentations from './presentations.js';
import * as queryByExample from './queryByExample.js';
import * as users from './users.js';
import * as validator from './validator.js';
import * as zcap from './zcap.js';
export {
ageCredentialHelpers, capabilities, cryptoSuites, exchanges,
helpers, inbox, presentations, users, validator, zcap
helpers, inbox, presentations, queryByExample, users, validator, zcap
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something minor to consider here about this export:

Our long term goal is to move the queryByExample code to a separate module where anyone could import that API (from there) if desired. However, once we do that, we'd have this API surface here (if we continue to export this), that we will have to do backwards compatible support for until we do a major release to remove it. I expect that we're exporting this now for testing purposes.

I think we'd probably export it with an underscore _queryByExample to signal this (and leave a comment that it is exposed for testing purposes only) ... and we wouldn't mention exposing this in API in the changelog. We can make that change now if you'd like, or we can just support it until we do a major change in the future -- it's not that big of a deal, but worth keeping this sort of future planning in mind when exporting new API, so thought I'd mention it.

};
export {
getCredentialStore, getProfileEdvClient, initialize, profileManager
Expand Down
27 changes: 24 additions & 3 deletions lib/presentations.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ import {createDiscloseCryptosuite as createBbsDiscloseCryptosuite} from
import {createDiscloseCryptosuite as createEcdsaSdDiscloseCryptosuite} from
'@digitalbazaar/ecdsa-sd-2023-cryptosuite';
import {DataIntegrityProof} from '@digitalbazaar/data-integrity';
import {debugLog} from './debug.js';
import {documentLoader} from './documentLoader.js';
import {ensureLocalCredentials} from './ageCredentialHelpers.js';
import jsonpointer from 'json-pointer';
import {matchCredentials} from './queryByExample.js';
import {profileManager} from './state.js';
import {supportedSuites} from './cryptoSuites.js';
import {v4 as uuid} from 'uuid';
Expand Down Expand Up @@ -389,8 +391,25 @@ async function _getMatches({
// match any open badge achievement ID
// FIXME: add more generalized matching
result.matches = matches
.filter(_matchContextFilter({credentialQuery}))
.filter(_openBadgeFilter({credentialQuery}));
.filter(_matchContextFilter({credentialQuery}));

// Full query by example matching implemented via queryByExample module
// Process all credentials at once for efficiency
if(credentialQuery?.example) {

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change

const allContents = result.matches.map(match => match.record.content);
const matchingContents = matchCredentials({
credentials: allContents, queryByExample: credentialQuery
});

// Map results back to original records using reference comparison
result.matches = result.matches.filter(match =>
matchingContents.includes(match.record.content)
);
Comment on lines +406 to +408
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style fix and could be more efficient:

Suggested change
result.matches = result.matches.filter(match =>
matchingContents.includes(match.record.content)
);
const contentSet = new Set(matchingContents);
result.matches = result.matches.filter(
match => contentSet.has(match.record.content));

}

result.matches =
result.matches.filter(_openBadgeFilter({credentialQuery}));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
result.matches.filter(_openBadgeFilter({credentialQuery}));
result.matches.filter(_openBadgeFilter({credentialQuery}));


// create derived VCs for each match based on specific `credentialQuery`
const updatedQuery = {...vprQuery, credentialQuery};
Expand All @@ -399,7 +418,6 @@ async function _getMatches({
vprQuery: updatedQuery, matches: result.matches
});
}

return results;
}

Expand Down Expand Up @@ -459,6 +477,9 @@ function _matchContextFilter({credentialQuery}) {
async function _matchQueryByExample({
verifiablePresentationRequest, query, credentialStore, matches
}) {
debugLog('_matchQueryByExample called with query type:',
query.type); // DEBUG

matches.push(...await _getMatches({
verifiablePresentationRequest, vprQuery: query, credentialStore
}));
Expand Down
Loading