cmd/wallet-js-sdk/src/credential/credential-manager.js
/**
   * Saves given credential into wallet content store along with credential metadata & manifest details along with saved credential.
   *
   *  @param {string} auth - authorization token for wallet operations.
   *  @param {Object} contents - credential(s) to be saved in wallet content store.
   *  @param {Array<Object>} contents.credentials - array of credentials to be saved in wallet content store.
   *  @param {Object} contents.presentation - presentation from which all the credentials to be saved in wallet content store.
   *  If credential fulfillment presentation is provided then no need to supply descriptor map along with manifest.
   *  Refer @see {@link https://identity.foundation/credential-manifest/#credential-fulfillment|Credential Fulfillment} for more details.
   *  @param {Object} options - options for saving credential.
   *  @param {boolean} options.verify - (optional) to verify credential before save.
   *  @param {String} options.collection - (optional) ID of the wallet collection to which the credential should belong.
   *  @param {String} options.manifest - (required) credential manifest of the credential being saved.
   *  Refer @see {@link https://identity.foundation/credential-manifest/#credential-manifest-2|Credential Manifest} for more details.
   *
   *  @returns {Promise<Object>} - empty promise or error if operation fails.
   */
Saves given credential into wallet content store along with credential metadata & manifest details along with saved credential.
@param {string} auth - authorization token for wallet operations.
@param {Object} contents - credential(s) to be saved in wallet content store.
@param {Array} contents.credentials - array of credentials to be saved in wallet content store.
@param {Object} contents.presentation - presentation from which all the credentials to be saved in wallet content store.
If credential fulfillment presentation is provided then no need to supply descriptor map along with manifest.

@returns {Promise} - empty promise or error if operation fails.
Saves given credential into wallet content store along with credential metadata & manifest details along with saved credential . @param { string } auth - authorization token for wallet operations . @param { Object } contents - credential ( s ) to be saved in wallet content store . @param { Array } contents . credentials - array of credentials to be saved in wallet content store . @param { Object } contents . presentation - presentation from which all the credentials to be saved in wallet content store . If credential fulfillment presentation is provided then no need to supply descriptor map along with manifest . @returns { Promise } - empty promise or error if operation fails .
async save(
    auth,
    { credentials = [], presentation = { verifiableCredential: [] } } = {},
    { verify = false, collection = "", manifest, descriptorMap } = {}
  ) {
    if (!manifest) {
      throw "credential manifest information is required";
    }
    let contents =
      credentials.length > 0 ? credentials : presentation.verifiableCredential;
    if (verify) {
      const _doVerify = async (rawCredential) => {
        let { verified, error } = await this.wallet.verify(auth, {
          rawCredential,
        });
        if (!verified) {
          console.error(`verification failed for ${rawCredential.id}`);
          throw `credential verification failed`;
        }
      };
      await Promise.all(contents.map(_doVerify));
    }
    const _saveCredential = async (credential) => {
      await this.wallet.add({
        auth,
        contentType: contentTypes.CREDENTIAL,
        content: credential,
        collectionID: collection,
      });
    };
    const _saveMetadata = async (descriptor) => {
      const { id, format, path } = descriptor;
      if (format != SUPPORTED_VC_FORMAT) {
        console.warn(
          `unsupported credential format '${format}', supporting only '${SUPPORTED_VC_FORMAT}' for now`
        );
        return;
      }
      const credentialMatch = jp.query(
        credentials.length > 0 ? credentials : presentation,
        path
      );
      if (credentialMatch.length != 1) {
        throw "credential match from descriptor should resolve to a single credential";
      }
      await this.saveCredentialMetadata(auth, {
        credential: credentialMatch[0],
        descriptorID: id,
        manifest,
        collection,
      });
    };
    let descriptors;
    if (descriptorMap) {
      descriptors = descriptorMap;
    } else if (presentation["credential_fulfillment"]) {
      if (presentation["credential_fulfillment"].manifest_id != manifest.id) {
        throw "credential fulfillment not matching with manifest provided";
      }
      descriptors = presentation["credential_fulfillment"].descriptor_map;
    } else {
      throw "descriptor map is required to save mapping between credential being saved and manifest";
    }
    await Promise.all(
      contents.map(_saveCredential).concat(descriptors.map(_saveMetadata))
    );
  }
async save ( auth , { credentials = [ ] , presentation = { verifiableCredential : [ ] } } = { } , { verify = false , collection = "" , manifest , descriptorMap } = { } ) { if ( ! manifest ) { throw "credential manifest information is required" ; } let contents = credentials . length > 0 ? credentials : presentation . verifiableCredential ; if ( verify ) { const _doVerify = async ( rawCredential ) => { let { verified , error } = await this . wallet . verify ( auth , { rawCredential , } ) ; if ( ! verified ) { console . error ( ` ${ rawCredential . id } ` ) ; throw ` ` ; } } ; await Promise . all ( contents . map ( _doVerify ) ) ; } const _saveCredential = async ( credential ) => { await this . wallet . add ( { auth , contentType : contentTypes . CREDENTIAL , content : credential , collectionID : collection , } ) ; } ; const _saveMetadata = async ( descriptor ) => { const { id , format , path } = descriptor ; if ( format != SUPPORTED_VC_FORMAT ) { console . warn ( ` ${ format } ${ SUPPORTED_VC_FORMAT } ` ) ; return ; } const credentialMatch = jp . query ( credentials . length > 0 ? credentials : presentation , path ) ; if ( credentialMatch . length != 1 ) { throw "credential match from descriptor should resolve to a single credential" ; } await this . saveCredentialMetadata ( auth , { credential : credentialMatch [ 0 ] , descriptorID : id , manifest , collection , } ) ; } ; let descriptors ; if ( descriptorMap ) { descriptors = descriptorMap ; } else if ( presentation [ "credential_fulfillment" ] ) { if ( presentation [ "credential_fulfillment" ] . manifest_id != manifest . id ) { throw "credential fulfillment not matching with manifest provided" ; } descriptors = presentation [ "credential_fulfillment" ] . descriptor_map ; } else { throw "descriptor map is required to save mapping between credential being saved and manifest" ; } await Promise . all ( contents . map ( _saveCredential ) . concat ( descriptors . map ( _saveMetadata ) ) ) ; }
Saves given credential into wallet content store along with credential metadata & manifest details along with saved credential.
Saves given credential into wallet content store along with credential metadata & manifest details along with saved credential .
// credential array takes precedence over presentation. // verify all credentials if required. // prepare save credential // prepare save metadata // validate fulfillment and collection descriptor map. // validate fulfillment against manifest provided // save all credentials & metadata first, to catch any duplicate entry issues before saving manifests.