@bifold/core 2.1.9 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/lib/commonjs/components/buttons/Button.js +26 -10
  2. package/lib/commonjs/components/buttons/Button.js.map +1 -1
  3. package/lib/commonjs/constants.js.map +1 -1
  4. package/lib/commonjs/contexts/reducers/store.js +48 -0
  5. package/lib/commonjs/contexts/reducers/store.js.map +1 -1
  6. package/lib/commonjs/contexts/store.js +5 -1
  7. package/lib/commonjs/contexts/store.js.map +1 -1
  8. package/lib/commonjs/hooks/useBifoldAgentSetup.js +5 -5
  9. package/lib/commonjs/hooks/useBifoldAgentSetup.js.map +1 -1
  10. package/lib/commonjs/localization/en/en.json +10 -4
  11. package/lib/commonjs/localization/fr/fr.json +11 -4
  12. package/lib/commonjs/localization/pt-br/pt-br.json +11 -4
  13. package/lib/commonjs/modules/openid/screens/OpenIDProofChangeCredential.js +7 -4
  14. package/lib/commonjs/modules/openid/screens/OpenIDProofChangeCredential.js.map +1 -1
  15. package/lib/commonjs/navigators/DeliveryStack.js +15 -3
  16. package/lib/commonjs/navigators/DeliveryStack.js.map +1 -1
  17. package/lib/commonjs/navigators/SettingStack.js +9 -0
  18. package/lib/commonjs/navigators/SettingStack.js.map +1 -1
  19. package/lib/commonjs/screens/ConfigureMediator.js +156 -0
  20. package/lib/commonjs/screens/ConfigureMediator.js.map +1 -0
  21. package/lib/commonjs/screens/ContactDetails.js +2 -2
  22. package/lib/commonjs/screens/ContactDetails.js.map +1 -1
  23. package/lib/commonjs/screens/CredentialDetails.js +2 -2
  24. package/lib/commonjs/screens/CredentialDetails.js.map +1 -1
  25. package/lib/commonjs/screens/ProofRequest.js +17 -1
  26. package/lib/commonjs/screens/ProofRequest.js.map +1 -1
  27. package/lib/commonjs/screens/Settings.js +6 -0
  28. package/lib/commonjs/screens/Settings.js.map +1 -1
  29. package/lib/commonjs/theme.js +55 -0
  30. package/lib/commonjs/theme.js.map +1 -1
  31. package/lib/commonjs/types/navigators.js +1 -0
  32. package/lib/commonjs/types/navigators.js.map +1 -1
  33. package/lib/commonjs/utils/helpers.js +10 -0
  34. package/lib/commonjs/utils/helpers.js.map +1 -1
  35. package/lib/commonjs/utils/mediatorhelpers.js +63 -0
  36. package/lib/commonjs/utils/mediatorhelpers.js.map +1 -0
  37. package/lib/module/components/buttons/Button.js +26 -10
  38. package/lib/module/components/buttons/Button.js.map +1 -1
  39. package/lib/module/constants.js.map +1 -1
  40. package/lib/module/contexts/reducers/store.js +47 -0
  41. package/lib/module/contexts/reducers/store.js.map +1 -1
  42. package/lib/module/contexts/store.js +5 -1
  43. package/lib/module/contexts/store.js.map +1 -1
  44. package/lib/module/hooks/useBifoldAgentSetup.js +5 -5
  45. package/lib/module/hooks/useBifoldAgentSetup.js.map +1 -1
  46. package/lib/module/localization/en/en.json +10 -4
  47. package/lib/module/localization/fr/fr.json +11 -4
  48. package/lib/module/localization/pt-br/pt-br.json +11 -4
  49. package/lib/module/modules/openid/screens/OpenIDProofChangeCredential.js +7 -4
  50. package/lib/module/modules/openid/screens/OpenIDProofChangeCredential.js.map +1 -1
  51. package/lib/module/navigators/DeliveryStack.js +14 -3
  52. package/lib/module/navigators/DeliveryStack.js.map +1 -1
  53. package/lib/module/navigators/SettingStack.js +9 -0
  54. package/lib/module/navigators/SettingStack.js.map +1 -1
  55. package/lib/module/screens/ConfigureMediator.js +149 -0
  56. package/lib/module/screens/ConfigureMediator.js.map +1 -0
  57. package/lib/module/screens/ContactDetails.js +2 -2
  58. package/lib/module/screens/ContactDetails.js.map +1 -1
  59. package/lib/module/screens/CredentialDetails.js +2 -2
  60. package/lib/module/screens/CredentialDetails.js.map +1 -1
  61. package/lib/module/screens/ProofRequest.js +17 -1
  62. package/lib/module/screens/ProofRequest.js.map +1 -1
  63. package/lib/module/screens/Settings.js +6 -0
  64. package/lib/module/screens/Settings.js.map +1 -1
  65. package/lib/module/theme.js +55 -0
  66. package/lib/module/theme.js.map +1 -1
  67. package/lib/module/types/navigators.js +1 -0
  68. package/lib/module/types/navigators.js.map +1 -1
  69. package/lib/module/utils/helpers.js +10 -0
  70. package/lib/module/utils/helpers.js.map +1 -1
  71. package/lib/module/utils/mediatorhelpers.js +55 -0
  72. package/lib/module/utils/mediatorhelpers.js.map +1 -0
  73. package/lib/typescript/src/components/buttons/Button.d.ts.map +1 -1
  74. package/lib/typescript/src/constants.d.ts.map +1 -1
  75. package/lib/typescript/src/contexts/reducers/store.d.ts +7 -1
  76. package/lib/typescript/src/contexts/reducers/store.d.ts.map +1 -1
  77. package/lib/typescript/src/contexts/store.d.ts.map +1 -1
  78. package/lib/typescript/src/hooks/useBifoldAgentSetup.d.ts.map +1 -1
  79. package/lib/typescript/src/modules/openid/screens/OpenIDProofChangeCredential.d.ts.map +1 -1
  80. package/lib/typescript/src/navigators/DeliveryStack.d.ts.map +1 -1
  81. package/lib/typescript/src/navigators/SettingStack.d.ts.map +1 -1
  82. package/lib/typescript/src/screens/ConfigureMediator.d.ts +6 -0
  83. package/lib/typescript/src/screens/ConfigureMediator.d.ts.map +1 -0
  84. package/lib/typescript/src/screens/ProofRequest.d.ts.map +1 -1
  85. package/lib/typescript/src/screens/Settings.d.ts.map +1 -1
  86. package/lib/typescript/src/theme.d.ts +82 -0
  87. package/lib/typescript/src/theme.d.ts.map +1 -1
  88. package/lib/typescript/src/types/navigators.d.ts +5 -1
  89. package/lib/typescript/src/types/navigators.d.ts.map +1 -1
  90. package/lib/typescript/src/types/state.d.ts +2 -0
  91. package/lib/typescript/src/types/state.d.ts.map +1 -1
  92. package/lib/typescript/src/utils/helpers.d.ts.map +1 -1
  93. package/lib/typescript/src/utils/mediatorhelpers.d.ts +4 -0
  94. package/lib/typescript/src/utils/mediatorhelpers.d.ts.map +1 -0
  95. package/package.json +3 -3
  96. package/src/components/buttons/Button.tsx +50 -20
  97. package/src/constants.ts +0 -1
  98. package/src/contexts/reducers/store.ts +46 -0
  99. package/src/contexts/store.tsx +3 -0
  100. package/src/hooks/useBifoldAgentSetup.ts +5 -5
  101. package/src/localization/en/en.json +10 -4
  102. package/src/localization/fr/fr.json +11 -4
  103. package/src/localization/pt-br/pt-br.json +11 -4
  104. package/src/modules/openid/screens/OpenIDProofChangeCredential.tsx +5 -4
  105. package/src/navigators/DeliveryStack.tsx +14 -3
  106. package/src/navigators/SettingStack.tsx +10 -0
  107. package/src/screens/ConfigureMediator.tsx +160 -0
  108. package/src/screens/ContactDetails.tsx +2 -2
  109. package/src/screens/CredentialDetails.tsx +2 -2
  110. package/src/screens/ProofRequest.tsx +26 -0
  111. package/src/screens/Settings.tsx +7 -0
  112. package/src/theme.ts +55 -0
  113. package/src/types/navigators.ts +2 -0
  114. package/src/types/state.ts +2 -0
  115. package/src/utils/helpers.ts +9 -0
  116. package/src/utils/mediatorhelpers.ts +60 -0
