code: def revoc_info(creds: dict, filt: dict = None) -> dict:
      
  
      rv = {}
      for uuid2creds in (creds.get('attrs', {}), creds.get('predicates', {})):
          for inner_creds in uuid2creds.values():
              for cred in inner_creds:
                  cred_info = cred['cred_info']
                  (rr_id, cr_id) = (cred_info['rev_reg_id'], cred_info['cred_rev_id'])
                  if (rr_id, cr_id) in rv or rr_id is None or cr_id is None:
                      continue
                  if not filt:
                      rv[(rr_id, cr_id)] = cred_info['attrs']
                      continue
                  if ({attr: str(filt[attr]) for attr in filt}.items() <= cred_info['attrs'].items()):
                      rv[(rr_id, cr_id)] = cred_info['attrs']
      return rv
docs: Given a creds structure, return a dict mapping pairs
      (revocation registry identifier, credential revocation identifier)
      to (decoded) attribute name:value dicts.
  
      If the caller includes a filter of attribute:value pairs, retain only matching attributes.
  
      :param creds: creds structure returned by HolderProver.get_creds() as above
      :param filt: dict mapping attributes to values of interest; e.g.,
  
      ::
  
          {
              'legalName': 'Flan Nebula',
              'effectiveDate': '2018-01-01',
              'endDate': None
          }
  
      :return: dict mapping (rev_reg_id, cred_rev_id) pairs to decoded attributes