async def create_cred(<EOL>self,<EOL>cred_offer_json,<EOL>cred_req_json: str,<EOL>cred_attrs: dict,<EOL>rr_size: int = None) -> (str, str, int):
LOGGER.debug(<EOL>'<STR_LIT>',<EOL>cred_offer_json,<EOL>cred_req_json,<EOL>cred_attrs,<EOL>rr_size)<EOL>cd_id = json.loads(cred_offer_json)['<STR_LIT>']<EOL>cred_def = json.loads(await self.get_cred_def(cd_id))  <EOL>if '<STR_LIT>' in cred_def['<STR_LIT:value>']:<EOL><INDENT>with REVO_CACHE.lock:<EOL><INDENT>rr_id = Tails.current_rev_reg_id(self._dir_tails, cd_id)<EOL>tails = REVO_CACHE[rr_id].tails<EOL>assert tails  <EOL>try:<EOL><INDENT>(cred_json, cred_revoc_id, rr_delta_json) = await anoncreds.issuer_create_credential(<EOL>self.wallet.handle,<EOL>cred_offer_json,<EOL>cred_req_json,<EOL>json.dumps({k: cred_attr_value(cred_attrs[k]) for k in cred_attrs}),<EOL>tails.rr_id,<EOL>tails.reader_handle)<EOL>rre_req_json = await ledger.build_revoc_reg_entry_request(<EOL>self.did,<EOL>tails.rr_id,<EOL>'<STR_LIT>',<EOL>rr_delta_json)<EOL>await self._sign_submit(rre_req_json)<EOL>resp_json = await self._sign_submit(rre_req_json)<EOL>resp = json.loads(resp_json)<EOL>rv = (cred_json, cred_revoc_id, resp['<STR_LIT:result>']['<STR_LIT>']['<STR_LIT>'])<EOL><DEDENT>except IndyError as x_indy:<EOL><INDENT>if x_indy.error_code == ErrorCode.AnoncredsRevocationRegistryFullError:<EOL><INDENT>(tag, rr_size_suggested) = Tails.next_tag(self._dir_tails, cd_id)<EOL>rr_id = rev_reg_id(cd_id, tag)<EOL>await self._create_rev_reg(rr_id, rr_size or rr_size_suggested)<EOL>REVO_CACHE[rr_id].tails = await Tails(self._dir_tails, cd_id).open()<EOL>return await self.create_cred(cred_offer_json, cred_req_json, cred_attrs)  <EOL><DEDENT>else:<EOL><INDENT>LOGGER.debug(<EOL>'<STR_LIT>',<EOL>x_indy.error_code)<EOL>raise<EOL><DEDENT><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>try:<EOL><INDENT>(cred_json, _, _) = await anoncreds.issuer_create_credential(<EOL>self.wallet.handle,<EOL>cred_offer_json,<EOL>cred_req_json,<EOL>json.dumps({k: cred_attr_value(cred_attrs[k]) for k in cred_attrs}),<EOL>None,<EOL>None)<EOL>rv = (cred_json, _, _)<EOL><DEDENT>except IndyError as x_indy:<EOL><INDENT>LOGGER.debug('<STR_LIT>', x_indy.error_code)<EOL>raise<EOL><DEDENT><DEDENT>LOGGER.debug('<STR_LIT>', rv)<EOL>return rv<EOL>
Create credential as Issuer out of credential request and dict of key:value (raw, unencoded)
entries for attributes.

Return credential json, and if cred def supports revocation, credential revocation identifier
and revocation registry delta ledger timestamp (epoch seconds).

If the credential definition supports revocation, and the current revocation registry is full,
the processing creates a new revocation registry en passant. Depending on the revocation
registry size (by default starting at 256 and doubling iteratively through 4096), this
operation may delay credential creation by several seconds.

:param cred_offer_json: credential offer json as created by Issuer
:param cred_req_json: credential request json as created by HolderProver
:param cred_attrs: dict mapping each attribute to its raw value (the operation encodes it); e.g.,

::

    {
        'favourite_drink': 'martini',
        'height': 180,
        'last_visit_date': '2017-12-31',
        'weaknesses': None
    }

:param rr_size: size of new revocation registry (default as per _create_rev_reg()) if necessary
:return: newly issued credential json; credential revocation identifier (if cred def supports
    revocation, None otherwise), and ledger timestamp (if cred def supports revocation, None otherwise)