@@ -97,6 +97,9 @@ class ADAManagerError(BaseError):
97
97
98
98
class ADAManager :
99
99
100
+ # Record for indication a connection is labelled as Auditor (client)
101
+ RECORD_TYPE_AUDITOR_CONNECTION = "auditor_connection"
102
+
100
103
# Record for indicating a connection is labelled as MyData DID registry (client)
101
104
RECORD_TYPE_MYDATA_DID_REGISTRY_CONNECTION = "mydata_did_registry_connection"
102
105
@@ -363,6 +366,33 @@ async def fetch_mydata_did_registry_connection_record(self) -> typing.Tuple[typi
363
366
except (StorageError , StorageNotFoundError , StorageDuplicateError ) as e :
364
367
return None , e
365
368
369
+ async def fetch_auditor_connection_record (self ) -> typing .Tuple [typing .Union [ConnectionRecord , None ], typing .Union [None , Exception ]]:
370
+ # Wallet instance from context
371
+ wallet : IndyWallet = await self .context .inject (BaseWallet )
372
+
373
+ # Storage instance from context
374
+ storage : BaseStorage = await self .context .inject (BaseStorage )
375
+
376
+ auditor_connection_record = None
377
+
378
+ try :
379
+
380
+ # Search for existing connection_id marked as Auditor
381
+ auditor_connection_record : StorageRecord = await storage .search_records (
382
+ self .RECORD_TYPE_AUDITOR_CONNECTION ,
383
+ ).fetch_single ()
384
+
385
+ # Auditor connection identifier
386
+ auditor_connection_id = auditor_connection_record .value
387
+
388
+ # Fetch connection record from storage
389
+ connection_record : ConnectionRecord = await ConnectionRecord .retrieve_by_id (self .context , auditor_connection_id )
390
+
391
+ return connection_record , None
392
+
393
+ except (StorageError , StorageNotFoundError , StorageDuplicateError ) as e :
394
+ return None , e
395
+
366
396
async def send_create_did_message (self , did : str ) -> MyDataDIDRegistryDIDCommTransactionRecord :
367
397
"""
368
398
Send create-did didcomm message to MyData DID Registry.
@@ -1828,6 +1858,126 @@ async def list_da_personal_data_category_from_wallet(self) -> typing.List[str]:
1828
1858
f"Failed to fetch all data agreements from wallet: { e } "
1829
1859
)
1830
1860
1861
+ async def mark_connection_id_as_auditor (self , connection_record : ConnectionRecord ):
1862
+ """Associate the connection with Auditor"""
1863
+
1864
+ assert connection_record .connection_id , "Connection ID is required"
1865
+
1866
+ try :
1867
+
1868
+ # Fetch storage from context
1869
+ storage : IndyStorage = await self .context .inject (BaseStorage )
1870
+
1871
+ # Search for existing connection_id marked as Auditor
1872
+ connection_record_list = await storage .search_records (
1873
+ self .RECORD_TYPE_AUDITOR_CONNECTION ,
1874
+ {"connection_id" : connection_record .connection_id },
1875
+ ).fetch_all ()
1876
+
1877
+ # If no record found, create a new one
1878
+ if not connection_record_list :
1879
+ record = StorageRecord (
1880
+ self .RECORD_TYPE_AUDITOR_CONNECTION ,
1881
+ connection_record .connection_id ,
1882
+ {"connection_id" : connection_record .connection_id },
1883
+ )
1884
+
1885
+ await storage .add_record (record )
1886
+ else :
1887
+ # Update the existing record with the new connection_id
1888
+ record = connection_record_list [0 ]
1889
+
1890
+ await storage .update_record_value (record = record , value = connection_record .connection_id )
1891
+ await storage .update_record_tags (record = record , tags = {"connection_id" : connection_record .connection_id })
1892
+
1893
+ except StorageError as e :
1894
+ # Raise an error
1895
+ raise ADAManagerError (
1896
+ f"Failed to mark connection as Auditor: { e } "
1897
+ )
1898
+ except StorageDuplicateError as e :
1899
+ # Raise an error
1900
+ raise ADAManagerError (
1901
+ f"Failed to mark connection as Auditor: { e } "
1902
+ )
1903
+
1904
+ async def fetch_current_auditor_connection_id (self ) -> typing .Union [None , str ]:
1905
+ """
1906
+ Fetch current Auditor connection id.
1907
+ """
1908
+
1909
+ try :
1910
+
1911
+ # Fetch storage from context
1912
+ storage : IndyStorage = await self .context .inject (BaseStorage )
1913
+
1914
+ # Search for existing connection_id marked as Auditor
1915
+ connection_record_list = await storage .search_records (
1916
+ self .RECORD_TYPE_AUDITOR_CONNECTION ,
1917
+ ).fetch_all ()
1918
+
1919
+ if len (connection_record_list ) > 1 :
1920
+ # Raise an error
1921
+ raise ADAManagerError (
1922
+ f"More than one connection marked as Auditor"
1923
+ )
1924
+
1925
+ if not connection_record_list :
1926
+ # if no record found
1927
+ return None
1928
+ else :
1929
+ # if record found
1930
+ record = connection_record_list [0 ]
1931
+
1932
+ return record .value
1933
+ except StorageError as e :
1934
+ # Raise an error
1935
+ raise ADAManagerError (
1936
+ f"Failed to fetch current Auditor connection id: { e } "
1937
+ )
1938
+ except StorageDuplicateError as e :
1939
+ # Raise an error
1940
+ raise ADAManagerError (
1941
+ f"Failed to fetch current Auditor connection id: { e } "
1942
+ )
1943
+
1944
+ async def unmark_connection_id_as_auditor (self ) -> bool :
1945
+ """
1946
+ Disassociate the connection with Auditor.
1947
+ """
1948
+
1949
+ try :
1950
+
1951
+ # Fetch storage from context
1952
+ storage : IndyStorage = await self .context .inject (BaseStorage )
1953
+
1954
+ # Search for existing connection_id marked as Auditor
1955
+ connection_record_list = await storage .search_records (
1956
+ self .RECORD_TYPE_AUDITOR_CONNECTION ,
1957
+ ).fetch_all ()
1958
+
1959
+ if not connection_record_list :
1960
+ # if no record found
1961
+ return False
1962
+ else :
1963
+ # if record found
1964
+ record = connection_record_list [0 ]
1965
+
1966
+ await storage .delete_record (record )
1967
+
1968
+ return True
1969
+
1970
+ except StorageError as e :
1971
+ # Raise an error
1972
+ raise ADAManagerError (
1973
+ f"Failed to unmark connection as Auditor: { e } "
1974
+ )
1975
+ except StorageDuplicateError as e :
1976
+ # Raise an error
1977
+ raise ADAManagerError (
1978
+ f"Failed to unmark connection as Auditor: { e } "
1979
+ )
1980
+
1831
1981
async def mark_connection_id_as_mydata_did_registry (self , connection_record : ConnectionRecord ):
1832
1982
"""
1833
1983
Associate the connection with MyData DID registry.
@@ -2095,7 +2245,7 @@ async def delete_data_agreement_instance_metadata(self, *, tag_query: dict = Non
2095
2245
for storage_record in storage_records :
2096
2246
await storage .delete_record (storage_record )
2097
2247
2098
- async def query_data_agreement_instance_metadata (self , * , tag_query : dict = None ) -> typing .List [dict ]:
2248
+ async def query_data_agreement_instance_metadata (self , * , tag_query : dict = None ) -> typing .List [StorageRecord ]:
2099
2249
"""Query data agreement instance metadata"""
2100
2250
2101
2251
# Fetch storage from context
@@ -2619,3 +2769,67 @@ async def construct_data_agreement_termination_terminate_message(self, *, data_
2619
2769
)
2620
2770
2621
2771
return (updated_data_agreement_instance , data_agreement_terminate_message )
2772
+
2773
+ async def query_data_agreement_instances (self , tag_query : dict = None ) -> typing .List [dict ]:
2774
+ """Query data agreement instances"""
2775
+
2776
+ da_instance_metadata_records = await self .query_data_agreement_instance_metadata (
2777
+ tag_query = tag_query
2778
+ )
2779
+
2780
+ data_agreement_instances = []
2781
+
2782
+ for da_instance_metadata_record in da_instance_metadata_records :
2783
+
2784
+ # Identify the method of use
2785
+
2786
+ if da_instance_metadata_record .tags .get ("method_of_use" ) == DataAgreementV1Record .METHOD_OF_USE_DATA_SOURCE :
2787
+
2788
+ try :
2789
+ # Fetch credential exchange record
2790
+ cred_ex_record : V10CredentialExchange = await V10CredentialExchange .retrieve_by_id (
2791
+ self .context ,
2792
+ da_instance_metadata_record .tags .get (
2793
+ "data_exchange_record_id" )
2794
+ )
2795
+
2796
+ if cred_ex_record .data_agreement :
2797
+ # Load the data agreement to DataAgreementInstance
2798
+ data_agreement_instance : DataAgreementInstance = DataAgreementInstanceSchema ().load (
2799
+ cred_ex_record .data_agreement
2800
+ )
2801
+
2802
+ # Append the data agreement instance to data_agreement_instances
2803
+ data_agreement_instances .append ({
2804
+ "data_exchange_record_id" : da_instance_metadata_record .tags .get ("data_exchange_record_id" ),
2805
+ "data_agreement" : data_agreement_instance .serialize ()
2806
+ })
2807
+
2808
+ except StorageError :
2809
+ pass
2810
+
2811
+ if da_instance_metadata_record .tags .get ("method_of_use" ) == DataAgreementV1Record .METHOD_OF_USE_DATA_USING_SERVICE :
2812
+ try :
2813
+ # Fetch presentation exchange record
2814
+ pres_ex_record : V10PresentationExchange = await V10PresentationExchange .retrieve_by_id (
2815
+ self .context ,
2816
+ da_instance_metadata_record .tags .get (
2817
+ "data_exchange_record_id" )
2818
+ )
2819
+
2820
+ if pres_ex_record .data_agreement :
2821
+ # Load the data agreement to DataAgreementInstance
2822
+ data_agreement_instance : DataAgreementInstance = DataAgreementInstanceSchema ().load (
2823
+ pres_ex_record .data_agreement
2824
+ )
2825
+
2826
+ # Append the data agreement instance to data_agreement_instances
2827
+ data_agreement_instances .append ({
2828
+ "data_exchange_record_id" : da_instance_metadata_record .tags .get ("data_exchange_record_id" ),
2829
+ "data_agreement" : data_agreement_instance .serialize ()
2830
+ })
2831
+
2832
+ except StorageError :
2833
+ pass
2834
+
2835
+ return data_agreement_instances
0 commit comments