@@ -0,0 +1,160 @@
1
+ import { FlatList, StyleSheet, View, Pressable } from 'react-native'
2
+ import BouncyCheckbox from 'react-native-bouncy-checkbox'
3
+ import { SafeAreaView } from 'react-native-safe-area-context'
4
+ import Icon from 'react-native-vector-icons/MaterialCommunityIcons'
5
+ import { useStore } from '../contexts/store'
6
+ import { DispatchAction } from '../contexts/reducers/store'
7
+ import { useTheme } from '../contexts/theme'
8
+ import { ThemedText } from '../components/texts/ThemedText'
9
+ import { testIdWithKey } from '../utils/testable'
10
+ import { useEffect, useState } from 'react'
11
+ import { LockoutReason, useAuth } from '../contexts/auth'
12
+ import { useAgent } from '@credo-ts/react-hooks'
13
+ import { MediationRecipientService } from '@credo-ts/core'
14
+ import DismissiblePopupModal from '../components/modals/DismissiblePopupModal'
15
+ import { useTranslation } from 'react-i18next'
16
+ import { StackScreenProps } from '@react-navigation/stack'
17
+ import { Screens, SettingStackParams } from '../types/navigators'
18
+ import { setMediationToDefault } from '../utils/mediatorhelpers'
19
+
20
+ type MediatorItem = {
21
+ id: string
22
+ label: string
23
+ testID: string
24
+ }
25
+ type ConfigureMediatorProps = StackScreenProps<SettingStackParams, Screens.ConfigureMediator>
26
+
27
+ const ConfigureMediator = ({ route }: ConfigureMediatorProps) => {
28
+ const [store, dispatch] = useStore()
29
+ const { agent } = useAgent()
30
+ const { ColorPallet, SettingsTheme } = useTheme()
31
+ const { t } = useTranslation()
32
+ const { lockOutUser } = useAuth()
33
+ const supportedMediators = store.preferences.availableMediators
34
+ const scannedMediatorUri = route.params?.scannedMediatorUri
35
+ const [isModalVisible, setIsModalVisible] = useState(false)
36
+ const [pendingMediatorId, setPendingMediatorId] = useState<string | null>(null)
37
+
38
+ useEffect(() => {
39
+ if (scannedMediatorUri && !store.preferences.availableMediators.includes(scannedMediatorUri)) {
40
+ dispatch({
41
+ type: DispatchAction.ADD_AVAILABLE_MEDIATOR,
42
+ payload: [scannedMediatorUri],
43
+ })
44
+ }
45
+ }, [scannedMediatorUri, dispatch, store.preferences.availableMediators])
46
+ const mediators: MediatorItem[] = supportedMediators.map((mediator) => ({
47
+ id: mediator,
48
+ label: String(mediator),
49
+ testID: testIdWithKey(mediator),
50
+ }))
51
+ const styles = StyleSheet.create({
52
+ container: {
53
+ backgroundColor: ColorPallet.brand.primaryBackground,
54
+ width: '100%',
55
+ },
56
+ section: {
57
+ backgroundColor: SettingsTheme.groupBackground,
58
+ paddingHorizontal: 25,
59
+ paddingVertical: 16,
60
+ },
61
+ sectionRow: {
62
+ flexDirection: 'row',
63
+ alignItems: 'center',
64
+ justifyContent: 'space-between',
65
+ },
66
+ itemSeparator: {
67
+ borderBottomWidth: 1,
68
+ borderBottomColor: ColorPallet.brand.primaryBackground,
69
+ marginHorizontal: 25,
70
+ },
71
+ checkboxContainer: {
72
+ justifyContent: 'center',
73
+ },
74
+ })
75
+
76
+ const confirmMediatorChange = async () => {
77
+ if (!pendingMediatorId || !agent) return
78
+
79
+ await agent.dependencyManager.resolve(MediationRecipientService).clearDefaultMediator(agent.context)
80
+ agent.config.logger.info(`successfully cleared default mediator`)
81
+ await setMediationToDefault(agent, pendingMediatorId)
82
+ dispatch({
83
+ type: DispatchAction.SET_SELECTED_MEDIATOR,
84
+ payload: [pendingMediatorId],
85
+ })
86
+ lockOutUser(LockoutReason.Logout)
87
+ setIsModalVisible(false)
88
+ }
89
+
90
+ const handleMediatorChange = async (mediatorId: string) => {
91
+ if (mediatorId === store.preferences.selectedMediator) return
92
+ setPendingMediatorId(mediatorId)
93
+ setIsModalVisible(true)
94
+ }
95
+
96
+ const MediatorRow = ({
97
+ label,
98
+ id,
99
+ testID,
100
+ selected,
101
+ onPress,
102
+ }: {
103
+ label: string
104
+ id: string
105
+ testID: string
106
+ selected: boolean
107
+ onPress: (id: string) => void
108
+ }) => (
109
+ <View style={[styles.section, styles.sectionRow]}>
110
+ <ThemedText variant="title">{label}</ThemedText>
111
+ <Pressable
112
+ style={styles.checkboxContainer}
113
+ accessibilityLabel={label}
114
+ accessibilityRole="radio"
115
+ testID={testIdWithKey(testID)}
116
+ >
117
+ <BouncyCheckbox
118
+ disableText
119
+ fillColor={ColorPallet.brand.secondaryBackground}
120
+ unfillColor={ColorPallet.brand.secondaryBackground}
121
+ size={36}
122
+ innerIconStyle={{ borderColor: ColorPallet.brand.primary, borderWidth: 2 }}
123
+ ImageComponent={() => <Icon name="circle" size={18} color={ColorPallet.brand.primary} />}
124
+ onPress={() => onPress(id)}
125
+ isChecked={selected}
126
+ disableBuiltInState
127
+ />
128
+ </Pressable>
129
+ </View>
130
+ )
131
+
132
+ return (
133
+ <SafeAreaView style={styles.container}>
134
+ <FlatList
135
+ data={mediators}
136
+ keyExtractor={(item) => item.id}
137
+ renderItem={({ item }) => (
138
+ <MediatorRow
139
+ label={item.label.split('?')[0]}
140
+ id={item.id}
141
+ testID={item.testID}
142
+ selected={store.preferences.selectedMediator === item.id}
143
+ onPress={handleMediatorChange}
144
+ />
145
+ )}
146
+ />
147
+ {isModalVisible && (
148
+ <DismissiblePopupModal
149
+ title={t('Settings.ChangeMediator')}
150
+ description={t('Settings.ChangeMediatorDescription')}
151
+ onCallToActionLabel={t('Global.Confirm')}
152
+ onCallToActionPressed={() => confirmMediatorChange()}
153
+ onDismissPressed={() => setIsModalVisible(false)}
154
+ />
155
+ )}
156
+ </SafeAreaView>
157
+ )
158
+ }
159
+
160
+ export default ConfigureMediator
@@ -311,13 +311,13 @@ const ContactDetails: React.FC<ContactDetailsProps> = ({ route }) => {
311
311
  {store?.preferences.developerModeEnabled && (
312
312
  <TouchableOpacity
313
313
  onPress={callViewJSONDetails}
314
- accessibilityLabel={t('ContactDetails.JSONDetails')}
314
+ accessibilityLabel={t('Global.ViewJSON')}
315
315
  accessibilityRole={'button'}
316
316
  testID={testIdWithKey('JSONDetails')}
317
317
  style={[styles.contentContainer, styles.actionContainer, { marginTop: 10 }]}
318
318
  >
319
319
  <Assets.svg.iconCode width={20} height={20} color={ColorPallet.brand.text} />
320
- <ThemedText>{t('ContactDetails.JSONDetails')}</ThemedText>
320
+ <ThemedText>{t('Global.ViewJSON')}</ThemedText>
321
321
  </TouchableOpacity>
322
322
  )}
323
323
  <TouchableOpacity
@@ -414,13 +414,13 @@ const CredentialDetails: React.FC<CredentialDetailsProps> = ({ navigation, route
414
414
  >
415
415
  <TouchableOpacity
416
416
  onPress={callViewJSONDetails}
417
- accessibilityLabel={t('ContactDetails.JSONDetails')}
417
+ accessibilityLabel={t('Global.ViewJSON')}
418
418
  accessibilityRole={'button'}
419
419
  testID={testIdWithKey('JSONDetails')}
420
420
  style={{ flexDirection: 'row', gap: 8 }}
421
421
  >
422
422
  <Assets.svg.iconCode width={20} height={20} color={ColorPallet.brand.secondary} />
423
- <ThemedText>{t('ContactDetails.JSONDetails')}</ThemedText>
423
+ <ThemedText>{t('Global.ViewJSON')}</ThemedText>
424
424
  </TouchableOpacity>
425
425
  </View>
426
426
  )}
@@ -637,6 +637,19 @@ const ProofRequest: React.FC<ProofRequestProps> = ({ navigation, proofId }) => {
637
637
  navigation.getParent()?.navigate(TabStacks.HomeStack, { screen: Screens.Home })
638
638
  }, [navigation])
