async def create_cred_offer(self, schema_seq_no: int) -> str:
        """
        Create credential offer as Issuer for given schema.

        Raise CorruptWallet if the wallet has no private key for the corresponding credential definition.
        Raise WalletState for closed wallet.

        :param schema_seq_no: schema sequence number
        :return: credential offer json for use in storing credentials at HolderProver.
        """

        LOGGER.debug('Issuer.create_cred_offer >>> schema_seq_no: %s', schema_seq_no)

        if not self.wallet.handle:
            LOGGER.debug('Issuer.create_cred_offer <!< Wallet %s is closed', self.name)
            raise WalletState('Wallet {} is closed'.format(self.name))

        if not self.pool:
            LOGGER.debug('Issuer.create_cred_offer <!< issuer %s has no pool', self.name)
            raise AbsentPool('Issuer {} has no pool: cannot create cred offer'.format(self.name))

        rv = None
        cd_id = cred_def_id(self.did, schema_seq_no, self.pool.protocol)
        try:
            rv = await anoncreds.issuer_create_credential_offer(self.wallet.handle, cd_id)
        except IndyError as x_indy:
            if x_indy.error_code == ErrorCode.WalletNotFoundError:
                LOGGER.debug(
                    'Issuer.create_cred_offer <!< did not issue cred definition from wallet %s',
                    self.name)
                raise CorruptWallet('Cannot create cred offer: did not issue cred definition from wallet {}'.format(
                    self.name))
            LOGGER.debug(
                'Issuer.create_cred_offer <!< cannot create cred offer, indy error code %s',
                x_indy.error_code)
            raise

        LOGGER.debug('Issuer.create_cred_offer <<< %s', rv)
        return rv