async def create_request( self, connection: ConnectionRecord, my_label: str = None, my_endpoint: str = None, ) -> ConnectionRequest: """ Create a new connection request for a previously-received invitation. Args: connection: The `ConnectionRecord` representing the invitation to accept my_label: My label my_endpoint: My endpoint Returns: A new `ConnectionRequest` message to send to the other agent """ wallet: BaseWallet = await self.context.inject(BaseWallet) if connection.my_did: my_info = await wallet.get_local_did(connection.my_did) else: # Create new DID for connection my_info = await wallet.create_local_did() connection.my_did = my_info.did # Create connection request message if not my_endpoint: my_endpoints = [] default_endpoint = self.context.settings.get("default_endpoint") if default_endpoint: my_endpoints.append(default_endpoint) my_endpoints.extend( self.context.settings.get("additional_endpoints", [])) else: my_endpoints = [my_endpoint] did_doc = await self.create_did_document( my_info, connection.inbound_connection_id, my_endpoints) if not my_label: my_label = self.context.settings.get("default_label") request = ConnectionRequest( label=my_label, connection=ConnectionDetail(did=connection.my_did, did_doc=did_doc), ) # Update connection state connection.request_id = request._id connection.state = ConnectionRecord.STATE_REQUEST await connection.save(self.context, reason="Created connection request") return request
async def establish_inbound(self, connection: ConnectionRecord, inbound_connection_id: str, outbound_handler) -> str: """Assign the inbound routing connection for a connection record. Returns: the current routing state (request or done) """ # The connection must have a verkey, but in the case of a received # invitation we might not have created one yet wallet: BaseWallet = await self.context.inject(BaseWallet) if connection.my_did: my_info = await wallet.get_local_did(connection.my_did) else: # Create new DID for connection my_info = await wallet.create_local_did() connection.my_did = my_info.did try: router = await ConnectionRecord.retrieve_by_id( self.context, inbound_connection_id) except StorageNotFoundError: raise ConnectionManagerError( f"Routing connection not found: {inbound_connection_id}") if not router.is_ready: raise ConnectionManagerError( f"Routing connection is not ready: {inbound_connection_id}") connection.inbound_connection_id = inbound_connection_id route_mgr = RoutingManager(self.context) await route_mgr.send_create_route(inbound_connection_id, my_info.verkey, outbound_handler) connection.routing_state = ConnectionRecord.ROUTING_STATE_REQUEST await connection.save(self.context) return connection.routing_state
async def create_response(self, connection: ConnectionRecord, my_endpoint: str = None) -> ConnectionResponse: """ Create a connection response for a received connection request. Args: connection: The `ConnectionRecord` with a pending connection request my_endpoint: The endpoint I can be reached at Returns: A tuple of the updated `ConnectionRecord` new `ConnectionResponse` message """ ConnectionRecord.log_state( self.context, "Creating connection response", {"connection_id": connection.connection_id}, ) if connection.state not in ( ConnectionRecord.STATE_REQUEST, ConnectionRecord.STATE_RESPONSE, ): raise ConnectionManagerError( "Connection is not in the request or response state") request = await connection.retrieve_request(self.context) wallet: BaseWallet = await self.context.inject(BaseWallet) if connection.my_did: my_info = await wallet.get_local_did(connection.my_did) else: my_info = await wallet.create_local_did() connection.my_did = my_info.did # Create connection response message if not my_endpoint: my_endpoints = [] default_endpoint = self.context.settings.get("default_endpoint") if default_endpoint: my_endpoints.append(default_endpoint) my_endpoints.extend( self.context.settings.get("additional_endpoints", [])) did_doc = await self.create_did_document( my_info, connection.inbound_connection_id, my_endpoints) response = ConnectionResponse( connection=ConnectionDetail(did=my_info.did, did_doc=did_doc)) # Assign thread information response.assign_thread_from(request) response.assign_trace_from(request) # Sign connection field using the invitation key wallet: BaseWallet = await self.context.inject(BaseWallet) await response.sign_field("connection", connection.invitation_key, wallet) # Update connection state connection.state = ConnectionRecord.STATE_RESPONSE await connection.save( self.context, reason="Created connection response", log_params={"response": response}, ) return response