639
639
 
640
+ const callViewJSONDetails = useCallback(() => {
641
+ navigation.navigate(Stacks.ContactStack, {
642
+ screen: Screens.JSONDetails,
643
+ params: {
644
+ jsonBlob:
645
+ '"proof":' +
646
+ JSON.stringify(proof, null, 2) +
647
+ '\n"retrievedCredentials":' +
648
+ JSON.stringify(retrievedCredentials, null, 2),
649
+ },
650
+ })
651
+ }, [navigation, proof, retrievedCredentials])
652
+
640
653
  const shareDisabledErrors = useMemo(() => {
641
654
  return {
642
655
  hasCredentialError: !hasAvailableCredentials,
@@ -802,6 +815,19 @@ const ProofRequest: React.FC<ProofRequestProps> = ({ navigation, proofId }) => {
802
815
  onPress={toggleDeclineModalVisible}
803
816
  />
804
817
  </View>
818
+ {store.preferences.developerModeEnabled && (
819
+ <>
820
+ <View style={styles.footerButton}>
821
+ <Button
822
+ title={t('Global.ViewJSON')}
823
+ accessibilityLabel={t('Global.ViewJSON')}
824
+ testID={testIdWithKey('JSONDetails')}
825
+ buttonType={ButtonType.Secondary}
826
+ onPress={callViewJSONDetails}
827
+ />
828
+ </View>
829
+ </>
830
+ )}
805
831
  </>
806
832
  )}
807
833
  </>
@@ -218,6 +218,13 @@ const Settings: React.FC<SettingsProps> = ({ navigation }) => {
218
218
  testID: testIdWithKey('DeveloperOptions'),
219
219
  onPress: () => navigation.navigate(Screens.Developer),
220
220
  },
221
+ {
222
+ title: t('Settings.ConfigureMediator'),
223
+ value: store.preferences.selectedMediator,
224
+ accessibilityLabel: t('Settings.ConfigureMediator'),
225
+ testID: testIdWithKey('ConfigureMediator'),
226
+ onPress: () => navigation.navigate(Screens.ConfigureMediator),
227
+ },
221
228
  {
222
229
  title: t('Settings.Logout'),
223
230
  accessibilityLabel: t('Settings.Logout'),
package/src/theme.ts CHANGED
@@ -521,6 +521,16 @@ export const Buttons = StyleSheet.create({
521
521
  borderRadius: 4,
522
522
  backgroundColor: ColorPallet.brand.primary,
523
523
  },
524
+ criticalText: {
525
+ ...TextTheme.bold,
526
+ color: ColorPallet.brand.buttonText,
527
+ textAlign: 'center',
528
+ },
529
+ criticalTextDisabled: {
530
+ ...TextTheme.bold,
531
+ color: ColorPallet.brand.buttonText,
532
+ textAlign: 'center',
533
+ },
524
534
  primary: {
525
535
  padding: 16,
526
536
  borderRadius: 4,
@@ -583,13 +593,39 @@ export const Buttons = StyleSheet.create({
583
593
  borderRadius: 4,
584
594
  backgroundColor: ColorPallet.brand.primary,
585
595
  },
596
+ modalCriticalDisabled: {
597
+ padding: 16,
598
+ borderRadius: 4,
599
+ backgroundColor: ColorPallet.brand.primaryDisabled,
600
+ },
601
+ modalCriticalText: {
602
+ ...TextTheme.bold,
603
+ color: ColorPallet.brand.buttonText,
604
+ textAlign: 'center',
605
+ },
606
+ modalCriticalTextDisabled: {
607
+ ...TextTheme.bold,
608
+ color: ColorPallet.brand.buttonText,
609
+ textAlign: 'center',
610
+ },
586
611
  modalPrimary: {
587
612
  padding: 16,
588
613
  borderRadius: 4,
589
614
  backgroundColor: ColorPallet.brand.modalPrimary,
590
615
  },
616
+ modalPrimaryDisabled: {
617
+ padding: 16,
618
+ borderRadius: 4,
619
+ backgroundColor: ColorPallet.brand.primaryDisabled,
620
+ },
591
621
  modalPrimaryText: {
592
622
  ...TextTheme.bold,
623
+ color: ColorPallet.brand.buttonText,
624
+ textAlign: 'center',
625
+ },
626
+ modalPrimaryTextDisabled: {
627
+ ...TextTheme.bold,
628
+ color: ColorPallet.brand.buttonText,
593
629
  textAlign: 'center',
594
630
  },
595
631
  modalSecondary: {
@@ -598,19 +634,38 @@ export const Buttons = StyleSheet.create({
598
634
  borderWidth: 2,
599
635
  borderColor: ColorPallet.brand.modalPrimary,
600
636
  },
637
+ modalSecondaryDisabled: {
638
+ padding: 16,
639
+ borderRadius: 4,
640
+ borderWidth: 2,
641
+ borderColor: ColorPallet.brand.secondaryDisabled,
642
+ },
601
643
  modalSecondaryText: {
602
644
  ...TextTheme.bold,
603
645
  color: ColorPallet.brand.modalPrimary,
604
646
  textAlign: 'center',
605
647
  },
648
+ modalSecondaryTextDisabled: {
649
+ ...TextTheme.bold,
650
+ color: ColorPallet.brand.secondaryDisabled,
651
+ textAlign: 'center',
652
+ },
606
653
  modalTertiary: {
607
654
  padding: 16,
608
655
  },
656
+ modalTertiaryDisabled: {
657
+ padding: 16,
658
+ },
609
659
  modalTertiaryText: {
610
660
  ...TextTheme.bold,
611
661
  color: ColorPallet.brand.modalPrimary,
612
662
  textAlign: 'center',
613
663
  },
664
+ modalTertiaryTextDisabled: {
665
+ ...TextTheme.bold,
666
+ color: ColorPallet.brand.tertiaryDisabled,
667
+ textAlign: 'center',
668
+ },
614
669
  })
615
670
 
616
671
  export const ListItems = StyleSheet.create({
@@ -58,6 +58,7 @@ export enum Screens {
58
58
  HistoryDetails = 'History details',
59
59
  AutoLock = 'AutoLock',
60
60
  UpdateAvailable = 'Update Available',
61
+ ConfigureMediator = 'Configure Mediator',
61
62
  }
62
63
 
63
64
  export enum Stacks {
@@ -171,6 +172,7 @@ export type SettingStackParams = {
171
172
  [Screens.TogglePushNotifications]: undefined
172
173
  [Screens.HistorySettings]: undefined
173
174
  [Screens.AutoLock]: undefined
175
+ [Screens.ConfigureMediator]: { scannedMediatorUri: string } | undefined
174
176
  }
175
177
 
176
178
  export type NotificationStackParams = {
@@ -33,6 +33,8 @@ export interface Preferences {
33
33
  alternateContactNames: Record<string, string>
34
34
  autoLockTime: number
35
35
  theme?: string
36
+ selectedMediator: string
37
+ availableMediators: string[]
36
38
  }
37
39
 
38
40
  export interface Tours {
@@ -57,6 +57,7 @@ import {
57
57
  } from './anonCredsProofRequestMapper'
58
58
  import { parseCredDefFromId } from './cred-def'
59
59
  import { isOpenIdCredentialOffer, isOpenIdPresentationRequest } from './parsers'
60
+ import { isMediatorInvitation } from './mediatorhelpers'
60
61
 
61
62
  export { parsedCredDefNameFromCredential } from './cred-def'
62
63
 
@@ -1091,6 +1092,14 @@ export const connectFromScanOrDeepLink = async (
1091
1092
 
1092
1093
  return
1093
1094
  }
1095
+ if (await isMediatorInvitation(agent, uri)) {
1096
+ navigation.navigate(Stacks.SettingStack as any, {
1097
+ screen: Screens.ConfigureMediator,
1098
+ params: { scannedMediatorUri: uri },
1099
+ })
1100
+
1101
+ return
1102
+ }
1094
1103
 
1095
1104
  const aUrl = processBetaUrlIfRequired(uri)
1096
1105
  const receivedInvitation = await connectFromInvitation(aUrl, agent, implicitInvitations, reuseConnection)
@@ -0,0 +1,60 @@
1
+ import { Agent, MediationRecord } from '@credo-ts/core'
2
+
3
+ export const isMediatorInvitation = async (agent: Agent, url: string): Promise<boolean> => {
4
+ const invitation = await agent.oob.parseInvitation(url)
5
+ if (!invitation) {
6
+ return false
7
+ }
8
+ if (invitation.goalCode === 'aries.vc.mediate') {
9
+ agent.config.logger.info(`Invitation is a mediator invitation with goal code: ${invitation.goalCode}`)
10
+ return true
11
+ }
12
+ agent.config.logger.info(`Invitation is not a mediator invitation, goal code: ${invitation.goalCode}`)
13
+ return false
14
+ }
15
+
16
+ const provisionMediationRecordFromMediatorUrl = async (
17
+ agent: Agent,
18
+ url: string
19
+ ): Promise<MediationRecord | undefined> => {
20
+ try {
21
+ const invitation = await agent.oob.parseInvitation(url)
22
+ if (!invitation) {
23
+ agent.config.logger.warn(`No invitation found in URL: ${url}`)
24
+ return undefined
25
+ }
26
+ const outOfBandRecord = await agent.oob.findByReceivedInvitationId(invitation.id)
27
+ let [connection] = outOfBandRecord ? await agent.connections.findAllByOutOfBandId(outOfBandRecord.id) : []
28
+
29
+ if (!connection) {
30
+ agent.config.logger.warn(`No connection found for out-of-band record: ${outOfBandRecord?.id}`)
31
+ const invite = await agent.oob.parseInvitation(url)
32
+ const { connectionRecord: newConnection } = await agent.oob.receiveInvitation(invite)
33
+ if (!newConnection) {
34
+ agent.config.logger.warn(`Failed to create connection from invitation: ${JSON.stringify(invite, null, 2)}`)
35
+ return
36
+ }
37
+ connection = newConnection
38
+ }
39
+ const result = connection.isReady ? connection : await agent.connections.returnWhenIsConnected(connection.id)
40
+ return agent.mediationRecipient.provision(result)
41
+ } catch (error) {
42
+ agent.config.logger.warn(`Failed to get connection ID from mediator URL: ${error}`)
43
+ return
44
+ }
45
+ }
46
+
47
+ export const setMediationToDefault = async (agent: Agent, mediatorUrl: string) => {
48
+ const mediationRecord = await provisionMediationRecordFromMediatorUrl(agent, mediatorUrl)
49
+ if (!mediationRecord) {
50
+ agent.config.logger.warn(`No connection record found for mediator URL: ${mediatorUrl}`)
51
+ return
52
+ }
53
+ const currentDefault = await agent.mediationRecipient.findDefaultMediator()
54
+ if (currentDefault?.connectionId === mediationRecord.id) {
55
+ agent.config.logger.info(`Default mediator already set for connection ID: ${mediationRecord.id}`)
56
+ return
57
+ }
58
+ await agent.mediationRecipient.setDefaultMediator(mediationRecord)
59
+ agent.config.logger.info(`setting default mediator with record: ${JSON.stringify(mediationRecord)}`)
60
+ }