diff --git a/aries_cloudagent/indy/models/cred_abstract.py b/aries_cloudagent/indy/models/cred_abstract.py index 999ccb8c2f..d48f35e51e 100644 --- a/aries_cloudagent/indy/models/cred_abstract.py +++ b/aries_cloudagent/indy/models/cred_abstract.py @@ -303,7 +303,7 @@ def __init__( self, data_model_versions_supported: Sequence[str] = None, binding_required: str = None, - binding_methods: str = None, + binding_method: str = None, credential: Union[dict, VerifiableCredential] = None, **kwargs, ): @@ -318,7 +318,7 @@ def __init__( super().__init__(**kwargs) self.data_model_versions_supported = data_model_versions_supported self.binding_required = binding_required - self.binding_methods = binding_methods + self.binding_method = binding_method self.credential = credential @@ -331,22 +331,22 @@ class Meta: model_class = VCDICredAbstract unknown = EXCLUDE - data_model_versions_supported = fields.List( - fields.Str(), required=True, metadata={"description": "", "example": ""} - ) + data_model_versions_supported = fields.List( + fields.Str(), required=True, metadata={"description": "", "example": ""} + ) - binding_required = fields.Bool( - required=False, metadata={"description": "", "example": ""} - ) + binding_required = fields.Bool( + required=False, metadata={"description": "", "example": ""} + ) - binding_method = fields.Nested( - BindingMethodSchema(), - required=binding_required, - metadata={"description": "", "example": ""}, - ) + binding_method = fields.Nested( + BindingMethodSchema(), + required=binding_required, + metadata={"description": "", "example": ""}, + ) - credential = fields.Nested( - CredentialSchema(), - required=True, - metadata={"description": "", "example": ""}, - ) + credential = fields.Nested( + CredentialSchema(), + required=True, + metadata={"description": "", "example": ""}, + ) diff --git a/aries_cloudagent/protocols/issue_credential/v2_0/formats/vc_di/handler.py b/aries_cloudagent/protocols/issue_credential/v2_0/formats/vc_di/handler.py index 5b11b59f2c..29e6afc083 100644 --- a/aries_cloudagent/protocols/issue_credential/v2_0/formats/vc_di/handler.py +++ b/aries_cloudagent/protocols/issue_credential/v2_0/formats/vc_di/handler.py @@ -44,6 +44,7 @@ from ......multitenant.base import BaseMultitenantManager from ......revocation_anoncreds.models.issuer_cred_rev_record import IssuerCredRevRecord from ......storage.base import BaseStorage +from ......wallet.base import BaseWallet from ...message_types import ( ATTACHMENT_FORMAT, CRED_20_ISSUE, @@ -204,17 +205,16 @@ async def create_offer( ledger = self.profile.inject(BaseLedger) cache = self.profile.inject_or(BaseCache) + async with self.profile.session() as session: + wallet = session.inject(BaseWallet) + public_did_info = await wallet.get_public_did() + public_did = public_did_info.did + cred_def_id = await issuer.match_created_credential_definitions( **cred_proposal_message.attachment(VCDICredFormatHandler.format) ) async def _create(): - # TODO - implement a separate create_credential_offer for vcdi - # IC - need to create a new "issuer.create_credential_offer_vc_di()" - # method that creates the offer in the new format, and then - # call it from here (instead of "issuer.create_credential_offer()") - # (see the corresponding method in "formats/indy/handler.py", the new method - # should work basically the same way, except using the new VCDI format) offer_json = await issuer.create_credential_offer(cred_def_id) return json.loads(offer_json) @@ -253,7 +253,35 @@ async def _create(): if not cred_offer: cred_offer = await _create() - return self.get_format_data(CRED_20_OFFER, cred_offer) + vcdi_cred_offer = { + "data_model_versions_supported": ["1.1"], + "binding_required": True, + "binding_method": { + "anoncreds_link_secret": { + "cred_def_id": cred_offer["cred_def_id"], + "key_correctness_proof": cred_offer["key_correctness_proof"], + "nonce": cred_offer["nonce"], + }, + "didcomm_signed_attachment": { + "algs_supported": ["EdDSA"], + "did_methods_supported": ["key"], + "nonce": cred_offer["nonce"], + }, + }, + "credential": { + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://w3id.org/security/data-integrity/v2", + {"@vocab": "https://www.w3.org/ns/credentials/issuer-dependent#"}, + ], + "type": ["VerifiableCredential"], + "issuer": public_did, + "credentialSubject": cred_proposal_message.credential_preview.attr_dict(), + "issuanceDate": "2024-01-10T04:44:29.563418Z", + }, + } + + return self.get_format_data(CRED_20_OFFER, vcdi_cred_offer) async def receive_offer( self, cred_ex_record: V20CredExRecord, cred_offer_message: V20CredOffer diff --git a/aries_cloudagent/protocols/issue_credential/v2_0/formats/vc_di/tests/test_handler.py b/aries_cloudagent/protocols/issue_credential/v2_0/formats/vc_di/tests/test_handler.py index 1876019d0e..3c2e2a0c4f 100644 --- a/aries_cloudagent/protocols/issue_credential/v2_0/formats/vc_di/tests/test_handler.py +++ b/aries_cloudagent/protocols/issue_credential/v2_0/formats/vc_di/tests/test_handler.py @@ -45,6 +45,7 @@ # (see "formats/indy/tests/test_handler.py" for the unit tests for the # existing Indy tests, these should work basically the same way) + class TestV20VCDICredFormatHandler(IsolatedAsyncioTestCase): async def asyncSetUp(self): # any required setup, see "formats/indy/tests/test_handler.py" @@ -86,5 +87,3 @@ async def test_issue_credential_revocable(self): async def test_issue_credential_non_revocable(self): # any required tests, see "formats/indy/tests/test_handler.py" assert False - -