@bifold/core 2.4.5 → 2.5.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.
- package/lib/commonjs/contexts/reducers/store.js +3 -2
- package/lib/commonjs/contexts/reducers/store.js.map +1 -1
- package/lib/commonjs/index.js +119 -104
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/screens/AttemptLockout.js +27 -35
- package/lib/commonjs/screens/AttemptLockout.js.map +1 -1
- package/lib/commonjs/screens/ContactDetails.js +1 -1
- package/lib/commonjs/screens/ContactDetails.js.map +1 -1
- package/lib/commonjs/screens/CredentialDetails.js +1 -1
- package/lib/commonjs/screens/CredentialDetails.js.map +1 -1
- package/lib/commonjs/screens/JSONDetails.js +6 -3
- package/lib/commonjs/screens/JSONDetails.js.map +1 -1
- package/lib/commonjs/screens/MobileVerifierLoading.js +4 -3
- package/lib/commonjs/screens/MobileVerifierLoading.js.map +1 -1
- package/lib/commonjs/screens/PINCreate.js +3 -10
- package/lib/commonjs/screens/PINCreate.js.map +1 -1
- package/lib/commonjs/screens/WhatAreContacts.js +3 -2
- package/lib/commonjs/screens/WhatAreContacts.js.map +1 -1
- package/lib/module/contexts/reducers/store.js +3 -2
- package/lib/module/contexts/reducers/store.js.map +1 -1
- package/lib/module/index.js +42 -45
- package/lib/module/index.js.map +1 -1
- package/lib/module/screens/AttemptLockout.js +28 -36
- package/lib/module/screens/AttemptLockout.js.map +1 -1
- package/lib/module/screens/ContactDetails.js +1 -1
- package/lib/module/screens/ContactDetails.js.map +1 -1
- package/lib/module/screens/CredentialDetails.js +1 -1
- package/lib/module/screens/CredentialDetails.js.map +1 -1
- package/lib/module/screens/JSONDetails.js +6 -3
- package/lib/module/screens/JSONDetails.js.map +1 -1
- package/lib/module/screens/MobileVerifierLoading.js +4 -3
- package/lib/module/screens/MobileVerifierLoading.js.map +1 -1
- package/lib/module/screens/PINCreate.js +3 -10
- package/lib/module/screens/PINCreate.js.map +1 -1
- package/lib/module/screens/WhatAreContacts.js +3 -2
- package/lib/module/screens/WhatAreContacts.js.map +1 -1
- package/lib/typescript/src/contexts/reducers/store.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +57 -61
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/screens/AttemptLockout.d.ts.map +1 -1
- package/lib/typescript/src/screens/JSONDetails.d.ts.map +1 -1
- package/lib/typescript/src/screens/MobileVerifierLoading.d.ts.map +1 -1
- package/lib/typescript/src/screens/PINCreate.d.ts.map +1 -1
- package/lib/typescript/src/screens/WhatAreContacts.d.ts.map +1 -1
- package/lib/typescript/src/types/navigators.d.ts +1 -1
- package/lib/typescript/src/types/navigators.d.ts.map +1 -1
- package/package.json +3 -4
- package/src/App.tsx +0 -79
- package/src/animated-components.ts +0 -30
- package/src/assets/fonts/MaterialIcons.ttf +0 -0
- package/src/assets/icons/code.svg +0 -4
- package/src/assets/icons/large-arrow.svg +0 -5
- package/src/assets/icons/pencil.svg +0 -15
- package/src/assets/icons/trash.svg +0 -31
- package/src/assets/img/Artwork_1024x1024.png +0 -0
- package/src/assets/img/HistoryCardAcceptedIcon.svg +0 -4
- package/src/assets/img/HistoryCardExpiredIcon.svg +0 -4
- package/src/assets/img/HistoryCardRevokedIcon.svg +0 -4
- package/src/assets/img/HistoryInformationSentIcon.svg +0 -4
- package/src/assets/img/HistoryPinUpdatedIcon.svg +0 -4
- package/src/assets/img/IconChevronRight.svg +0 -5
- package/src/assets/img/activity-indicator-circle.svg +0 -90
- package/src/assets/img/app-lockout.svg +0 -1
- package/src/assets/img/biometrics.svg +0 -74
- package/src/assets/img/chat-loading.svg +0 -1
- package/src/assets/img/check-in-circle.svg +0 -18
- package/src/assets/img/connection-pending.svg +0 -112
- package/src/assets/img/contact-book.svg +0 -21
- package/src/assets/img/credential-card.svg +0 -18
- package/src/assets/img/credential-declined.svg +0 -28
- package/src/assets/img/credential-in-hand.svg +0 -48
- package/src/assets/img/credential-list.svg +0 -60
- package/src/assets/img/credential-pending.svg +0 -96
- package/src/assets/img/credential-success.svg +0 -48
- package/src/assets/img/delete-notification.svg +0 -1
- package/src/assets/img/empty-wallet.svg +0 -23
- package/src/assets/img/error-filled.svg +0 -12
- package/src/assets/img/exclamation-mark.svg +0 -17
- package/src/assets/img/home-center-img.svg +0 -71
- package/src/assets/img/icon-credential-offer-dark.svg +0 -7
- package/src/assets/img/icon-credential-offer-light.svg +0 -7
- package/src/assets/img/icon-info-recieved-dark.svg +0 -8
- package/src/assets/img/icon-info-recieved-light.svg +0 -8
- package/src/assets/img/icon-info-sent-dark.svg +0 -8
- package/src/assets/img/icon-info-sent-light.svg +0 -8
- package/src/assets/img/icon-proof-request-dark.svg +0 -11
- package/src/assets/img/icon-proof-request-light.svg +0 -11
- package/src/assets/img/information-received.svg +0 -1
- package/src/assets/img/logo-large.png +0 -0
- package/src/assets/img/logo-large@2x.png +0 -0
- package/src/assets/img/logo-large@3x.png +0 -0
- package/src/assets/img/logo.svg +0 -15
- package/src/assets/img/message-text-icon-outline.svg +0 -1
- package/src/assets/img/message-text-icon.svg +0 -1
- package/src/assets/img/no_information_shared.svg +0 -36
- package/src/assets/img/preface.svg +0 -15
- package/src/assets/img/proof-declined.svg +0 -66
- package/src/assets/img/proof-pending.svg +0 -61
- package/src/assets/img/proof-success.svg +0 -72
- package/src/assets/img/push-notifications.svg +0 -1
- package/src/assets/img/qrcode-scan-icon.svg +0 -1
- package/src/assets/img/scan-share.svg +0 -102
- package/src/assets/img/secure-check.svg +0 -4
- package/src/assets/img/secure-image.svg +0 -64
- package/src/assets/img/update-available.svg +0 -26
- package/src/assets/img/verifier-request-declined.svg +0 -34
- package/src/assets/img/wallet-back.svg +0 -20
- package/src/assets/img/wallet-front.svg +0 -32
- package/src/assets/img/wallet-icon-outline.svg +0 -1
- package/src/assets/img/wallet-icon.svg +0 -1
- package/src/assets/img/wallet.svg +0 -43
- package/src/assets/oca-bundles.json +0 -174
- package/src/components/animated/ButtonLoading.tsx +0 -32
- package/src/components/animated/ConnectionLoading.tsx +0 -53
- package/src/components/animated/CredentialAdded.tsx +0 -72
- package/src/components/animated/CredentialPending.tsx +0 -63
- package/src/components/animated/LoadingIndicator.tsx +0 -49
- package/src/components/animated/PresentationLoading.tsx +0 -52
- package/src/components/animated/RecordLoading.tsx +0 -75
- package/src/components/animated/SendingProof.tsx +0 -53
- package/src/components/animated/SentProof.tsx +0 -72
- package/src/components/buttons/Button-api.tsx +0 -46
- package/src/components/buttons/Button.tsx +0 -125
- package/src/components/buttons/HeaderHome.tsx +0 -25
- package/src/components/buttons/IconButton.tsx +0 -93
- package/src/components/buttons/InfoIcon.tsx +0 -35
- package/src/components/buttons/SettingsMenu.tsx +0 -26
- package/src/components/buttons/ToggleButton.tsx +0 -93
- package/src/components/buttons/index.ts +0 -4
- package/src/components/chat/ActionSlider.tsx +0 -104
- package/src/components/chat/ChatActions.tsx +0 -33
- package/src/components/chat/ChatBubble.tsx +0 -20
- package/src/components/chat/ChatEvent.tsx +0 -31
- package/src/components/chat/ChatMessage.tsx +0 -142
- package/src/components/chat/MessageInput.tsx +0 -46
- package/src/components/chat/index.ts +0 -4
- package/src/components/forms/WalletNameForm.tsx +0 -148
- package/src/components/index.ts +0 -4
- package/src/components/inputs/BiometryControl.tsx +0 -190
- package/src/components/inputs/BulletPoint.tsx +0 -32
- package/src/components/inputs/CheckBoxRow.tsx +0 -67
- package/src/components/inputs/InlineErrorText.tsx +0 -60
- package/src/components/inputs/LimitedTextInput.tsx +0 -71
- package/src/components/inputs/PINInput.tsx +0 -175
- package/src/components/inputs/SingleSelectBlock.tsx +0 -53
- package/src/components/listItems/ContactCredentialListItem.tsx +0 -79
- package/src/components/listItems/ContactListItem.tsx +0 -121
- package/src/components/listItems/NotificationListItem.tsx +0 -514
- package/src/components/misc/AvatarView.tsx +0 -33
- package/src/components/misc/CardWatermark.tsx +0 -52
- package/src/components/misc/ConnectionAlert.tsx +0 -123
- package/src/components/misc/ConnectionImage.tsx +0 -45
- package/src/components/misc/ContentGradient.tsx +0 -40
- package/src/components/misc/CredentialCard.tsx +0 -161
- package/src/components/misc/CredentialCard10.tsx +0 -329
- package/src/components/misc/CredentialCard11.tsx +0 -701
- package/src/components/misc/CredentialCard11ActionFooter.tsx +0 -55
- package/src/components/misc/CredentialCard11Issuer.tsx +0 -74
- package/src/components/misc/CredentialCard11Logo.tsx +0 -61
- package/src/components/misc/EmptyList.tsx +0 -27
- package/src/components/misc/EmptyListContacts.tsx +0 -55
- package/src/components/misc/ErrorBoundary.tsx +0 -200
- package/src/components/misc/FauxHeader.tsx +0 -75
- package/src/components/misc/InfoBox.tsx +0 -283
- package/src/components/misc/NoNewUpdates.tsx +0 -38
- package/src/components/misc/PINHeader.tsx +0 -25
- package/src/components/misc/PINValidationHelper.tsx +0 -48
- package/src/components/misc/Pagination.tsx +0 -114
- package/src/components/misc/QRRenderer.tsx +0 -53
- package/src/components/misc/QRScanner.tsx +0 -395
- package/src/components/misc/QRScannerTorch.tsx +0 -74
- package/src/components/misc/ScanCamera.tsx +0 -86
- package/src/components/misc/ScanTab.tsx +0 -45
- package/src/components/misc/SharedProofData.tsx +0 -98
- package/src/components/misc/UnorderedList.tsx +0 -28
- package/src/components/misc/VerifierCredentialCard.tsx +0 -378
- package/src/components/misc/index.ts +0 -2
- package/src/components/modals/AlertModal.tsx +0 -42
- package/src/components/modals/AppGuideModal.tsx +0 -142
- package/src/components/modals/CameraDisclosureModal.tsx +0 -126
- package/src/components/modals/CommonRemoveModal.tsx +0 -337
- package/src/components/modals/DeveloperModal.tsx +0 -32
- package/src/components/modals/DismissiblePopupModal.tsx +0 -169
- package/src/components/modals/ErrorModal.tsx +0 -107
- package/src/components/modals/ImageModal.tsx +0 -80
- package/src/components/modals/NetInfoModal.tsx +0 -35
- package/src/components/modals/PopupModal.tsx +0 -56
- package/src/components/modals/ProofCancelModal.tsx +0 -79
- package/src/components/modals/SafeAreaModal.tsx +0 -17
- package/src/components/record/Record.tsx +0 -100
- package/src/components/record/RecordBinaryField.tsx +0 -55
- package/src/components/record/RecordDateIntField.tsx +0 -63
- package/src/components/record/RecordField.tsx +0 -154
- package/src/components/record/RecordFooter.tsx +0 -17
- package/src/components/record/RecordHeader.tsx +0 -17
- package/src/components/record/RecordRemove.tsx +0 -66
- package/src/components/texts/HeaderTitle.tsx +0 -25
- package/src/components/texts/HighlightTextBox.tsx +0 -41
- package/src/components/texts/InfoTextBox.tsx +0 -129
- package/src/components/texts/Link.tsx +0 -41
- package/src/components/texts/Text.tsx +0 -21
- package/src/components/texts/ThemedText.tsx +0 -24
- package/src/components/toast/BaseToast.tsx +0 -128
- package/src/components/toast/ToastConfig.tsx +0 -21
- package/src/components/tour/AttachTourStep.tsx +0 -73
- package/src/components/tour/CredentialOfferTourSteps.tsx +0 -41
- package/src/components/tour/CredentialsTourSteps.tsx +0 -41
- package/src/components/tour/HomeTourSteps.tsx +0 -104
- package/src/components/tour/ProofRequestTourSteps.tsx +0 -41
- package/src/components/tour/SpotCutout.tsx +0 -65
- package/src/components/tour/TourBox.tsx +0 -255
- package/src/components/tour/TourOverlay.tsx +0 -134
- package/src/components/views/Banner.tsx +0 -181
- package/src/components/views/CredentialCardLogo.tsx +0 -77
- package/src/components/views/CredentialDetailPrimaryHeader.tsx +0 -107
- package/src/components/views/CredentialDetailSecondaryHeader.tsx +0 -60
- package/src/components/views/HeaderWithBanner.tsx +0 -17
- package/src/components/views/HomeFooterView.tsx +0 -110
- package/src/components/views/HomeHeaderView.tsx +0 -12
- package/src/components/views/KeyboardView.tsx +0 -41
- package/src/components/views/LoadingPlaceholder.tsx +0 -168
- package/src/components/views/LoadingView.tsx +0 -29
- package/src/components/views/ProgressBar.tsx +0 -53
- package/src/components/views/PushNotificationsContent.tsx +0 -51
- package/src/components/views/PushNotificationsDisabledContent.tsx +0 -47
- package/src/configs/ledgers/indy/index.ts +0 -8
- package/src/configs/ledgers/indy/ledgers.json +0 -51
- package/src/constants.ts +0 -107
- package/src/container-api.ts +0 -247
- package/src/container-impl.ts +0 -243
- package/src/contexts/activity.tsx +0 -145
- package/src/contexts/animated-components.ts +0 -9
- package/src/contexts/auth.tsx +0 -240
- package/src/contexts/index.ts +0 -3
- package/src/contexts/navigation.tsx +0 -19
- package/src/contexts/network.tsx +0 -125
- package/src/contexts/reducers/index.ts +0 -3
- package/src/contexts/reducers/store.ts +0 -754
- package/src/contexts/store.tsx +0 -103
- package/src/contexts/theme.tsx +0 -51
- package/src/contexts/tour/tour-context.tsx +0 -160
- package/src/contexts/tour/tour-provider.tsx +0 -160
- package/src/hooks/bundle-resolver.ts +0 -95
- package/src/hooks/chat-messages.tsx +0 -263
- package/src/hooks/connections.ts +0 -37
- package/src/hooks/credential-card-styles.ts +0 -144
- package/src/hooks/credentials.ts +0 -11
- package/src/hooks/deep-links.ts +0 -49
- package/src/hooks/developer-mode.ts +0 -25
- package/src/hooks/lockout.ts +0 -77
- package/src/hooks/notifications.ts +0 -108
- package/src/hooks/oob.ts +0 -17
- package/src/hooks/proof-request-templates.ts +0 -40
- package/src/hooks/proofs.ts +0 -32
- package/src/hooks/screen-capture.ts +0 -52
- package/src/hooks/useBifoldAgentSetup.ts +0 -169
- package/src/hooks/useOnboardingState.ts +0 -53
- package/src/hooks/usePINValidation.ts +0 -98
- package/src/index.ts +0 -239
- package/src/layout/ScreenLayout.tsx +0 -53
- package/src/localization/en/en.json +0 -951
- package/src/localization/en/index.ts +0 -3
- package/src/localization/fr/fr.json +0 -933
- package/src/localization/fr/index.ts +0 -3
- package/src/localization/index.ts +0 -66
- package/src/localization/pt-br/index.ts +0 -3
- package/src/localization/pt-br/pt-br.json +0 -911
- package/src/modules/history/context/historyManager.tsx +0 -247
- package/src/modules/history/index.ts +0 -2
- package/src/modules/history/navigation/HistoryStack.tsx +0 -29
- package/src/modules/history/services/queue.service.tsx +0 -31
- package/src/modules/history/types/index.ts +0 -92
- package/src/modules/history/ui/HistoryPage.tsx +0 -133
- package/src/modules/history/ui/HistorySettings.tsx +0 -183
- package/src/modules/history/ui/assets/img/HistoryCardAcceptedIcon.svg +0 -4
- package/src/modules/history/ui/assets/img/HistoryCardExpiredIcon.svg +0 -4
- package/src/modules/history/ui/assets/img/HistoryCardRevokedIcon.svg +0 -4
- package/src/modules/history/ui/assets/img/HistoryInformationSentIcon.svg +0 -4
- package/src/modules/history/ui/assets/img/HistoryPinUpdatedIcon.svg +0 -4
- package/src/modules/history/ui/assets/img/IconChevronRight.svg +0 -3
- package/src/modules/history/ui/components/BulletPoint.tsx +0 -49
- package/src/modules/history/ui/components/HistoryListItem.tsx +0 -251
- package/src/modules/history/ui/components/HistoryMenu.tsx +0 -25
- package/src/modules/history/ui/components/SingleSelectBlock.tsx +0 -72
- package/src/modules/openid/components/CredentialRowCard.tsx +0 -64
- package/src/modules/openid/components/OpenIDCredentialCard.tsx +0 -276
- package/src/modules/openid/context/OpenIDCredentialRecordProvider.tsx +0 -296
- package/src/modules/openid/display.tsx +0 -467
- package/src/modules/openid/displayProof.tsx +0 -86
- package/src/modules/openid/hooks/openid.tsx +0 -111
- package/src/modules/openid/metadata.tsx +0 -59
- package/src/modules/openid/offerResolve.tsx +0 -281
- package/src/modules/openid/resolverProof.tsx +0 -286
- package/src/modules/openid/screens/OpenIDCredentialDetails.tsx +0 -214
- package/src/modules/openid/screens/OpenIDCredentialOffer.tsx +0 -192
- package/src/modules/openid/screens/OpenIDProofChangeCredential.tsx +0 -133
- package/src/modules/openid/screens/OpenIDProofPresentation.tsx +0 -423
- package/src/modules/openid/types.tsx +0 -111
- package/src/modules/openid/utils/utils.tsx +0 -119
- package/src/navigators/ConnectStack.tsx +0 -68
- package/src/navigators/ContactStack.tsx +0 -91
- package/src/navigators/CredentialStack.tsx +0 -48
- package/src/navigators/DeliveryStack.tsx +0 -76
- package/src/navigators/HomeStack.tsx +0 -37
- package/src/navigators/MainStack.tsx +0 -146
- package/src/navigators/NotificationStack.tsx +0 -56
- package/src/navigators/OnboardingScreens.ts +0 -142
- package/src/navigators/OnboardingStack.tsx +0 -205
- package/src/navigators/ProofRequestStack.tsx +0 -113
- package/src/navigators/RootStack.tsx +0 -71
- package/src/navigators/SettingStack.tsx +0 -174
- package/src/navigators/TabStack.tsx +0 -304
- package/src/navigators/defaultLayoutOptions.tsx +0 -17
- package/src/navigators/defaultStackOptions.tsx +0 -102
- package/src/navigators/index.ts +0 -27
- package/src/onboarding.ts +0 -90
- package/src/screens/AttemptLockout.tsx +0 -153
- package/src/screens/AutoLock.tsx +0 -140
- package/src/screens/Biometry.tsx +0 -54
- package/src/screens/Chat.tsx +0 -141
- package/src/screens/ConfigureMediator.tsx +0 -160
- package/src/screens/Connection.tsx +0 -394
- package/src/screens/ContactDetails.tsx +0 -350
- package/src/screens/CredentialDetails.tsx +0 -473
- package/src/screens/CredentialOffer.tsx +0 -334
- package/src/screens/CredentialOfferAccept.tsx +0 -189
- package/src/screens/DataRetention.tsx +0 -91
- package/src/screens/Developer.tsx +0 -289
- package/src/screens/Home.tsx +0 -173
- package/src/screens/JSONDetails.tsx +0 -102
- package/src/screens/Language.tsx +0 -97
- package/src/screens/ListContacts.tsx +0 -112
- package/src/screens/ListCredentials.tsx +0 -135
- package/src/screens/ListProofRequests.tsx +0 -148
- package/src/screens/MobileVerifierLoading.tsx +0 -106
- package/src/screens/NameWallet.tsx +0 -9
- package/src/screens/Onboarding.tsx +0 -162
- package/src/screens/OnboardingPages.tsx +0 -160
- package/src/screens/PINChange.tsx +0 -249
- package/src/screens/PINCreate.tsx +0 -185
- package/src/screens/PINEnter.tsx +0 -432
- package/src/screens/PINExplainer.tsx +0 -85
- package/src/screens/PINVerify.tsx +0 -195
- package/src/screens/PasteUrl.tsx +0 -140
- package/src/screens/Preface.tsx +0 -78
- package/src/screens/ProofChangeCredential.tsx +0 -179
- package/src/screens/ProofDetails.tsx +0 -348
- package/src/screens/ProofRequest.tsx +0 -999
- package/src/screens/ProofRequestAccept.tsx +0 -133
- package/src/screens/ProofRequestDetails.tsx +0 -270
- package/src/screens/ProofRequestUsageHistory.tsx +0 -152
- package/src/screens/ProofRequesting.tsx +0 -245
- package/src/screens/PushNotifications.tsx +0 -59
- package/src/screens/RenameContact.tsx +0 -155
- package/src/screens/RenameWallet.tsx +0 -26
- package/src/screens/Scan.tsx +0 -145
- package/src/screens/ScanHelp.tsx +0 -48
- package/src/screens/Settings.tsx +0 -415
- package/src/screens/Splash.tsx +0 -80
- package/src/screens/Terms.tsx +0 -127
- package/src/screens/ToggleBiometry.tsx +0 -153
- package/src/screens/TogglePushNotifications.tsx +0 -118
- package/src/screens/Tours.tsx +0 -93
- package/src/screens/UpdateAvailable.tsx +0 -119
- package/src/screens/WhatAreContacts.tsx +0 -71
- package/src/services/bifoldLogger.ts +0 -3
- package/src/services/keychain.ts +0 -184
- package/src/services/logger.ts +0 -89
- package/src/services/storage.ts +0 -136
- package/src/theme-builder.ts +0 -157
- package/src/theme.interface.ts +0 -580
- package/src/theme.ts +0 -1346
- package/src/types/attempt-lockout-config.ts +0 -8
- package/src/types/attestation.ts +0 -17
- package/src/types/chat.ts +0 -4
- package/src/types/config.ts +0 -64
- package/src/types/contact-details.ts +0 -5
- package/src/types/credential-list-footer.ts +0 -3
- package/src/types/credential-status.ts +0 -3
- package/src/types/credentials.ts +0 -7
- package/src/types/decline.ts +0 -5
- package/src/types/error.ts +0 -40
- package/src/types/fn.ts +0 -2
- package/src/types/genesis.ts +0 -35
- package/src/types/index.ts +0 -2
- package/src/types/metadata.ts +0 -16
- package/src/types/navigators.ts +0 -239
- package/src/types/notification.ts +0 -24
- package/src/types/permissions.ts +0 -2
- package/src/types/proof-items.ts +0 -32
- package/src/types/react-i18next.d.ts +0 -10
- package/src/types/remove.ts +0 -8
- package/src/types/security.ts +0 -32
- package/src/types/settings.ts +0 -28
- package/src/types/state.ts +0 -97
- package/src/types/tour.ts +0 -20
- package/src/types/version-check.ts +0 -18
- package/src/utils/PINValidation.ts +0 -98
- package/src/utils/agent.ts +0 -128
- package/src/utils/anonCredsProofRequestMapper.ts +0 -205
- package/src/utils/contacts.ts +0 -59
- package/src/utils/cred-def.ts +0 -33
- package/src/utils/credential.ts +0 -37
- package/src/utils/crypto.ts +0 -12
- package/src/utils/fileCache.ts +0 -152
- package/src/utils/helpers.ts +0 -1292
- package/src/utils/ledger.ts +0 -212
- package/src/utils/luminance.ts +0 -40
- package/src/utils/mediatorhelpers.ts +0 -71
- package/src/utils/migration.ts +0 -40
- package/src/utils/network.tsx +0 -55
- package/src/utils/oca.ts +0 -173
- package/src/utils/parsers.tsx +0 -111
- package/src/utils/proofBundle.ts +0 -220
- package/src/utils/schema.ts +0 -28
- package/src/utils/testable.ts +0 -17
package/src/utils/helpers.ts
DELETED
|
@@ -1,1292 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
AnonCredsCredentialInfo,
|
|
3
|
-
AnonCredsCredentialsForProofRequest,
|
|
4
|
-
AnonCredsPredicateType,
|
|
5
|
-
AnonCredsProofRequest,
|
|
6
|
-
AnonCredsProofRequestRestriction,
|
|
7
|
-
AnonCredsRequestedAttribute,
|
|
8
|
-
AnonCredsRequestedAttributeMatch,
|
|
9
|
-
AnonCredsRequestedPredicate,
|
|
10
|
-
AnonCredsRequestedPredicateMatch,
|
|
11
|
-
getCredentialsForAnonCredsProofRequest,
|
|
12
|
-
} from '@credo-ts/anoncreds'
|
|
13
|
-
import {
|
|
14
|
-
Agent,
|
|
15
|
-
BasicMessageRecord,
|
|
16
|
-
ConnectionRecord,
|
|
17
|
-
CredentialExchangeRecord,
|
|
18
|
-
CredentialState,
|
|
19
|
-
HandshakeProtocol,
|
|
20
|
-
ProofExchangeRecord,
|
|
21
|
-
ProofState,
|
|
22
|
-
parseDid,
|
|
23
|
-
OutOfBandRecord,
|
|
24
|
-
CredentialPreviewAttribute,
|
|
25
|
-
OutOfBandRole,
|
|
26
|
-
} from '@credo-ts/core'
|
|
27
|
-
import { BasicMessageRole } from '@credo-ts/core/build/modules/basic-messages/BasicMessageRole'
|
|
28
|
-
import { useConnectionById } from '@credo-ts/react-hooks'
|
|
29
|
-
import { BrandingOverlay, CaptureBaseAttributeType } from '@bifold/oca'
|
|
30
|
-
import { Attribute, CredentialOverlay, Predicate } from '@bifold/oca/build/legacy'
|
|
31
|
-
import { Buffer } from 'buffer'
|
|
32
|
-
import moment from 'moment'
|
|
33
|
-
import { parseUrl } from 'query-string'
|
|
34
|
-
import { ReactNode } from 'react'
|
|
35
|
-
import { TFunction } from 'react-i18next'
|
|
36
|
-
import { DeviceEventEmitter } from 'react-native'
|
|
37
|
-
|
|
38
|
-
import { EventTypes, domain } from '../constants'
|
|
39
|
-
import { i18n } from '../localization/index'
|
|
40
|
-
import { BifoldLogger } from '../services/logger'
|
|
41
|
-
import { Role } from '../types/chat'
|
|
42
|
-
import { BifoldError } from '../types/error'
|
|
43
|
-
import { Screens, Stacks } from '../types/navigators'
|
|
44
|
-
import {
|
|
45
|
-
CredentialDataForProof,
|
|
46
|
-
ProofCredentialAttributes,
|
|
47
|
-
ProofCredentialItems,
|
|
48
|
-
ProofCredentialPredicates,
|
|
49
|
-
} from '../types/proof-items'
|
|
50
|
-
import { ChildFn } from '../types/tour'
|
|
51
|
-
|
|
52
|
-
import { BifoldAgent } from './agent'
|
|
53
|
-
import {
|
|
54
|
-
createAnonCredsProofRequest,
|
|
55
|
-
filterInvalidProofRequestMatches,
|
|
56
|
-
getDescriptorMetadata,
|
|
57
|
-
} from './anonCredsProofRequestMapper'
|
|
58
|
-
import { parseCredDefFromId } from './cred-def'
|
|
59
|
-
import { isOpenIdCredentialOffer, isOpenIdPresentationRequest } from './parsers'
|
|
60
|
-
import { isMediatorInvitation } from './mediatorhelpers'
|
|
61
|
-
|
|
62
|
-
export { parsedCredDefNameFromCredential } from './cred-def'
|
|
63
|
-
|
|
64
|
-
export { parsedCredDefName } from './cred-def'
|
|
65
|
-
export { parsedSchema } from './schema'
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Generates a numerical hash based on a given string
|
|
69
|
-
* @see https://stackoverflow.com/questions/3426404/create-a-hexadecimal-colour-based-on-a-string-with-javascript
|
|
70
|
-
* @param { string } s given string
|
|
71
|
-
* @returns { number } numerical hash value
|
|
72
|
-
*/
|
|
73
|
-
export const hashCode = (s: string): number => {
|
|
74
|
-
return s.split('').reduce((hash, char) => char.charCodeAt(0) + ((hash << 5) - hash), 0)
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Generates a pseudorandom number between 0 and 1 based on a seed
|
|
79
|
-
* @see https://gist.github.com/tommyettinger/46a874533244883189143505d203312c
|
|
80
|
-
* @see https://stackoverflow.com/questions/521295/seeding-the-random-number-generator-in-javascript
|
|
81
|
-
* @param { number } seed any number
|
|
82
|
-
* @returns { number } pseudorandom number between 0 and 1
|
|
83
|
-
*/
|
|
84
|
-
const mulberry32 = (seed: number) => {
|
|
85
|
-
let t = (seed += 0x6d2b79f5)
|
|
86
|
-
t = Math.imul(t ^ (t >>> 15), t | 1)
|
|
87
|
-
t ^= t + Math.imul(t ^ (t >>> 7), t | 61)
|
|
88
|
-
return ((t ^ (t >>> 14)) >>> 0) / 4294967296
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Converts a numerical hash into a hexidecimal color string
|
|
93
|
-
* @see https://helderesteves.com/generating-random-colors-js/#Generating_random_dark_colors
|
|
94
|
-
* @param { number } hash numerical hash value (generated by hashCode function above)
|
|
95
|
-
* @returns { string } hexidecimal string eg. #32d3cc
|
|
96
|
-
*/
|
|
97
|
-
export const hashToRGBA = (hash: number) => {
|
|
98
|
-
let color = '#'
|
|
99
|
-
const colorRangeUpperBound = 256
|
|
100
|
-
|
|
101
|
-
// once for r, g, b
|
|
102
|
-
for (let i = 0; i < 3; i++) {
|
|
103
|
-
// append a pseudorandom two-char hexidecimal value from the lower half of the color spectrum (to limit to darker colors)
|
|
104
|
-
color += ('0' + Math.floor((mulberry32(hash + i) * colorRangeUpperBound) / 2).toString(16)).slice(-2)
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
return color
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
*
|
|
111
|
-
* @param time
|
|
112
|
-
* @param params see below
|
|
113
|
-
* shortMonth: whether to use Jun in place of June, Mar in place of March for example (overridden by `format`)
|
|
114
|
-
* format: an optional custom moment format string to create the formatted date from
|
|
115
|
-
* includeHour: whether to add the hour and minute and am/pm. eg 9:32 pm (overridden by `chatFormat` and `trim`)
|
|
116
|
-
* chatFormat: whether to style the date to appear like a chat message timestamp eg. '7 minutes ago' or 'Just now'
|
|
117
|
-
* trim: if true, if it's the same day the date will be trimmed to just the hour, if it's the same year then the year will be trimmed from the date
|
|
118
|
-
* eg. if the current year is 2023, February 12, 2023 will be trimmed to February 12
|
|
119
|
-
* @returns formatted time string
|
|
120
|
-
*/
|
|
121
|
-
export function formatTime(
|
|
122
|
-
time: Date,
|
|
123
|
-
params?: { shortMonth?: boolean; format?: string; includeHour?: boolean; chatFormat?: boolean; trim?: boolean }
|
|
124
|
-
): string {
|
|
125
|
-
const getMonthKey = 'MMMM'
|
|
126
|
-
const momentTime = moment(time)
|
|
127
|
-
const monthKey = momentTime.format(getMonthKey)
|
|
128
|
-
const customMonthFormatRe = /M+/
|
|
129
|
-
const shortMonth = params?.shortMonth
|
|
130
|
-
const format = params?.format
|
|
131
|
-
const includeHour = params?.includeHour
|
|
132
|
-
const chatFormat = params?.chatFormat
|
|
133
|
-
const trim = params?.trim
|
|
134
|
-
const shortDateFormatMaskLength = 3
|
|
135
|
-
const millisecondsAgo = moment().diff(momentTime)
|
|
136
|
-
const lessThanAMinuteAgo = millisecondsAgo / 1000 / 60 < 1
|
|
137
|
-
const lessThanAnHourAgo = millisecondsAgo / 1000 / 60 / 60 < 1
|
|
138
|
-
const now = new Date()
|
|
139
|
-
const sameYear = time.getFullYear() === now.getFullYear()
|
|
140
|
-
const sameDay = time.getDate() === now.getDate() && time.getMonth() === now.getMonth() && sameYear
|
|
141
|
-
const isPortuguese = i18n.resolvedLanguage === 'pt-BR'
|
|
142
|
-
const isNonEnglish = i18n.resolvedLanguage === 'fr' || isPortuguese
|
|
143
|
-
const hoursFormat = isNonEnglish ? 'HH:mm' : 'h:mm a'
|
|
144
|
-
// for the shortened approach eg. in chat bubbles
|
|
145
|
-
if (chatFormat) {
|
|
146
|
-
if (lessThanAMinuteAgo) {
|
|
147
|
-
return i18n.t('Date.JustNow')
|
|
148
|
-
}
|
|
149
|
-
if (lessThanAnHourAgo) {
|
|
150
|
-
const minutesAgo = Math.floor(millisecondsAgo / 1000 / 60)
|
|
151
|
-
return minutesAgo === 1 ? `${i18n.t('Date.MinuteAgo')}` : `${i18n.t('Date.MinutesAgo', { count: minutesAgo })}`
|
|
152
|
-
}
|
|
153
|
-
if (sameDay) {
|
|
154
|
-
return momentTime.format(hoursFormat)
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
let formatString = i18n.t('Date.ShortFormat')
|
|
159
|
-
let formattedTime = ''
|
|
160
|
-
// if sameDay and abbreviated
|
|
161
|
-
if (sameDay && trim) {
|
|
162
|
-
return momentTime.format(hoursFormat)
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
if (format) {
|
|
166
|
-
formatString = format
|
|
167
|
-
formattedTime = momentTime.format(format)
|
|
168
|
-
} else {
|
|
169
|
-
if (!shortMonth) {
|
|
170
|
-
formatString = i18n.t('Date.LongFormat')
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
// if translation fails
|
|
174
|
-
if (formatString === 'Date.ShortFormat' || formatString === 'Date.LongFormat' || formatString === undefined) {
|
|
175
|
-
formatString = 'MMM D'
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
// if trim is true, don't include the year for same year times
|
|
179
|
-
formattedTime =
|
|
180
|
-
trim && sameYear
|
|
181
|
-
? momentTime.format(formatString)
|
|
182
|
-
: // if non-english, don't include comma between year and month
|
|
183
|
-
isNonEnglish
|
|
184
|
-
? `${momentTime.format(formatString)} ${momentTime.format('YYYY')}`
|
|
185
|
-
: `${momentTime.format(formatString)}, ${momentTime.format('YYYY')}`
|
|
186
|
-
if (includeHour) {
|
|
187
|
-
formattedTime = `${formattedTime}, ${momentTime.format(hoursFormat)}`
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
const customMonthFormat = formatString?.match(customMonthFormatRe)?.[0]
|
|
192
|
-
|
|
193
|
-
if (customMonthFormat) {
|
|
194
|
-
let monthReplacement = ''
|
|
195
|
-
const monthReplacementKey = momentTime.format(customMonthFormat)
|
|
196
|
-
if (customMonthFormat.length === shortDateFormatMaskLength) {
|
|
197
|
-
// then we know we're dealing with a short date format: 'MMM'
|
|
198
|
-
monthReplacement = i18n.t(`Date.MonthShort.${monthKey}`)
|
|
199
|
-
} else if (customMonthFormat.length > shortDateFormatMaskLength) {
|
|
200
|
-
// then we know we're working with a long date format: 'MMMM'
|
|
201
|
-
monthReplacement = i18n.t(`Date.MonthLong.${monthKey}`)
|
|
202
|
-
}
|
|
203
|
-
// if translation doesn't work
|
|
204
|
-
if (monthReplacement === `Date.MonthLong.${monthKey}` || monthReplacement === `Date.MonthShort.${monthKey}`) {
|
|
205
|
-
monthReplacement = monthReplacementKey
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
if (monthReplacement) {
|
|
209
|
-
formattedTime = formattedTime.replace(monthReplacementKey, monthReplacement)
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
return formattedTime
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
// need to use rolling b64 encode/decode to prevent hermes from 2048 byte truncation
|
|
216
|
-
export function b64encode(inp: string) {
|
|
217
|
-
return (
|
|
218
|
-
inp
|
|
219
|
-
.match(/.{1,3}/g)
|
|
220
|
-
?.map((chunk) => {
|
|
221
|
-
return Buffer.from(chunk).toString('base64')
|
|
222
|
-
})
|
|
223
|
-
.join('') ?? ''
|
|
224
|
-
)
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
export function b64decode(b64: string) {
|
|
228
|
-
return (
|
|
229
|
-
b64
|
|
230
|
-
.match(/.{1,4}/g)
|
|
231
|
-
?.map((chunk) => {
|
|
232
|
-
if (chunk.length < 4) {
|
|
233
|
-
chunk += '='.repeat(4 - chunk.length)
|
|
234
|
-
}
|
|
235
|
-
return Buffer.from(chunk, 'base64').toString()
|
|
236
|
-
})
|
|
237
|
-
.join('') ?? ''
|
|
238
|
-
)
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
export function formatIfDate(format: string | undefined, value: string | number | null) {
|
|
242
|
-
const potentialDate = value ? value.toString() : null
|
|
243
|
-
if (format === 'YYYYMMDD' && potentialDate && potentialDate.length === format.length) {
|
|
244
|
-
const year = potentialDate.substring(0, 4)
|
|
245
|
-
const month = potentialDate.substring(4, 6)
|
|
246
|
-
const day = potentialDate.substring(6, 8)
|
|
247
|
-
// NOTE: JavaScript counts months from 0 to 11: January = 0, December = 11.
|
|
248
|
-
const date = new Date(Number(year), Number(month) - 1, Number(day))
|
|
249
|
-
if (!isNaN(date.getDate())) {
|
|
250
|
-
return formatTime(date, { shortMonth: true })
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
return value
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
export function getConnectionName(
|
|
257
|
-
connection: ConnectionRecord | undefined,
|
|
258
|
-
alternateContactNames: Record<string, string>
|
|
259
|
-
): string {
|
|
260
|
-
return (
|
|
261
|
-
(connection?.id && alternateContactNames[connection?.id]) ||
|
|
262
|
-
connection?.theirLabel ||
|
|
263
|
-
connection?.alias ||
|
|
264
|
-
connection?.id ||
|
|
265
|
-
''
|
|
266
|
-
)
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
export function useCredentialConnectionLabel(credential?: CredentialExchangeRecord) {
|
|
270
|
-
const connection = useConnectionById(credential?.connectionId ?? '')
|
|
271
|
-
|
|
272
|
-
if (!credential) {
|
|
273
|
-
return ''
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
if (credential.connectionId) {
|
|
277
|
-
return connection?.alias || connection?.theirLabel || credential.connectionId
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
return 'Unknown Contact'
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
export function useConnectionImageUrl(connectionId: string) {
|
|
284
|
-
const connection = useConnectionById(connectionId)
|
|
285
|
-
if (!connection) {
|
|
286
|
-
return undefined
|
|
287
|
-
}
|
|
288
|
-
return connection.imageUrl ?? undefined
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
export function firstValidCredential(
|
|
292
|
-
fields: AnonCredsRequestedAttributeMatch[] | AnonCredsRequestedPredicateMatch[],
|
|
293
|
-
revoked = true
|
|
294
|
-
): AnonCredsRequestedAttributeMatch | AnonCredsRequestedPredicateMatch | null {
|
|
295
|
-
if (!fields.length) {
|
|
296
|
-
return null
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
let first = null
|
|
300
|
-
const firstNonRevoked = fields.filter((field) => !field.revoked)[0]
|
|
301
|
-
if (firstNonRevoked) {
|
|
302
|
-
first = firstNonRevoked
|
|
303
|
-
} else if (fields.length && revoked) {
|
|
304
|
-
first = fields[0]
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
if (!first?.credentialInfo) {
|
|
308
|
-
return null
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
return first
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
/**
|
|
315
|
-
* A sorting function for the Array `sort()` function
|
|
316
|
-
* @param a First retrieved credential
|
|
317
|
-
* @param b Second retrieved credential
|
|
318
|
-
*/
|
|
319
|
-
export const credentialSortFn = (a: any, b: any) => {
|
|
320
|
-
if (a.revoked && !b.revoked) {
|
|
321
|
-
return 1
|
|
322
|
-
} else if (!a.revoked && b.revoked) {
|
|
323
|
-
return -1
|
|
324
|
-
} else {
|
|
325
|
-
return b.timestamp - a.timestamp
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
const credNameFromRestriction = (queries?: AnonCredsProofRequestRestriction[]): string => {
|
|
330
|
-
let schema_name = ''
|
|
331
|
-
let cred_def_id = ''
|
|
332
|
-
let schema_id = ''
|
|
333
|
-
queries?.forEach((query) => {
|
|
334
|
-
schema_name = (query?.schema_name as string) ?? schema_name
|
|
335
|
-
cred_def_id = (query?.cred_def_id as string) ?? cred_def_id
|
|
336
|
-
schema_id = (query?.schema_id as string) ?? schema_id
|
|
337
|
-
})
|
|
338
|
-
if (schema_name && (schema_name.toLowerCase() !== 'default' || schema_name.toLowerCase() !== 'credential')) {
|
|
339
|
-
return schema_name
|
|
340
|
-
} else {
|
|
341
|
-
return parseCredDefFromId(cred_def_id, schema_id)
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
export const credDefIdFromRestrictions = (queries?: AnonCredsProofRequestRestriction[]): string => {
|
|
346
|
-
return queries?.filter((rstr) => rstr.cred_def_id)[0]?.cred_def_id ?? ''
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
export const schemaIdFromRestrictions = (queries?: AnonCredsProofRequestRestriction[]): string => {
|
|
350
|
-
const rstrWithSchemaId = queries?.filter(
|
|
351
|
-
(rstr) => rstr.schema_id || (rstr.issuer_did && rstr.schema_name && rstr.schema_version)
|
|
352
|
-
)[0]
|
|
353
|
-
|
|
354
|
-
// the '2' here is the enum of the transaction type which, for schemas, is always 2
|
|
355
|
-
const schemaId = rstrWithSchemaId
|
|
356
|
-
? rstrWithSchemaId.schema_id ||
|
|
357
|
-
`${rstrWithSchemaId.issuer_did}:2:${rstrWithSchemaId.schema_name}:${rstrWithSchemaId.schema_version}`
|
|
358
|
-
: ''
|
|
359
|
-
return schemaId
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
export const isDataUrl = (value: string | number | null) => {
|
|
363
|
-
return typeof value === 'string' && value.startsWith('data:image/')
|
|
364
|
-
}
|
|
365
|
-
export type Fields = Record<string, AnonCredsRequestedAttributeMatch[] | AnonCredsRequestedPredicateMatch[]>
|
|
366
|
-
|
|
367
|
-
/**
|
|
368
|
-
* Retrieve current credentials info filtered by `credentialDefinitionId` if given.
|
|
369
|
-
* @param credDefId Credential Definition Id
|
|
370
|
-
* @returns Array of `AnonCredsCredentialInfo`
|
|
371
|
-
*/
|
|
372
|
-
export const getCredentialInfo = (credId: string, fields: Fields): AnonCredsCredentialInfo[] => {
|
|
373
|
-
const credentialInfo: AnonCredsCredentialInfo[] = []
|
|
374
|
-
|
|
375
|
-
Object.keys(fields).forEach((proofKey) => {
|
|
376
|
-
credentialInfo.push(...fields[proofKey].map((attr) => attr.credentialInfo))
|
|
377
|
-
})
|
|
378
|
-
|
|
379
|
-
return !credId ? credentialInfo : credentialInfo.filter((cred) => cred.credentialId === credId)
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
/**
|
|
383
|
-
* Evaluate if given attribute value satisfies the predicate.
|
|
384
|
-
* @param attribute Credential attribute value
|
|
385
|
-
* @param pValue Predicate value
|
|
386
|
-
* @param pType Predicate type ({@link AnonCredsPredicateType})
|
|
387
|
-
* @returns `true`if predicate is satisfied, otherwise `false`
|
|
388
|
-
*/
|
|
389
|
-
const evaluateOperation = (attribute: number, pValue: number, pType: AnonCredsPredicateType): boolean => {
|
|
390
|
-
if (pType === '>=') {
|
|
391
|
-
return attribute >= pValue
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
if (pType === '>') {
|
|
395
|
-
return attribute > pValue
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
if (pType === '<=') {
|
|
399
|
-
return attribute <= pValue
|
|
400
|
-
}
|
|
401
|
-
if (pType === '<') {
|
|
402
|
-
return attribute < pValue
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
return false
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
/**
|
|
409
|
-
* Given proof credential items, evaluate and return its predicates, setting `satisfied` property.
|
|
410
|
-
* @param proofCredentialsItems
|
|
411
|
-
* @returns Array of evaluated predicates
|
|
412
|
-
*/
|
|
413
|
-
export const evaluatePredicates =
|
|
414
|
-
(fields: Fields, credId?: string) =>
|
|
415
|
-
(proofCredentialItems: ProofCredentialItems): Predicate[] => {
|
|
416
|
-
const predicates = proofCredentialItems.predicates
|
|
417
|
-
if (!predicates || predicates.length == 0) {
|
|
418
|
-
return []
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
if ((credId && credId != proofCredentialItems.credId) || !proofCredentialItems.credId) {
|
|
422
|
-
return []
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
const credentialAttributes = getCredentialInfo(proofCredentialItems.credId, fields).map((ci) => ci.attributes)
|
|
426
|
-
|
|
427
|
-
return predicates.map((predicate: Predicate) => {
|
|
428
|
-
const { pType: pType, pValue: pValue, name: field } = predicate
|
|
429
|
-
let satisfied = false
|
|
430
|
-
|
|
431
|
-
if (field) {
|
|
432
|
-
const attribute = (credentialAttributes.find((attr) => attr[field] != undefined) ?? {})[field]
|
|
433
|
-
|
|
434
|
-
if (attribute && pValue) {
|
|
435
|
-
satisfied = evaluateOperation(Number(attribute), Number(pValue), pType as AnonCredsPredicateType)
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
return { ...predicate, satisfied }
|
|
440
|
-
})
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
// scans through requested attributes and records
|
|
444
|
-
// Builds and returns label: value attributes
|
|
445
|
-
// Flagging any attribute not found in wallet credentials
|
|
446
|
-
const addMissingDisplayAttributes = (
|
|
447
|
-
attrReq: AnonCredsRequestedAttribute,
|
|
448
|
-
records: CredentialExchangeRecord[]
|
|
449
|
-
): ProofCredentialAttributes => {
|
|
450
|
-
const { name, names, restrictions } = attrReq
|
|
451
|
-
const credName = credNameFromRestriction(restrictions)
|
|
452
|
-
const credDefId = credDefIdFromRestrictions(restrictions)
|
|
453
|
-
const schemaId = schemaIdFromRestrictions(restrictions)
|
|
454
|
-
|
|
455
|
-
//there is no credId in this context so use credName as a placeholder
|
|
456
|
-
const processedAttributes: ProofCredentialAttributes = {
|
|
457
|
-
credExchangeRecord: undefined,
|
|
458
|
-
altCredentials: [credName],
|
|
459
|
-
credId: credName,
|
|
460
|
-
schemaId,
|
|
461
|
-
credDefId,
|
|
462
|
-
credName: credName,
|
|
463
|
-
attributes: [] as Attribute[],
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
// Filter records for requested schema id of credential definition id
|
|
467
|
-
const filteredCredentialRecords = records.filter(
|
|
468
|
-
(record: CredentialExchangeRecord) =>
|
|
469
|
-
getCredentialSchemaIdForRecord(record) === schemaId || getCredentialDefinitionIdForRecord(record) === credDefId
|
|
470
|
-
)
|
|
471
|
-
|
|
472
|
-
// for reach requested attribute
|
|
473
|
-
// scan through filtered credential attributes
|
|
474
|
-
// display any that are found
|
|
475
|
-
// flag any not found attributes with an error
|
|
476
|
-
for (const attributeName of [...(names ?? (name && [name]) ?? [])]) {
|
|
477
|
-
// filter through credential record attributes for a given name
|
|
478
|
-
const [attribute] = filteredCredentialRecords.map((item: CredentialExchangeRecord) => {
|
|
479
|
-
return item.credentialAttributes?.filter(
|
|
480
|
-
(attribute: CredentialPreviewAttribute) => attribute.name === attributeName
|
|
481
|
-
)
|
|
482
|
-
})
|
|
483
|
-
if (attribute && attribute.length > 0) {
|
|
484
|
-
// attribute found, display as expected
|
|
485
|
-
processedAttributes.attributes?.push(
|
|
486
|
-
new Attribute({
|
|
487
|
-
revoked: false,
|
|
488
|
-
credentialId: credName,
|
|
489
|
-
name: attributeName,
|
|
490
|
-
value: attribute[0].value,
|
|
491
|
-
hasError: false,
|
|
492
|
-
})
|
|
493
|
-
)
|
|
494
|
-
} else {
|
|
495
|
-
// no attribute found, flag this with an error
|
|
496
|
-
processedAttributes.attributes?.push(
|
|
497
|
-
new Attribute({
|
|
498
|
-
revoked: false,
|
|
499
|
-
credentialId: credName,
|
|
500
|
-
name: attributeName,
|
|
501
|
-
value: '',
|
|
502
|
-
hasError: true,
|
|
503
|
-
})
|
|
504
|
-
)
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
return processedAttributes
|
|
508
|
-
}
|
|
509
|
-
export const processProofAttributes = (
|
|
510
|
-
t: TFunction<'translation', undefined>,
|
|
511
|
-
request?: AnonCredsProofRequest,
|
|
512
|
-
credentials?: AnonCredsCredentialsForProofRequest, // credentials that 100% validate the proof request
|
|
513
|
-
credentialRecords?: CredentialExchangeRecord[], // all the credentials in the wallet
|
|
514
|
-
groupByReferent?: boolean
|
|
515
|
-
): { [key: string]: ProofCredentialAttributes } => {
|
|
516
|
-
const processedAttributes = {} as { [key: string]: ProofCredentialAttributes }
|
|
517
|
-
const requestedProofAttributes = request?.requested_attributes
|
|
518
|
-
const retrievedCredentialAttributes = credentials?.attributes
|
|
519
|
-
const requestNonRevoked = request?.non_revoked // non_revoked interval can sometimes be top level
|
|
520
|
-
|
|
521
|
-
// no proof or credential attributes, nothing to process, leave early
|
|
522
|
-
if (!requestedProofAttributes || !retrievedCredentialAttributes) {
|
|
523
|
-
return {}
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
for (const key of Object.keys(retrievedCredentialAttributes)) {
|
|
527
|
-
const altCredentials = [...(retrievedCredentialAttributes[key] ?? [])]
|
|
528
|
-
.sort(credentialSortFn)
|
|
529
|
-
.map((cred) => cred.credentialId)
|
|
530
|
-
|
|
531
|
-
const credentialList = [...(retrievedCredentialAttributes[key] ?? [])].sort(credentialSortFn)
|
|
532
|
-
const { name, names, non_revoked, restrictions } = requestedProofAttributes[key]
|
|
533
|
-
|
|
534
|
-
// system assumes one of these values is present in a proof request
|
|
535
|
-
const proofCredDefId = credDefIdFromRestrictions(restrictions)
|
|
536
|
-
const proofSchemaId = schemaIdFromRestrictions(restrictions)
|
|
537
|
-
|
|
538
|
-
// No credentials satisfy proof request, process attribute errors
|
|
539
|
-
if (credentialList.length <= 0) {
|
|
540
|
-
const missingAttributes = addMissingDisplayAttributes(requestedProofAttributes[key], credentialRecords ?? [])
|
|
541
|
-
const missingCredGroupKey = groupByReferent ? key : missingAttributes.credName
|
|
542
|
-
if (!processedAttributes[missingCredGroupKey]) {
|
|
543
|
-
processedAttributes[missingCredGroupKey] = missingAttributes
|
|
544
|
-
} else {
|
|
545
|
-
processedAttributes[missingCredGroupKey].attributes?.push(...(missingAttributes.attributes ?? []))
|
|
546
|
-
}
|
|
547
|
-
}
|
|
548
|
-
//iterate over all credentials that satisfy the proof
|
|
549
|
-
for (const credential of credentialList) {
|
|
550
|
-
let credName = key
|
|
551
|
-
if (credential?.credentialInfo?.credentialDefinitionId || credential?.credentialInfo?.schemaId) {
|
|
552
|
-
credName = parseCredDefFromId(
|
|
553
|
-
credential?.credentialInfo?.credentialDefinitionId,
|
|
554
|
-
credential?.credentialInfo?.schemaId
|
|
555
|
-
)
|
|
556
|
-
}
|
|
557
|
-
let revoked = false
|
|
558
|
-
let credExchangeRecord = undefined
|
|
559
|
-
if (credential) {
|
|
560
|
-
credExchangeRecord = credentialRecords?.find(
|
|
561
|
-
(record) =>
|
|
562
|
-
record.credentials.map((cred) => cred.credentialRecordId).includes(credential.credentialId) ||
|
|
563
|
-
record.id === credential.credentialId
|
|
564
|
-
)
|
|
565
|
-
revoked = credExchangeRecord?.revocationNotification !== undefined
|
|
566
|
-
} else {
|
|
567
|
-
continue
|
|
568
|
-
}
|
|
569
|
-
for (const attributeName of [...(names ?? (name && [name]) ?? [])]) {
|
|
570
|
-
if (!processedAttributes[credential.credentialId]) {
|
|
571
|
-
// init processedAttributes object
|
|
572
|
-
processedAttributes[credential.credentialId] = {
|
|
573
|
-
credExchangeRecord,
|
|
574
|
-
altCredentials,
|
|
575
|
-
credId: credential?.credentialId,
|
|
576
|
-
schemaId: credential?.credentialInfo?.schemaId ?? proofSchemaId,
|
|
577
|
-
credDefId: credential?.credentialInfo?.credentialDefinitionId ?? proofCredDefId,
|
|
578
|
-
credName,
|
|
579
|
-
attributes: [],
|
|
580
|
-
}
|
|
581
|
-
}
|
|
582
|
-
|
|
583
|
-
const attributeValue = credential ? credential.credentialInfo.attributes[attributeName] : null
|
|
584
|
-
processedAttributes[credential.credentialId].attributes?.push(
|
|
585
|
-
new Attribute({
|
|
586
|
-
...requestedProofAttributes[key],
|
|
587
|
-
revoked,
|
|
588
|
-
credentialId: credential.credentialId,
|
|
589
|
-
name: attributeName,
|
|
590
|
-
value: attributeValue,
|
|
591
|
-
nonRevoked: requestNonRevoked ?? non_revoked,
|
|
592
|
-
})
|
|
593
|
-
)
|
|
594
|
-
}
|
|
595
|
-
}
|
|
596
|
-
}
|
|
597
|
-
|
|
598
|
-
return processedAttributes
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
export const mergeAttributesAndPredicates = (
|
|
602
|
-
attributes: { [key: string]: ProofCredentialAttributes },
|
|
603
|
-
predicates: { [key: string]: ProofCredentialPredicates }
|
|
604
|
-
) => {
|
|
605
|
-
const merged: { [key: string]: ProofCredentialAttributes & ProofCredentialPredicates } = { ...attributes }
|
|
606
|
-
for (const [key, predicate] of Object.entries(predicates)) {
|
|
607
|
-
const existingEntry = merged[key]
|
|
608
|
-
if (existingEntry) {
|
|
609
|
-
const mergedAltCreds = existingEntry.altCredentials?.filter((credId: string) =>
|
|
610
|
-
predicate.altCredentials?.includes(credId)
|
|
611
|
-
)
|
|
612
|
-
merged[key] = { ...existingEntry, ...predicate }
|
|
613
|
-
merged[key].altCredentials = mergedAltCreds
|
|
614
|
-
} else {
|
|
615
|
-
merged[key] = predicate
|
|
616
|
-
}
|
|
617
|
-
}
|
|
618
|
-
return merged
|
|
619
|
-
}
|
|
620
|
-
|
|
621
|
-
const addMissingDisplayPredicates = (predReq: AnonCredsRequestedPredicate) => {
|
|
622
|
-
const { name, p_type: pType, p_value: pValue, restrictions } = predReq
|
|
623
|
-
|
|
624
|
-
const credName = credNameFromRestriction(restrictions)
|
|
625
|
-
const credDefId = credDefIdFromRestrictions(restrictions)
|
|
626
|
-
const schemaId = schemaIdFromRestrictions(restrictions)
|
|
627
|
-
|
|
628
|
-
//there is no credId in this context so use credName as a placeholder
|
|
629
|
-
const processedPredicates: ProofCredentialPredicates = {
|
|
630
|
-
credExchangeRecord: undefined,
|
|
631
|
-
altCredentials: [credName],
|
|
632
|
-
credId: credName,
|
|
633
|
-
schemaId,
|
|
634
|
-
credDefId,
|
|
635
|
-
credName: credName,
|
|
636
|
-
predicates: [] as Predicate[],
|
|
637
|
-
}
|
|
638
|
-
|
|
639
|
-
processedPredicates.predicates?.push(
|
|
640
|
-
new Predicate({
|
|
641
|
-
revoked: false,
|
|
642
|
-
credentialId: credName,
|
|
643
|
-
name: name,
|
|
644
|
-
pValue,
|
|
645
|
-
pType,
|
|
646
|
-
})
|
|
647
|
-
)
|
|
648
|
-
return processedPredicates
|
|
649
|
-
}
|
|
650
|
-
export const processProofPredicates = (
|
|
651
|
-
request?: AnonCredsProofRequest,
|
|
652
|
-
credentials?: AnonCredsCredentialsForProofRequest,
|
|
653
|
-
credentialRecords?: CredentialExchangeRecord[],
|
|
654
|
-
groupByReferent?: boolean
|
|
655
|
-
): { [key: string]: ProofCredentialPredicates } => {
|
|
656
|
-
const processedPredicates = {} as { [key: string]: ProofCredentialPredicates }
|
|
657
|
-
const requestedProofPredicates = request?.requested_predicates
|
|
658
|
-
const retrievedCredentialPredicates = credentials?.predicates
|
|
659
|
-
const requestNonRevoked = request?.non_revoked // // non_revoked interval can sometimes be top level
|
|
660
|
-
|
|
661
|
-
if (!requestedProofPredicates || !retrievedCredentialPredicates) {
|
|
662
|
-
return {}
|
|
663
|
-
}
|
|
664
|
-
|
|
665
|
-
for (const key of Object.keys(retrievedCredentialPredicates)) {
|
|
666
|
-
const altCredentials = [...(retrievedCredentialPredicates[key] ?? [])]
|
|
667
|
-
.sort(credentialSortFn)
|
|
668
|
-
.map((cred) => cred.credentialId)
|
|
669
|
-
|
|
670
|
-
const credentialList = [...(retrievedCredentialPredicates[key] ?? [])].sort(credentialSortFn)
|
|
671
|
-
const { name, p_type: pType, p_value: pValue, non_revoked, restrictions } = requestedProofPredicates[key]
|
|
672
|
-
const proofCredDefId = credDefIdFromRestrictions(restrictions)
|
|
673
|
-
const proofSchemaId = schemaIdFromRestrictions(restrictions)
|
|
674
|
-
|
|
675
|
-
if (credentialList.length <= 0) {
|
|
676
|
-
const missingPredicates = addMissingDisplayPredicates(requestedProofPredicates[key])
|
|
677
|
-
const missingCredGroupKey = groupByReferent ? key : missingPredicates.credName
|
|
678
|
-
if (!processedPredicates[missingCredGroupKey]) {
|
|
679
|
-
processedPredicates[missingCredGroupKey] = missingPredicates
|
|
680
|
-
} else {
|
|
681
|
-
processedPredicates[missingCredGroupKey].predicates?.push(...(missingPredicates.predicates ?? []))
|
|
682
|
-
}
|
|
683
|
-
}
|
|
684
|
-
|
|
685
|
-
for (const credential of credentialList) {
|
|
686
|
-
let revoked = false
|
|
687
|
-
let credExchangeRecord = undefined
|
|
688
|
-
if (credential) {
|
|
689
|
-
credExchangeRecord = credentialRecords?.find(
|
|
690
|
-
(record) =>
|
|
691
|
-
record.credentials.map((cred) => cred.credentialRecordId).includes(credential.credentialId) ||
|
|
692
|
-
record.id === credential.credentialId
|
|
693
|
-
)
|
|
694
|
-
revoked = credExchangeRecord?.revocationNotification !== undefined
|
|
695
|
-
} else {
|
|
696
|
-
continue
|
|
697
|
-
}
|
|
698
|
-
const { credentialDefinitionId, schemaId } = { ...credential, ...credential?.credentialInfo }
|
|
699
|
-
|
|
700
|
-
const credNameRestriction = credNameFromRestriction(requestedProofPredicates[key]?.restrictions)
|
|
701
|
-
|
|
702
|
-
let credName = credNameRestriction ?? key
|
|
703
|
-
if (credential?.credentialInfo?.credentialDefinitionId || credential?.credentialInfo?.schemaId) {
|
|
704
|
-
credName = parseCredDefFromId(
|
|
705
|
-
credential?.credentialInfo?.credentialDefinitionId,
|
|
706
|
-
credential?.credentialInfo?.schemaId
|
|
707
|
-
)
|
|
708
|
-
}
|
|
709
|
-
if (!processedPredicates[credential.credentialId]) {
|
|
710
|
-
processedPredicates[credential.credentialId] = {
|
|
711
|
-
altCredentials,
|
|
712
|
-
credExchangeRecord,
|
|
713
|
-
credId: credential.credentialId,
|
|
714
|
-
schemaId: schemaId ?? proofSchemaId,
|
|
715
|
-
credDefId: credentialDefinitionId ?? proofCredDefId,
|
|
716
|
-
credName: credName,
|
|
717
|
-
predicates: [],
|
|
718
|
-
}
|
|
719
|
-
}
|
|
720
|
-
|
|
721
|
-
processedPredicates[credential.credentialId].predicates?.push(
|
|
722
|
-
new Predicate({
|
|
723
|
-
...requestedProofPredicates[key],
|
|
724
|
-
credentialId: credential?.credentialId,
|
|
725
|
-
name,
|
|
726
|
-
revoked,
|
|
727
|
-
pValue,
|
|
728
|
-
pType,
|
|
729
|
-
nonRevoked: requestNonRevoked ?? non_revoked,
|
|
730
|
-
})
|
|
731
|
-
)
|
|
732
|
-
}
|
|
733
|
-
}
|
|
734
|
-
return processedPredicates
|
|
735
|
-
}
|
|
736
|
-
|
|
737
|
-
export const retrieveCredentialsForProof = async (
|
|
738
|
-
agent: BifoldAgent,
|
|
739
|
-
proof: ProofExchangeRecord,
|
|
740
|
-
fullCredentials: CredentialExchangeRecord[],
|
|
741
|
-
t: TFunction<'translation', undefined>,
|
|
742
|
-
groupByReferent?: boolean
|
|
743
|
-
): Promise<CredentialDataForProof | undefined> => {
|
|
744
|
-
// This is the only valid state to retrieve credentials for a proof
|
|
745
|
-
// `getCredentialsForRequest` will fail otherwise.
|
|
746
|
-
// if a proof is declined, it will move out of a RequestReceived state
|
|
747
|
-
// and this will fail because it is running against a declined proof
|
|
748
|
-
if (proof.state !== ProofState.RequestReceived) {
|
|
749
|
-
return
|
|
750
|
-
}
|
|
751
|
-
|
|
752
|
-
try {
|
|
753
|
-
const format = await agent.proofs.getFormatData(proof.id)
|
|
754
|
-
const hasPresentationExchange = format.request?.presentationExchange !== undefined
|
|
755
|
-
const hasAnonCreds = format.request?.anoncreds !== undefined
|
|
756
|
-
const hasIndy = format.request?.indy !== undefined
|
|
757
|
-
|
|
758
|
-
// Will fail if credential not in state 'request-received'
|
|
759
|
-
const credentialsAsPromise = agent.proofs.getCredentialsForRequest({
|
|
760
|
-
proofRecordId: proof.id,
|
|
761
|
-
proofFormats: {
|
|
762
|
-
// FIXME: Credo will try to use the format, even if the value is undefined (but the key is present)
|
|
763
|
-
// We should ignore the key, if the value is undefined. For now this is a workaround.
|
|
764
|
-
...(hasIndy
|
|
765
|
-
? {
|
|
766
|
-
indy: {
|
|
767
|
-
// Setting `filterByNonRevocationRequirements` to `false` returns all
|
|
768
|
-
// credentials even if they are revokable (and revoked). We need this to
|
|
769
|
-
// be able to show why a proof cannot be satisfied. Otherwise we can only
|
|
770
|
-
// show failure.
|
|
771
|
-
filterByNonRevocationRequirements: true,
|
|
772
|
-
},
|
|
773
|
-
}
|
|
774
|
-
: {}),
|
|
775
|
-
...(hasAnonCreds
|
|
776
|
-
? {
|
|
777
|
-
anoncreds: {
|
|
778
|
-
// Setting `filterByNonRevocationRequirements` to `false` returns all
|
|
779
|
-
// credentials even if they are revokable (and revoked). We need this to
|
|
780
|
-
// be able to show why a proof cannot be satisfied. Otherwise we can only
|
|
781
|
-
// show failure.
|
|
782
|
-
filterByNonRevocationRequirements: true,
|
|
783
|
-
},
|
|
784
|
-
}
|
|
785
|
-
: {}),
|
|
786
|
-
...(hasPresentationExchange ? { presentationExchange: {} } : {}),
|
|
787
|
-
},
|
|
788
|
-
})
|
|
789
|
-
|
|
790
|
-
// Will fail if credential not in state 'request-received'
|
|
791
|
-
const credentialsWithRevokedAsPromise = agent.proofs.getCredentialsForRequest({
|
|
792
|
-
proofRecordId: proof.id,
|
|
793
|
-
proofFormats: {
|
|
794
|
-
// FIXME: Credo will try to use the format, even if the value is undefined (but the key is present)
|
|
795
|
-
// We should ignore the key, if the value is undefined. For now this is a workaround.
|
|
796
|
-
...(hasIndy
|
|
797
|
-
? {
|
|
798
|
-
indy: {
|
|
799
|
-
// Setting `filterByNonRevocationRequirements` to `false` returns all
|
|
800
|
-
// credentials even if they are revokable (and revoked). We need this to
|
|
801
|
-
// be able to show why a proof cannot be satisfied. Otherwise we can only
|
|
802
|
-
// show failure.
|
|
803
|
-
filterByNonRevocationRequirements: false,
|
|
804
|
-
},
|
|
805
|
-
}
|
|
806
|
-
: {}),
|
|
807
|
-
...(hasAnonCreds
|
|
808
|
-
? {
|
|
809
|
-
anoncreds: {
|
|
810
|
-
// Setting `filterByNonRevocationRequirements` to `false` returns all
|
|
811
|
-
// credentials even if they are revokable (and revoked). We need this to
|
|
812
|
-
// be able to show why a proof cannot be satisfied. Otherwise we can only
|
|
813
|
-
// show failure.
|
|
814
|
-
filterByNonRevocationRequirements: false,
|
|
815
|
-
},
|
|
816
|
-
}
|
|
817
|
-
: {}),
|
|
818
|
-
...(hasPresentationExchange ? { presentationExchange: {} } : {}),
|
|
819
|
-
},
|
|
820
|
-
})
|
|
821
|
-
|
|
822
|
-
const [credentials, credentialsWithRevoked] = await Promise.all([
|
|
823
|
-
credentialsAsPromise,
|
|
824
|
-
credentialsWithRevokedAsPromise,
|
|
825
|
-
])
|
|
826
|
-
|
|
827
|
-
// In the case where there are only revoked credentials to satisfy a proof,
|
|
828
|
-
// include them for errors on the proof screen, otherwise leave them out
|
|
829
|
-
const addRevokedCredsIfNeeded = (proofFormat: 'indy' | 'anoncreds', proofItem: 'attributes' | 'predicates') => {
|
|
830
|
-
if (credentials.proofFormats[proofFormat] && credentialsWithRevoked.proofFormats[proofFormat]) {
|
|
831
|
-
Object.keys(credentials.proofFormats[proofFormat]?.[proofItem] ?? {}).forEach((key) => {
|
|
832
|
-
if (
|
|
833
|
-
credentials.proofFormats[proofFormat] &&
|
|
834
|
-
!credentials.proofFormats[proofFormat]?.[proofItem][key]?.length
|
|
835
|
-
) {
|
|
836
|
-
credentials.proofFormats[proofFormat]?.[proofItem][key].push(
|
|
837
|
-
...(credentialsWithRevoked.proofFormats[proofFormat]?.[proofItem][key] ?? ([] as any[]))
|
|
838
|
-
)
|
|
839
|
-
}
|
|
840
|
-
})
|
|
841
|
-
}
|
|
842
|
-
}
|
|
843
|
-
|
|
844
|
-
for (const proofFormat of ['indy', 'anoncreds']) {
|
|
845
|
-
for (const proofItem of ['attributes', 'predicates']) {
|
|
846
|
-
addRevokedCredsIfNeeded(proofFormat as 'indy' | 'anoncreds', proofItem as 'attributes' | 'predicates')
|
|
847
|
-
}
|
|
848
|
-
}
|
|
849
|
-
|
|
850
|
-
if (!credentials) {
|
|
851
|
-
throw new Error(t('ProofRequest.RequestedCredentialsCouldNotBeFound'))
|
|
852
|
-
}
|
|
853
|
-
|
|
854
|
-
if (!format) {
|
|
855
|
-
throw new Error(t('ProofRequest.RequestedCredentialsCouldNotBeFound'))
|
|
856
|
-
}
|
|
857
|
-
|
|
858
|
-
if (!(format && credentials && fullCredentials)) {
|
|
859
|
-
return
|
|
860
|
-
}
|
|
861
|
-
|
|
862
|
-
if (hasPresentationExchange) {
|
|
863
|
-
// FIXME: non revocation requirements
|
|
864
|
-
const presentationExchange = format.request?.presentationExchange
|
|
865
|
-
const difPexCredentialsForRequest = credentials.proofFormats.presentationExchange
|
|
866
|
-
|
|
867
|
-
if (!difPexCredentialsForRequest || !presentationExchange) throw new Error('Invalid presentation request')
|
|
868
|
-
|
|
869
|
-
const presentationDefinition = presentationExchange.presentation_definition
|
|
870
|
-
const descriptorMetadata = getDescriptorMetadata(difPexCredentialsForRequest)
|
|
871
|
-
const anonCredsProofRequest = createAnonCredsProofRequest(presentationDefinition, descriptorMetadata)
|
|
872
|
-
const anonCredsCredentialsForRequest = await getCredentialsForAnonCredsProofRequest(
|
|
873
|
-
agent.context,
|
|
874
|
-
anonCredsProofRequest,
|
|
875
|
-
{ filterByNonRevocationRequirements: false }
|
|
876
|
-
)
|
|
877
|
-
|
|
878
|
-
const filtered = filterInvalidProofRequestMatches(anonCredsCredentialsForRequest, descriptorMetadata)
|
|
879
|
-
const processedAttributes = processProofAttributes(
|
|
880
|
-
t,
|
|
881
|
-
anonCredsProofRequest,
|
|
882
|
-
filtered,
|
|
883
|
-
fullCredentials,
|
|
884
|
-
groupByReferent
|
|
885
|
-
)
|
|
886
|
-
const processedPredicates = processProofPredicates(
|
|
887
|
-
anonCredsProofRequest,
|
|
888
|
-
filtered,
|
|
889
|
-
fullCredentials,
|
|
890
|
-
groupByReferent
|
|
891
|
-
)
|
|
892
|
-
const groupedProof = Object.values(mergeAttributesAndPredicates(processedAttributes, processedPredicates))
|
|
893
|
-
|
|
894
|
-
return {
|
|
895
|
-
groupedProof,
|
|
896
|
-
retrievedCredentials: filtered,
|
|
897
|
-
fullCredentials,
|
|
898
|
-
descriptorMetadata,
|
|
899
|
-
}
|
|
900
|
-
}
|
|
901
|
-
|
|
902
|
-
const proofRequest = format.request?.anoncreds ?? format.request?.indy
|
|
903
|
-
const proofFormat = credentials.proofFormats.anoncreds ?? credentials.proofFormats.indy
|
|
904
|
-
|
|
905
|
-
const attributes = processProofAttributes(t, proofRequest, proofFormat, fullCredentials, groupByReferent)
|
|
906
|
-
const predicates = processProofPredicates(proofRequest, proofFormat, fullCredentials, groupByReferent)
|
|
907
|
-
const groupedProof = Object.values(mergeAttributesAndPredicates(attributes, predicates))
|
|
908
|
-
|
|
909
|
-
return { groupedProof, retrievedCredentials: proofFormat, fullCredentials }
|
|
910
|
-
} catch (err: unknown) {
|
|
911
|
-
const error = new BifoldError(t('Error.Title1043'), t('Error.Message1043'), (err as Error)?.message ?? err, 1043)
|
|
912
|
-
DeviceEventEmitter.emit(EventTypes.ERROR_ADDED, error)
|
|
913
|
-
}
|
|
914
|
-
}
|
|
915
|
-
|
|
916
|
-
export const pTypeToText = (
|
|
917
|
-
item: Predicate,
|
|
918
|
-
t: TFunction<'translation', undefined>,
|
|
919
|
-
attributeTypes?: Record<string, string>
|
|
920
|
-
) => {
|
|
921
|
-
const itemCopy = { ...item }
|
|
922
|
-
const pTypeMap: { [key: string]: string | undefined } = {
|
|
923
|
-
'>=': t('ProofRequest.PredicateGe'),
|
|
924
|
-
'>': t('ProofRequest.PredicateGr'),
|
|
925
|
-
'<=': t('ProofRequest.PredicateLe'),
|
|
926
|
-
'<': t('ProofRequest.PredicateLs'),
|
|
927
|
-
}
|
|
928
|
-
const pTypeDateMap: { [key: string]: string | undefined } = {
|
|
929
|
-
'>=': t('ProofRequest.PredicateGeDate'),
|
|
930
|
-
'>': t('ProofRequest.PredicateGeDate'),
|
|
931
|
-
'<=': t('ProofRequest.PredicateLeDate'),
|
|
932
|
-
'<': t('ProofRequest.PredicateLeDate'),
|
|
933
|
-
}
|
|
934
|
-
const pTypeDateOffset: { [key: string]: number | undefined } = {
|
|
935
|
-
'>=': -1,
|
|
936
|
-
'<=': 1,
|
|
937
|
-
}
|
|
938
|
-
if (attributeTypes && attributeTypes[item.name ?? ''] == CaptureBaseAttributeType.DateTime) {
|
|
939
|
-
itemCopy.pType = pTypeDateMap[item.pType] ?? item.pType
|
|
940
|
-
itemCopy.pValue = parseInt(`${itemCopy.pValue}`) + (pTypeDateOffset[item.pType] ?? 0)
|
|
941
|
-
} else {
|
|
942
|
-
itemCopy.pType = pTypeMap[item.pType] ?? item.pType
|
|
943
|
-
}
|
|
944
|
-
return itemCopy
|
|
945
|
-
}
|
|
946
|
-
|
|
947
|
-
/**
|
|
948
|
-
* @deprecated The function should not be used
|
|
949
|
-
*/
|
|
950
|
-
export const sortCredentialsForAutoSelect = (
|
|
951
|
-
credentials: AnonCredsCredentialsForProofRequest
|
|
952
|
-
): AnonCredsCredentialsForProofRequest => {
|
|
953
|
-
const requestedAttributes = Object.values(credentials?.attributes).pop()
|
|
954
|
-
const requestedPredicates = Object.values(credentials?.predicates).pop()
|
|
955
|
-
const sortFn = (a: any, b: any) => {
|
|
956
|
-
if (a.revoked && !b.revoked) {
|
|
957
|
-
return 1
|
|
958
|
-
} else if (!a.revoked && b.revoked) {
|
|
959
|
-
return -1
|
|
960
|
-
} else {
|
|
961
|
-
return b.timestamp - a.timestamp
|
|
962
|
-
}
|
|
963
|
-
}
|
|
964
|
-
|
|
965
|
-
requestedAttributes && requestedAttributes.sort(sortFn)
|
|
966
|
-
requestedPredicates && requestedPredicates.sort(sortFn)
|
|
967
|
-
|
|
968
|
-
return credentials
|
|
969
|
-
}
|
|
970
|
-
|
|
971
|
-
/**
|
|
972
|
-
* This cleanup function prevents any errors associated with
|
|
973
|
-
* receiving the same invitation twice if a previous
|
|
974
|
-
* invitation was not completed. Does nothing if no previously
|
|
975
|
-
* received invitations exist
|
|
976
|
-
* @param agent an Agent instance
|
|
977
|
-
* @param invitationId specifically a *received* invitation id
|
|
978
|
-
*/
|
|
979
|
-
export const removeExistingInvitationsById = async (agent: Agent | undefined, invitationId: string): Promise<void> => {
|
|
980
|
-
// This is implemented just as findByReceivedInvitationId is
|
|
981
|
-
// in Credo only this is able to return multiple if they exist
|
|
982
|
-
const oobRecords =
|
|
983
|
-
(await agent?.oob.findAllByQuery({
|
|
984
|
-
invitationId,
|
|
985
|
-
role: OutOfBandRole.Receiver,
|
|
986
|
-
})) || []
|
|
987
|
-
|
|
988
|
-
for (const r of oobRecords) {
|
|
989
|
-
await agent?.oob.deleteById(r.id)
|
|
990
|
-
agent?.config.logger.info('Successfully removed an existing oob invitation')
|
|
991
|
-
}
|
|
992
|
-
}
|
|
993
|
-
|
|
994
|
-
/**
|
|
995
|
-
* Get a oob record and connection record from a URI using built-in Credo methods
|
|
996
|
-
* @param uri a URI that is either a redirect URL or contains a base64 encoded connection invite in query params
|
|
997
|
-
* @param agent an Agent instance
|
|
998
|
-
* @param implicitInvitations a boolean to determine if implicit invitation behavior should be used
|
|
999
|
-
* @param reuseConnection a boolean to determine if connection reuse should be allowed
|
|
1000
|
-
* @returns an object containing an OOB record and, if not connectionless, a connection record
|
|
1001
|
-
*/
|
|
1002
|
-
export const connectFromInvitation = async (
|
|
1003
|
-
uri: string,
|
|
1004
|
-
agent: Agent | undefined,
|
|
1005
|
-
implicitInvitations: boolean = false,
|
|
1006
|
-
reuseConnection: boolean = false
|
|
1007
|
-
): Promise<OutOfBandRecord> => {
|
|
1008
|
-
const invitation = await agent?.oob.parseInvitation(uri)
|
|
1009
|
-
|
|
1010
|
-
if (!invitation) {
|
|
1011
|
-
throw new Error('Could not parse invitation from URL')
|
|
1012
|
-
}
|
|
1013
|
-
|
|
1014
|
-
if (implicitInvitations) {
|
|
1015
|
-
try {
|
|
1016
|
-
if (invitation.getDidServices().length > 0) {
|
|
1017
|
-
const did = parseDid(invitation.getDidServices()[0])
|
|
1018
|
-
const record = await agent?.oob.receiveImplicitInvitation({
|
|
1019
|
-
did: did.did,
|
|
1020
|
-
label: invitation.label,
|
|
1021
|
-
handshakeProtocols: invitation.handshakeProtocols as HandshakeProtocol[] | undefined,
|
|
1022
|
-
})
|
|
1023
|
-
|
|
1024
|
-
return record?.outOfBandRecord as OutOfBandRecord
|
|
1025
|
-
}
|
|
1026
|
-
} catch (e) {
|
|
1027
|
-
// don't throw an error, will try to connect again below
|
|
1028
|
-
}
|
|
1029
|
-
}
|
|
1030
|
-
|
|
1031
|
-
const record = await agent?.oob.receiveInvitation(invitation, { reuseConnection })
|
|
1032
|
-
return record?.outOfBandRecord as OutOfBandRecord
|
|
1033
|
-
}
|
|
1034
|
-
|
|
1035
|
-
const processBetaUrlIfRequired = (uri: string): string => {
|
|
1036
|
-
let aUrl = uri
|
|
1037
|
-
|
|
1038
|
-
// _oob is a beta query param, not supported by Credo.
|
|
1039
|
-
aUrl = uri.replace('_oob', 'oob')
|
|
1040
|
-
|
|
1041
|
-
// _url is a beta query param, not supported by Credo.
|
|
1042
|
-
if (uri.includes('_url')) {
|
|
1043
|
-
const queryParams = parseUrl(uri)?.query
|
|
1044
|
-
const b64UrlRedirect = queryParams['_url']
|
|
1045
|
-
aUrl = b64decode(b64UrlRedirect as string)
|
|
1046
|
-
}
|
|
1047
|
-
|
|
1048
|
-
return aUrl
|
|
1049
|
-
}
|
|
1050
|
-
|
|
1051
|
-
/**
|
|
1052
|
-
* Receive a message from a scan or deeplink and navigate accordingly
|
|
1053
|
-
* @param uri a URI either containing a base64 encoded connection invite in the query parameters or a redirect URL itself
|
|
1054
|
-
* @param agent an Agent instance
|
|
1055
|
-
* @param logger injected logger from DI container
|
|
1056
|
-
* @param navigation a navigation object from either the Scan screen, Home screen, or PasteUrl screen
|
|
1057
|
-
* @param isDeepLink a boolean to communicate where the uri is coming from
|
|
1058
|
-
* @param implicitInvitations a boolean to determine if implicit invitation behavior should be used
|
|
1059
|
-
* @param reuseConnection a boolean to determine if connection reuse should be allowed
|
|
1060
|
-
* @throws Error with message containing the primary and beta error messages if both fail
|
|
1061
|
-
*/
|
|
1062
|
-
export const connectFromScanOrDeepLink = async (
|
|
1063
|
-
uri: string,
|
|
1064
|
-
agent: Agent | undefined,
|
|
1065
|
-
logger: BifoldLogger,
|
|
1066
|
-
navigation: any,
|
|
1067
|
-
isDeepLink: boolean,
|
|
1068
|
-
implicitInvitations: boolean = false,
|
|
1069
|
-
reuseConnection: boolean = false
|
|
1070
|
-
) => {
|
|
1071
|
-
if (!agent) {
|
|
1072
|
-
return
|
|
1073
|
-
}
|
|
1074
|
-
|
|
1075
|
-
// TODO:(jl) Do we care if the connection is a deep link?
|
|
1076
|
-
logger.info(`Attempting to connect from ${isDeepLink ? 'deeplink' : 'qr scan'}`)
|
|
1077
|
-
try {
|
|
1078
|
-
if (isOpenIdCredentialOffer(uri)) {
|
|
1079
|
-
navigation.navigate(Stacks.ConnectionStack as any, {
|
|
1080
|
-
screen: Screens.Connection,
|
|
1081
|
-
params: { oobRecordId: '', openIDUri: uri },
|
|
1082
|
-
})
|
|
1083
|
-
|
|
1084
|
-
return
|
|
1085
|
-
}
|
|
1086
|
-
|
|
1087
|
-
if (isOpenIdPresentationRequest(uri)) {
|
|
1088
|
-
navigation.navigate(Stacks.ConnectionStack as any, {
|
|
1089
|
-
screen: Screens.Connection,
|
|
1090
|
-
params: { oobRecordId: '', openIDPresentationUri: uri },
|
|
1091
|
-
})
|
|
1092
|
-
|
|
1093
|
-
return
|
|
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
|
-
}
|
|
1103
|
-
|
|
1104
|
-
const aUrl = processBetaUrlIfRequired(uri)
|
|
1105
|
-
const receivedInvitation = await connectFromInvitation(aUrl, agent, implicitInvitations, reuseConnection)
|
|
1106
|
-
|
|
1107
|
-
if (receivedInvitation?.id) {
|
|
1108
|
-
navigation.navigate(Stacks.ConnectionStack as any, {
|
|
1109
|
-
screen: Screens.Connection,
|
|
1110
|
-
params: { oobRecordId: receivedInvitation.id },
|
|
1111
|
-
})
|
|
1112
|
-
}
|
|
1113
|
-
} catch (error: unknown) {
|
|
1114
|
-
logger.error('Problem during connect strategy, error:', error as Error)
|
|
1115
|
-
|
|
1116
|
-
throw error
|
|
1117
|
-
}
|
|
1118
|
-
}
|
|
1119
|
-
|
|
1120
|
-
/**
|
|
1121
|
-
* Create a new connection invitation
|
|
1122
|
-
*
|
|
1123
|
-
* @param agent an Agent instance
|
|
1124
|
-
* @param goalCode add goalCode to connection invitation
|
|
1125
|
-
* @returns a connection record
|
|
1126
|
-
*/
|
|
1127
|
-
export const createConnectionInvitation = async (agent: Agent | undefined, goalCode?: string) => {
|
|
1128
|
-
const record = await agent?.oob.createInvitation({ goalCode })
|
|
1129
|
-
if (!record) {
|
|
1130
|
-
throw new Error('Could not create new invitation')
|
|
1131
|
-
}
|
|
1132
|
-
const invitationUrl = record.outOfBandInvitation.toUrl({ domain })
|
|
1133
|
-
|
|
1134
|
-
return {
|
|
1135
|
-
record,
|
|
1136
|
-
invitation: record.outOfBandInvitation,
|
|
1137
|
-
invitationUrl,
|
|
1138
|
-
}
|
|
1139
|
-
}
|
|
1140
|
-
|
|
1141
|
-
/**
|
|
1142
|
-
* Create a new connection invitation with a goal code specifying that it will be deleted after issuing or verifying once depending on type
|
|
1143
|
-
*
|
|
1144
|
-
* @param agent an Agent instance
|
|
1145
|
-
* @param type add goalCode to connection invitation
|
|
1146
|
-
* @returns a connection record
|
|
1147
|
-
*/
|
|
1148
|
-
export const createTempConnectionInvitation = async (agent: Agent | undefined, type: 'issue' | 'verify') => {
|
|
1149
|
-
return createConnectionInvitation(agent, `aries.vc.${type}.once`)
|
|
1150
|
-
}
|
|
1151
|
-
|
|
1152
|
-
/**
|
|
1153
|
-
* Typeguard to check if any React children is represented as a function
|
|
1154
|
-
* instead of a Node. I,e., when it's a {@link ChildFn}.
|
|
1155
|
-
*
|
|
1156
|
-
* @param children any React children
|
|
1157
|
-
* @returns true if the children is a function, false otherwise
|
|
1158
|
-
*/
|
|
1159
|
-
export function isChildFunction<T>(children: ReactNode | ChildFn<T>): children is ChildFn<T> {
|
|
1160
|
-
return typeof children === 'function'
|
|
1161
|
-
}
|
|
1162
|
-
|
|
1163
|
-
// Fetches the credential definition id for a given credential exchange record, returns null if ID is not found
|
|
1164
|
-
export const getCredentialDefinitionIdForRecord = (record: CredentialExchangeRecord): string | null => {
|
|
1165
|
-
// assumes record is anonCred
|
|
1166
|
-
return record.metadata.get('_anoncreds/credential')?.credentialDefinitionId ?? null
|
|
1167
|
-
}
|
|
1168
|
-
|
|
1169
|
-
// Fetches the schema id for a given credential exchange record, returns null if ID is not found
|
|
1170
|
-
export const getCredentialSchemaIdForRecord = (record: CredentialExchangeRecord): string | null => {
|
|
1171
|
-
// assumes record is anonCred
|
|
1172
|
-
return record.metadata.get('_anoncreds/credential')?.schemaId ?? null
|
|
1173
|
-
}
|
|
1174
|
-
|
|
1175
|
-
export function getCredentialEventRole(record: CredentialExchangeRecord) {
|
|
1176
|
-
switch (record.state) {
|
|
1177
|
-
// assuming only Holder states are supported here
|
|
1178
|
-
case CredentialState.ProposalSent:
|
|
1179
|
-
return Role.me
|
|
1180
|
-
case CredentialState.OfferReceived:
|
|
1181
|
-
return Role.them
|
|
1182
|
-
case CredentialState.RequestSent:
|
|
1183
|
-
return Role.me
|
|
1184
|
-
case CredentialState.Declined:
|
|
1185
|
-
return Role.me
|
|
1186
|
-
case CredentialState.CredentialReceived:
|
|
1187
|
-
return Role.me
|
|
1188
|
-
case CredentialState.Done:
|
|
1189
|
-
return Role.me
|
|
1190
|
-
default:
|
|
1191
|
-
return Role.me
|
|
1192
|
-
}
|
|
1193
|
-
}
|
|
1194
|
-
|
|
1195
|
-
export function getCredentialEventLabel(record: CredentialExchangeRecord) {
|
|
1196
|
-
switch (record.state) {
|
|
1197
|
-
// assuming only Holder states are supported here
|
|
1198
|
-
case CredentialState.ProposalSent:
|
|
1199
|
-
return 'Chat.CredentialProposalSent'
|
|
1200
|
-
case CredentialState.OfferReceived:
|
|
1201
|
-
return 'Chat.CredentialOfferReceived'
|
|
1202
|
-
case CredentialState.RequestSent:
|
|
1203
|
-
return 'Chat.CredentialRequestSent'
|
|
1204
|
-
case CredentialState.Declined:
|
|
1205
|
-
return 'Chat.CredentialDeclined'
|
|
1206
|
-
case CredentialState.CredentialReceived:
|
|
1207
|
-
case CredentialState.Done:
|
|
1208
|
-
return 'Chat.CredentialReceived'
|
|
1209
|
-
default:
|
|
1210
|
-
return ''
|
|
1211
|
-
}
|
|
1212
|
-
}
|
|
1213
|
-
|
|
1214
|
-
export function getProofEventRole(record: ProofExchangeRecord) {
|
|
1215
|
-
switch (record.state) {
|
|
1216
|
-
case ProofState.RequestSent:
|
|
1217
|
-
return Role.me
|
|
1218
|
-
case ProofState.ProposalReceived:
|
|
1219
|
-
return Role.me
|
|
1220
|
-
case ProofState.PresentationReceived:
|
|
1221
|
-
return Role.them
|
|
1222
|
-
case ProofState.RequestReceived:
|
|
1223
|
-
return Role.them
|
|
1224
|
-
case ProofState.ProposalSent:
|
|
1225
|
-
case ProofState.PresentationSent:
|
|
1226
|
-
return Role.me
|
|
1227
|
-
case ProofState.Declined:
|
|
1228
|
-
return Role.me
|
|
1229
|
-
case ProofState.Abandoned:
|
|
1230
|
-
return Role.them
|
|
1231
|
-
case ProofState.Done:
|
|
1232
|
-
return record.isVerified !== undefined ? Role.them : Role.me
|
|
1233
|
-
default:
|
|
1234
|
-
return Role.me
|
|
1235
|
-
}
|
|
1236
|
-
}
|
|
1237
|
-
|
|
1238
|
-
export function getProofEventLabel(record: ProofExchangeRecord) {
|
|
1239
|
-
switch (record.state) {
|
|
1240
|
-
case ProofState.RequestSent:
|
|
1241
|
-
case ProofState.ProposalReceived:
|
|
1242
|
-
return 'Chat.ProofRequestSent'
|
|
1243
|
-
case ProofState.PresentationReceived:
|
|
1244
|
-
return 'Chat.ProofPresentationReceived'
|
|
1245
|
-
case ProofState.RequestReceived:
|
|
1246
|
-
return 'Chat.ProofRequestReceived'
|
|
1247
|
-
case ProofState.ProposalSent:
|
|
1248
|
-
case ProofState.PresentationSent:
|
|
1249
|
-
return 'Chat.ProofRequestSatisfied'
|
|
1250
|
-
case ProofState.Declined:
|
|
1251
|
-
return 'Chat.ProofRequestRejected'
|
|
1252
|
-
case ProofState.Abandoned:
|
|
1253
|
-
return 'Chat.ProofRequestRejectReceived'
|
|
1254
|
-
case ProofState.Done:
|
|
1255
|
-
return record.isVerified !== undefined ? 'Chat.ProofPresentationReceived' : 'Chat.ProofRequestSatisfied'
|
|
1256
|
-
default:
|
|
1257
|
-
return ''
|
|
1258
|
-
}
|
|
1259
|
-
}
|
|
1260
|
-
|
|
1261
|
-
export function getMessageEventRole(record: BasicMessageRecord) {
|
|
1262
|
-
return record.role === BasicMessageRole.Sender ? Role.me : Role.them
|
|
1263
|
-
}
|
|
1264
|
-
|
|
1265
|
-
export function generateRandomWalletName() {
|
|
1266
|
-
let name = 'My Wallet - '
|
|
1267
|
-
for (let i = 0; i < 4; i++) {
|
|
1268
|
-
name = name.concat(Math.floor(Math.random() * 10).toString())
|
|
1269
|
-
}
|
|
1270
|
-
|
|
1271
|
-
return name
|
|
1272
|
-
}
|
|
1273
|
-
|
|
1274
|
-
/**
|
|
1275
|
-
* Returns the secondary background color for a credential card.
|
|
1276
|
-
*
|
|
1277
|
-
* @param {CredentialOverlay<BrandingOverlay>} overlay - The credential card containing branding information.
|
|
1278
|
-
* @param {boolean} [proof] - Optional flag indicating if the context of the credential card is a proof.
|
|
1279
|
-
* @returns {string | undefined} - The secondary background color of the branding or undefined if not applicable.
|
|
1280
|
-
*/
|
|
1281
|
-
export function getSecondaryBackgroundColor(
|
|
1282
|
-
overlay: CredentialOverlay<BrandingOverlay>,
|
|
1283
|
-
proof?: boolean
|
|
1284
|
-
): string | undefined {
|
|
1285
|
-
if (proof) {
|
|
1286
|
-
return overlay.brandingOverlay?.primaryBackgroundColor
|
|
1287
|
-
} else {
|
|
1288
|
-
return overlay.brandingOverlay?.backgroundImageSlice
|
|
1289
|
-
? 'rgba(0, 0, 0, 0)'
|
|
1290
|
-
: overlay.brandingOverlay?.secondaryBackgroundColor
|
|
1291
|
-
}
|
|
1292
|
-
}
|