From a7d02df6f75f86519f8ddd3b7acc6761e014f239 Mon Sep 17 00:00:00 2001 From: hawkbee <49282360+hawkbee1@users.noreply.github.com> Date: Thu, 29 Feb 2024 18:12:27 +0100 Subject: [PATCH 01/45] merge from october and translation branches to main * Revert "Revert "Update app_fr.arb (#2423)"" This reverts commit d1b5156785fd67ed5f105c6fadd248db57cd22c6. * Add translations * Add account ownership manually #2291 * Account ownership cards : logic change #2291 * feat: Update jwt #2291 * Profile DEFAULT : set credential manifest support to OFF #2432 * feat: Support qr to add enterprise account #2433 * version update to 2.3.6+396 * feat: Remove enterprise from onboarding #2433 * feat: Remove draft 8 #2436 * update email and phonepass url #2438 #2439 * feat: Url management * feat: Support deeplink for configuration #2442 * Do not support scan for enterprise login #2442 and add over 18 for diip #2431 * version update to 2.3.7+397 * feat: Re-support enterpise login with scan * enterprise call bug fix * version update to 2.3.8+398 * refactor: Bug fix on external issuer draft 13, ldp_vc #2443 * linter update and class update * Show crypto associated credential based on vcformat and didkey type * version update to 2.3.9+399 * code optimisation - fetch data once * bug fix for crypto card * show token endpoint in developer mode * credential endpoint response added * version update to 2.3.10+400 * update enterprise #2447 * update profile logic * show crypto account with specific vc format * feat: Add enterprise wallet attestation only once #2451 * add wallet attestation card #2451 * Profile DIIP add issuer for phone proof in discover #2440 * refactor: crypto account ownership signed with correct key #2446 * version update 2.3.11+401 * move new translation keys to bottom of app_en.arb * remove dulicates from translation files * update translations * remove obsolete translation files * update language selection * version: 2.3.12+402 --------- Co-authored-by: Bibash Shrestha --- android/app/src/main/AndroidManifest.xml | 6 + ios/Runner/Info.plist | 10 + lib/app/shared/constants/constants.dart | 1 - lib/app/shared/constants/enterprise.dart | 3 - .../shared/constants/secure_storage_keys.dart | 4 +- lib/app/shared/constants/urls.dart | 55 +- lib/app/shared/enum/credential_category.dart | 4 +- .../response_string/response_string.dart | 3 + .../response_string_extension.dart | 7 + .../shared/enum/status/qr_scan_status.dart | 1 + .../credential_subject_type.dart | 2 +- .../credential_subject_type_extension.dart | 163 +- .../enum/type/profile/did_key_type.dart | 12 + .../helper_functions/helper_functions.dart | 197 +- .../message_handler/global_message.dart | 4 + .../message_handler/response_message.dart | 13 + lib/app/view/app.dart | 13 + lib/credentials/cubit/credentials_cubit.dart | 246 +- .../cubit/credentials_helper_function.dart | 111 +- .../verify_age/view/camera_page.dart | 6 + .../cubit/crypto_bottom_sheet_cubit.dart | 4 + .../discover/view/discover_page.dart | 6 +- .../widgets/discover_credential_item.dart | 2 + .../widget/profile_selector_widget.dart | 9 +- .../drawer/src/view/drawer_page.dart | 10 +- .../cubit/restore_credential_cubit.dart | 4 +- lib/dashboard/home/home/cubit/home_cubit.dart | 4 + .../home/home/widgets/wallet_dialog.dart | 5 +- .../cubit/credential_details_cubit.dart | 218 +- .../detail/view/credentials_details_page.dart | 19 +- .../helper_functions/discover_credential.dart | 31 + .../cubit/generate_linkedin_qr_cubit.dart | 1 - .../view/generate_linkedin_qr_page.dart | 1 - .../list/view/home_credentials_list_page.dart | 11 +- .../home_credential_category_list.dart | 6 + .../credential_model/credential_model.dart | 1 + .../view/oid4c4vc_credential_pick_page.dart | 14 +- .../view/credentials_receive_page.dart | 12 +- .../widgets/credential_display.dart | 7 +- .../credentials/widgets/list_item.dart | 26 +- .../cubit/missing_credentials_cubit.dart | 7 +- lib/dashboard/profile/models/profile.dart | 4 +- .../cubit/qr_code_scan_cubit.dart | 247 +- .../cubit/qr_code_scan_state.dart | 13 +- .../self_issued_credential_button_cubit.dart | 8 +- lib/enterprise/cubit/enterprise_cubit.dart | 404 +++ lib/enterprise/cubit/enterprise_state.dart | 48 + lib/enterprise/enterprise.dart | 1 + lib/l10n/arb/app_ca.arb | 1031 ++++++ lib/l10n/arb/app_de.arb | 3 - lib/l10n/arb/app_en.arb | 23 +- lib/l10n/arb/app_es.arb | 1030 +++++- lib/l10n/arb/app_fr.arb | 764 ++--- lib/l10n/arb/app_it.arb | 3 - lib/l10n/untranslated.json | 2829 +---------------- lib/lang/cubit/lang_cubit.dart | 6 +- lib/oidc4vc/add_credential_data.dart | 96 + lib/oidc4vc/add_oidc4vc_credential.dart | 3 + lib/oidc4vc/get_and_add_credential.dart | 162 - .../get_and_add_deffered_credential.dart | 9 +- .../get_authorization_uri_for_issuer.dart | 3 +- lib/oidc4vc/get_credential.dart | 91 + .../initiate_oidv4vc_credential_issuance.dart | 26 +- lib/oidc4vc/oidc4vc.dart | 3 +- lib/onboarding/enterprise/enterprise.dart | 3 - .../cubit/initialization_cubit.dart | 309 -- .../cubit/initialization_state.dart | 68 - .../initialization/initialization.dart | 2 - .../view/initialization_page.dart | 236 -- .../enterprise/otp/cubit/otp_cubit.dart | 16 - .../enterprise/otp/cubit/otp_state.dart | 51 - lib/onboarding/enterprise/otp/login.dart | 2 - lib/onboarding/enterprise/otp/otp.dart | 2 - .../enterprise/otp/view/otp_page.dart | 118 - .../enterprise/update/cubit/update_cubit.dart | 182 -- .../enterprise/update/cubit/update_state.dart | 63 - lib/onboarding/enterprise/update/update.dart | 2 - .../enterprise/update/view/update_page.dart | 205 -- lib/onboarding/onboarding.dart | 1 - lib/onboarding/starter/view/starter_page.dart | 21 +- lib/polygon_id/cubit/polygon_id_cubit.dart | 8 +- lib/scan/cubit/scan_cubit.dart | 4 + lib/splash/bloclisteners/blocklisteners.dart | 124 +- .../helper_function/is_wallet_created.dart | 8 +- lib/splash/view/splash_page.dart | 7 + lib/wallet/cubit/wallet_cubit.dart | 40 +- packages/oidc4vc/lib/src/oidc4vc.dart | 59 +- .../oidc4vc/lib/src/oidc4vci_draft_type.dart | 15 +- packages/oidc4vc/lib/src/vc_format_type.dart | 27 + pubspec.lock | 116 +- pubspec.yaml | 2 +- 91 files changed, 4369 insertions(+), 5388 deletions(-) delete mode 100644 lib/app/shared/constants/enterprise.dart create mode 100644 lib/enterprise/cubit/enterprise_cubit.dart create mode 100644 lib/enterprise/cubit/enterprise_state.dart create mode 100644 lib/enterprise/enterprise.dart create mode 100644 lib/l10n/arb/app_ca.arb delete mode 100644 lib/l10n/arb/app_de.arb delete mode 100644 lib/l10n/arb/app_it.arb create mode 100644 lib/oidc4vc/add_credential_data.dart delete mode 100644 lib/oidc4vc/get_and_add_credential.dart create mode 100644 lib/oidc4vc/get_credential.dart delete mode 100644 lib/onboarding/enterprise/enterprise.dart delete mode 100644 lib/onboarding/enterprise/initialization/cubit/initialization_cubit.dart delete mode 100644 lib/onboarding/enterprise/initialization/cubit/initialization_state.dart delete mode 100644 lib/onboarding/enterprise/initialization/initialization.dart delete mode 100644 lib/onboarding/enterprise/initialization/view/initialization_page.dart delete mode 100644 lib/onboarding/enterprise/otp/cubit/otp_cubit.dart delete mode 100644 lib/onboarding/enterprise/otp/cubit/otp_state.dart delete mode 100644 lib/onboarding/enterprise/otp/login.dart delete mode 100644 lib/onboarding/enterprise/otp/otp.dart delete mode 100644 lib/onboarding/enterprise/otp/view/otp_page.dart delete mode 100644 lib/onboarding/enterprise/update/cubit/update_cubit.dart delete mode 100644 lib/onboarding/enterprise/update/cubit/update_state.dart delete mode 100644 lib/onboarding/enterprise/update/update.dart delete mode 100644 lib/onboarding/enterprise/update/view/update_page.dart diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index e6980ebd5..7d05d7d19 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -95,6 +95,12 @@ + + + + + + diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index a23ba09bf..afc217aef 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -136,6 +136,16 @@ wc-altme + + CFBundleTypeRole + Editor + CFBundleURLName + configuration + CFBundleURLSchemes + + configuration + + CFBundleTypeRole Editor diff --git a/lib/app/shared/constants/constants.dart b/lib/app/shared/constants/constants.dart index c4de983fe..0ae5cdf5f 100644 --- a/lib/app/shared/constants/constants.dart +++ b/lib/app/shared/constants/constants.dart @@ -1,7 +1,6 @@ export 'accentuations.dart'; export 'altme_strings.dart'; export 'constants_json.dart'; -export 'enterprise.dart'; export 'icon_strings.dart'; export 'image_strings.dart'; export 'parameters.dart'; diff --git a/lib/app/shared/constants/enterprise.dart b/lib/app/shared/constants/enterprise.dart deleted file mode 100644 index f186cdc0a..000000000 --- a/lib/app/shared/constants/enterprise.dart +++ /dev/null @@ -1,3 +0,0 @@ -class Enterprise { - static const bool enableEnterprise = false; -} diff --git a/lib/app/shared/constants/secure_storage_keys.dart b/lib/app/shared/constants/secure_storage_keys.dart index b4a306007..a5065719a 100644 --- a/lib/app/shared/constants/secure_storage_keys.dart +++ b/lib/app/shared/constants/secure_storage_keys.dart @@ -68,5 +68,7 @@ class SecureStorageKeys { static const String customProfileSettings = 'customProfileSettings'; static const String enterpriseProfileSetting = 'enterpriseProfileSetting'; - static const String walletProviderType = 'walletProviderType'; + static const String enterpriseEmail = 'enterpriseEmail'; + static const String enterprisePassword = 'enterprisePassword'; + static const String enterpriseWalletProvider = 'enterpriseWalletProvider'; } diff --git a/lib/app/shared/constants/urls.dart b/lib/app/shared/constants/urls.dart index 80f5f2599..a37da92d3 100644 --- a/lib/app/shared/constants/urls.dart +++ b/lib/app/shared/constants/urls.dart @@ -21,8 +21,6 @@ class Urls { /// email pass static const String emailPassUrl = 'https://issuer.talao.co/emailpass'; - static const String emailPassUrlJWTVCJSON = - 'https://issuer.talao.co/emailpass?format=jwt_vc_json'; /// tezotopia voucher static const String tezotopiaVoucherUrl = @@ -32,11 +30,8 @@ class Urls { static const String tezotopiaMembershipCardUrl = 'https://issuer.talao.co/tezotopia/membershipcard/'; - /// liveness - static const String livenessCardUrl = - 'https://talao.co/id360/oidc4vc?format=ldp_vc&type=liveness'; - static const String livenessCardJWTVCJSON = - 'https://talao.co/id360/oidc4vc?format=jwt_vc_json&type=liveness'; + /// id360 url + static const String id360Url = 'https://talao.co/id360/oidc4vc'; /// polygon static const String defaultPolygonIdCardUrl = @@ -65,52 +60,6 @@ class Urls { /// twitter card static const String twitterCardUrl = 'https://issuer.talao.co/twitter/'; - /// verifiableIdCard - static const String verifiableIdCardUrlLDPVC = - 'https://talao.co/id360/oidc4vc?format=ldp_vc&type=verifiableid'; - - static const String verifiableIdCardUrlJWTVCJSON = - 'https://talao.co/id360/oidc4vc?format=jwt_vc_json&type=verifiableid'; - - static const String verifiableIdCardUrlVCSDJWT = - 'https://talao.co/id360/oidc4vc?format=vcsd-jwt&type=identitycredential'; - - /// over 13 - static const String over13Url = - 'https://talao.co/id360/oidc4vc?format=ldp_vc&type=over13'; - static const String over13JWTVCJSON = - 'https://talao.co/id360/oidc4vc?format=jwt_vc_json&type=over13'; - - /// over 15 - static const String over15Url = - 'https://talao.co/id360/oidc4vc?format=ldp_vc&type=over15'; - static const String over15JWTVCJSON = - 'https://talao.co/id360/oidc4vc?format=jwt_vc_json&type=over15'; - - /// over 18 - static const String over18Url = - 'https://talao.co/id360/oidc4vc?format=ldp_vc&type=over18'; - static const String over18JWTVCJSON = - 'https://talao.co/id360/oidc4vc?format=jwt_vc_json&type=over18'; - - /// over 21 - static const String over21Url = - 'https://talao.co/id360/oidc4vc?format=ldp_vc&type=over21'; - static const String over21JWTVCJSON = - 'https://talao.co/id360/oidc4vc?format=jwt_vc_json&type=over21'; - - /// over 50 - static const String over50Url = - 'https://talao.co/id360/oidc4vc?format=ldp_vc&type=over50'; - static const String over50JWTVCJSON = - 'https://talao.co/id360/oidc4vc?format=jwt_vc_json&type=over50'; - - /// over 65 - static const String over65Url = - 'https://talao.co/id360/oidc4vc?format=ldp_vc&type=over65'; - static const String over65JWTVCJSON = - 'https://talao.co/id360/oidc4vc?format=jwt_vc_json&type=over65'; - /// linkedin card static const String linkedinCardUrl = 'https://issuer.talao.co/passbase/endpoint/linkedincard/'; diff --git a/lib/app/shared/enum/credential_category.dart b/lib/app/shared/enum/credential_category.dart index 54eca369e..05b2e467c 100644 --- a/lib/app/shared/enum/credential_category.dart +++ b/lib/app/shared/enum/credential_category.dart @@ -115,8 +115,8 @@ extension CredentialCategoryX on CredentialCategory { return CredentialCategoryConfig( homeTitle: '${l10n.my} ${l10n.blockchainAccounts.toLowerCase()}', homeSubTitle: l10n.blockchainAccountsCredentialHomeSubtitle, - discoverTitle: '${l10n.get} ${l10n.blockchainAccounts.toLowerCase()}', - discoverSubTitle: '', + discoverTitle: l10n.blockchainCardsDiscoverTitle, + discoverSubTitle: l10n.blockchainCardsDiscoverSubtitle, ); case CredentialCategory.educationCards: return CredentialCategoryConfig( diff --git a/lib/app/shared/enum/message/response_string/response_string.dart b/lib/app/shared/enum/message/response_string/response_string.dart index 0c66ebff2..f150ac1d9 100644 --- a/lib/app/shared/enum/message/response_string/response_string.dart +++ b/lib/app/shared/enum/message/response_string/response_string.dart @@ -155,4 +155,7 @@ enum ResponseString { RESPONSE_STRING_theCredentialOfferIsInvalid, RESPONSE_STRING_theServiceIsNotAvailable, RESPONSE_STRING_theIssuanceOfThisCredentialIsPending, + RESPONSE_STRING_successfullyAddedEnterpriseAccount, + + RESPONSE_STRING_successfullyUpdatedEnterpriseAccount, } diff --git a/lib/app/shared/enum/message/response_string/response_string_extension.dart b/lib/app/shared/enum/message/response_string/response_string_extension.dart index 2bd7cedbc..90b6d7e26 100644 --- a/lib/app/shared/enum/message/response_string/response_string_extension.dart +++ b/lib/app/shared/enum/message/response_string/response_string_extension.dart @@ -490,6 +490,13 @@ extension ResponseStringX on ResponseString { case ResponseString.RESPONSE_STRING_theIssuanceOfThisCredentialIsPending: return globalMessage .RESPONSE_STRING_theIssuanceOfThisCredentialIsPending; + + case ResponseString.RESPONSE_STRING_successfullyAddedEnterpriseAccount: + return globalMessage.RESPONSE_STRING_successfullyAddedEnterpriseAccount; + + case ResponseString.RESPONSE_STRING_successfullyUpdatedEnterpriseAccount: + return globalMessage + .RESPONSE_STRING_successfullyUpdatedEnterpriseAccount; } } } diff --git a/lib/app/shared/enum/status/qr_scan_status.dart b/lib/app/shared/enum/status/qr_scan_status.dart index 22a7432a0..06d8365fa 100644 --- a/lib/app/shared/enum/status/qr_scan_status.dart +++ b/lib/app/shared/enum/status/qr_scan_status.dart @@ -8,4 +8,5 @@ enum QrScanStatus { error, success, goBack, + pauseForDialog, } diff --git a/lib/app/shared/enum/type/credential_subject_type/credential_subject_type.dart b/lib/app/shared/enum/type/credential_subject_type/credential_subject_type.dart index 6babd77a9..27debc610 100644 --- a/lib/app/shared/enum/type/credential_subject_type/credential_subject_type.dart +++ b/lib/app/shared/enum/type/credential_subject_type/credential_subject_type.dart @@ -1,5 +1,5 @@ import 'package:altme/app/app.dart'; -import 'package:altme/dashboard/home/home.dart'; +import 'package:altme/dashboard/dashboard.dart'; import 'package:flutter/material.dart'; import 'package:oidc4vc/oidc4vc.dart'; diff --git a/lib/app/shared/enum/type/credential_subject_type/credential_subject_type_extension.dart b/lib/app/shared/enum/type/credential_subject_type/credential_subject_type_extension.dart index 35e860f4b..7f2631af7 100644 --- a/lib/app/shared/enum/type/credential_subject_type/credential_subject_type_extension.dart +++ b/lib/app/shared/enum/type/credential_subject_type/credential_subject_type_extension.dart @@ -560,7 +560,7 @@ extension CredentialSubjectTypeExtension on CredentialSubjectType { } } - bool get weCanRemoveItIfCredentialExist { + bool get supportSingleOnly { switch (this) { case CredentialSubjectType.defiCompliance: case CredentialSubjectType.livenessCard: @@ -583,13 +583,13 @@ extension CredentialSubjectTypeExtension on CredentialSubjectType { case CredentialSubjectType.tezVoucher: case CredentialSubjectType.diplomaCard: case CredentialSubjectType.twitterCard: - return true; - case CredentialSubjectType.walletCredential: case CredentialSubjectType.tezosAssociatedWallet: case CredentialSubjectType.ethereumAssociatedWallet: case CredentialSubjectType.fantomAssociatedWallet: case CredentialSubjectType.polygonAssociatedWallet: case CredentialSubjectType.binanceAssociatedWallet: + return true; + case CredentialSubjectType.walletCredential: case CredentialSubjectType.tezosPooAddress: case CredentialSubjectType.ethereumPooAddress: case CredentialSubjectType.fantomPooAddress: @@ -626,6 +626,13 @@ extension CredentialSubjectTypeExtension on CredentialSubjectType { List get getVCFormatType { switch (this) { + case CredentialSubjectType.ethereumAssociatedWallet: + case CredentialSubjectType.fantomAssociatedWallet: + case CredentialSubjectType.polygonAssociatedWallet: + case CredentialSubjectType.binanceAssociatedWallet: + case CredentialSubjectType.tezosAssociatedWallet: + return VCFormatType.values; + case CredentialSubjectType.over13: case CredentialSubjectType.over15: case CredentialSubjectType.over21: @@ -633,14 +640,8 @@ extension CredentialSubjectTypeExtension on CredentialSubjectType { case CredentialSubjectType.over65: case CredentialSubjectType.gender: case CredentialSubjectType.ageRange: - case CredentialSubjectType.ethereumAssociatedWallet: - case CredentialSubjectType.fantomAssociatedWallet: - case CredentialSubjectType.polygonAssociatedWallet: - case CredentialSubjectType.binanceAssociatedWallet: - case CredentialSubjectType.tezosAssociatedWallet: case CredentialSubjectType.defiCompliance: case CredentialSubjectType.tezotopiaMembership: - case CredentialSubjectType.phonePass: case CredentialSubjectType.chainbornMembership: return [VCFormatType.ldpVc]; @@ -652,9 +653,13 @@ extension CredentialSubjectTypeExtension on CredentialSubjectType { ]; case CredentialSubjectType.over18: + case CredentialSubjectType.phonePass: case CredentialSubjectType.livenessCard: case CredentialSubjectType.emailPass: - return [VCFormatType.ldpVc, VCFormatType.jwtVcJson]; + return [ + VCFormatType.ldpVc, + VCFormatType.jwtVcJson, + ]; case CredentialSubjectType.nationality: case CredentialSubjectType.identityPass: @@ -697,7 +702,7 @@ extension CredentialSubjectTypeExtension on CredentialSubjectType { } } - DiscoverDummyCredential dummyCredential(VCFormatType vcFormatType) { + DiscoverDummyCredential dummyCredential(ProfileSetting profileSetting) { String? image; String? link; String? websiteLink; @@ -706,6 +711,12 @@ extension CredentialSubjectTypeExtension on CredentialSubjectType { ResponseString? howToGetIt; ResponseString? longDescription; + final vcFormatType = profileSetting + .selfSovereignIdentityOptions.customOidc4vcProfile.vcFormatType; + + final oidc4vcDraftType = profileSetting + .selfSovereignIdentityOptions.customOidc4vcProfile.oidc4vciDraft; + switch (this) { case CredentialSubjectType.defiCompliance: image = ImageStrings.dummyDefiComplianceCard; @@ -743,16 +754,9 @@ extension CredentialSubjectTypeExtension on CredentialSubjectType { case CredentialSubjectType.emailPass: image = ImageStrings.dummyEmailPassCard; - switch (vcFormatType) { - case VCFormatType.ldpVc: - link = Urls.emailPassUrl; - case VCFormatType.jwtVcJson: - link = Urls.emailPassUrlJWTVCJSON; - case VCFormatType.jwtVc: - case VCFormatType.jwtVcJsonLd: - case VCFormatType.vcSdJWT: - link = ''; - } + link = '${Urls.emailPassUrl}' + '?draft=${oidc4vcDraftType.numbering}' + '&format=${vcFormatType.urlValue}'; whyGetThisCard = ResponseString.RESPONSE_STRING_emailPassWhyGetThisCard; expirationDateDetails = @@ -762,16 +766,9 @@ extension CredentialSubjectTypeExtension on CredentialSubjectType { case CredentialSubjectType.over13: image = ImageStrings.dummyOver13Card; - switch (vcFormatType) { - case VCFormatType.ldpVc: - link = Urls.over13Url; - case VCFormatType.jwtVcJson: - link = Urls.over13JWTVCJSON; - case VCFormatType.jwtVc: - case VCFormatType.jwtVcJsonLd: - case VCFormatType.vcSdJWT: - link = ''; - } + link = '${Urls.id360Url}' + '?format=${vcFormatType.urlValue}' + '&type=over13'; whyGetThisCard = ResponseString.RESPONSE_STRING_over13WhyGetThisCard; expirationDateDetails = @@ -781,16 +778,9 @@ extension CredentialSubjectTypeExtension on CredentialSubjectType { case CredentialSubjectType.over15: image = ImageStrings.dummyOver15Card; - switch (vcFormatType) { - case VCFormatType.ldpVc: - link = Urls.over15Url; - case VCFormatType.jwtVcJson: - link = Urls.over15JWTVCJSON; - case VCFormatType.jwtVc: - case VCFormatType.jwtVcJsonLd: - case VCFormatType.vcSdJWT: - link = ''; - } + link = '${Urls.id360Url}' + '?format=${vcFormatType.urlValue}' + '&type=over15'; whyGetThisCard = ResponseString.RESPONSE_STRING_over15WhyGetThisCard; expirationDateDetails = @@ -799,20 +789,11 @@ extension CredentialSubjectTypeExtension on CredentialSubjectType { case CredentialSubjectType.over18: image = ImageStrings.dummyOver18Card; - switch (vcFormatType) { - case VCFormatType.ldpVc: - - /// id360 link use to oidc4vc over18 credential. - /// another link is automatically used when getting the credential - /// through yoti. - link = Urls.over18Url; - case VCFormatType.jwtVcJson: - link = Urls.over18JWTVCJSON; - case VCFormatType.jwtVc: - case VCFormatType.jwtVcJsonLd: - case VCFormatType.vcSdJWT: - link = ''; - } + + link = '${Urls.id360Url}' + '?format=${vcFormatType.urlValue}' + '&type=over18'; + whyGetThisCard = ResponseString.RESPONSE_STRING_over18WhyGetThisCard; expirationDateDetails = ResponseString.RESPONSE_STRING_over18ExpirationDate; @@ -821,16 +802,9 @@ extension CredentialSubjectTypeExtension on CredentialSubjectType { case CredentialSubjectType.over21: image = ImageStrings.dummyOver21Card; - switch (vcFormatType) { - case VCFormatType.ldpVc: - link = Urls.over21Url; - case VCFormatType.jwtVcJson: - link = Urls.over21JWTVCJSON; - case VCFormatType.jwtVc: - case VCFormatType.jwtVcJsonLd: - case VCFormatType.vcSdJWT: - link = ''; - } + link = '${Urls.id360Url}' + '?format=${vcFormatType.urlValue}' + '&type=over21'; whyGetThisCard = ResponseString.RESPONSE_STRING_over18WhyGetThisCard; expirationDateDetails = @@ -840,16 +814,9 @@ extension CredentialSubjectTypeExtension on CredentialSubjectType { case CredentialSubjectType.over50: image = ImageStrings.dummyOver50Card; - switch (vcFormatType) { - case VCFormatType.ldpVc: - link = Urls.over50Url; - case VCFormatType.jwtVcJson: - link = Urls.over50JWTVCJSON; - case VCFormatType.jwtVc: - case VCFormatType.jwtVcJsonLd: - case VCFormatType.vcSdJWT: - link = ''; - } + link = '${Urls.id360Url}' + '?format=${vcFormatType.urlValue}' + '&type=over50'; whyGetThisCard = ResponseString.RESPONSE_STRING_over18WhyGetThisCard; expirationDateDetails = @@ -859,16 +826,9 @@ extension CredentialSubjectTypeExtension on CredentialSubjectType { case CredentialSubjectType.over65: image = ImageStrings.dummyOver65Card; - switch (vcFormatType) { - case VCFormatType.ldpVc: - link = Urls.over65Url; - case VCFormatType.jwtVcJson: - link = Urls.over65JWTVCJSON; - case VCFormatType.jwtVc: - case VCFormatType.jwtVcJsonLd: - case VCFormatType.vcSdJWT: - link = ''; - } + link = '${Urls.id360Url}' + '?format=${vcFormatType.urlValue}' + '&type=over65'; whyGetThisCard = ResponseString.RESPONSE_STRING_over18WhyGetThisCard; expirationDateDetails = @@ -897,17 +857,9 @@ extension CredentialSubjectTypeExtension on CredentialSubjectType { case CredentialSubjectType.verifiableIdCard: image = ImageStrings.dummyVerifiableIdCard; - switch (vcFormatType) { - case VCFormatType.ldpVc: - link = Urls.verifiableIdCardUrlLDPVC; - case VCFormatType.jwtVcJson: - link = Urls.verifiableIdCardUrlJWTVCJSON; - case VCFormatType.jwtVc: - case VCFormatType.jwtVcJsonLd: - link = ''; - case VCFormatType.vcSdJWT: - link = Urls.verifiableIdCardUrlVCSDJWT; - } + link = '${Urls.id360Url}' + '?format=${vcFormatType.urlValue}' + '&type=verifiableid'; whyGetThisCard = ResponseString.RESPONSE_STRING_verifiableIdCardWhyGetThisCard; @@ -959,7 +911,11 @@ extension CredentialSubjectTypeExtension on CredentialSubjectType { case CredentialSubjectType.phonePass: image = ImageStrings.dummyPhonePassCard; - link = Urls.phonePassUrl; + + link = '${Urls.phonePassUrl}' + '?draft=${oidc4vcDraftType.numbering}' + '&format=${vcFormatType.urlValue}'; + whyGetThisCard = ResponseString.RESPONSE_STRING_phoneProofWhyGetThisCard; expirationDateDetails = @@ -969,16 +925,9 @@ extension CredentialSubjectTypeExtension on CredentialSubjectType { case CredentialSubjectType.livenessCard: image = ImageStrings.livenessDummy; - switch (vcFormatType) { - case VCFormatType.ldpVc: - link = Urls.livenessCardUrl; - case VCFormatType.jwtVcJson: - link = Urls.livenessCardJWTVCJSON; - case VCFormatType.jwtVc: - case VCFormatType.jwtVcJsonLd: - case VCFormatType.vcSdJWT: - link = ''; - } + link = '${Urls.id360Url}' + '?format=${vcFormatType.urlValue}' + '&type=liveness'; whyGetThisCard = ResponseString.RESPONSE_STRING_livenessCardWhyGetThisCard; diff --git a/lib/app/shared/enum/type/profile/did_key_type.dart b/lib/app/shared/enum/type/profile/did_key_type.dart index 59c4cf969..3d3eb16df 100644 --- a/lib/app/shared/enum/type/profile/did_key_type.dart +++ b/lib/app/shared/enum/type/profile/did_key_type.dart @@ -44,4 +44,16 @@ extension DidKeyTypeX on DidKeyType { return l10n.jwkDecentralizedIDP256; } } + + bool get supportCryptoCredential { + switch (this) { + case DidKeyType.secp256k1: + case DidKeyType.p256: + case DidKeyType.jwkP256: + return true; + case DidKeyType.edDSA: + case DidKeyType.ebsiv3: + return false; + } + } } diff --git a/lib/app/shared/helper_functions/helper_functions.dart b/lib/app/shared/helper_functions/helper_functions.dart index 7df4a6b40..852530946 100644 --- a/lib/app/shared/helper_functions/helper_functions.dart +++ b/lib/app/shared/helper_functions/helper_functions.dart @@ -2,7 +2,7 @@ import 'dart:convert'; import 'dart:io'; import 'package:altme/app/app.dart'; -import 'package:altme/dashboard/home/home.dart'; +import 'package:altme/dashboard/dashboard.dart'; import 'package:altme/oidc4vc/oidc4vc.dart'; import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:convert/convert.dart'; @@ -582,8 +582,17 @@ bool isSIOPV2OROIDC4VPUrl(Uri uri) { return isOpenIdUrl || isAuthorizeEndPoint || isSiopv2Url; } -Future<(OIDC4VCType?, OpenIdConfiguration?, OpenIdConfiguration?, dynamic)> - getIssuanceData({ +/// OIDC4VCType?, OpenIdConfiguration?, OpenIdConfiguration?, +/// credentialOfferJson, issuer, pre-authorizedCode +Future< + ( + OIDC4VCType?, + OpenIdConfiguration?, + OpenIdConfiguration?, + dynamic, + String?, + String?, + )> getIssuanceData({ required String url, required DioClient client, required OIDC4VC oidc4vc, @@ -596,6 +605,7 @@ Future<(OIDC4VCType?, OpenIdConfiguration?, OpenIdConfiguration?, dynamic)> dynamic credentialOfferJson; String? issuer; + String? preAuthorizedCode; if (keys.contains('credential_offer') || keys.contains('credential_offer_uri')) { @@ -604,18 +614,32 @@ Future<(OIDC4VCType?, OpenIdConfiguration?, OpenIdConfiguration?, dynamic)> scannedResponse: uri.toString(), dioClient: client, ); - if (credentialOfferJson == null) throw Exception(); - issuer = credentialOfferJson['credential_issuer'].toString(); + if (credentialOfferJson != null) { + final dynamic preAuthorizedCodeGrant = credentialOfferJson['grants'] + ['urn:ietf:params:oauth:grant-type:pre-authorized_code']; + + if (preAuthorizedCodeGrant != null && + preAuthorizedCodeGrant is Map && + preAuthorizedCodeGrant.containsKey('pre-authorized_code')) { + preAuthorizedCode = + preAuthorizedCodeGrant['pre-authorized_code'] as String; + } + + issuer = credentialOfferJson['credential_issuer'].toString(); + } } if (keys.contains('issuer')) { /// issuance case 1 issuer = uri.queryParameters['issuer'].toString(); + + /// preAuthorizedCode can be null + preAuthorizedCode = uri.queryParameters['pre-authorized_code']; } if (issuer == null) { - return (null, null, null, null); + return (null, null, null, null, null, null); } final OpenIdConfiguration openIdConfiguration = await oidc4vc.getOpenIdConfig( @@ -667,6 +691,8 @@ Future<(OIDC4VCType?, OpenIdConfiguration?, OpenIdConfiguration?, dynamic)> openIdConfiguration, authorizationServerConfiguration, credentialOfferJson, + issuer, + preAuthorizedCode, ); } @@ -677,6 +703,8 @@ Future<(OIDC4VCType?, OpenIdConfiguration?, OpenIdConfiguration?, dynamic)> openIdConfiguration, authorizationServerConfiguration, credentialOfferJson, + issuer, + preAuthorizedCode, ); } else { return ( @@ -684,6 +712,8 @@ Future<(OIDC4VCType?, OpenIdConfiguration?, OpenIdConfiguration?, dynamic)> openIdConfiguration, authorizationServerConfiguration, credentialOfferJson, + issuer, + preAuthorizedCode, ); } } @@ -692,6 +722,8 @@ Future<(OIDC4VCType?, OpenIdConfiguration?, OpenIdConfiguration?, dynamic)> openIdConfiguration, authorizationServerConfiguration, credentialOfferJson, + issuer, + preAuthorizedCode, ); } } @@ -701,6 +733,8 @@ Future<(OIDC4VCType?, OpenIdConfiguration?, OpenIdConfiguration?, dynamic)> openIdConfiguration, authorizationServerConfiguration, credentialOfferJson, + issuer, + preAuthorizedCode, ); } @@ -973,47 +1007,6 @@ Future getHost({ } } -Future<(String?, String?)> getIssuerAndPreAuthorizedCode({ - required String scannedResponse, - required DioClient dioClient, -}) async { - String? preAuthorizedCode; - String? issuer; - - final Uri uriFromScannedResponse = Uri.parse(scannedResponse); - - final keys = []; - uriFromScannedResponse.queryParameters.forEach((key, value) => keys.add(key)); - - if (keys.contains('issuer')) { - issuer = uriFromScannedResponse.queryParameters['issuer'].toString(); - //preAuthorizedCode can be null - preAuthorizedCode = - uriFromScannedResponse.queryParameters['pre-authorized_code']; - } else if (keys.contains('credential_offer') || - keys.contains('credential_offer_uri')) { - final dynamic credentialOfferJson = await getCredentialOfferJson( - scannedResponse: scannedResponse, - dioClient: dioClient, - ); - if (credentialOfferJson == null) throw Exception(); - - final dynamic preAuthorizedCodeGrant = credentialOfferJson['grants'] - ['urn:ietf:params:oauth:grant-type:pre-authorized_code']; - - if (preAuthorizedCodeGrant != null && - preAuthorizedCodeGrant is Map && - preAuthorizedCodeGrant.containsKey('pre-authorized_code')) { - preAuthorizedCode = - preAuthorizedCodeGrant['pre-authorized_code'] as String; - } - - issuer = credentialOfferJson['credential_issuer'].toString(); - } - - return (preAuthorizedCode, issuer); -} - bool isURL(String input) { final bool uri = Uri.tryParse(input)?.hasAbsolutePath ?? false; return uri; @@ -1143,6 +1136,8 @@ bool hasIDTokenOrVPToken(String responseType) { String getFormattedStringOIDC4VCI({ required String url, + required String tokenEndpoint, + required String credentialEndpoint, OpenIdConfiguration? openIdConfiguration, OpenIdConfiguration? authorizationServerConfiguration, dynamic credentialOfferJson, @@ -1153,8 +1148,8 @@ String getFormattedStringOIDC4VCI({ ${credentialOfferJson != null ? const JsonEncoder.withIndent(' ').convert(credentialOfferJson) : 'None'}\n ENDPOINTS : authorization server endpoint : ${openIdConfiguration?.authorizationServer ?? 'None'} - token endpoint : ${openIdConfiguration?.tokenEndpoint ?? authorizationServerConfiguration?.tokenEndpoint ?? 'None'} - credential endpoint : ${openIdConfiguration?.credentialEndpoint ?? 'None'} + token endpoint : $tokenEndpoint} + credential endpoint : $credentialEndpoint} deferred endpoint : ${openIdConfiguration?.deferredCredentialEndpoint ?? 'None'} batch endpoint : ${openIdConfiguration?.batchEndpoint ?? 'None'}\n CREDENTIAL SUPPORTED : @@ -1180,6 +1175,18 @@ $codeForAuthorisedFlow '''; } +String getFormattedStringResponse({ + required Map? tokenData, + required List? credentialData, +}) { + return ''' +TOKEN RESPONSE : +${tokenData != null ? const JsonEncoder.withIndent(' ').convert(tokenData) : 'None'}\n +CREDENTIAL RESPONSE : +${credentialData != null ? const JsonEncoder.withIndent(' ').convert(credentialData) : 'None'}\n +'''; +} + Future getFormattedStringOIDC4VPSIOPV2({ required String url, required DioClient client, @@ -1334,3 +1341,95 @@ String getUpdatedUrlForSIOPV2OIC4VP({ final String newUrl = '$uri&$queryString'; return newUrl; } + +bool supportCryptoCredential(ProfileSetting profileSetting) { + final customOidc4vcProfile = + profileSetting.selfSovereignIdentityOptions.customOidc4vcProfile; + + /// suported VC format + final supportCryptoCredentialByVCFormat = + customOidc4vcProfile.vcFormatType.supportCryptoCredential; + + /// supported did key + final supportCryptoCredentialByDidKey = + customOidc4vcProfile.defaultDid.supportCryptoCredential; + + /// match format 1 + final matchFormat1 = + supportCryptoCredentialByVCFormat && supportCryptoCredentialByDidKey; + + /// match format 2 + final matchFormat2 = customOidc4vcProfile.defaultDid == DidKeyType.edDSA && + customOidc4vcProfile.vcFormatType == VCFormatType.ldpVc && + !customOidc4vcProfile.cryptoHolderBinding; + + final supportAssociatedCredential = matchFormat1 || matchFormat2; + + return supportAssociatedCredential; +} + +Future<(String?, String?, String?)> getClientDetails({ + required ProfileCubit profileCubit, + required bool isEBSIV3, +}) async { + try { + String? clientId; + String? clientSecret; + String? authorization; + + final customOidc4vcProfile = profileCubit.state.model.profileSetting + .selfSovereignIdentityOptions.customOidc4vcProfile; + + switch (customOidc4vcProfile.clientAuthentication) { + case ClientAuthentication.none: + break; + case ClientAuthentication.clientSecretPost: + clientId = customOidc4vcProfile.clientId; + clientSecret = customOidc4vcProfile.clientSecret; + case ClientAuthentication.clientSecretBasic: + clientId = customOidc4vcProfile.clientId; + clientSecret = customOidc4vcProfile.clientSecret; + authorization = base64UrlEncode(utf8.encode('$clientId:$clientSecret')) + .replaceAll('=', ''); + case ClientAuthentication.clientId: + final didKeyType = customOidc4vcProfile.defaultDid; + + final privateKey = await fetchPrivateKey( + oidc4vc: profileCubit.oidc4vc, + secureStorage: profileCubit.secureStorageProvider, + isEBSIV3: isEBSIV3, + didKeyType: didKeyType, + ); + + final (did, _) = await fetchDidAndKid( + privateKey: privateKey, + isEBSIV3: isEBSIV3, + didKitProvider: profileCubit.didKitProvider, + secureStorage: profileCubit.secureStorageProvider, + didKeyType: didKeyType, + ); + + switch (customOidc4vcProfile.clientType) { + case ClientType.jwkThumbprint: + final tokenParameters = TokenParameters( + privateKey: jsonDecode(privateKey) as Map, + did: '', // just added as it is required field + mediaType: MediaType.basic, // just added as it is required field + clientType: ClientType + .jwkThumbprint, // just added as it is required field + proofHeaderType: customOidc4vcProfile.proofHeader, + clientId: '', + ); + clientId = tokenParameters.thumbprint; + case ClientType.did: + clientId = did; + case ClientType.confidential: + clientId = customOidc4vcProfile.clientId; + } + } + + return (clientId, clientSecret, authorization); + } catch (e) { + return (null, null, null); + } +} diff --git a/lib/app/shared/message_handler/global_message.dart b/lib/app/shared/message_handler/global_message.dart index 12fd1be28..b6bc96a76 100644 --- a/lib/app/shared/message_handler/global_message.dart +++ b/lib/app/shared/message_handler/global_message.dart @@ -384,4 +384,8 @@ class GlobalMessage { l10n.theServiceIsNotAvailable; String get RESPONSE_STRING_theIssuanceOfThisCredentialIsPending => l10n.theIssuanceOfThisCredentialIsPending; + String get RESPONSE_STRING_successfullyAddedEnterpriseAccount => + l10n.successfullyAddedEnterpriseAccount; + String get RESPONSE_STRING_successfullyUpdatedEnterpriseAccount => + l10n.successfullyUpdatedEnterpriseAccount; } diff --git a/lib/app/shared/message_handler/response_message.dart b/lib/app/shared/message_handler/response_message.dart index 6bf827389..cae348f84 100644 --- a/lib/app/shared/message_handler/response_message.dart +++ b/lib/app/shared/message_handler/response_message.dart @@ -752,6 +752,19 @@ class ResponseMessage with MessageHandler { .RESPONSE_STRING_theIssuanceOfThisCredentialIsPending.localise( context, ); + + case ResponseString.RESPONSE_STRING_successfullyAddedEnterpriseAccount: + return ResponseString + .RESPONSE_STRING_successfullyAddedEnterpriseAccount.localise( + context, + ); + + case ResponseString + .RESPONSE_STRING_successfullyUpdatedEnterpriseAccount: + return ResponseString + .RESPONSE_STRING_successfullyUpdatedEnterpriseAccount.localise( + context, + ); } } return ''; diff --git a/lib/app/view/app.dart b/lib/app/view/app.dart index 55e6ab974..2d741f9c2 100644 --- a/lib/app/view/app.dart +++ b/lib/app/view/app.dart @@ -11,6 +11,7 @@ import 'package:altme/connection_bridge/connection_bridge.dart'; import 'package:altme/credentials/credentials.dart'; import 'package:altme/dashboard/dashboard.dart'; import 'package:altme/deep_link/deep_link.dart'; +import 'package:altme/enterprise/enterprise.dart'; import 'package:altme/flavor/cubit/flavor_cubit.dart'; import 'package:altme/kyc_verification/cubit/kyc_verification_cubit.dart'; import 'package:altme/l10n/l10n.dart'; @@ -139,6 +140,15 @@ class App extends StatelessWidget { polygonId: PolygonId(), credentialsCubit: context.read(), profileCubit: context.read(), + walletCubit: context.read(), + ), + ), + BlocProvider( + create: (context) => EnterpriseCubit( + client: DioClient('', Dio()), + jwtDecode: JWTDecode(), + profileCubit: context.read(), + walletCubit: context.read(), ), ), BlocProvider( @@ -148,6 +158,7 @@ class App extends StatelessWidget { didKitProvider: DIDKitProvider(), secureStorageProvider: secureStorageProvider, profileCubit: context.read(), + walletCubit: context.read(), oidc4vc: OIDC4VC(), ), ), @@ -167,6 +178,8 @@ class App extends StatelessWidget { polygonIdCubit: context.read(), didKitProvider: DIDKitProvider(), oidc4vc: OIDC4VC(), + walletCubit: context.read(), + enterpriseCubit: context.read(), ), ), BlocProvider( diff --git a/lib/credentials/cubit/credentials_cubit.dart b/lib/credentials/cubit/credentials_cubit.dart index 659d1cdf3..f2763b090 100644 --- a/lib/credentials/cubit/credentials_cubit.dart +++ b/lib/credentials/cubit/credentials_cubit.dart @@ -49,7 +49,9 @@ class CredentialsCubit extends Cubit { final log = getLogger('CredentialsCubit'); - Future loadAllCredentials() async { + Future loadAllCredentials({ + required BlockchainType blockchainType, + }) async { final log = getLogger('loadAllCredentials'); final String? ssiKey = await secureStorageProvider.get(SecureStorageKeys.ssiKey); @@ -60,7 +62,10 @@ class CredentialsCubit extends Cubit { emit(state.copyWith(status: CredentialsStatus.loading)); final savedCredentials = await credentialsRepository.findAll(/* filters */); - final dummies = _getAvalaibleDummyCredentials(savedCredentials); + final dummies = _getAvalaibleDummyCredentials( + credentials: savedCredentials, + blockchainType: blockchainType, + ); final List updatedCredentials = []; @@ -103,7 +108,9 @@ class CredentialsCubit extends Cubit { log.i('credentials loaded from repository - ${savedCredentials.length}'); } - Future addWalletCredential() async { + Future addWalletCredential({ + required BlockchainType? blockchainType, + }) async { final log = getLogger('addRequiredCredentials'); final walletType = profileCubit.state.model.walletType; @@ -165,6 +172,7 @@ class CredentialsCubit extends Cubit { await insertCredential( credential: walletCredential, showMessage: false, + blockchainType: blockchainType, ); } } @@ -180,13 +188,17 @@ class CredentialsCubit extends Cubit { Future deleteById({ required String id, + required BlockchainType? blockchainType, bool showMessage = true, }) async { emit(state.loading()); await credentialsRepository.deleteById(id); final credentials = List.of(state.credentials) ..removeWhere((element) => element.id == id); - final dummies = _getAvalaibleDummyCredentials(credentials); + final dummies = _getAvalaibleDummyCredentials( + credentials: credentials, + blockchainType: blockchainType, + ); emit( state.copyWith( status: CredentialsStatus.delete, @@ -246,6 +258,7 @@ class CredentialsCubit extends Cubit { Future insertCredential({ required CredentialModel credential, + required BlockchainType? blockchainType, bool showMessage = true, bool showStatus = true, bool isPendingCredential = false, @@ -262,7 +275,10 @@ class CredentialsCubit extends Cubit { ), ); if (!isPendingCredential) { - await modifyCredential(credential: updatedCredential); + await modifyCredential( + credential: updatedCredential, + blockchainType: blockchainType, + ); } await credentialsRepository.insert(updatedCredential); credentials = List.of(state.credentials)..add(updatedCredential); @@ -276,12 +292,20 @@ class CredentialsCubit extends Cubit { ), ); if (!isPendingCredential) { - await modifyCredential(credential: updatedCredential); + await modifyCredential( + credential: updatedCredential, + blockchainType: blockchainType, + ); } await credentialsRepository.insert(updatedCredential); credentials = List.of(state.credentials)..add(updatedCredential); } else { - if (!isPendingCredential) await modifyCredential(credential: credential); + if (!isPendingCredential) { + await modifyCredential( + credential: credential, + blockchainType: blockchainType, + ); + } await credentialsRepository.insert(credential); credentials = List.of(state.credentials)..add(credential); } @@ -291,7 +315,10 @@ class CredentialsCubit extends Cubit { enableCredentialCategory(category: credentialCategory); - final dummies = _getAvalaibleDummyCredentials(credentials); + final dummies = _getAvalaibleDummyCredentials( + credentials: credentials, + blockchainType: blockchainType, + ); emit( state.copyWith( @@ -358,6 +385,7 @@ class CredentialsCubit extends Cubit { Future modifyCredential({ required CredentialModel credential, bool showMessage = true, + required BlockchainType? blockchainType, }) async { final credentialSubjectModel = credential.credentialPreview.credentialSubjectModel; @@ -387,6 +415,7 @@ class CredentialsCubit extends Cubit { await deleteById( id: storedCredential.id, showMessage: false, + blockchainType: blockchainType, ); break; } @@ -419,6 +448,7 @@ class CredentialsCubit extends Cubit { await deleteById( id: storedCredential.id, showMessage: false, + blockchainType: blockchainType, ); break; } @@ -463,7 +493,53 @@ class CredentialsCubit extends Cubit { return resultList; } - Future insertOrUpdateAssociatedWalletCredential({ + Future insertAssociatedWalletCredential({ + required CryptoAccountData cryptoAccountData, + }) async { + final supportAssociatedCredential = + supportCryptoCredential(profileCubit.state.model.profileSetting); + + if (!supportAssociatedCredential) throw Exception(); + + final didKeyType = profileCubit.state.model.profileSetting + .selfSovereignIdentityOptions.customOidc4vcProfile.defaultDid; + + final privateKey = await getPrivateKey( + secureStorage: getSecureStorage, + didKeyType: didKeyType, + oidc4vc: oidc4vc, + ); + + final (did, _) = await getDidAndKid( + didKeyType: didKeyType, + privateKey: privateKey, + secureStorage: getSecureStorage, + didKitProvider: didKitProvider, + ); + + final private = jsonDecode(privateKey) as Map; + + final credential = await generateAssociatedWalletCredential( + cryptoAccountData: cryptoAccountData, + didKitProvider: didKitProvider, + blockchainType: cryptoAccountData.blockchainType, + keyGenerator: keyGenerator, + did: did, + customOidc4vcProfile: profileCubit.state.model.profileSetting + .selfSovereignIdentityOptions.customOidc4vcProfile, + oidc4vc: oidc4vc, + privateKey: private, + ); + + if (credential != null) { + await insertCredential( + credential: credential, + blockchainType: cryptoAccountData.blockchainType, + ); + } + } + + Future updateAssociatedWalletCredential({ required BlockchainType blockchainType, required CryptoAccountData cryptoAccountData, }) async { @@ -485,7 +561,7 @@ class CredentialsCubit extends Cubit { credentialList: oldCredentialList, ); - /// update or create AssociatedAddres credential with new name + /// update AssociatedAddres credential with new name if (filteredCredentialList.isNotEmpty) { //find old id of the credential final oldCredential = oldCredentialList.where((CredentialModel element) { @@ -516,52 +592,58 @@ class CredentialsCubit extends Cubit { return false; }).first; - // final credential = state.credentials.where((element) => element.); - final credential = await createOrUpdateAssociatedWalletCredential( - blockchainType: blockchainType, + final did = oldCredential.credentialPreview.credentialSubjectModel.id; + + if (did == null) { + throw Exception(); + } + + final didKeyType = profileCubit.state.model.profileSetting + .selfSovereignIdentityOptions.customOidc4vcProfile.defaultDid; + + final privateKey = await getPrivateKey( + secureStorage: getSecureStorage, + didKeyType: didKeyType, + oidc4vc: oidc4vc, + ); + + final private = jsonDecode(privateKey) as Map; + + final credential = await generateAssociatedWalletCredential( cryptoAccountData: cryptoAccountData, + didKitProvider: didKitProvider, + blockchainType: blockchainType, + keyGenerator: keyGenerator, oldId: oldCredential.id, + did: oldCredential.credentialPreview.credentialSubjectModel.id!, + customOidc4vcProfile: profileCubit.state.model.profileSetting + .selfSovereignIdentityOptions.customOidc4vcProfile, + oidc4vc: oidc4vc, + privateKey: private, ); + if (credential != null) { await updateCredential(credential: credential); } - } else { - final credential = await createOrUpdateAssociatedWalletCredential( - blockchainType: blockchainType, - cryptoAccountData: cryptoAccountData, - ); - if (credential != null) { - await insertCredential(credential: credential); - } } } - Future createOrUpdateAssociatedWalletCredential({ - required BlockchainType blockchainType, - required CryptoAccountData cryptoAccountData, - String? oldId, - }) async { - return generateAssociatedWalletCredential( - cryptoAccountData: cryptoAccountData, - didKitProvider: didKitProvider, - blockchainType: blockchainType, - keyGenerator: keyGenerator, - oldId: oldId, - oidc4vc: oidc4vc, - profileCubit: profileCubit, - ); - } - ///get dummy cards Map> - _getAvalaibleDummyCredentials(List credentials) { + _getAvalaibleDummyCredentials({ + required List credentials, + required BlockchainType? blockchainType, + }) { final dummies = >{}; // entreprise user may have options to display some dummies (true/false) - final profileSetting = profileCubit.state.model.profileSetting; - final vcFormatType = profileCubit.state.model.profileSetting + final profileModel = profileCubit.state.model; + final profileSetting = profileModel.profileSetting; + final vcFormatType = profileSetting .selfSovereignIdentityOptions.customOidc4vcProfile.vcFormatType; + final isDutchProfile = profileModel.profileType == ProfileType.dutch; + final discoverCardsOptions = profileSetting.discoverCardsOptions; // entreprise user may have a list of external issuer final externalIssuers = @@ -598,7 +680,7 @@ class CredentialsCubit extends Cubit { final displayOver18Jwt = vcFormatType == VCFormatType.jwtVcJson && discoverCardsOptions.displayOver18Jwt; - if (displayOver18 || displayOver18Jwt) { + if (isDutchProfile || displayOver18 || displayOver18Jwt) { allSubjectTypeForCategory.add(CredentialSubjectType.over18); } } @@ -698,12 +780,17 @@ class CredentialsCubit extends Cubit { } } - if (discoverCardsOptions.displayPhonePass && - !allSubjectTypeForCategory - .contains(CredentialSubjectType.phonePass)) { - allSubjectTypeForCategory.add( - CredentialSubjectType.phonePass, - ); + if (!allSubjectTypeForCategory + .contains(CredentialSubjectType.phonePass)) { + final displayPhonePass = vcFormatType == VCFormatType.ldpVc && + discoverCardsOptions.displayPhonePass; + final displayPhonePassJwt = + vcFormatType == VCFormatType.jwtVcJson && + discoverCardsOptions.displayPhonePassJwt; + + if (displayPhonePass || displayPhonePassJwt) { + allSubjectTypeForCategory.add(CredentialSubjectType.phonePass); + } } case CredentialCategory.educationCards: @@ -712,9 +799,8 @@ class CredentialsCubit extends Cubit { if (discoverCardsOptions.displayDefi && !allSubjectTypeForCategory .contains(CredentialSubjectType.defiCompliance)) { - allSubjectTypeForCategory.add( - CredentialSubjectType.defiCompliance, - ); + allSubjectTypeForCategory + .add(CredentialSubjectType.defiCompliance); } case CredentialCategory.humanityProofCards: @@ -724,7 +810,14 @@ class CredentialsCubit extends Cubit { case CredentialCategory.walletIntegrity: break; case CredentialCategory.blockchainAccountsCards: - break; + allSubjectTypeForCategory.addAll([ + CredentialSubjectType.tezosAssociatedWallet, + CredentialSubjectType.ethereumAssociatedWallet, + CredentialSubjectType.fantomAssociatedWallet, + CredentialSubjectType.binanceAssociatedWallet, + CredentialSubjectType.polygonAssociatedWallet, + ]); + case CredentialCategory.othersCards: break; case CredentialCategory.polygonidCards: @@ -742,6 +835,28 @@ class CredentialsCubit extends Cubit { continue; } + final Map + blockchainToSubjectType = { + BlockchainType.tezos: CredentialSubjectType.tezosAssociatedWallet, + BlockchainType.fantom: CredentialSubjectType.fantomAssociatedWallet, + BlockchainType.binance: CredentialSubjectType.binanceAssociatedWallet, + BlockchainType.ethereum: + CredentialSubjectType.ethereumAssociatedWallet, + BlockchainType.polygon: CredentialSubjectType.polygonAssociatedWallet, + }; + final isCurrentBlockchainAccount = + blockchainToSubjectType[blockchainType] == subjectType; + final isBlockchainAccount = subjectType.isBlockchainAccount; + + final supportAssociatedCredential = + supportCryptoCredential(profileCubit.state.model.profileSetting); + + /// remove if credential is blockchain account and + /// profile do not support + if (isBlockchainAccount && !supportAssociatedCredential) { + continue; + } + final credentialsOfSameType = credentials .where( (element) => @@ -751,19 +866,30 @@ class CredentialsCubit extends Cubit { ) .toList(); - /// if repetition is not allowed - if (subjectType.weCanRemoveItIfCredentialExist && - credentialsOfSameType.isNotEmpty) { + if (credentialsOfSameType.isNotEmpty && subjectType.supportSingleOnly) { + /// credential available case for (final credential in credentialsOfSameType) { - if (vcFormatType.value == credential.getFormat) { - /// remove if format matched - continue; + if (isBlockchainAccount && supportAssociatedCredential) { + /// do not add if it is blockchain } else { - requiredDummySubjects.add(subjectType); + if (vcFormatType.value == credential.getFormat) { + /// do not add if format matched + /// there can be same credentials with different format + } else { + requiredDummySubjects.add(subjectType); + } } } } else { - requiredDummySubjects.add(subjectType); + /// credential not available case + + if (isBlockchainAccount && + supportAssociatedCredential && + !isCurrentBlockchainAccount) { + /// do not add if current blockchain acccount does not match + } else { + requiredDummySubjects.add(subjectType); + } } } @@ -773,7 +899,7 @@ class CredentialsCubit extends Cubit { // add dummies from the category dummies[category]?.addAll( requiredDummySubjects - .map((item) => item.dummyCredential(vcFormatType)) + .map((item) => item.dummyCredential(profileSetting)) .toList(), ); } diff --git a/lib/credentials/cubit/credentials_helper_function.dart b/lib/credentials/cubit/credentials_helper_function.dart index 090dd6e77..0a5594f65 100644 --- a/lib/credentials/cubit/credentials_helper_function.dart +++ b/lib/credentials/cubit/credentials_helper_function.dart @@ -6,8 +6,10 @@ Future generateAssociatedWalletCredential({ required DIDKitProvider didKitProvider, required BlockchainType blockchainType, required KeyGenerator keyGenerator, - required ProfileCubit profileCubit, + required String did, + required CustomOidc4VcProfile customOidc4vcProfile, required OIDC4VC oidc4vc, + required Map privateKey, String? oldId, }) async { final log = @@ -56,22 +58,6 @@ Future generateAssociatedWalletCredential({ } log.i('hardcoded verificationMethod - $verificationMethod'); - final didKeyType = profileCubit.state.model.profileSetting - .selfSovereignIdentityOptions.customOidc4vcProfile.defaultDid; - - final privateKey = await getPrivateKey( - secureStorage: getSecureStorage, - didKeyType: didKeyType, - oidc4vc: oidc4vc, - ); - - final (did, _) = await getDidAndKid( - didKeyType: didKeyType, - privateKey: privateKey, - secureStorage: getSecureStorage, - didKitProvider: didKitProvider, - ); - final options = { 'proofPurpose': 'assertionMethod', 'verificationMethod': verificationMethod, @@ -187,10 +173,28 @@ Future generateAssociatedWalletCredential({ .RESPONSE_STRING_FAILED_TO_VERIFY_SELF_ISSUED_CREDENTIAL, ); } else { - return _createCredential(vc, oldId, credentialManifest); + return _createCredential( + vc: vc, + oldId: oldId, + credentialManifest: credentialManifest, + customOidc4vcProfile: customOidc4vcProfile, + oidc4vc: oidc4vc, + privateKey: privateKey, + kid: verificationMethod, + issuer: issuer, + ); } } else { - return _createCredential(vc, oldId, credentialManifest); + return _createCredential( + vc: vc, + oldId: oldId, + credentialManifest: credentialManifest, + customOidc4vcProfile: customOidc4vcProfile, + oidc4vc: oidc4vc, + privateKey: privateKey, + kid: verificationMethod, + issuer: issuer, + ); } } catch (e, s) { log.e( @@ -202,22 +206,71 @@ Future generateAssociatedWalletCredential({ } } -Future _createCredential( - String vc, +Future _createCredential({ + required String vc, + required CredentialManifest credentialManifest, + required CustomOidc4VcProfile customOidc4vcProfile, + required OIDC4VC oidc4vc, + required Map privateKey, + required String issuer, + required String kid, String? oldId, - CredentialManifest credentialManifest, -) async { - final jsonCredential = jsonDecode(vc) as Map; +}) async { + final jsonLd = jsonDecode(vc) as Map; + + String? jwt; + DateTime dateTime = DateTime.now(); + + if (customOidc4vcProfile.vcFormatType != VCFormatType.ldpVc) { + /// id -> jti (optional) + /// issuer -> iss (compulsary) + /// issuanceDate -> iat (optional) + /// expirationDate -> exp (optional) + + try { + dateTime = DateTime.parse(jsonLd['issuanceDate'].toString()); + } catch (e) { + dateTime = DateTime.now(); + } + + final iat = (dateTime.millisecondsSinceEpoch / 1000).round(); + + final jsonContent = { + 'iat': iat, + 'exp': iat + 1000, + 'iss': jsonLd['issuer'], + 'jti': jsonLd['id'] ?? 'urn:uuid:${const Uuid().v4()}', + 'sub': issuer, + 'vc': jsonLd, + }; + + final tokenParameters = TokenParameters( + privateKey: privateKey, + did: issuer, + kid: kid, + mediaType: MediaType.basic, + clientType: customOidc4vcProfile.clientType, + proofHeaderType: customOidc4vcProfile.proofHeader, + clientId: customOidc4vcProfile.clientId ?? '', + ); + + /// sign and get token + jwt = oidc4vc.generateToken( + payload: jsonContent, + tokenParameters: tokenParameters, + ); + } + final id = oldId ?? 'urn:uuid:${const Uuid().v4()}'; return CredentialModel( id: id, image: 'image', - data: jsonCredential, + data: jsonLd, shareLink: '', - jwt: null, - format: 'ldp_vc', - credentialPreview: Credential.fromJson(jsonCredential), + jwt: jwt, + format: customOidc4vcProfile.vcFormatType.value, + credentialPreview: Credential.fromJson(jsonLd), credentialManifest: credentialManifest, - activities: [Activity(acquisitionAt: DateTime.now())], + activities: [Activity(acquisitionAt: dateTime)], ); } diff --git a/lib/dashboard/ai_age_verification/verify_age/view/camera_page.dart b/lib/dashboard/ai_age_verification/verify_age/view/camera_page.dart index cddc48d88..ee1241a14 100644 --- a/lib/dashboard/ai_age_verification/verify_age/view/camera_page.dart +++ b/lib/dashboard/ai_age_verification/verify_age/view/camera_page.dart @@ -4,6 +4,7 @@ import 'package:altme/app/app.dart'; import 'package:altme/credentials/cubit/credentials_cubit.dart'; import 'package:altme/dashboard/dashboard.dart'; import 'package:altme/l10n/l10n.dart'; +import 'package:altme/wallet/cubit/wallet_cubit.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -120,6 +121,11 @@ class _CameraViewState extends State { .selfSovereignIdentityOptions .customOidc4vcProfile .oidc4vciDraft, + blockchainType: context + .read() + .state + .currentAccount! + .blockchainType, ); LoadingView().hide(); await Navigator.pushReplacement( diff --git a/lib/dashboard/crypto_account_switcher/crypto_bottom_sheet/cubit/crypto_bottom_sheet_cubit.dart b/lib/dashboard/crypto_account_switcher/crypto_bottom_sheet/cubit/crypto_bottom_sheet_cubit.dart index dd7148369..aa9d54a5a 100644 --- a/lib/dashboard/crypto_account_switcher/crypto_bottom_sheet/cubit/crypto_bottom_sheet_cubit.dart +++ b/lib/dashboard/crypto_account_switcher/crypto_bottom_sheet/cubit/crypto_bottom_sheet_cubit.dart @@ -33,6 +33,10 @@ class CryptoBottomSheetCubit extends Cubit { Future setCurrentWalletAccount(int index) async { emit(state.loading()); await walletCubit.setCurrentWalletAccount(index); + await walletCubit.credentialsCubit.loadAllCredentials( + blockchainType: + walletCubit.state.cryptoAccount.data[index].blockchainType, + ); emit(state.success(currentCryptoIndex: index)); } diff --git a/lib/dashboard/discover/view/discover_page.dart b/lib/dashboard/discover/view/discover_page.dart index ed3e64efb..4ce2acaed 100644 --- a/lib/dashboard/discover/view/discover_page.dart +++ b/lib/dashboard/discover/view/discover_page.dart @@ -2,6 +2,7 @@ import 'package:altme/app/shared/widget/widget.dart'; import 'package:altme/credentials/credentials.dart'; import 'package:altme/dashboard/dashboard.dart'; import 'package:altme/theme/theme.dart'; +import 'package:altme/wallet/cubit/wallet_cubit.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -14,7 +15,10 @@ class DiscoverPage extends StatefulWidget { class _DiscoverPageState extends State { Future onRefresh() async { - await context.read().loadAllCredentials(); + await context.read().loadAllCredentials( + blockchainType: + context.read().state.currentAccount!.blockchainType, + ); } @override diff --git a/lib/dashboard/discover/widgets/discover_credential_item.dart b/lib/dashboard/discover/widgets/discover_credential_item.dart index 0f00bc589..97c23c2ee 100644 --- a/lib/dashboard/discover/widgets/discover_credential_item.dart +++ b/lib/dashboard/discover/widgets/discover_credential_item.dart @@ -34,11 +34,13 @@ class DiscoverCredentialItem extends StatelessWidget { dummyCredential: dummyCredential, buttonText: l10n.getThisCard, onCallBack: () async { + LoadingView().show(context: context); await discoverCredential( dummyCredential: dummyCredential, context: context, ); Navigator.pop(context); + LoadingView().hide(); }, ), ); diff --git a/lib/dashboard/drawer/profile/widget/profile_selector_widget.dart b/lib/dashboard/drawer/profile/widget/profile_selector_widget.dart index 63a884ae7..d90ee4b3d 100644 --- a/lib/dashboard/drawer/profile/widget/profile_selector_widget.dart +++ b/lib/dashboard/drawer/profile/widget/profile_selector_widget.dart @@ -3,6 +3,7 @@ import 'package:altme/credentials/cubit/credentials_cubit.dart'; import 'package:altme/dashboard/profile/profile.dart'; import 'package:altme/l10n/l10n.dart'; import 'package:altme/theme/theme.dart'; +import 'package:altme/wallet/wallet.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -80,7 +81,13 @@ class ProfileSelectorWidget extends StatelessWidget { .setProfile(profileType); await context .read() - .loadAllCredentials(); + .loadAllCredentials( + blockchainType: context + .read() + .state + .currentAccount! + .blockchainType, + ); }, shape: const RoundedRectangleBorder( side: BorderSide( diff --git a/lib/dashboard/drawer/src/view/drawer_page.dart b/lib/dashboard/drawer/src/view/drawer_page.dart index da38868c4..cf3489ed9 100644 --- a/lib/dashboard/drawer/src/view/drawer_page.dart +++ b/lib/dashboard/drawer/src/view/drawer_page.dart @@ -1,8 +1,8 @@ import 'package:altme/app/app.dart'; import 'package:altme/dashboard/dashboard.dart'; import 'package:altme/dashboard/drawer/profile/view/pick_profile_menu.dart'; +import 'package:altme/enterprise/cubit/enterprise_cubit.dart'; import 'package:altme/l10n/l10n.dart'; -import 'package:altme/onboarding/onboarding.dart'; import 'package:altme/theme/theme.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -57,9 +57,11 @@ class DrawerView extends StatelessWidget { DrawerCategoryItem( title: l10n.updateYourWalletConfigNow, padding: const EdgeInsets.all(16), - onClick: () { - Navigator.of(context) - .push(EnterpriseUpdatePage.route()); + onClick: () async { + Navigator.of(context).pop(); + await context + .read() + .updateTheConfiguration(); }, ), const SizedBox(height: Sizes.spaceSmall), diff --git a/lib/dashboard/drawer/ssi/restore/restore_credential/cubit/restore_credential_cubit.dart b/lib/dashboard/drawer/ssi/restore/restore_credential/cubit/restore_credential_cubit.dart index 573b5321d..cf0091b77 100644 --- a/lib/dashboard/drawer/ssi/restore/restore_credential/cubit/restore_credential_cubit.dart +++ b/lib/dashboard/drawer/ssi/restore/restore_credential/cubit/restore_credential_cubit.dart @@ -139,7 +139,9 @@ class RestoreCredentialCubit extends Cubit { credentials: credentialList, isPolygonIdCredentials: isPolygonIdCredentials, ); - await credentialsCubit.loadAllCredentials(); + await credentialsCubit.loadAllCredentials( + blockchainType: walletCubit.state.currentAccount!.blockchainType, + ); emit(state.success(recoveredCredentialLength: credentialList.length)); } catch (e) { if (e is MessageHandler) { diff --git a/lib/dashboard/home/home/cubit/home_cubit.dart b/lib/dashboard/home/home/cubit/home_cubit.dart index ad72fe910..1c7ec0980 100644 --- a/lib/dashboard/home/home/cubit/home_cubit.dart +++ b/lib/dashboard/home/home/cubit/home_cubit.dart @@ -42,6 +42,7 @@ class HomeCubit extends Cubit { required CredentialsCubit credentialsCubit, required CameraCubit cameraCubit, required OIDC4VCIDraftType oidc4vciDraftType, + required BlockchainType blockchainType, }) async { // launch url to get Over18, Over15, Over13,Over21,Over50,Over65, // AgeRange Credentials @@ -99,6 +100,7 @@ class HomeCubit extends Cubit { credentialsCubit: credentialsCubit, cameraCubit: cameraCubit, oidc4vciDraftType: oidc4vciDraftType, + blockchainType: blockchainType, ); await ageEstimate( @@ -156,6 +158,7 @@ class HomeCubit extends Cubit { required CredentialsCubit credentialsCubit, required CameraCubit cameraCubit, required OIDC4VCIDraftType oidc4vciDraftType, + required BlockchainType blockchainType, }) async { /// if credential of this type is already in the wallet do nothing /// Ensure credentialType = name of credential type in CredentialModel @@ -210,6 +213,7 @@ class HomeCubit extends Cubit { await credentialsCubit.insertCredential( credential: credentialModel, showMessage: true, + blockchainType: blockchainType, ); await cameraCubit.incrementAcquiredCredentialsQuantity(); emit(state.copyWith(status: AppStatus.success)); diff --git a/lib/dashboard/home/home/widgets/wallet_dialog.dart b/lib/dashboard/home/home/widgets/wallet_dialog.dart index 3a884e629..63cf03f99 100644 --- a/lib/dashboard/home/home/widgets/wallet_dialog.dart +++ b/lib/dashboard/home/home/widgets/wallet_dialog.dart @@ -35,8 +35,9 @@ class WalletDialog extends StatelessWidget { Text( l10n.createTitle, style: Theme.of(context).textTheme.defaultDialogTitle.copyWith( - fontSize: 18, - color: Theme.of(context).colorScheme.dialogText), + fontSize: 18, + color: Theme.of(context).colorScheme.dialogText, + ), textAlign: TextAlign.center, ), const SizedBox(height: 5), diff --git a/lib/dashboard/home/tab_bar/credentials/detail/cubit/credential_details_cubit.dart b/lib/dashboard/home/tab_bar/credentials/detail/cubit/credential_details_cubit.dart index b11cbf777..0d3d5f5c8 100644 --- a/lib/dashboard/home/tab_bar/credentials/detail/cubit/credential_details_cubit.dart +++ b/lib/dashboard/home/tab_bar/credentials/detail/cubit/credential_details_cubit.dart @@ -39,136 +39,156 @@ class CredentialDetailsCubit extends Cubit { } Future verifyCredential(CredentialModel item) async { - emit(state.copyWith(status: AppStatus.loading)); - await Future.delayed(const Duration(milliseconds: 500)); + try { + emit(state.copyWith(status: AppStatus.loading)); + await Future.delayed(const Duration(milliseconds: 500)); - if (item.credentialPreview.credentialSubjectModel.credentialSubjectType == - CredentialSubjectType.walletCredential) { - emit( - state.copyWith( - credentialStatus: CredentialStatus.active, - status: AppStatus.idle, - ), - ); - return; - } + if (!profileCubit.state.model.profileSetting.selfSovereignIdentityOptions + .customOidc4vcProfile.securityLevel) { + emit( + state.copyWith( + credentialStatus: CredentialStatus.notVerified, + status: AppStatus.idle, + ), + ); + return; + } - if (item.expirationDate != null) { - final DateTime dateTimeExpirationDate = - DateTime.parse(item.expirationDate!); - if (!dateTimeExpirationDate.isAfter(DateTime.now())) { + if (item.credentialPreview.credentialSubjectModel.credentialSubjectType == + CredentialSubjectType.walletCredential) { emit( state.copyWith( - credentialStatus: CredentialStatus.suspended, + credentialStatus: CredentialStatus.active, status: AppStatus.idle, ), ); return; } - } - if (item.jwt != null) { - /// issuer did - final issuerDid = item.issuer; + if (item.expirationDate != null) { + final DateTime dateTimeExpirationDate = + DateTime.parse(item.expirationDate!); + if (!dateTimeExpirationDate.isAfter(DateTime.now())) { + emit( + state.copyWith( + credentialStatus: CredentialStatus.suspended, + status: AppStatus.idle, + ), + ); + return; + } + } + + if (item.jwt != null) { + /// issuer did + final issuerDid = item.issuer; - String? issuerKid; - late final String encodedData; - if (item.jwt == null) { - issuerKid = item.data['proof']['verificationMethod'] as String; - } else { - encodedData = item.jwt!; + String? issuerKid; + late final String encodedData; + if (item.jwt == null) { + issuerKid = item.data['proof']['verificationMethod'] as String; + } else { + encodedData = item.jwt!; - final Map header = - decodeHeader(jwtDecode: jwtDecode, token: encodedData); + final Map header = + decodeHeader(jwtDecode: jwtDecode, token: encodedData); - if (header.containsKey('kid')) { - issuerKid = header['kid'].toString(); + if (header.containsKey('kid')) { + issuerKid = header['kid'].toString(); + } } - } - final VerificationType isVerified = await verifyEncodedData( - issuerDid, - issuerKid, - encodedData, - ); + final VerificationType isVerified = await verifyEncodedData( + issuerDid, + issuerKid, + encodedData, + ); - late CredentialStatus credentialStatus; + late CredentialStatus credentialStatus; - switch (isVerified) { - case VerificationType.verified: - credentialStatus = CredentialStatus.active; - case VerificationType.notVerified: - credentialStatus = CredentialStatus.notVerified; - case VerificationType.unKnown: - credentialStatus = CredentialStatus.suspended; - } + switch (isVerified) { + case VerificationType.verified: + credentialStatus = CredentialStatus.active; + case VerificationType.notVerified: + credentialStatus = CredentialStatus.notVerified; + case VerificationType.unKnown: + credentialStatus = CredentialStatus.suspended; + } - emit( - state.copyWith( - credentialStatus: credentialStatus, - status: AppStatus.idle, - ), - ); - } else if (item.isPolygonssuer) { - final mnemonic = - await secureStorageProvider.get(SecureStorageKeys.ssiMnemonic); - await polygonIdCubit.initialise(); + emit( + state.copyWith( + credentialStatus: credentialStatus, + status: AppStatus.idle, + ), + ); + } else if (item.isPolygonssuer) { + final mnemonic = + await secureStorageProvider.get(SecureStorageKeys.ssiMnemonic); + await polygonIdCubit.initialise(); - String network = Parameters.POLYGON_MAIN_NETWORK; + String network = Parameters.POLYGON_MAIN_NETWORK; - if (item.issuer.contains('polygon:main')) { - network = Parameters.POLYGON_MAIN_NETWORK; - } else { - network = Parameters.POLYGON_TEST_NETWORK; - } + if (item.issuer.contains('polygon:main')) { + network = Parameters.POLYGON_MAIN_NETWORK; + } else { + network = Parameters.POLYGON_TEST_NETWORK; + } - final List claim = - await polygonIdCubit.polygonId.getClaimById( - claimId: item.id, - mnemonic: mnemonic!, - network: network, - ); + final List claim = + await polygonIdCubit.polygonId.getClaimById( + claimId: item.id, + mnemonic: mnemonic!, + network: network, + ); - late CredentialStatus credentialStatus; + late CredentialStatus credentialStatus; - if (claim.isEmpty) { - credentialStatus = CredentialStatus.suspended; + if (claim.isEmpty) { + credentialStatus = CredentialStatus.suspended; + } else { + switch (claim[0].state) { + case ClaimState.active: + credentialStatus = CredentialStatus.active; + case ClaimState.expired: + credentialStatus = CredentialStatus.expired; + case ClaimState.pending: + credentialStatus = CredentialStatus.pending; + case ClaimState.revoked: + credentialStatus = CredentialStatus.revoked; + } + } + + emit( + state.copyWith( + credentialStatus: credentialStatus, + status: AppStatus.idle, + ), + ); } else { - switch (claim[0].state) { - case ClaimState.active: - credentialStatus = CredentialStatus.active; - case ClaimState.expired: - credentialStatus = CredentialStatus.expired; - case ClaimState.pending: - credentialStatus = CredentialStatus.pending; - case ClaimState.revoked: - credentialStatus = CredentialStatus.revoked; + if (item.credentialPreview.credentialStatus.type != '') { + final CredentialStatus credentialStatus = + await item.checkRevocationStatus(); + if (credentialStatus == CredentialStatus.active) { + await verifyProofOfPurpose(item); + } else { + emit( + state.copyWith( + credentialStatus: CredentialStatus.suspended, + status: AppStatus.idle, + ), + ); + } + } else { + await verifyProofOfPurpose(item); } } - + } catch (e) { emit( state.copyWith( - credentialStatus: credentialStatus, + credentialStatus: CredentialStatus.notVerified, status: AppStatus.idle, ), ); - } else { - if (item.credentialPreview.credentialStatus.type != '') { - final CredentialStatus credentialStatus = - await item.checkRevocationStatus(); - if (credentialStatus == CredentialStatus.active) { - await verifyProofOfPurpose(item); - } else { - emit( - state.copyWith( - credentialStatus: CredentialStatus.suspended, - status: AppStatus.idle, - ), - ); - } - } else { - await verifyProofOfPurpose(item); - } } } diff --git a/lib/dashboard/home/tab_bar/credentials/detail/view/credentials_details_page.dart b/lib/dashboard/home/tab_bar/credentials/detail/view/credentials_details_page.dart index f500586b9..a5fed0007 100644 --- a/lib/dashboard/home/tab_bar/credentials/detail/view/credentials_details_page.dart +++ b/lib/dashboard/home/tab_bar/credentials/detail/view/credentials_details_page.dart @@ -8,6 +8,7 @@ import 'package:altme/dashboard/home/tab_bar/credentials/models/activity/activit import 'package:altme/l10n/l10n.dart'; import 'package:altme/polygon_id/polygon_id.dart'; import 'package:altme/theme/theme.dart'; +import 'package:altme/wallet/cubit/wallet_cubit.dart'; import 'package:did_kit/did_kit.dart'; import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; @@ -115,7 +116,11 @@ class _CredentialsDetailsViewState extends State { if (confirm) { final credentialsCubit = context.read(); - await credentialsCubit.deleteById(id: widget.credentialModel.id); + await credentialsCubit.deleteById( + id: widget.credentialModel.id, + blockchainType: + context.read().state.currentAccount!.blockchainType, + ); } } @@ -165,14 +170,8 @@ class _CredentialsDetailsViewState extends State { reversedList.removeLast(); } - final vcFormatType = context - .read() - .state - .model - .profileSetting - .selfSovereignIdentityOptions - .customOidc4vcProfile - .vcFormatType; + final profileSetting = + context.read().state.model.profileSetting; return BasePage( title: widget.readOnly ? l10n.linkedInProfile : l10n.cardDetails, @@ -191,7 +190,7 @@ class _CredentialsDetailsViewState extends State { CredentialDisplay( credentialModel: widget.credentialModel, credDisplayType: CredDisplayType.Detail, - vcFormatType: vcFormatType, + profileSetting: profileSetting, ), const SizedBox(height: 20), Column( diff --git a/lib/dashboard/home/tab_bar/credentials/helper_functions/discover_credential.dart b/lib/dashboard/home/tab_bar/credentials/helper_functions/discover_credential.dart index b90f47b60..bedb7cb03 100644 --- a/lib/dashboard/home/tab_bar/credentials/helper_functions/discover_credential.dart +++ b/lib/dashboard/home/tab_bar/credentials/helper_functions/discover_credential.dart @@ -1,15 +1,46 @@ import 'package:altme/app/app.dart'; +import 'package:altme/credentials/cubit/credentials_cubit.dart'; import 'package:altme/dashboard/dashboard.dart'; import 'package:altme/kyc_verification/kyc_verification.dart'; +import 'package:altme/wallet/wallet.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:oidc4vc/oidc4vc.dart'; +import 'package:secure_storage/secure_storage.dart'; import 'package:uuid/uuid.dart'; Future discoverCredential({ required DiscoverDummyCredential dummyCredential, required BuildContext context, }) async { + if (dummyCredential.credentialSubjectType.isBlockchainAccount) { + final String? ssiMnemonic = + await getSecureStorage.get(SecureStorageKeys.ssiMnemonic); + + /// tracking added accounts + final String totalAccountsYet = await getSecureStorage.get( + SecureStorageKeys.cryptoAccounTrackingIndex, + ) ?? + '0'; + + final credentialCubit = context.read(); + final walletCubit = context.read(); + + final cryptoAccountData = await walletCubit.generateAccount( + mnemonicOrKey: ssiMnemonic!, + isImported: false, + isSecretKey: false, + blockchainType: walletCubit.state.currentAccount!.blockchainType, + totalAccountsYet: int.parse(totalAccountsYet), + ); + + await credentialCubit.insertAssociatedWalletCredential( + cryptoAccountData: cryptoAccountData, + ); + + return; + } + final profileCubit = context.read(); final customOidc4vcProfile = profileCubit.state.model.profileSetting diff --git a/lib/dashboard/home/tab_bar/credentials/linkedin_credential/generate_linkedin_qr/cubit/generate_linkedin_qr_cubit.dart b/lib/dashboard/home/tab_bar/credentials/linkedin_credential/generate_linkedin_qr/cubit/generate_linkedin_qr_cubit.dart index 03ae5f0b7..8f10133b5 100644 --- a/lib/dashboard/home/tab_bar/credentials/linkedin_credential/generate_linkedin_qr/cubit/generate_linkedin_qr_cubit.dart +++ b/lib/dashboard/home/tab_bar/credentials/linkedin_credential/generate_linkedin_qr/cubit/generate_linkedin_qr_cubit.dart @@ -2,7 +2,6 @@ import 'dart:convert'; import 'package:altme/app/app.dart'; import 'package:altme/dashboard/dashboard.dart'; -import 'package:altme/dashboard/home/home.dart'; import 'package:did_kit/did_kit.dart'; import 'package:equatable/equatable.dart'; import 'package:file_saver/file_saver.dart'; diff --git a/lib/dashboard/home/tab_bar/credentials/linkedin_credential/generate_linkedin_qr/view/generate_linkedin_qr_page.dart b/lib/dashboard/home/tab_bar/credentials/linkedin_credential/generate_linkedin_qr/view/generate_linkedin_qr_page.dart index 38191056f..d11284061 100644 --- a/lib/dashboard/home/tab_bar/credentials/linkedin_credential/generate_linkedin_qr/view/generate_linkedin_qr_page.dart +++ b/lib/dashboard/home/tab_bar/credentials/linkedin_credential/generate_linkedin_qr/view/generate_linkedin_qr_page.dart @@ -1,6 +1,5 @@ import 'package:altme/app/app.dart'; import 'package:altme/dashboard/dashboard.dart'; -import 'package:altme/dashboard/home/home.dart'; import 'package:altme/l10n/l10n.dart'; import 'package:did_kit/did_kit.dart'; import 'package:file_saver/file_saver.dart'; diff --git a/lib/dashboard/home/tab_bar/credentials/list/view/home_credentials_list_page.dart b/lib/dashboard/home/tab_bar/credentials/list/view/home_credentials_list_page.dart index 1eebee99d..cf4bc9077 100644 --- a/lib/dashboard/home/tab_bar/credentials/list/view/home_credentials_list_page.dart +++ b/lib/dashboard/home/tab_bar/credentials/list/view/home_credentials_list_page.dart @@ -2,6 +2,7 @@ import 'package:altme/app/app.dart'; import 'package:altme/credentials/cubit/credentials_cubit.dart'; import 'package:altme/dashboard/dashboard.dart'; import 'package:altme/theme/theme.dart'; +import 'package:altme/wallet/wallet.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -22,12 +23,18 @@ class _HomeCredentialsListPageState extends State @override void initState() { - context.read().loadAllCredentials(); + context.read().loadAllCredentials( + blockchainType: + context.read().state.currentAccount!.blockchainType, + ); super.initState(); } Future onRefresh() async { - await context.read().loadAllCredentials(); + await context.read().loadAllCredentials( + blockchainType: + context.read().state.currentAccount!.blockchainType, + ); } @override diff --git a/lib/dashboard/home/tab_bar/credentials/list/widgets/home_credential_category_list.dart b/lib/dashboard/home/tab_bar/credentials/list/widgets/home_credential_category_list.dart index 441baf113..0ed79c44f 100644 --- a/lib/dashboard/home/tab_bar/credentials/list/widgets/home_credential_category_list.dart +++ b/lib/dashboard/home/tab_bar/credentials/list/widgets/home_credential_category_list.dart @@ -54,6 +54,12 @@ class HomeCredentialCategoryList extends StatelessWidget { return true; } + // /// crypto credential account to be shown always + // if (element.credentialPreview.credentialSubjectModel + // .credentialSubjectType.isBlockchainAccount ) { + // return true; + // } + /// do not load the credential if vc format is different if (vcFormatType.value != element.getFormat) { return false; diff --git a/lib/dashboard/home/tab_bar/credentials/models/credential_model/credential_model.dart b/lib/dashboard/home/tab_bar/credentials/models/credential_model/credential_model.dart index b5d3be039..80417c9c4 100644 --- a/lib/dashboard/home/tab_bar/credentials/models/credential_model/credential_model.dart +++ b/lib/dashboard/home/tab_bar/credentials/models/credential_model/credential_model.dart @@ -121,6 +121,7 @@ class CredentialModel extends Equatable { PendingInfo? pendingInfo, String? format, Map? claims, + Map? credentialSupported, }) { return CredentialModel( id: id ?? this.id, diff --git a/lib/dashboard/home/tab_bar/credentials/oid4c4vc_pick/oid4c4vc_credential_pick/view/oid4c4vc_credential_pick_page.dart b/lib/dashboard/home/tab_bar/credentials/oid4c4vc_pick/oid4c4vc_credential_pick/view/oid4c4vc_credential_pick_page.dart index 99999aa1d..97f10f077 100644 --- a/lib/dashboard/home/tab_bar/credentials/oid4c4vc_pick/oid4c4vc_credential_pick/view/oid4c4vc_credential_pick_page.dart +++ b/lib/dashboard/home/tab_bar/credentials/oid4c4vc_pick/oid4c4vc_credential_pick/view/oid4c4vc_credential_pick_page.dart @@ -114,17 +114,11 @@ class Oidc4vcCredentialPickView extends StatelessWidget { getCredTypeFromName(credential) ?? CredentialSubjectType.defaultCredential; - final vcFormatType = context - .read() - .state - .model - .profileSetting - .selfSovereignIdentityOptions - .customOidc4vcProfile - .vcFormatType; + final profileSetting = + context.read().state.model.profileSetting; final DiscoverDummyCredential discoverDummyCredential = - credentialSubjectType.dummyCredential(vcFormatType); + credentialSubjectType.dummyCredential(profileSetting); Display? display; @@ -166,7 +160,7 @@ class Oidc4vcCredentialPickView extends StatelessWidget { display: display, ), credDisplayType: CredDisplayType.List, - vcFormatType: vcFormatType, + profileSetting: profileSetting, displyalDescription: false, ) else diff --git a/lib/dashboard/home/tab_bar/credentials/receive/view/credentials_receive_page.dart b/lib/dashboard/home/tab_bar/credentials/receive/view/credentials_receive_page.dart index f3394776f..ebc6dbc06 100644 --- a/lib/dashboard/home/tab_bar/credentials/receive/view/credentials_receive_page.dart +++ b/lib/dashboard/home/tab_bar/credentials/receive/view/credentials_receive_page.dart @@ -62,14 +62,8 @@ class _CredentialsReceivePageState extends State { final textColor = Theme.of(context).colorScheme.valueColor; - final vcFormatType = context - .read() - .state - .model - .profileSetting - .selfSovereignIdentityOptions - .customOidc4vcProfile - .vcFormatType; + final profileSetting = + context.read().state.model.profileSetting; return BasePage( title: l10n.credentialReceiveTitle, @@ -96,7 +90,7 @@ class _CredentialsReceivePageState extends State { CredentialDisplay( credentialModel: credentialModel, credDisplayType: CredDisplayType.Detail, - vcFormatType: vcFormatType, + profileSetting: profileSetting, ), if (outputDescriptors != null) ...[ const SizedBox(height: 30), diff --git a/lib/dashboard/home/tab_bar/credentials/widgets/credential_display.dart b/lib/dashboard/home/tab_bar/credentials/widgets/credential_display.dart index 8b821d0e0..86e788f63 100644 --- a/lib/dashboard/home/tab_bar/credentials/widgets/credential_display.dart +++ b/lib/dashboard/home/tab_bar/credentials/widgets/credential_display.dart @@ -1,20 +1,19 @@ import 'package:altme/app/app.dart'; import 'package:altme/dashboard/dashboard.dart'; import 'package:flutter/material.dart'; -import 'package:oidc4vc/oidc4vc.dart'; class CredentialDisplay extends StatelessWidget { const CredentialDisplay({ super.key, required this.credentialModel, required this.credDisplayType, - required this.vcFormatType, + required this.profileSetting, this.displyalDescription = true, }); final CredentialModel credentialModel; final CredDisplayType credDisplayType; - final VCFormatType vcFormatType; + final ProfileSetting profileSetting; final bool displyalDescription; @override @@ -68,7 +67,7 @@ class CredentialDisplay extends StatelessWidget { CredentialSubjectType.defaultCredential; final DiscoverDummyCredential discoverDummyCredential = - credentialSubjectType.dummyCredential(vcFormatType); + credentialSubjectType.dummyCredential(profileSetting); return Opacity( opacity: 0.5, diff --git a/lib/dashboard/home/tab_bar/credentials/widgets/list_item.dart b/lib/dashboard/home/tab_bar/credentials/widgets/list_item.dart index 496eb8eed..5364df7ee 100644 --- a/lib/dashboard/home/tab_bar/credentials/widgets/list_item.dart +++ b/lib/dashboard/home/tab_bar/credentials/widgets/list_item.dart @@ -84,14 +84,9 @@ class CredentialsDisplayItem extends StatelessWidget { @override Widget build(BuildContext context) { - final vcFormatType = context - .read() - .state - .model - .profileSetting - .selfSovereignIdentityOptions - .customOidc4vcProfile - .vcFormatType; + final profileSetting = + context.read().state.model.profileSetting; + return _BaseItem( enabled: true, onTap: onTap, @@ -99,7 +94,7 @@ class CredentialsDisplayItem extends StatelessWidget { ? CredentialDisplay( credentialModel: credentialModel, credDisplayType: CredDisplayType.List, - vcFormatType: vcFormatType, + profileSetting: profileSetting, ) : DisplaySelectionElement( credentialModel: credentialModel, @@ -122,21 +117,16 @@ class DisplaySelectionElement extends StatelessWidget { @override Widget build(BuildContext context) { //final credential = Credential.fromJsonOrDummy(credentialModel.data); - final vcFormatType = context - .read() - .state - .model - .profileSetting - .selfSovereignIdentityOptions - .customOidc4vcProfile - .vcFormatType; + final profileSetting = + context.read().state.model.profileSetting; + return CredentialSelectionPadding( child: Column( children: [ CredentialDisplay( credentialModel: credentialModel, credDisplayType: CredDisplayType.List, - vcFormatType: vcFormatType, + profileSetting: profileSetting, ), Align( alignment: Alignment.centerRight, diff --git a/lib/dashboard/missing_creentials/cubit/missing_credentials_cubit.dart b/lib/dashboard/missing_creentials/cubit/missing_credentials_cubit.dart index 41ea65a25..f03fc4df3 100644 --- a/lib/dashboard/missing_creentials/cubit/missing_credentials_cubit.dart +++ b/lib/dashboard/missing_creentials/cubit/missing_credentials_cubit.dart @@ -35,8 +35,7 @@ class MissingCredentialsCubit extends Cubit { final List dummyCredentials = []; - final vcFormatType = profileCubit.state.model.profileSetting - .selfSovereignIdentityOptions.customOidc4vcProfile.vcFormatType; + final profileSetting = profileCubit.state.model.profileSetting; if (credentialManifest != null) { final PresentationDefinition? presentationDefinition = @@ -69,7 +68,7 @@ class MissingCredentialsCubit extends Cubit { if (credentialSubjectType != null) { dummyCredentials.add( - credentialSubjectType.dummyCredential(vcFormatType), + credentialSubjectType.dummyCredential(profileSetting), ); } } @@ -92,7 +91,7 @@ class MissingCredentialsCubit extends Cubit { if (credentialSubjectType != null) { dummyCredentials - .add(credentialSubjectType.dummyCredential(vcFormatType)); + .add(credentialSubjectType.dummyCredential(profileSetting)); } } } diff --git a/lib/dashboard/profile/models/profile.dart b/lib/dashboard/profile/models/profile.dart index 8bd7c244f..44f292681 100644 --- a/lib/dashboard/profile/models/profile.dart +++ b/lib/dashboard/profile/models/profile.dart @@ -101,7 +101,7 @@ class ProfileModel extends Equatable { displayManageDecentralizedId: true, customOidc4vcProfile: CustomOidc4VcProfile( clientAuthentication: ClientAuthentication.clientId, - credentialManifestSupport: true, + credentialManifestSupport: false, cryptoHolderBinding: false, defaultDid: Parameters.didKeyTypeForDefault, oidc4vciDraft: OIDC4VCIDraftType.draft11, @@ -160,7 +160,7 @@ class ProfileModel extends Equatable { displayEmailPass: true, displayEmailPassJwt: true, displayPhonePass: false, - displayPhonePassJwt: false, + displayPhonePassJwt: true, displayAgeRange: false, displayGender: false, displayExternalIssuer: [], diff --git a/lib/dashboard/qr_code/qr_code_scan/cubit/qr_code_scan_cubit.dart b/lib/dashboard/qr_code/qr_code_scan/cubit/qr_code_scan_cubit.dart index 915103b89..c44679af8 100644 --- a/lib/dashboard/qr_code/qr_code_scan/cubit/qr_code_scan_cubit.dart +++ b/lib/dashboard/qr_code/qr_code_scan/cubit/qr_code_scan_cubit.dart @@ -7,10 +7,12 @@ import 'package:altme/credentials/credentials.dart'; import 'package:altme/dashboard/dashboard.dart'; import 'package:altme/dashboard/home/tab_bar/credentials/present/pick/credential_manifest/helpers/apply_submission_requirements.dart'; import 'package:altme/deep_link/deep_link.dart'; +import 'package:altme/enterprise/cubit/enterprise_cubit.dart'; import 'package:altme/oidc4vc/oidc4vc.dart'; import 'package:altme/polygon_id/polygon_id.dart'; import 'package:altme/query_by_example/query_by_example.dart'; import 'package:altme/scan/scan.dart'; +import 'package:altme/wallet/cubit/wallet_cubit.dart'; import 'package:beacon_flutter/beacon_flutter.dart'; import 'package:bloc/bloc.dart'; import 'package:credential_manifest/credential_manifest.dart'; @@ -42,6 +44,8 @@ class QRCodeScanCubit extends Cubit { required this.polygonIdCubit, required this.didKitProvider, required this.oidc4vc, + required this.walletCubit, + required this.enterpriseCubit, }) : super(const QRCodeScanState()); final DioClient client; @@ -58,6 +62,8 @@ class QRCodeScanCubit extends Cubit { final PolygonIdCubit polygonIdCubit; final DIDKitProvider didKitProvider; final OIDC4VC oidc4vc; + final WalletCubit walletCubit; + final EnterpriseCubit enterpriseCubit; final log = getLogger('QRCodeScanCubit'); @@ -105,6 +111,11 @@ class QRCodeScanCubit extends Cubit { scannedResponse.substring('${Urls.appDeepLink}?uri='.length), ); await verify(uri: Uri.parse(url)); + } else if (scannedResponse.startsWith('configuration://?')) { + /// enterprise + final uri = Uri.parse(scannedResponse); + emit(state.copyWith(qrScanStatus: QrScanStatus.goBack)); + await enterpriseCubit.requestTheConfiguration(uri); } else { final uri = Uri.parse(scannedResponse); await verify(uri: uri); @@ -210,8 +221,12 @@ class QRCodeScanCubit extends Cubit { } Future accept({ - required Issuer issuer, + required Issuer approvedIssuer, required QRCodeScanCubit qrCodeScanCubit, + required dynamic credentialOfferJson, + required OpenIdConfiguration? openIdConfiguration, + required String? issuer, + required String? preAuthorizedCode, OIDC4VCType? oidcType, }) async { emit(state.loading()); @@ -222,12 +237,26 @@ class QRCodeScanCubit extends Cubit { try { if (isOIDC4VCIUrl(state.uri!) && oidcType != null) { /// issuer side (oidc4VCI) + + if (issuer == null) { + throw ResponseMessage( + data: { + 'error': 'invalid_issuer_metadata', + 'error_description': 'The issuer configuration is invalid.', + }, + ); + } + await startOIDC4VCCredentialIssuance( scannedResponse: state.uri.toString(), isEBSIV3: oidcType == OIDC4VCType.EBSIV3, qrCodeScanCubit: qrCodeScanCubit, oidc4vciDraftType: profileCubit.state.model.profileSetting .selfSovereignIdentityOptions.customOidc4vcProfile.oidc4vciDraft, + credentialOfferJson: credentialOfferJson, + openIdConfiguration: openIdConfiguration, + issuer: issuer, + preAuthorizedCode: preAuthorizedCode, ); return; } @@ -274,7 +303,7 @@ class QRCodeScanCubit extends Cubit { route: CredentialsReceivePage.route( uri: state.uri!, preview: data as Map, - issuer: issuer, + issuer: approvedIssuer, ), ), ); @@ -328,7 +357,7 @@ class QRCodeScanCubit extends Cubit { route: QueryByExamplePresentPage.route( uri: state.uri!, preview: data as Map, - issuer: issuer, + issuer: approvedIssuer, ), ), ); @@ -345,7 +374,7 @@ class QRCodeScanCubit extends Cubit { route: QueryByExamplePresentPage.route( uri: state.uri!, preview: data as Map, - issuer: issuer, + issuer: approvedIssuer, ), ), ); @@ -358,7 +387,7 @@ class QRCodeScanCubit extends Cubit { route: CredentialsReceivePage.route( uri: state.uri!, preview: data as Map, - issuer: issuer, + issuer: approvedIssuer, ), ), ); @@ -381,6 +410,10 @@ class QRCodeScanCubit extends Cubit { required bool isEBSIV3, required QRCodeScanCubit qrCodeScanCubit, required OIDC4VCIDraftType oidc4vciDraftType, + required dynamic credentialOfferJson, + required OpenIdConfiguration? openIdConfiguration, + required String issuer, + required String? preAuthorizedCode, }) async { emit( state.copyWith( @@ -393,14 +426,11 @@ class QRCodeScanCubit extends Cubit { uriFromScannedResponse.queryParameters .forEach((key, value) => keys.add(key)); - dynamic credentialOfferJson; + final customOidc4vcProfile = profileCubit.state.model.profileSetting + .selfSovereignIdentityOptions.customOidc4vcProfile; if (keys.contains('credential_offer') || keys.contains('credential_offer_uri')) { - credentialOfferJson = await getCredentialOfferJson( - scannedResponse: scannedResponse, - dioClient: client, - ); if (credentialOfferJson != null) { final dynamic preAuthorizedCodeGrant = credentialOfferJson['grants'] ['urn:ietf:params:oauth:grant-type:pre-authorized_code']; @@ -444,15 +474,13 @@ class QRCodeScanCubit extends Cubit { oidc4vc: oidc4vc, isEBSIV3: isEBSIV3, credentialOfferJson: credentialOfferJson, - cryptoHolderBinding: profileCubit - .state - .model - .profileSetting - .selfSovereignIdentityOptions - .customOidc4vcProfile - .cryptoHolderBinding, + cryptoHolderBinding: + customOidc4vcProfile.cryptoHolderBinding, oidc4vciDraftType: oidc4vciDraftType, profileCubit: profileCubit, + openIdConfiguration: openIdConfiguration, + preAuthorizedCode: preAuthorizedCode, + issuer: issuer, ); }, ), @@ -474,15 +502,12 @@ class QRCodeScanCubit extends Cubit { userPin: null, credentialOfferJson: credentialOfferJson, isEBSIV3: isEBSIV3, - cryptoHolderBinding: profileCubit - .state - .model - .profileSetting - .selfSovereignIdentityOptions - .customOidc4vcProfile - .cryptoHolderBinding, + cryptoHolderBinding: customOidc4vcProfile.cryptoHolderBinding, oidc4vciDraftType: oidc4vciDraftType, profileCubit: profileCubit, + openIdConfiguration: openIdConfiguration, + preAuthorizedCode: preAuthorizedCode, + issuer: issuer, ); } @@ -756,6 +781,8 @@ class QRCodeScanCubit extends Cubit { OpenIdConfiguration? openIdConfiguration, OpenIdConfiguration? authorizationServerConfiguration, _, + String? issuer, + _, ) = await getIssuanceData( url: url, client: client, @@ -775,9 +802,10 @@ class QRCodeScanCubit extends Cubit { await getAndAddDefferedCredential( credentialModel: credentialModel, credentialsCubit: credentialsCubit, - dioClient: client, + issuer: issuer, oidc4vc: oidc4vc, jwtDecode: jwtDecode, + blockchainType: walletCubit.state.currentAccount!.blockchainType, ); } catch (e) { emitError(e); @@ -1119,64 +1147,14 @@ class QRCodeScanCubit extends Cubit { required dynamic credentialOfferJson, }) async { try { - String? clientId; - String? clientSecret; - String? authorization; + final (clientId, clientSecret, authorization) = await getClientDetails( + profileCubit: profileCubit, + isEBSIV3: isEBSIV3, + ); final customOidc4vcProfile = profileCubit.state.model.profileSetting .selfSovereignIdentityOptions.customOidc4vcProfile; - final scope = customOidc4vcProfile.scope; - - switch (customOidc4vcProfile.clientAuthentication) { - case ClientAuthentication.none: - break; - case ClientAuthentication.clientSecretPost: - clientId = customOidc4vcProfile.clientId; - clientSecret = customOidc4vcProfile.clientSecret; - case ClientAuthentication.clientSecretBasic: - clientId = customOidc4vcProfile.clientId; - clientSecret = customOidc4vcProfile.clientSecret; - authorization = - base64UrlEncode(utf8.encode('$clientId:$clientSecret')) - .replaceAll('=', ''); - case ClientAuthentication.clientId: - final didKeyType = customOidc4vcProfile.defaultDid; - - final privateKey = await fetchPrivateKey( - oidc4vc: oidc4vc, - secureStorage: secureStorageProvider, - isEBSIV3: isEBSIV3, - didKeyType: didKeyType, - ); - - final (did, _) = await fetchDidAndKid( - privateKey: privateKey, - isEBSIV3: isEBSIV3, - didKitProvider: didKitProvider, - secureStorage: secureStorageProvider, - didKeyType: didKeyType, - ); - switch (customOidc4vcProfile.clientType) { - case ClientType.jwkThumbprint: - final tokenParameters = TokenParameters( - privateKey: jsonDecode(privateKey) as Map, - did: '', // just added as it is required field - mediaType: - MediaType.basic, // just added as it is required field - clientType: ClientType - .jwkThumbprint, // just added as it is required field - proofHeaderType: customOidc4vcProfile.proofHeader, - clientId: '', - ); - clientId = tokenParameters.thumbprint; - case ClientType.did: - clientId = did; - case ClientType.confidential: - clientId = customOidc4vcProfile.clientId; - } - } - if (preAuthorizedCode != null) { await addCredentialsInLoop( selectedCredentials: selectedCredentials, @@ -1192,6 +1170,7 @@ class QRCodeScanCubit extends Cubit { ); } else { emit(state.loading()); + final scope = customOidc4vcProfile.scope; await getAuthorizationUriForIssuer( scannedResponse: state.uri.toString(), @@ -1215,6 +1194,8 @@ class QRCodeScanCubit extends Cubit { } } + Completer? completer; + Future addCredentialsInLoop({ required List selectedCredentials, required bool isEBSIV3, @@ -1224,7 +1205,7 @@ class QRCodeScanCubit extends Cubit { required String? codeForAuthorisedFlow, required String? codeVerifier, required String? authorization, - required String clientId, + required String? clientId, required String? clientSecret, }) async { try { @@ -1234,30 +1215,88 @@ class QRCodeScanCubit extends Cubit { final customOidc4vcProfile = profileCubit.state.model.profileSetting .selfSovereignIdentityOptions.customOidc4vcProfile; - await getAndAddCredential( - scannedResponse: state.uri.toString(), - credentialsCubit: credentialsCubit, - oidc4vc: oidc4vc, - isEBSIV3: isEBSIV3, - didKitProvider: didKitProvider, - secureStorageProvider: getSecureStorage, - credential: selectedCredentials[i], - isLastCall: i + 1 == selectedCredentials.length, - dioClient: client, - userPin: userPin, - issuer: issuer, - preAuthorizedCode: preAuthorizedCode, - codeForAuthorisedFlow: codeForAuthorisedFlow, - codeVerifier: codeVerifier, - cryptoHolderBinding: customOidc4vcProfile.cryptoHolderBinding, - authorization: authorization, - oidc4vciDraftType: customOidc4vcProfile.oidc4vciDraft, - didKeyType: customOidc4vcProfile.defaultDid, - clientId: clientId, - clientSecret: clientSecret, - profileCubit: profileCubit, - jwtDecode: jwtDecode, - ); + if (preAuthorizedCode != null || + (codeForAuthorisedFlow != null && codeVerifier != null)) { + /// codeForAuthorisedFlow != null + /// this is second phase flow for authorization_code + /// first phase is need for the authentication + /// + /// preAuthorizedCode != null + /// this is full phase flow for preAuthorizedCode + + /// get credentials + final ( + List encodedCredentialOrFutureTokens, + String? deferredCredentialEndpoint, + String format, + OpenIdConfiguration? openIdConfiguration, + Map? tokenResponse, + ) = await getCredential( + oidc4vc: oidc4vc, + isEBSIV3: isEBSIV3, + didKitProvider: didKitProvider, + credential: selectedCredentials[i], + userPin: userPin, + issuer: issuer, + preAuthorizedCode: preAuthorizedCode, + codeForAuthorisedFlow: codeForAuthorisedFlow, + codeVerifier: codeVerifier, + cryptoHolderBinding: customOidc4vcProfile.cryptoHolderBinding, + authorization: authorization, + oidc4vciDraftType: customOidc4vcProfile.oidc4vciDraft, + didKeyType: customOidc4vcProfile.defaultDid, + clientId: clientId, + clientSecret: clientSecret, + profileCubit: profileCubit, + ); + + if (profileCubit.state.model.isDeveloperMode) { + completer = Completer(); + + final formattedData = getFormattedStringResponse( + tokenData: tokenResponse, + credentialData: encodedCredentialOrFutureTokens, + ); + emit( + state.copyWith( + qrScanStatus: QrScanStatus.pauseForDialog, + dialogData: formattedData, + ), + ); + + final value = await completer!.future; + + if (value) { + completer = null; + } else { + completer = null; + oidc4vc.resetNonceAndAccessTokenAndAuthorizationDetails(); + goBack(); + return; + } + } + + await addCredentialData( + scannedResponse: state.uri.toString(), + credentialsCubit: credentialsCubit, + secureStorageProvider: getSecureStorage, + credential: selectedCredentials[i], + isLastCall: i + 1 == selectedCredentials.length, + issuer: issuer, + profileCubit: profileCubit, + jwtDecode: jwtDecode, + blockchainType: walletCubit.state.currentAccount!.blockchainType, + deferredCredentialEndpoint: deferredCredentialEndpoint, + encodedCredentialOrFutureTokens: encodedCredentialOrFutureTokens, + format: format, + openIdConfiguration: openIdConfiguration, + tokenResponse: tokenResponse, + ); + + /// add credentials + } else { + throw Exception(); + } } oidc4vc.resetNonceAndAccessTokenAndAuthorizationDetails(); diff --git a/lib/dashboard/qr_code/qr_code_scan/cubit/qr_code_scan_state.dart b/lib/dashboard/qr_code/qr_code_scan/cubit/qr_code_scan_state.dart index 1308501d2..7769b822b 100644 --- a/lib/dashboard/qr_code/qr_code_scan/cubit/qr_code_scan_state.dart +++ b/lib/dashboard/qr_code/qr_code_scan/cubit/qr_code_scan_state.dart @@ -8,6 +8,7 @@ class QRCodeScanState extends Equatable { this.route, this.isScan = false, this.message, + this.dialogData, }); factory QRCodeScanState.fromJson(Map json) => @@ -20,6 +21,7 @@ class QRCodeScanState extends Equatable { final bool isScan; final StateMessage? message; + final String? dialogData; Map toJson() => _$QRCodeScanStateToJson(this); @@ -54,6 +56,7 @@ class QRCodeScanState extends Equatable { Route? route, Uri? uri, bool? isScan, + String? dialogData, }) { return QRCodeScanState( status: qrScanStatus, @@ -61,9 +64,17 @@ class QRCodeScanState extends Equatable { isScan: isScan ?? this.isScan, uri: uri ?? this.uri, route: route, // route should be cleared when one route is done + dialogData: dialogData, ); } @override - List get props => [status, uri, route, isScan, message]; + List get props => [ + status, + uri, + route, + isScan, + message, + dialogData, + ]; } diff --git a/lib/dashboard/self_issued_credential_button/cubit/self_issued_credential_button_cubit.dart b/lib/dashboard/self_issued_credential_button/cubit/self_issued_credential_button_cubit.dart index abf776c48..b43d0343c 100644 --- a/lib/dashboard/self_issued_credential_button/cubit/self_issued_credential_button_cubit.dart +++ b/lib/dashboard/self_issued_credential_button/cubit/self_issued_credential_button_cubit.dart @@ -5,6 +5,7 @@ import 'package:altme/credentials/credentials.dart'; import 'package:altme/dashboard/dashboard.dart'; import 'package:altme/dashboard/home/tab_bar/credentials/models/activity/activity.dart'; import 'package:altme/dashboard/self_issued_credential_button/models/self_issued_credential.dart'; +import 'package:altme/wallet/wallet.dart'; import 'package:bloc/bloc.dart'; import 'package:did_kit/did_kit.dart'; @@ -26,6 +27,7 @@ class SelfIssuedCredentialCubit extends Cubit { required this.didKitProvider, required this.profileCubit, required this.oidc4vc, + required this.walletCubit, }) : super(const SelfIssuedCredentialButtonState()); final CredentialsCubit credentialsCubit; @@ -34,6 +36,7 @@ class SelfIssuedCredentialCubit extends Cubit { final DIDKitProvider didKitProvider; final ProfileCubit profileCubit; final OIDC4VC oidc4vc; + final WalletCubit walletCubit; Future createSelfIssuedCredential({ required SelfIssuedCredentialDataModel selfIssuedCredentialDataModel, @@ -155,7 +158,10 @@ class SelfIssuedCredentialCubit extends Cubit { credentialPreview: Credential.fromJson(jsonCredential), activities: [Activity(acquisitionAt: DateTime.now())], ); - await credentialsCubit.insertCredential(credential: credentialModel); + await credentialsCubit.insertCredential( + credential: credentialModel, + blockchainType: walletCubit.state.currentAccount!.blockchainType, + ); emit( state.success( messageHandler: ResponseMessage( diff --git a/lib/enterprise/cubit/enterprise_cubit.dart b/lib/enterprise/cubit/enterprise_cubit.dart new file mode 100644 index 000000000..8b9a8a4d6 --- /dev/null +++ b/lib/enterprise/cubit/enterprise_cubit.dart @@ -0,0 +1,404 @@ +import 'dart:convert'; + +import 'package:altme/app/app.dart'; +import 'package:altme/dashboard/profile/profile.dart'; +import 'package:altme/oidc4vc/oidc4vc.dart'; +import 'package:altme/wallet/wallet.dart'; +import 'package:equatable/equatable.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:json_annotation/json_annotation.dart'; +import 'package:jwt_decode/jwt_decode.dart'; +import 'package:oidc4vc/oidc4vc.dart'; +import 'package:uuid/uuid.dart'; + +part 'enterprise_cubit.g.dart'; + +part 'enterprise_state.dart'; + +class EnterpriseCubit extends Cubit { + EnterpriseCubit({ + required this.client, + required this.jwtDecode, + required this.profileCubit, + required this.walletCubit, + }) : super(const EnterpriseState()); + + final DioClient client; + final JWTDecode jwtDecode; + final ProfileCubit profileCubit; + final WalletCubit walletCubit; + + Future requestTheConfiguration(Uri uri) async { + try { + emit(state.loading()); + + final String? email = uri.queryParameters['login']; + final String? password = uri.queryParameters['password']; + final String? url = uri.queryParameters['wallet-provider']; + + if (email == null || password == null || url == null) { + throw ResponseMessage( + data: { + 'error': 'invalid_request', + 'error_description': + 'The email or password or provider is missing.', + }, + ); + } + + final savedEmail = await profileCubit.secureStorageProvider.get( + SecureStorageKeys.enterpriseEmail, + ); + + if (savedEmail != null && email == savedEmail) { + /// if email is matched then update the configuration + await updateTheConfiguration(); + return; + } + + /// get vc and store it in the wallet + final walletAttestationData = await getWalletAttestationData(url); + + /// request the configuration and verify + await verifyAndGetConfiguration( + email: email, + password: password, + jwtVc: walletAttestationData, + url: url, + ); + + /// save data + await profileCubit.secureStorageProvider + .set(SecureStorageKeys.enterpriseEmail, email); + + await profileCubit.secureStorageProvider + .set(SecureStorageKeys.enterprisePassword, password); + + await profileCubit.secureStorageProvider + .set(SecureStorageKeys.enterpriseWalletProvider, url); + + /// uprade wallet to enterprise + await profileCubit.setWalletType( + walletType: WalletType.enterprise, + ); + + /// load credentials + await walletCubit.credentialsCubit.loadAllCredentials( + blockchainType: walletCubit.state.currentAccount!.blockchainType, + ); + + // if enterprise and walletAttestation data is available and added + await walletCubit.credentialsCubit.addWalletCredential( + blockchainType: walletCubit.state.currentAccount?.blockchainType, + ); + + emit( + state.copyWith( + message: StateMessage.success( + messageHandler: ResponseMessage( + message: ResponseString + .RESPONSE_STRING_successfullyAddedEnterpriseAccount, + ), + ), + ), + ); + } catch (e) { + emitError(e); + } + } + + Future verifyAndGetConfiguration({ + required String email, + required String password, + required String jwtVc, + required String url, + }) async { + /// request the configuration + final encodedData = utf8.encode('$email:$password'); + final base64Encoded = base64UrlEncode(encodedData).replaceAll('=', ''); + + final headers = { + 'Content-Type': 'application/x-www-form-urlencoded', + 'Authorization': 'Basic $base64Encoded', + }; + + final data = { + 'grant_type': 'urn:ietf:params:oauth:grant-type:jwt-bearer', + 'assertion': jwtVc, + }; + + final response = await client.post( + '$url/configuration', + headers: headers, + data: data, + ); + + /// parse + final header = jwtDecode.parseJwtHeader(response as String); + final issuerKid = header['kid'].toString(); + final issuerDid = issuerKid.split('#')[0]; + + /// verify + final VerificationType isVerified = await verifyEncodedData( + issuerDid, + issuerKid, + response, + ); + + final profileSettingJson = jwtDecode.parseJwt(response); + + await profileCubit.secureStorageProvider.set( + SecureStorageKeys.enterpriseProfileSetting, + jsonEncode(profileSettingJson), + ); + + final profileSetting = ProfileSetting.fromJson(profileSettingJson); + + ///save to profileCubit + await profileCubit.setProfileSetting( + profileSetting: profileSetting, + profileType: ProfileType.enterprise, + ); + + // if (isVerified == VerificationType.verified) { + // emit( + // state.copyWith( + // status: AppStatus.idle, + // message: const StateMessage.info( + // showDialog: true, + // stringMessage: 'Verfied', + // ), + // ), + // ); + // } else { + // emit( + // state.copyWith( + // status: AppStatus.idle, + // message: const StateMessage.info( + // showDialog: true, + // stringMessage: 'Not Verfied', + // ), + // ), + // ); + // } + + emit( + state.copyWith( + status: AppStatus.success, + message: null, + ), + ); + } + + Future getNonce(String url) async { + final dynamic getRepsponse = await client.get('$url/nonce'); + final nonce = getRepsponse['nonce'].toString(); + return nonce; + } + + Future> getDataForRequest(String nonce) async { + /// get private key + final p256KeyForWallet = + await getWalletP256Key(profileCubit.secureStorageProvider); + final privateKey = jsonDecode(p256KeyForWallet) as Map; + + final customOidc4vcProfile = profileCubit.state.model.profileSetting + .selfSovereignIdentityOptions.customOidc4vcProfile; + + final tokenParameters = TokenParameters( + privateKey: privateKey, + did: '', + kid: null, + mediaType: MediaType.walletAttestation, + clientType: customOidc4vcProfile.clientType, + proofHeaderType: customOidc4vcProfile.proofHeader, + clientId: customOidc4vcProfile.clientId ?? '', + ); + + final thumbPrint = tokenParameters.thumbprint; + + final publicJWKString = sortedPublcJwk(p256KeyForWallet); + final publicJWK = jsonDecode(publicJWKString) as Map; + + final iat = (DateTime.now().millisecondsSinceEpoch / 1000).round(); + + final payload = { + 'iss': thumbPrint, + 'aud': 'https://wallet-provider.altme.io', + 'jti': const Uuid().v4(), + 'nonce': nonce, + 'cnf': { + 'jwk': { + ...publicJWK, + 'kid': thumbPrint, + }, + }, + 'iat': iat, + 'exp': iat + 1000, + }; + + /// sign and get token + final jwtToken = profileCubit.oidc4vc.generateToken( + payload: payload, + tokenParameters: tokenParameters, + ); + + final data = { + 'grant_type': 'urn:ietf:params:oauth:grant-type:jwt-bearer', + 'assertion': jwtToken, + }; + return data; + } + + Future getWalletAttestationData(String url) async { + /// GET nonce + final nonce = await getNonce(url); + + /// get data to send to attestation request + final Map data = await getDataForRequest(nonce); + + /// get vc + final response = await client.post( + '$url/token', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, + data: data, + ); + + String jwtVc = response.toString(); + + /// parse + final header = jwtDecode.parseJwtHeader(jwtVc!); + final issuerKid = header['kid'].toString(); + final issuerDid = issuerKid.split('#')[0]; + + /// verify + final VerificationType isVerified = await verifyEncodedData( + issuerDid, + issuerKid, + jwtVc, + ); + + await profileCubit.secureStorageProvider.set( + SecureStorageKeys.walletAttestationData, + jwtVc, + ); + + return jwtVc; + } + + Future updateTheConfiguration() async { + try { + emit(state.loading()); + + final provider = await profileCubit.secureStorageProvider.get( + SecureStorageKeys.enterpriseWalletProvider, + ); + + if (provider == null) { + throw ResponseMessage( + data: { + 'error': 'invalid_request', + 'error_description': 'The wallet provider does not match.', + }, + ); + } + + final walletAttestationData = + await profileCubit.secureStorageProvider.get( + SecureStorageKeys.walletAttestationData, + ); + + final headers = { + 'Content-Type': 'application/x-www-form-urlencoded', + }; + + final data = { + 'grant_type': 'urn:ietf:params:oauth:grant-type:jwt-bearer', + 'assertion': walletAttestationData, + }; + + final response = await client.post( + '$provider/update', + headers: headers, + data: data, + ); + + /// parse + final header = jwtDecode.parseJwtHeader(response as String); + final issuerKid = header['kid'].toString(); + final issuerDid = issuerKid.split('#')[0]; + + /// verify + final VerificationType isVerified = await verifyEncodedData( + issuerDid, + issuerKid, + response, + ); + + final profileSettingJson = jwtDecode.parseJwt(response); + + await profileCubit.secureStorageProvider.set( + SecureStorageKeys.enterpriseProfileSetting, + jsonEncode(profileSettingJson), + ); + + final profileSetting = ProfileSetting.fromJson(profileSettingJson); + + ///save to profileCubit + await profileCubit.setProfileSetting( + profileSetting: profileSetting, + profileType: ProfileType.enterprise, + ); + // if (isVerified == VerificationType.verified) { + // emit( + // state.copyWith( + // status: AppStatus.idle, + // message: const StateMessage.info( + // showDialog: true, + // stringMessage: 'Verfied', + // ), + // ), + // ); + // } else { + // emit( + // state.copyWith( + // status: AppStatus.idle, + // message: const StateMessage.info( + // showDialog: true, + // stringMessage: 'Not Verfied', + // ), + // ), + // ); + // } + + emit( + state.copyWith( + status: AppStatus.success, + message: StateMessage.success( + messageHandler: ResponseMessage( + message: ResponseString + .RESPONSE_STRING_successfullyUpdatedEnterpriseAccount, + ), + ), + ), + ); + } catch (e) { + emitError(e); + } + } + + void emitError(dynamic e) { + final messageHandler = getMessageHandler(e); + + emit( + state.error( + message: StateMessage.error( + messageHandler: messageHandler, + showDialog: true, + ), + ), + ); + } +} diff --git a/lib/enterprise/cubit/enterprise_state.dart b/lib/enterprise/cubit/enterprise_state.dart new file mode 100644 index 000000000..994bc02f3 --- /dev/null +++ b/lib/enterprise/cubit/enterprise_state.dart @@ -0,0 +1,48 @@ +part of 'enterprise_cubit.dart'; + +@JsonSerializable() +class EnterpriseState extends Equatable { + const EnterpriseState({ + this.status = AppStatus.init, + this.message, + }); + + factory EnterpriseState.fromJson(Map json) => + _$EnterpriseStateFromJson(json); + + final AppStatus status; + final StateMessage? message; + + EnterpriseState loading() { + return copyWith( + status: AppStatus.loading, + message: null, + ); + } + + EnterpriseState error({required StateMessage message}) { + return copyWith( + status: AppStatus.error, + message: message, + ); + } + + EnterpriseState copyWith({ + required StateMessage? message, + AppStatus? status, + WalletProviderType? walletProviderType, + }) { + return EnterpriseState( + status: status ?? this.status, + message: message, + ); + } + + Map toJson() => _$EnterpriseStateToJson(this); + + @override + List get props => [ + status, + message, + ]; +} diff --git a/lib/enterprise/enterprise.dart b/lib/enterprise/enterprise.dart new file mode 100644 index 000000000..b261f2b65 --- /dev/null +++ b/lib/enterprise/enterprise.dart @@ -0,0 +1 @@ +export 'cubit/enterprise_cubit.dart'; diff --git a/lib/l10n/arb/app_ca.arb b/lib/l10n/arb/app_ca.arb new file mode 100644 index 000000000..a08e3b4dd --- /dev/null +++ b/lib/l10n/arb/app_ca.arb @@ -0,0 +1,1031 @@ +{ + "@@locale": "ca", + "genericError": "S’ha produït un error", + "@genericError": { + "description": "Missatge d'error genèric", + "type": "text", + "placeholders": {} + }, + "credentialListTitle": "Credencials", + "@credentialListTitle": { + "description": "Títol de la pàgina de llista de credencials", + "type": "text", + "placeholders": {} + }, + "credentialDetailIssuedBy": "Emès per {issuer}", + "@credentialDetailIssuedBy": { + "description": "Emissor de les credencials a la pàgina de detalls", + "type": "text", + "placeholders": { + "issuer": {} + } + }, + "listActionRefresh": "Actualitzar", + "@listActionRefresh": { + "description": "Botó d’acció per actualitzar el contingut", + "type": "text", + "placeholders": {} + }, + "listActionViewList": "Veure com a llista", + "@listActionViewList": { + "description": "Botó d’acció per visualitzar en mode llista", + "type": "text", + "placeholders": {} + }, + "listActionViewGrid": "Veure com una quadrícula", + "@listActionViewGrid": { + "description": "Botó d’acció per visualitzar en mode quadrícula", + "type": "text", + "placeholders": {} + }, + "listActionFilter": "Filtre", + "@listActionFilter": { + "description": "Botó d’acció per obrir opcions de filtre", + "type": "text", + "placeholders": {} + }, + "listActionSort": "Ordenar", + "@listActionSort": { + "description": "Botó d’acció per obrir opcions d’ordenar", + "type": "text", + "placeholders": {} + }, + "onBoardingStartSubtitle": "Lorem ipsum dolor sit ame", + "onBoardingTosTitle": "Termes i condicions", + "onBoardingTosText": "En tocar acceptar \"Estic d’acord amb els termes i condicions, així com amb la cessió d’aquesta informació.\"", + "onBoardingTosButton": "Acceptar", + "onBoardingRecoveryTitle": "Recuperació de contrasenya", + "onBoardingRecoveryButton": "Recuperar", + "onBoardingGenPhraseTitle": "Frase de recuperació", + "onBoardingGenPhraseButton": "Continuar", + "onBoardingGenTitle": "Generació de clau privada", + "onBoardingGenButton": "Generar", + "onBoardingSuccessTitle": "Identificador creat", + "onBoardingSuccessButton": "Continuar", + "credentialDetailShare": "Compartir amb codi QR", + "credentialAddedMessage": "S’ha afegit una nova credencial!", + "credentialDetailDeleteCard": "Eliminar la targeta", + "credentialDetailDeleteConfirmationDialog": "Segur que vols eliminar la targeta?", + "credentialDetailDeleteConfirmationDialogYes": "Sí", + "credentialDetailDeleteConfirmationDialogNo": "No", + "credentialDetailDeleteSuccessMessage": "Eliminada correctament.", + "credentialDetailEditConfirmationDialog": "Segur que vols editar la credencial?", + "credentialDetailEditConfirmationDialogYes": "Guardar", + "credentialDetailEditConfirmationDialogNo": "Cancel·lar", + "credentialDetailEditSuccessMessage": "Modificació realitzada.", + "credentialDetailCopyFieldValue": "S'ha copiat el valor del camp al porta-retalls.", + "credentialDetailStatus": "Estat de verificació", + "credentialPresentTitle": "Selecciona credencial/s", + "credentialPresentTitleDIDAuth": "Sol. autent. DID", + "credentialPresentRequiredCredential": "Algú demana per les teves", + "credentialPresentConfirm": "Selecciona credencial/s", + "credentialPresentCancel": "Refusar", + "credentialPickPresent": "Presentar", + "credentialPickTitle": "Selecciona credencial/s", + "selectYourTezosAssociatedWallet": "Selecciona la teva cartera Tezos associada", + "credentialPickSelect": "Selecciona la teva credencial", + "siopV2credentialPickSelect": "Tria una sola credencial de la teva cartera per presentar-la", + "credentialPickAlertMessage": "Vols donar un àlies a aquesta credencial?", + "credentialReceiveTitle": "Oferta de credencial", + "credentialReceiveHost": "vol enviar-te una credencial", + "credentialAddThisCard": "Afegir aquesta targeta", + "credentialReceiveCancel": "Anul·lar aquesta targeta", + "credentialDetailListTitle": "La meva cartera", + "communicationHostAllow": "Permetre", + "communicationHostDeny": "Denegar", + "scanTitle": "Escanejar codi QR", + "scanPromptHost": "Confies en aquest amfitrió?", + "scanRefuseHost": "Sol·licitud de comunicació denegada.", + "scanUnsupportedMessage": "L’URL extreta no és vàlida.", + "qrCodeSharing": "Estàs compartint", + "qrCodeNoValidMessage": "El codi QR no conté un missatge vàlid.", + "profileTitle": "Perfil", + "personalTitle": "Personal", + "termsTitle": "Termes i condicions", + "recoveryKeyTitle": "Frase de recuperació", + "showRecoveryPhrase": "Mostra frase de recuperació", + "warningDialogTitle": "Atenció", + "warningDialogSubtitle": "La pàgina de recuperació conté informació confidencial que pot posar el vostre identificador en mans equivocades. No obris aquesta pàgina en públic ni la comparteixis.", + "recoveryText": "Indica la teva frase de recuperació", + "recoveryMnemonicHintText": "Indica aquí la teva frase de recuperació.\nQuan hagis introduït les 12 paraules,\ntoca Importar.", + "recoveryMnemonicError": "Indica una frase de recordatori vàlida", + "showDialogYes": "Continuar", + "showDialogNo": "Cancel·lar", + "supportTitle": "Ajuda", + "noticesTitle": "Avisos", + "resetWalletButton": "Reiniciar cartera", + "resetWalletConfirmationText": "Segur que vols reiniciar la cartera?", + "selectThemeText": "Seleccionar tema", + "lightThemeText": "Tema clar", + "darkThemeText": "Tema fosc", + "systemThemeText": "Tema del sistema", + "genPhraseInstruction": "Escriu les paraules, descarrega el fitxer de còpia de seguretat i guarda-les en un lloc segur", + "genPhraseExplanation": "Necessites les paraules en l’ordre correcte i el fitxer de còpia de seguretat per recuperar els certificats, si perds l’accés a la cartera", + "errorGeneratingKey": "Error en crear la clau, torna-ho a intentar", + "documentHeaderTooltipName": "John Doe", + "documentHeaderTooltipJob": "Comerciant de criptomonedes", + "documentHeaderTooltipLabel": "Estat:", + "documentHeaderTooltipValue": "Vàlid", + "didDisplayId": "DID", + "blockChainDisplayMethod": "Blockchain", + "blockChainAdress": "Adreça", + "didDisplayCopy": "Copiar DID al porta-retalls", + "adressDisplayCopy": "Copiar adreça al porta-retalls", + "personalSave": "Guardar", + "personalSubtitle": "La informació del perfil pot servir per completar un certificat quan sigui necessari", + "personalFirstName": "Nom", + "personalLastName": "Cognoms", + "personalPhone": "Telèfon", + "personalAddress": "Adreça", + "personalMail": "Correu electrònic", + "lastName": "Cognoms", + "firstName": "Nom", + "gender": "sexe", + "birthdate": "Data de naixement", + "birthplace": "Lloc de naixement", + "address": "Adreça", + "maritalStatus": "Estat civil", + "nationality": "Nacionalitat", + "identifier": "Identificador", + "issuer": "Emès per", + "workFor": "Ocupador", + "startDate": "Des de", + "endDate": "Fins", + "employmentType": "Tipus de treball", + "jobTitle": "Nom del càrrec", + "baseSalary": "Salari", + "expires": "Caduca", + "generalInformationLabel": "Dades generals", + "learningAchievement": "Assoliments", + "signedBy": "Firmat per", + "from": "Des de", + "to": "Fins", + "credential": "Credencial", + "issuanceDate": "Data d’emissió", + "appContactWebsite": "Lloc web", + "trustFrameworkDescription": "El marc de confiança el formen un conjunt de registres que proporcionen una base segura i fiable perquè les entitats del sistema puguin confiar i interactuar entre elles.", + "confimrDIDAuth": "Vols iniciar sessió al lloc?", + "evidenceLabel": "Prova", + "networkErrorBadRequest": "Petició incorrecta", + "networkErrorConflict": "Error degut a un conflicte", + "networkErrorPreconditionFailed": "El servidor no compleix una de les precondicions.", + "networkErrorCreated": "", + "networkErrorGatewayTimeout": "Temps d’espera esgotat a la passarel·la", + "networkErrorInternalServerError": "Error intern del servei. Contacta amb l’administrador del servidor", + "networkErrorMethodNotAllowed": "L’usuari no té drets d’accés al contingut", + "networkErrorNoInternetConnection": "No hi ha connexió a Internet", + "networkErrorNotAcceptable": "No acceptable", + "networkErrorNotImplemented": "No aplicat", + "networkErrorOk": "", + "networkErrorRequestCancelled": "Petició anul·lada", + "networkErrorRequestTimeout": "Temps d’espera esgotat", + "networkErrorSendTimeout": "Temps d’espera d’enviament en la connexió amb el servidor API", + "networkErrorServiceUnavailable": "Servei no disponible", + "networkErrorTooManyRequests": "L’usuari ha enviat massa sol·licituds en un període de temps determinat", + "networkErrorUnableToProcess": "No es poden processar les dades", + "networkErrorUnauthenticated": "L’usuari s’ha d’autenticar per obtenir la resposta sol·licitada", + "networkErrorUnauthorizedRequest": "Sol·licitud no autoritzada", + "networkErrorUnexpectedError": "Ha ocorregut un error inesperat", + "networkErrorNotFound": "No trobat", + "active": "Actiu", + "expired": "Expirat", + "revoked": "Revocat", + "ok": "OK", + "unavailable_feature_title": "Funció no disponible", + "unavailable_feature_message": "Funció no disponible al navegador", + "personalSkip": "SALTAR", + "restoreCredential": "Restaurar credencials", + "backupCredential": "Fer còpia de seguretat de les credencials", + "backupCredentialPhrase": "Escriu les paraules, descarrega el fitxer de còpia de seguretat i guarda-les en un lloc segur", + "backupCredentialPhraseExplanation": "Per fer una còpia de seguretat de les credencials, anota la teva frase de recuperació i guarda-la en un lloc segur.", + "backupCredentialButtonTitle": "Guardar l’arxiu", + "backupPolygonIdCredentialEmptyError": "No tens cap credencial d’identificador de Polygon a la cartera.", + "needStoragePermission": "Et cal un permís d’emmagatzematge per baixar aquest fitxer.", + "backupCredentialNotificationTitle": "Aconseguit", + "backupCredentialNotificationMessage": "L’arxiu s’ha descarregat amb èxit. Toca per obrir l’arxiu.", + "backupCredentialError": "Ha ocorregut un error. Intenta-ho més tard.", + "backupCredentialSuccessMessage": "L’arxiu s’ha descarregat amb èxit.", + "restorationCredentialWarningDialogSubtitle": "La restauració eliminarà totes les credencials que ja tens a la cartera.", + "recoveryCredentialPhrase": "Escriu les paraules i carrega l’arxiu de seguretat si l’havies guardat", + "recoveryCredentialPhraseExplanation": "Si has perdut les credencials, et calen les dues paraules en l’ordre correcte i una còpia de seguretat xifrada per recuperar-es", + "recoveryCredentialButtonTitle": "Carregar còpia de seguretat", + "recoveryCredentialSuccessMessage": "Recuperació correcta{postfix}.", + "recoveryCredentialJSONFormatErrorMessage": "Carrega un arxiu vàlid.", + "recoveryCredentialAuthErrorMessage": "El recordatori o l’arxiu carregat estan malmesos.", + "recoveryCredentialDefaultErrorMessage": "Ha ocorregut un error. Intenta-ho més tard.", + "@recoveryCredentialSuccessMessage": { + "description": "Recompte missatges correctes", + "type": "text", + "placeholders": { + "postfix": {} + } + }, + "selfIssuedCreatedSuccessfully": "Credencial autoemesa creada correctament", + "companyWebsite": "Web de l’empresa", + "submit": "Enviar", + "insertYourDIDKey": "Indica el DID", + "importYourRSAKeyJsonFile": "Importa un arxiu json amb clau RSA", + "didKeyAndRSAKeyVerifiedSuccessfully": "DID i clau RSA comprovades", + "pleaseEnterYourDIDKey": "Indica el teu DID", + "pleaseImportYourRSAKey": "Importa la teva clau RSA", + "confirm": "Confirmar", + "pleaseSelectRSAKeyFileWithJsonExtension": "Selecciona el fitxer amb clau RSA (d’extensió json)", + "rsaNotMatchedWithDIDKey": "La clau RSA no coincideix amb el DID", + "didKeyNotResolved": "DID no resolt", + "anUnknownErrorHappened": "Ha ocorregut un error desconegut", + "walletType": "Tipus de cartera", + "chooseYourWalletType": "Escull un tipus de cartera", + "proceed": "Continuar", + "enterpriseWallet": "Cartera empresarial", + "personalWallet": "Cartera personal", + "failedToVerifySelfIssuedCredential": "No s’ha pogut verificar la credencial autoemesa", + "failedToCreateSelfIssuedCredential": "No s’ha pogut crear la credencial autoemesa", + "credentialVerificationReturnWarning": "La verificació de credencials ha retornat alguns avisos. ", + "failedToVerifyCredential": "No s’ha pogut verificar la credencial.", + "somethingsWentWrongTryAgainLater": "Hi ha hagut un error, intenta-ho més tard. ", + "successfullyPresentedYourCredential": "Credencials presentades correctament", + "successfullyPresentedYourDID": "DID presentat correctament", + "thisQRCodeIsNotSupported": "Codi QR no compatible.", + "thisUrlDoseNotContainAValidMessage": "La URL no conté un missatge vàlid.", + "anErrorOccurredWhileConnectingToTheServer": "Hi ha hagut un error de connexió al servidor.", + "failedToSaveMnemonicPleaseTryAgain": "Error en guardar la clau, torna-ho a intentar", + "failedToLoadProfile": "Error en carregar el perfil. ", + "failedToSaveProfile": "Error en guardar el perfil. ", + "failedToLoadDID": "Error en carregar el DID. ", + "personalOpenIdRestrictionMessage": "La cartera personal no té accés.", + "credentialEmptyError": "No tens cap credencial a la cartera.", + "credentialPresentTitleSiopV2": "Presentar credencial", + "confirmSiopV2": "Confirma la credencial presentada", + "storagePermissionRequired": "Cal un permís d’emmagatzematge", + "storagePermissionDeniedMessage": "Permet l’accés a l’emmagatzematge per carregar el fitxer.", + "storagePermissionPermanentlyDeniedMessage": "Cal permís d’emmagatzematge per carregar el fitxer. Ves a la configuració de l’aplicació i dona accés al permís d’emmagatzematge.", + "cancel": "Cancel·lar", + "loading": "Un moment...", + "issuerWebsitesTitle": "Obtenir credencials", + "getCredentialTitle": "Obtenir credencials", + "participantCredential": "Passi GaiaX", + "phonePassCredential": "Prova de telèfon", + "emailPassCredential": "Prova de correu electrònic", + "needEmailPass": "Cal una prova de correu electrònic primer", + "signature": "Firma", + "proof": "Prova", + "verifyMe": "Verifica’m", + "yes": "Sí", + "no": "No", + "credentialAlias": "Àlies de credencial", + "verificationStatus": "Estat de verificació", + "cardsPending": "Targeta pendent", + "cardsActive": "Targeta activa", + "cardsProblem": "Problema amb la targeta", + "unableToProcessTheData": "No es poden processar les dades", + "unimplementedQueryType": "Tipus de consulta no implementat", + "onSubmittedPassBasePopUp": "Rebràs un correu electrònic", + "myCollection": "La meva col·lecció", + "items": "articles", + "succesfullyUpdated": "Actualitzats correctament", + "generate": "Generar", + "myAssets": "Els meus recursos", + "search": "Buscar", + "professional": "Professional", + "splashSubtitle": "Tingues la teva identitat i recursos digitals", + "poweredBy": "Impulsat per", + "splashLoading": "Carregant...", + "version": "Versió", + "cards": "Targetes", + "nfts": "NFT", + "coins": "Monedes", + "getCards": "Obtén credencials", + "close": "Tancar", + "profile": "Perfil", + "infos": "Dades", + "save": "Guardar", + "delete": "Esborrar", + "enterNewPinCode": "Crea un codi PIN\nper protegir la teva cartera", + "confirmYourPinCode": "Confirma el codi PIN", + "walletAltme": "Cartera Altme", + "createPersonalWallet": "Crear cartera personal", + "createTitle": "Crear o importar cartera", + "createSubtitle": "Vols crear una cartera nova o importar-ne una existent?", + "enterYourPinCode": "Indica el codi PIN", + "changePinCode": "Canvia el codi PIN", + "tryAgain": "Torna-ho a intentar", + "credentialSelectionListEmptyError": "No tens la credencial sol·licitada per seguir.", + "trustedIssuer": "Emissor aprovat per EBSI.", + "yourPinCodeChangedSuccessfully": "Codi PIN canviat correctament", + "advantagesCards": "Avantatges de les targetes", + "advantagesDiscoverCards": "Obtén premis exclusius", + "identityCards": "Targetes d’identitat", + "identityDiscoverCards": "Simplifica la verificació ID", + "contactInfoCredentials": "Informació de contacte", + "contactInfoDiscoverCredentials": "Verifica les teves dades de contacte", + "myProfessionalCards": "Targetes professionals", + "otherCards": "Altres targetes", + "inMyWallet": "A la meva cartera", + "details": "Detalls", + "getIt": "Obtenir", + "getItNow": "Obtenir ara", + "getThisCard": "Obtenir aquesta carta", + "drawerBiometrics": "Autenticació biomètrica", + "drawerTalaoCommunityCard": "Targeta de comunitat Talao", + "drawerTalaoCommunityCardTitle": "Importa la teva direcció d’Ethereum i obtén una targeta de comunitat.", + "drawerTalaoCommunityCardSubtitle": "Tindràs accés als millors descomptes, abonaments i targetes de vals del nostre ecosistema de socis.", + "drawerTalaoCommunityCardTextBoxMessage": "Després d’indicar la teva clau privada, toca Importar.\nAssegura’t d’indicar la clau privada d’Ethereum que conté el teu token Talao.", + "drawerTalaoCommunityCardSubtitle2": "La nostra cartera és d’autocustòdia. No tenim cap accés a les teves claus o fons privats.", + "drawerTalaoCommunityCardKeyError": "Indica una clau privada vàlida", + "loginWithBiometricsMessage": "Desbloqueja ràpidament la cartera sense contrasenya ni codi PIN", + "manage": "Gestionar", + "wallet": "Cartera", + "manageAccounts": "Gestionar comptes de blockchain", + "blockchainAccounts": "Comptes de blockchain", + "educationCredentials": "Credencials de formació", + "educationDiscoverCredentials": "Verifica la teva formació acadèmica", + "educationCredentialsDiscoverSubtitle": "Obtén el teu diploma digital (EBSI)", + "security": "Seguretat", + "networkAndRegistries": "Xarxa i registres", + "chooseNetwork": "Escull xarxa", + "chooseRegistry": "Escull registre", + "trustFramework": "Marc de confiança", + "network": "Xarxa", + "issuerRegistry": "Registre d’emissors", + "termsOfUse": "Condicions d’ús i privadesa", + "scanFingerprintToAuthenticate": "Escaneja l’empremta digital per autenticar-te", + "biometricsNotSupported": "Biomètrica no compatible", + "deviceDoNotSupportBiometricsAuthentication": "El dispositiu no admet l’autenticació biomètrica", + "biometricsEnabledMessage": "Ara pots desbloquejar l’app amb la teva biomètrica.", + "biometricsDisabledMessage": "S’ha desactivat la teva biomètrica.", + "exportSecretKey": "Exportar clau secreta", + "secretKey": "Clau secreta", + "chooseNetWork": "Escull xarxa", + "nftEmptyMessage": "La teva galeria digital està buida.", + "myAccount": "El meu compte", + "cryptoAccounts": "Comptes", + "cryptoAccount": "Compte", + "cryptoAddAccount": "Afegir compte", + "cryptoAddedMessage": "S’ha afegit correctament el teu compte criptogràfic.", + "cryptoEditConfirmationDialog": "Segur que vols editar el nom del compte criptogràfic?", + "cryptoEditConfirmationDialogYes": "Guardar", + "cryptoEditConfirmationDialogNo": "Cancel·lar", + "cryptoEditLabel": "Nom del compte", + "onBoardingFirstTitle": "Descobreix 3 ofertes web exclusives directament a la teva cartera.", + "onBoardingFirstSubtitle": "Aconsegueix targetes de soci, targetes de fidelitat, vals i molts més avantatges de les teves aplicacions i jocs preferits.", + "onBoardingSecondTitle": "La nostra cartera és molt més que una simple cartera digital.", + "onBoardingSecondSubtitle": "Guarda i gestiona les teves dades personals i accedeix a aplicacions web 3.0.", + "onBoardingThirdTitle": "Gestiona les teves dades amb total autonomia, seguretat i privadesa.", + "onBoardingThirdSubtitle": "La nostra cartera utilitza criptografia SSI per a un control total de les teves dades. Res no se’n va del teu telèfon.", + "onBoardingStart": "Comença", + "learnMoreAboutAltme": "Informa’t sobre la nostra cartera", + "scroll": "Desplaça’t", + "agreeTermsAndConditionCheckBox": "Accepto els termes i condicions.", + "readTermsOfUseCheckBox": "He llegit les condicions d’ús.", + "createOrImportNewAccount": "Crear o importar un compte nou.", + "selectAccount": "Seleccionar compte", + "onbordingSeedPhrase": "Frase llavor", + "onboardingPleaseStoreMessage": "Escriu la teva frase de recuperació", + "onboardingVerifyPhraseMessage": "Confirma paraules de recuperació", + "onboardingVerifyPhraseMessageDetails": "Per assegurar-te que la frase està ben escrita, selecciona les paraules en l'ordre correcte.", + "onboardingAltmeMessage": "La cartera no és autocustodiada. La frase de recuperació és l’única manera de recuperar el compte.", + "onboardingWroteDownMessage": "He escrit la meva frase de recuperació", + "copyToClipboard": "Copiar al porta-retalls", + "pinCodeMessage": "El codi PIN impedeix l’accés no autoritzat a la teva cartera. Pots canviar-lo en qualsevol moment.", + "enterNameForYourNewAccount": "Indica un nou pel teu nou compte", + "create": "Crear", + "import": "Importar", + "accountName": "Nom del compte", + "importWalletText": "Indica aquí la frase de recuperació o la clau privada.", + "importWalletTextRecoveryPhraseOnly": "Indica aquí la teva frase de recuperació.", + "recoveryPhraseDescriptions": "La frase de recuperació (de vegades anomenada frase inicial, clau privada o frase de seguretat) és una llista de 12 paraules creada per la cartera de criptomoneda per accedir als teus fons", + "importEasilyFrom": "Importa el teu compte des de:", + "templeWallet": "Cartera Temple", + "temple": "Temple", + "metaMaskWallet": "Cartera Metamask", + "metaMask": "Metamask", + "kukai": "Kukai", + "kukaiWallet": "Cartera Kukai", + "other": "Altres", + "otherWalletApp": "Altres app de cartera", + "importWalletHintText": "Quan hagis introduït les 12 paraules (frase de recuperació) o {numberCharacters} caràcters (clau privada), toca Importar.", + "@importWalletHintText": { + "description": "text de suggerència en importar un compte addicional", + "type": "text", + "placeholders": { + "numberCharacters": {} + } + }, + "importWalletHintTextRecoveryPhraseOnly": "Quan hagis introduït les 12 paraules (frase de recuperació) toca Importar.", + "kycDialogTitle": "Per obtenir aquesta targeta i altres targetes d’identitat, verifica la teva ID", + "idVerificationProcess": "Procés de verificació ID", + "idCheck": "Verificació ID", + "facialRecognition": "Reconeixement facial", + "kycDialogButton": "Comença la verificació ID", + "kycDialogFooter": "Conforme al RGPD +CCPA + nivell de seguretat SOC2", + "finishedVerificationTitle": "Verificació ID en\ncurs", + "finishedVerificationDescription": "Rebràs un correu electrònic per confirmar la verificació ID", + "verificationPendingTitle": "La teva verificació ID\nestà pendent", + "verificationPendingDescription": "La verificació sol requerir menys de 5 min. Rebràs un correu electrònic quan acabi la verificació.", + "verificationDeclinedTitle": "Verificació rebutjada", + "restartVerification": "Reiniciar verificació ID", + "verificationDeclinedDescription": "Verificació rebutjada. Reinicia la verificació ID.", + "verifiedTitle": "Ben fet! Verificació satisfactòria.", + "verifiedDescription": "Ja pots afegir la targeta “majors de 18”. Comencem.", + "verfiedButton": "Afegir la targeta majors de 18", + "verifiedNotificationTitle": "Verificació completada!", + "verifiedNotificationDescription": "Felicitats! La verificació s’ha fet correctament.", + "showDecentralizedID": "Mostra ID descentralitzat", + "manageDecentralizedID": "Gestiona ID descentralitzat", + "addressBook": "Llibre d’adreces", + "home": "La meva cartera", + "discover": "Descobrir", + "settings": "Configuració", + "privateKeyDescriptions": "Una clau privada és un número secret per signar transaccions i demostrar la propietat d’una adreça de blockchain. A Tezos, la clau privada sol tenir 54 caràcters.", + "importAccount": "Importar compte", + "imported": "Importat", + "cardDetails": "Detalls de la targeta", + "publicAddress": "Adreça pública", + "didKey": "Clau DID", + "export": "Exportar", + "copy": "Copiar", + "didPrivateKey": "Clau privada DID", + "reveal": "Mostrar", + "didPrivateKeyDescription": "Tingues molta cura amb vostres claus privades: controlen l’accés a la informació de les teves credencials.", + "didPrivateKeyDescriptionAlert": "No les comparteixis amb ningú. Aquesta cartera no és d’autocustòdia,mai t’ho demanarem.", + "iReadTheMessageCorrectly": "He llegit bé el missatge", + "beCareful": "Atenció", + "decentralizedIDKey": "Clau ID descentralitzada", + "copySecretKeyToClipboard": "Clau secreta copiada al porta-retalls.", + "copyDIDKeyToClipboard": "Clau DID copiada al porta-retalls.", + "seeAddress": "Veure adreça", + "revealPrivateKey": "Mostrar clau privada", + "share": "Compartir", + "shareWith": "Compartir amb", + "copiedToClipboard": "Copiada al porta-retalls.", + "privateKey": "Clau privada", + "decentralizedID": "IDentificador descentralitzat", + "did": "DID", + "accountPrivateKeyAlert": "No comparteixis la frase de recuperació amb ningú. Aquesta cartera no és d’autocustòdia,mai t’ho demanarem. Si dius la teva frase de recuperació, podries perdre els teus fons", + "sameAccountNameError": "Aquest nom de compte s’utilitzava abans; introdueix l’altre nom del compte", + "unknown": "Desconegut", + "credentialManifestDescription": "Descripció", + "credentialManifestInformations": "Dades", + "credentialDetailsActivity": "Activitat", + "credentialDetailsOrganisation": "Organització", + "credentialDetailsPresented": "Presentar", + "credentialDetailsOrganisationDetail": "Dades de l’organització:", + "credentialDetailsInWalletSince": "A la cartera des de", + "termsOfUseAndLicenses": "Condicions d’ús i llicències", + "licenses": "Llicències", + "sendTo": "Enviar a", + "next": "Següent", + "withdrawalInputHint": "Copiar o escanejar adreça", + "amount": "Import", + "amountSent": "Import enviat", + "max": "Màx", + "edit": "Editar", + "networkFee": "Tarifa de gas estimada", + "totalAmount": "Import total", + "selectToken": "Seleccionar token", + "insufficientBalance": "Saldo insuficient", + "slow": "Lent", + "average": "Mitjà", + "fast": "Ràpid", + "changeFee": "Tarifa de canvi", + "sent": "Enviat", + "done": "Fet", + "link": "Clicar per accedir", + "myTokens": "Els meus token", + "tezosMainNetwork": "Xarxa principal de Tezos", + "send": "Enviar", + "receive": "Rebre", + "recentTransactions": "Transaccions recents", + "sendOnlyToThisAddressDescription": "Enviar només {symbol} a aquesta adreça. Enviar altres tokens pot causar pèrdues permanents.", + "@sendOnlyToThisAddressDescription": { + "description": "nom del símbol en mostrar l'adreça a la pàgina de recepció", + "type": "text", + "placeholders": { + "symbol": {} + } + }, + "addTokens": "Afegir tokens", + "providedBy": "Proporcionat per", + "issuedOn": "Emès el", + "expirationDate": "Període de validesa", + "connect": "Connectar", + "connection": "Connexió", + "selectAccountToGrantAccess": "Seleccionar import per garantir accés:", + "requestPersmissionTo": "Demanar permís a:", + "viewAccountBalanceAndNFTs": "Veure saldo del compte i NFT", + "requestApprovalForTransaction": "Demanar autorització per a la transacció", + "connectedWithBeacon": "Connexió amb dApp", + "failedToConnectWithBeacon": "Error de connexió amb dApp", + "tezosNetwork": "Xarxa Tezos", + "confirm_sign": "Confirmar firma", + "sign": "Firma", + "payload_to_sign": "Càrrega per firmar", + "signedPayload": "Càrrega firmada", + "failedToSignPayload": "Error en firmar càrrega", + "voucher": "Cupó", + "tezotopia": "Tezotopia", + "operationCompleted": "Operació demanada completada. La transacció pot trigar uns minuts a aparèixer a la cartera.", + "operationFailed": "Error en completar l’operació demanada", + "membership": "Subscripció", + "switchNetworkMessage": "Canvia la teva xarxa a", + "fee": "Tarifa", + "addCards": "Afegir targetes", + "gaming": "Jocs", + "identity": "Identitat", + "payment": "Pagament", + "socialMedia": "Xarxes socials", + "advanceSettings": "Configuració avançada", + "categories": "Categories", + "selectCredentialCategoryWhichYouWantToShowInCredentialList": "Selecciona les categories de credencials per mostrar a la llista de credencials:", + "community": "Comunitat", + "tezos": "Tezos", + "rights": "Drets", + "disconnectAndRevokeRights": "Desconnectar i revocar drets", + "revokeAllRights": "Revocar tots els drets", + "revokeSubtitleMessage": "Segur que vols revocar tots els drets", + "revokeAll": "Revocar tots", + "succesfullyDisconnected": "desconnexió correcta de dApp.", + "connectedApps": "dApps connectades", + "manageConnectedApps": "Gestionar dApps connectades", + "noDappConnected": "Encara no hi ha dApp connectades", + "nftDetails": "Dades de NFT", + "failedToDoOperation": "Operació fallida", + "nft": "NFT", + "receiveNft": "Rebre NFT", + "sendOnlyNftToThisAddressDescription": "Rebre NFT de Tezos només en aquesta adreça. Enviar NFT d’altres xarxes pot causar pèrdues permanents.", + "beaconShareMessage": "Envia Tezos (XTZ) i NFT de Tezos (estàndard FA2) només a aquesta adreça. Enviar Tezos i NFT d’altres xarxes pot causar pèrdues permanents", + "advantagesCredentialHomeSubtitle": "Gaudeix d’avantatges exclusius a Web3", + "advantagesCredentialDiscoverSubtitle": "Descobreix targetes de fidelitat i passis exclusius", + "identityCredentialHomeSubtitle": "Demostra coses sobre tu mateix protegint les teves dades", + "identityCredentialDiscoverSubtitle": "Obtén credencials de verificació KYC i d’edat reutilitzables", + "myProfessionalCredentialDiscoverSubtitle": "Utilitza les teves targetes professionals amb seguretat", + "blockchainAccountsCredentialHomeSubtitle": "Demostra la propietat dels teus comptes de blockchain", + "educationCredentialHomeSubtitle": "Demostra instantàniament la teva formació acadèmica", + "passCredentialHomeSubtitle": "Utilitza passis exclusius: Potencia l’experiència Web3.", + "financeCardsCredentialHomeSubtitle": "Accedeix a noves oportunitats d’inversió a Web3", + "financeCardsCredentialDiscoverSubtitle": "Obtén avantatges exclusius de les comunitats que t’agraden", + "contactInfoCredentialHomeSubtitle": "Comparteix la teva informació de contacte al moment", + "contactInfoCredentialDiscoverSubtitle": "Obtén credencials fàcils de compartir", + "otherCredentialHomeSubtitle": "Altres tipus de targetes a la teva cartera", + "otherCredentialDiscoverSubtitle": "Altres tipus de targetes que pots afegir", + "showMore": "...Mostrar més", + "showLess": "Mostrar menys...", + "youHaveReceivedARewardOf": "Has rebut un premi de", + "gotIt": "Entesos", + "transactionErrorBalanceTooLow": "Una operació ha intentat gastar més tokens del que té el contracte", + "transactionErrorCannotPayStorageFee": "La tarifa d’emmagatzematge és superior al saldo del contracte", + "transactionErrorFeeTooLow": "Les tarifes de transacció són massa baixes", + "transactionErrorFeeTooLowForMempool": "Les tarifes de transacció són massa baixes per a la mempool completa", + "transactionErrorTxRollupBalanceTooLow": "S'ha intentat gastar un índex de tiquets d’un índex sense el saldo necessari", + "transactionErrorTxRollupInvalidZeroTransfer": "L’import de la transferència ha de ser superior a zero.", + "transactionErrorTxRollupUnknownAddress": "L’adreça ha d’existir en el context en signar una transferència amb ella.", + "transactionErrorInactiveChain": "Intent de validació d’una blockchain inactiva.", + "website": "Lloc web", + "whyGetThisCard": "Per què aquesta targeta", + "howToGetIt": "Com obtenir-la", + "emailPassWhyGetThisCard": "Algunes aplicacions/llocs web de Web 3 poden requerir aquesta prova per accedir al seu servei o obtenir avantatges: Targeta de membre, de fidelitat, premis, etc.", + "emailPassExpirationDate": "Aquesta targeta romandrà activa i reutilitzable durant 1 ANY.", + "emailPassHowToGetIt": "És molt fàcil. Altme verificarà el teu correu electrònic enviant un codi per correu electrònic.", + "tezotopiaMembershipWhyGetThisCard": "Aquesta targeta de membre dona un 25 % de reemborsament en efectiu en TOTES les transaccions del joc Tezotopia en comprar un Drops al mercat o encunyar un NFT a Starbase.", + "tezotopiaMembershipExpirationDate": "Aquesta targeta romandrà activa i reutilitzable durant 1 ANY.", + "tezotopiaMembershipLongDescription": "Tezotopia és un joc NFT metavers en temps real a Tezos, on els jugadors tenen una granja amb Tezotops, participen en batalles per obtenir recompenses i reclamen terra en una aventura espacial immersiva de blockchain. Explora el metavers, col·lecciona NFT i conquereix Tezotopia.", + "chainbornMembershipHowToGetIt": "Per obtenir aquesta targeta, cal invocar un “Heroi” al joc Chainborn i una prova de correu electrònic. Trobaràs la targeta “Prova de correu electrònic” a la secció “Descobrir” d'Altme.", + "chainbornMembershipWhyGetThisCard": "Sigues dels pocs que tenen accés al contingut exclusiu de la botiga Chainborn, airdrops i altres avantatges reservats als membres!", + "chainbornMembershipExpirationDate": "Aquesta targeta romandrà activa i reutilitzable durant 1 ANY.", + "chainbornMembershipLongDescription": "Chainborn és un emocionant joc de batalla de NFT on els jugadors utilitzen els seus propis NFT com a herois, competint per botí i glòria. Participa en emocionants lluites, guanya punts d’experiència per potenciar la força i la salut del teu heroi, i millora el valor dels teus NFT en aquesta apassionant aventura de Tezos.", + "twitterHowToGetIt": "Segueix els passos a TezosProfiles https://tzprofiles.com/connect. Després, demana la targeta “Compte de Twitter” a Altme. Assegura’t de signar la transacció a TZPROFILES amb el mateix compte que utilitzes a Altme.", + "twitterWhyGetThisCard": "Aquesta targeta és una prova que ets el propietari del teu compte de Twitter. Utilitza-la per demostrar la propietat del teu compte de Twitter sempre que ho necessitis.", + "twitterExpirationDate": "Aquesta targeta romandrà activa durant 1 ANY.", + "twitterDummyDesc": "Demostra la propietat dels teus comptes de Twitter", + "linkedinCardHowToGetIt": "Pots demanar aquesta targeta seguint la verificació KYC d’Altme. Només s’accedirà a la informació relacionada amb el teu nom, cognoms, nacionalitat i any de naixement des del teu perfil de LinkedIn.", + "linkedinCardWhyGetThisCard": "Aquesta targeta és una prova de la teva identitat per al teu perfil de LinkedIn. Des d’aquesta targeta, pots exportar un codi QR i mostrar-lo a la capçalera del teu compte de LinkedIn. En escanejar el codi QR amb la cartera Altme, qualsevol persona podrà verificar que la teva identitat coincideix amb l’URL del teu perfil de LinkedIn, i també podrà accedir a 2 dades més: la teva nacionalitat i el teu any de naixement.", + "linkedinCardExpirationDate": "Aquesta targeta romandrà activa i reutilitzable durant 1 ANY.", + "tezotopiaMembershipHowToGetIt": "Has de presentar una prova que tens més de 13 anys i una prova del teu correu electrònic.", + "over18WhyGetThisCard": "Algunes aplicacions/llocs web de Web 3 poden requerir aquesta prova per accedir al seu servei o obtenir avantatges: Targeta de membre, de fidelitat, premis, etc.", + "over18ExpirationDate": "Aquesta targeta romandrà activa i reutilitzable durant 1 ANY.", + "over18HowToGetIt": "Pots demanar aquesta targeta seguint la verificació KYC d’Altme.", + "over13WhyGetThisCard": "Algunes aplicacions/llocs web de Web 3 poden requerir aquesta prova per accedir al seu servei o obtenir avantatges: Targeta de membre, de fidelitat, premis, etc.", + "over13ExpirationDate": "Aquesta targeta romandrà activa i reutilitzable durant 1 ANY.", + "over13HowToGetIt": "Pots demanar aquesta targeta seguint la verificació KYC d’Altme.", + "over15WhyGetThisCard": "Algunes aplicacions/llocs web de Web 3 poden requerir aquesta prova per accedir al seu servei o obtenir avantatges: Targeta de membre, de fidelitat, premis, etc.", + "over15ExpirationDate": "Aquesta targeta romandrà activa i reutilitzable durant 1 ANY.", + "over15HowToGetIt": "Pots demanar aquesta targeta seguint la verificació KYC d’Altme.", + "passportFootprintWhyGetThisCard": "Algunes aplicacions/llocs web de Web 3 poden requerir aquesta prova per accedir al seu servei o obtenir avantatges: Targeta de membre, de fidelitat, premis, etc.", + "passportFootprintExpirationDate": "Aquesta targeta romandrà activa i reutilitzable durant 1 ANY.", + "passportFootprintHowToGetIt": "Pots demanar aquesta targeta seguint la verificació KYC d’Altme.", + "verifiableIdCardWhyGetThisCard": "Aquesta targeta d’identitat digital conté la mateixa informació que la teva targeta d’identitat física. La pots utilitzar al Web 3 per a una verificació KYC, per exemple.", + "verifiableIdCardExpirationDate": "Aquesta targeta romandrà activa i reutilitzable durant 1 ANY.", + "verifiableIdCardHowToGetIt": "Pots demanar aquesta targeta seguint la verificació KYC d’Altme.", + "verifiableIdCardDummyDesc": "Obtén la teva targeta d’identitat digital.", + "phoneProofWhyGetThisCard": "Algunes aplicacions/llocs web de Web 3 poden requerir aquesta prova per accedir al seu servei o obtenir avantatges: Targeta de membre, de fidelitat, premis, etc.", + "phoneProofExpirationDate": "Aquesta targeta romandrà activa i reutilitzable durant 1 ANY.", + "phoneProofHowToGetIt": "És molt fàcil. Altme verificarà el teu número de telèfon enviant un codi per SMS.", + "tezVoucherWhyGetThisCard": "Aquesta targeta cupó dona un 10 % de reemborsament en efectiu en TOTES les transaccions del joc Tezotopia en comprar un Drops al mercat o encunyar un NFT a Starbase.", + "tezVoucherExpirationDate": "Aquesta targeta romandrà activa i reutilitzable durant 30 dies.", + "tezVoucherHowToGetIt": " És molt fàcil. Demana-la de franc ara.", + "genderWhyGetThisCard": "Aquesta prova de gènere és útil per demostrar el teu gènere (masculí / femení) sense donar cap altra informació teva. Es fa servir en enquestes, etc.", + "genderExpirationDate": "Aquesta targeta romandrà activa i reutilitzable durant 1 ANY.", + "genderHowToGetIt": "Pots demanar aquesta targeta seguint la verificació KYC d’Altme.", + "nationalityWhyGetThisCard": "Aquesta credencial és útil per demostrar la teva nacionalitat sense donar cap altra informació teva. Pot demanar-se en aplicacions Web 3 en enquestes d'usuari, etc.", + "nationalityExpirationDate": "Aquesta targeta romandrà activa i reutilitzable durant 1 ANY.", + "nationalityHowToGetIt": "Pots demanar aquesta targeta seguint la verificació KYC d’Altme.", + "ageRangeWhyGetThisCard": "Aquesta credencial és útil per demostrar la teva edat sense donar cap altra informació teva. Pot caldre en aplicacions Web 3 per a enquestes d’usuari o per obtenir avantatges: Targeta de membre, etc.", + "ageRangeExpirationDate": "Aquesta targeta romandrà activa i reutilitzable durant 1 ANY.", + "ageRangeHowToGetIt": "Pots demanar aquesta targeta seguint la verificació KYC d’Altme.", + "defiComplianceWhyGetThisCard": "Obtén una prova verificable de conformitat amb KYC/AML, sol·licitada per protocols DeFi compatibles i dApps de Web3. Una vegada obtinguda, pots encunyar un NFT protector de privadesa i no transferible per a la verificació a la cadena de blocs sense mostrar dades personals.", + "defiComplianceExpirationDate": "Aquestes credencials romanen actives 3 mesos. Per renovació cal una comprovació de conformitat senzilla, sense nou KYC.", + "defiComplianceHowToGetIt": "És fàcil! Fes una verificació KYC única a la cartera Altme (desenvolupada per ID360) i sol·demana la teva credencial de conformitat DeFi.", + "rewardDialogTitle": "Ben fet 🥳", + "rewardDialogDescPart1": "Acabes de rebre", + "rewardDialogDescPart2": "al teu compte", + "origin": "Origen", + "nftTooBigToLoad": "NFT massa gran per carregar", + "seeTransaction": "Veure transacció", + "nftListSubtitle": "Aquí tens tots els NFT i objectes de col·lecció al teu compte.", + "tokenListSubtitle": "Aquí tens tots els tokens al teu compte.", + "my": "El meu", + "get": "Obtenir", + "seeMoreNFTInformationOn": "Veure més informació de NFT sobre", + "credentialStatus": "Estat", + "pass": "Passi", + "payloadFormatErrorMessage": "Format de càrrega incorrecte.", + "thisFeatureIsNotSupportedMessage": "Aquesta funció encara no s'admet", + "myWallet": "La meva cartera", + "ethereumNetwork": "Xarxa Ethereum", + "fantomNetwork": "Xarxa Fantom", + "polygonNetwork": "Xarxa Polygon", + "binanceNetwork": "Xarxa BNB Chain", + "step": "Pas", + "activateBiometricsTitle": "Activar biomètrica\nper afegir una capa de seguretat", + "loginWithBiometricsOnBoarding": "Inciar sessió amb biomètrica", + "option": "Opció", + "start": "Comença", + "iAgreeToThe": "Autoritzo els ", + "termsAndConditions": "Termes i condicions", + "walletReadyTitle": "La cartera està a punt!", + "walletReadySubtitle": "Anem a descobrim-ho tot \nWeb 3 té coses per oferir.", + "failedToInitCamera": "Error d’inici de càmera.", + "chooseMethodPageOver18Title": "Tria un mètode per aconseguir la prova més de 18", + "chooseMethodPageOver13Title": "Tria un mètode per aconseguir la prova més de 13", + "chooseMethodPageOver15Title": "Tria un mètode per aconseguir la prova més de 15", + "chooseMethodPageOver21Title": "Tria un mètode per aconseguir la prova més de 21", + "chooseMethodPageOver50Title": "Tria un mètode per aconseguir la prova més de 50", + "chooseMethodPageOver65Title": "Tria un mètode per aconseguir la prova més de 65", + "chooseMethodPageAgeRangeTitle": "Tria un mètode per aconseguir la prova d’edat", + "chooseMethodPageVerifiableIdTitle": "Tria un mètode per aconseguir la prova d’ID verificable", + "chooseMethodPageDefiComplianceTitle": "Tria un mètode per aconseguir la prova de conformitat amb DeFi", + "chooseMethodPageSubtitle": "Verifica’t amb una foto en temps real o amb una verificació clàssica de documents d’identitat.", + "kycTitle": "Foto ràpida (1 min)", + "kycSubtitle": "Verifica’t ràpidament amb una foto teva.", + "passbaseTitle": "Verificació completa del document d’identitat", + "passbaseSubtitle": "Verifica’t amb un document d’identitat, passaport o carnet de conduir.", + "verifyYourAge": "Verifica la teva edat", + "verifyYourAgeSubtitle": "El procés de verificació d’edat és molt fàcil i senzill. Només cal és una foto en temps real.", + "verifyYourAgeDescription": "En acceptar, accedeixes a que usem una imatge per calcular la teva edat. El càlcul el fa el nostre soci Yoti, que utilitza la imatge només per a aquest propòsit i l'elimina immediatament.\n\nPer saber-ne més, consulta la política de privadesa.", + "accept": "Acceptar", + "decline": "Rebutjar", + "yotiCameraAppbarTitle": "Col·loca la cara al centre", + "cameraSubtitle": "Tens 5 segons per fer la foto.\nMira que hi hagi prou llum abans de començar.", + "walletSecurity": "Seguretat de la cartera", + "walletSecurityDescription": "Protegeix la cartera amb el codi PIN i l’autenticació biomètrica", + "blockchainSettings": "Configuració de blockchain", + "blockchainSettingsDescription": "Administrar comptes, frase de recuperació, dApps connectades i xarxes", + "ssi": "Identitat Autònoma (DID)", + "ssiDescription": "Administra la ID descentralitzada i fes còpies de seguretat o restaura les teves credencials", + "helpCenter": "Centre d’assistència", + "helpCenterDescription": "Posa’t en contacte amb nosaltres i t’ajudarem a utilitzar la nostra cartera", + "about": "Informació", + "aboutDescription": "Llegeix les condicions d’ús, la privadesa i les llicències", + "resetWallet": "Reiniciar cartera", + "resetWalletDescription": "Esborra totes les dades emmagatzemades al teu telèfon i restableix la cartera.", + "showWalletRecoveryPhrase": "Mostra frase de recuperació de la cartera", + "showWalletRecoveryPhraseSubtitle": "La frase de recuperació actua com una clau de còpia de seguretat per restaurar l'accés a la cartera", + "blockchainNetwork": "Xarxa de blockchain (per defecte)", + "contactUs": "Contacte", + "officialWebsite": "Lloc web oficial", + "yourAppVersion": "La teva versió d’app", + "resetWalletTitle": "Segur que vols reiniciar la cartera?", + "resetWalletSubtitle": "L’acció esborrarà les teves dades. Comprova que has guardat la teva frase de recuperació i la còpia de seguretat de les teves credencials abans d’eliminar-les.", + "resetWalletSubtitle2": "La cartera és autocustodiada: no podem recuperar els fons o credencials en lloc teu.", + "resetWalletCheckBox1": "He escrit la meva frase de recuperació", + "resetWalletCheckBox2": "He guardat el fitxer de còpia de seguretat de les meves credencials", + "email": "Correu electrònic", + "fillingThisFieldIsMandatory": "És obligatori omplir aquest camp.", + "yourMessage": "El teu missatge", + "message": "Missatge", + "subject": "Assumpte", + "enterAValidEmail": "Indica un correu electrònic vàlid.", + "failedToSendEmail": "Enviament de correu electrònic fallit.", + "selectAMethodToAddAccount": "Seleccionar un mètode per afegir compte", + "createAccount": "Crear compte", + "createAccountDescription": "Crear compte protegit per la teva frase de recuperació", + "importAccountDescription": "Importar un compte d’una cartera existent", + "chooseABlockchainForAccountCreation": "Escull la blockchain on vols crear un nou compte.", + "tezosAccount": "Compte Tezos", + "tezosAccountDescription": "Crear una nova direcció de blockchain de Tezos", + "ethereumAccount": "Compte Ethereum", + "ethereumAccountDescription": "Crear una nova direcció de blockchain d’Ethereum", + "fantomAccount": "Compte Fantom", + "fantomAccountDescription": "Crear una nova direcció de blockchain de Fantom", + "polygonAccount": "Compte Polygon", + "polygonAccountDescription": "Crear una nova direcció de blockchain de Polygon", + "binanceAccount": "Compte BNB Chain", + "binanceAccountDescription": "Crear una nova direcció de blockchain de BNB Chain", + "setAccountNameDescription": "Vols donar un nom a aquest compte nou? És útil si en tens uns quants.", + "letsGo": "Som-hi!", + "congratulations": "Felicitats!", + "tezosAccountCreationCongratulations": "El teu nou compte de Tezos s’ha creat amb èxit.", + "ethereumAccountCreationCongratulations": "El teu nou compte d’Ethereum s’ha creat amb èxit.", + "fantomAccountCreationCongratulations": "El teu nou compte de Fantom s’ha creat amb èxit.", + "polygonAccountCreationCongratulations": "El teu nou compte de Polygon s’ha creat amb èxit.", + "binanceAccountCreationCongratulations": "El teu nou compte de BNB Chain s’ha creat amb èxit.", + "accountImportCongratulations": "El teu compte s’ha importat correctament.", + "saveBackupCredentialTitle": "Descarrega l’arxiu de còpia de seguretat.\nGuarda’l en un lloc segur.", + "saveBackupCredentialSubtitle": "Per recuperar totes les teves credencials, cal la frase de recuperació i aquest arxiu de còpia de seguretat.", + "saveBackupPolygonCredentialSubtitle": "Per recuperar totes les teves credencials ID de Polygon, cal la frase de recuperació i aquest arxiu de còpia de seguretat.", + "restoreCredentialStep1Title": "Pas 1: Indica les 12 paraules de la frase de recuperació", + "restorePhraseTextFieldHint": "Indica la frase de recuperació (o frase de recordatori) aquí...", + "restoreCredentialStep2Title": "Pas 2: Carrega les credencials a l’arxiu de còpia de seguretat", + "loadFile": "Carregar arxiu", + "uploadFile": "Pujar arxiu", + "creators": "Creadors", + "publishers": "Publicadors", + "creationDate": "Data de creació", + "myProfessionalrCards": "targetes professionals", + "myProfessionalrCardsSubtitle": "Utilitza les teves targetes professionals amb seguretat.", + "guardaWallet": "Cartera Guarda", + "exodusWallet": "Cartera Exodus", + "trustWallet": "Cartera Trust", + "myetherwallet": "Cartera MyEther", + "skip": "Saltar", + "userNotFitErrorMessage": "No pots obtenir aquesta targeta perquè no es compleixen algunes condicions.", + "youAreMissing": "Falten", + "credentialsRequestedBy": "credencials demanades per", + "transactionIsLikelyToFail": "La transacció probablement fallarà.", + "buy": "Comprar", + "thisFeatureIsNotSupportedYetForFantom": "Aquesta funció encara no s'admet a Fantom.", + "thisFeatureIsNotSupportedYetForBinance": "Aquesta funció encara no s'admet a BNB Chain.", + "faqs": "Preguntes freqüents", + "softwareLicenses": "Llicències de software", + "notAValidWalletAddress": "Adreça de cartera invàlida.", + "otherAccount": "Altre compte", + "thereIsNoAccountInYourWallet": "No hi ha comptes a la teva cartera", + "exportToLinkedIn": "Exportar a LinkedIn", + "addLinkedInInfo": "Afegir info de LinkedIn", + "whatsYourLinkedinProfileUrl": "Quina és la URL de perfil del teu LinkedIn?", + "invalidUrlError": "Indica una URL de LinkedIn vàlida", + "linkedInBannerSuccessfullyExported": "El teu bàner de LinkedIn s’ha exportat amb èxit.", + "credentialSuccessfullyExported": "La teva credencial s’ha exportat correctament.", + "linkedInBanner": "Bàner de LinkedIn", + "linkedInProfile": "Perfil de LinkedIn", + "checkLinkedinProfile": "Verifica un perfil de LinkedIn", + "scanAndDisplay": "Escanejar i mostrar", + "whatsNew": "Novetats", + "okGotIt": "Entesos!", + "support": "ajuda", + "transactionDoneDialogDescription": "Pot trigar uns minuts perquè la transferència es completi", + "withdrawalFailedMessage": "La retirada del compte no ha funcionat", + "credentialRequiredMessage": "Necessites tenir aquestes credencials a la cartera per adquirir aquesta targeta:", + "keyDecentralizedIdEdSA": "Clau d’ID descentralitzada EdDSA", + "keyDecentralizedIDSecp256k1": "Clau d’ID descentralitzada Secp256k1", + "polygonIdDecentralizedId": "ID descentralitzada de Polygon", + "ebsiV3DecentralizedId": "ID descentraltitzada de la v3 d’EBSI", + "requiredCredentialNotFoundTitle": "No hem trobat la credencial\nque et cal a la teva cartera.", + "requiredCredentialNotFoundSubTitle": "La credencial requerida no és a la teva cartera", + "requiredCredentialNotFoundDescription": "Contacta’ns a:", + "backToHome": "Tornar a l’inici", + "help": "Ajuda", + "searchCredentials": "Buscar credencials", + "supportChatWelcomeMessage": "Benvingut al nostre suport de xat! Som aquí per respondre a les teves preguntes o dubtes sobre la nostra cartera.", + "cardChatWelcomeMessage": "Benvingut al nostre suport de xat! Som aquí per respondre a les teves preguntes o dubtes.", + "creator": "Creador", + "contractAddress": "Adreça de contacte", + "lastMetadataSync": "Última sinc de metadades", + "e2eEncyptedChat": "Xat xifrat d’extrem a extrem.", + "pincodeAttemptMessage": "Has indicat un codi PIN incorrecte tres vegades. Per raons de seguretat, espera un minut abans de reintentar-ho.", + "verifyNow": "Comprovar ara", + "verifyLater": "Verificar més tard", + "welDone": "Ben fet!", + "mnemonicsVerifiedMessage": "Frase de recuperació guardada.", + "chatWith": "Xat amb", + "sendAnEmail": "Enviar un correu electrònic", + "livenessCardHowToGetIt": "És fàcil! Fes una verificació KYC única a la cartera Altme (desenvolupada per ID360) i sol·demana una credencial de Liveness.", + "livenessCardExpirationDate": "Aquesta credencial estarà activa durant 1 ANY. La renovació és senzilla", + "livenessCardWhyGetThisCard": "Obtén una prova verificable d’humanitat, que demanen la majoria dels protocols DeFi, GameFi i dApps de Web3. Una vegada obtinguda, pots encunyar un NFT protector de privadesa i no transferible per a la verificació a la cadena de blocs sense mostrar dades personals.", + "livenessCardLongDescription": "La credencial és una prova verificable d’humanitat. Utilitza-ho per demostrar que no ets un robot quan ho demanin els protocols DeFi, jocs Onchain o dApps de Web3.", + "chat": "Xat", + "polygonDecentralizedID": "ID descentralitzada de Polygon", + "needMnemonicVerificatinoDescription": "Cal que verifiquis les frases llavor de la cartera per protegir els teus actius.", + "succesfullyAuthenticated": "Autenticació correcta.", + "authenticationFailed": "Autenticació fallida.", + "documentType": "Tipus de document", + "countryCode": "Codi del país", + "deviceIncompatibilityMessage": "El dispositiu no és compatible amb aquesta funció.", + "tezosProofMessage": "", + "ethereumProofMessage": "", + "fantomProofMessage": "", + "polygonProofMessage": "", + "binanceProofMessage": "", + "yearsOld": "anys", + "youAreOver13": "Ets major de 13 anys", + "youAreOver15": "Ets major de 15 anys", + "youAreOver18": "Ets major de 18 anys", + "youAreOver21": "Ets major de 21 anys", + "youAreOver50": "Ets major de 50 anys", + "youAreOver65": "Ets major de 65 anys", + "polygon": "Polygon", + "ebsi": "EBSI", + "backupPolygonIdIdentity": "Fer còpia de seguretat de la identitat de PolygonId", + "restorePolygonIdCredentials": "Restaurar credencials de PolygonID", + "comingSoon": "Properament", + "financeCredentialsHomeTitle": "Les meves credencials financeres", + "financeCredentialsDiscoverTitle": "Verificar credencials financeres", + "financeCredentialsDiscoverSubtitle": "Accedeix a noves oportunitats d’inversió a Web3.", + "financeCredentialsHomeSubtitle": "Accedeix a noves oportunitats d’inversió a Web3", + "hummanityProofCredentialsHomeTitle": "La meva prova d’humanitat", + "hummanityProofCredentialsHomeSubtitle": "Demostra fàcilment que no ets un bot sinó un humà.", + "hummanityProofCredentialsDiscoverTitle": "Demostra que no ets un bot ni IA", + "hummanityProofCredentialsDiscoverSubtitle": "Obtén una prova d’humanitat reutilitzable per compartir", + "socialMediaCredentialsHomeTitle": "Els meus comptes de xarxes socials", + "socialMediaCredentialsHomeSubtitle": "Demostra la propietat dels comptes a l’instant amb una prova de humanitat", + "socialMediaCredentialsDiscoverTitle": "Verifica els teus comptes de xarxes socials", + "socialMediaCredentialsDiscoverSubtitle": "Demostra la propietat dels teus comptes quan calgui", + "walletIntegrityCredentialsHomeTitle": "Integritat de la cartera", + "walletIntegrityCredentialsHomeSubtitle": "TBD", + "walletIntegrityCredentialsDiscoverTitle": "Integritat de la cartera", + "walletIntegrityCredentialsDiscoverSubtitle": "TBD", + "polygonCredentialsHomeTitle": "Les meves credencials de PolygonID", + "polygonCredentialsHomeSubtitle": "Demostra els teus drets d’accés a l’ecosistema de Polygon", + "polygonCredentialsDiscoverTitle": "Obtenir credencials de PolygonID", + "polygonCredentialsDiscoverSubtitle": "Demostra els teus drets d’accés a l’ecosistema de Polygon", + "pendingCredentialsHomeTitle": "Credencials pendents", + "pendingCredentialsHomeSubtitle": "Demostra els teus drets d'accés.", + "restore": "Restaurar", + "backup": "Copiar", + "takePicture": "Fer una foto", + "kyc": "KYC", + "aiSystemWasNotAbleToEstimateYourAge": "El sistema d’IA no ha pogut calcular l’edat", + "youGotAgeCredentials": "Tens la teva credencial {credential}.", + "@youGotAgeCredentials": { + "description": "la descripció per obtenir credencials", + "placeholders": { + "credential": {} + } + }, + "yourAgeEstimationIs": "El càlcul de la teva edat amb IA és de {ageEstimate} anys", + "@yourAgeEstimationIs": { + "description": "", + "placeholders": { + "ageEstimate": {} + } + }, + "credentialNotFound": "Credencial no trobada", + "cryptographicProof": "Prova criptogràfica", + "downloadingCircuitLoadingMessage": "Descarregant circuits. Pot trigar una estona. Espera.", + "cryptoAccountAlreadyExistMessage": "Sembla que ja hi ha un compte amb aquesta informació criptogràfica", + "errorGeneratingProof": "Generació de prova fallida", + "createWalletMessage": "Crea una cartera primer.", + "successfullyGeneratingProof": "Prova generada correctament", + "wouldYouLikeToAcceptThisCredentialsFromThisOrganisation": "Vols acceptar aquesta/es credencial/s d’aquesta organització?", + "thisOrganisationRequestsThisInformation": "L’organització demana aquesta informació", + "iS": "és", + "isSmallerThan": "és inferior a", + "isBiggerThan": "és superior a", + "isOneOfTheFollowingValues": "és un dels següents valors", + "isNotOneOfTheFollowingValues": "no és un dels següents valors", + "isNot": "no és", + "approve": "Aprovar", + "noInformationWillBeSharedFromThisCredentialMessage": "No es compartirà cap informació d’aquesta credencial (prova de coneixement zero).", + "burn": "Destruir", + "wouldYouLikeToConfirmThatYouIntendToBurnThisNFT": "Segur que vols destruir el NFT?", + "pleaseAddXtoConnectToTheDapp": "Afegeix el compte {chain} per connectar-te a la dApp.", + "@pleaseAddXtoConnectToTheDapp": { + "description": "", + "placeholders": { + "chain": {} + } + }, + "pleaseSwitchPolygonNetwork": "Canvia a polygon {networkType} per realitzar aquesta acció.", + "@pleaseSwitchPolygonNetwork": { + "description": "", + "placeholders": { + "networkType": {} + } + }, + "oidc4vcProfile": "Perfil OIDC4VC", + "pleaseSwitchToCorrectOIDC4VCProfile": "Canvia al perfil OIDC4VC correcte.", + "authenticationSuccess": "Autenticació correcta", + "format": "Format", + "pleaseInsertTheSecredCodeReceived": "Escriu el codi secret que has rebut.", + "verifyIssuerWebsiteIdentity": "Verificar la identitat del lloc web de l'emissor", + "verifyIssuerWebsiteIdentitySubtitle": "Per defecte: desactivat\nActivar per verificar la identitat del lloc web abans de l’accés.", + "developerMode": "Mode desenvolupador", + "developerModeSubtitle": "Activa el mode desenvolupador per accedir a eines de depuració avançades", + "confirmVerifierAccess": "Confirma l’accés del verificador", + "confirmVerifierAccessSubtitle": "Per defecte: activat\nDesactiva per saltar la confirmació quan comparteixis les teves credencials verificables.", + "credentialManifestSupport": "Admet manifest de credencials", + "credentialManifestSupportSubtitle": "Per defecte: desactivat\nUtilitza la sintaxi de representació de la cartera DIF en comptes de l'atribut “display”.", + "secureAuthenticationWithPINCode": "Autenticació segura amb codi PIN", + "secureAuthenticationWithPINCodeSubtitle": "Per defecte: activat\nDesactivar per ometre el codi PIN per a l’autenticació del lloc web (no recomanat).", + "youcanSelectOnlyXCredential": "Només pots seleccionar {count} credencial/s.", + "@youcanSelectOnlyXCredential": { + "description": "", + "placeholders": { + "count": {} + } + }, + "theCredentialIsNotReady": "La credencial no està a punt.", + "theCredentialIsNoMoreReady": "La credencial ja no està disponible.", + "lowSecurity": "Seguretat baixa", + "highSecurity": "Seguretat alta", + "theRequestIsRejected": "S’ha refusat la sol·licitud.", + "userPinIsIncorrect": "PIN d’usuari incorrecte", + "security_level": "Nivell de seguretat", + "oidc4vc_settings": "Configuració d’OIDC4VC", + "userPinTitle": "Dígits PIN de l’usuari: codi_preautoritzat Flux", + "userPinSubtitle": "Per defecte: 6 DÍGITS\nPermetre gestionar codi PIN de 4 dígits", + "securityLevelTitle": "Nivell de cartera", + "securityLevelSubTitle": "Per defecte: Permissiu\nCanvia a “Estricte” per reforçar els controls a emissors i verificadors", + "responseTypeNotSupported": "Tipus de resposta no compatible", + "invalidRequest": "Sol·licitud no vàlida", + "subjectSyntaxTypeNotSupported": "Sintaxi del subjecte no compatible.", + "accessDenied": "Accés refusat", + "thisRequestIsNotSupported": "Sol·licitud no compatible", + "unsupportedCredential": "Credencial no compatible", + "aloginIsRequired": "Cal iniciar sessió", + "userConsentIsRequired": "Cal consentiment d’usuari", + "theWalletIsNotRegistered": "La cartera no està registrada", + "credentialIssuanceDenied": "Emissió de credencial denegada", + "thisCredentialFormatIsNotSupported": "Format de credencial no compatible", + "thisFormatIsNotSupported": "Format no compatible", + "moreDetails": "Més detalls", + "theCredentialOfferIsInvalid": "Oferta de credencial no vàlida", + "dateOfRequest": "Data de la demanda", + "keyDecentralizedIDP256": "Clau d’ID descentralitzada P-256", + "jwkDecentralizedIDP256": "JWK ID descentralitzada P-256", + "defaultDid": "DID per defecte", + "selectOneOfTheDid": "Selecciona un dels DID", + "subjectSyntaxType": "Tipus de sintaxis del subjecte", + "enableToUseTheJWKThumprintOfTheKey": "Per defecte: DID\nPermet utilitzar l’empremta digital JWK de la clau", + "cryptographicHolderBinding": "Enllaç criptogràfic del titular", + "cryptographicHolderBindingSubtitle": "Per defecte: activat\nDesactivar l’autorització de credencials de portador per tiquets poc fiables.", + "scopeParameters": "Paràmetres d’àmbit", + "scopeParametersSubtitle": "Per defecte: desactivat\nActivar per forçar la cartera a utilitzar l’àmbit en lloc dels detalls_d’autorització.", + "clientAuthenticationMethods": "Mètodes d’autenticació del client", + "clientAuthenticationMethodsSubtitle": "Per defecte: Identificador del client com a DID o JWK\nSelecciona altres mètodes d’autenticació si és necessari.", + "vcFormatType": "Format VC", + "vcFormatTypeSubtitle": "Per defecte: ldp_vc\nSelecciona un dels formats VC.", + "theServiceIsNotAvailable": "Servei no disponible", + "issuerDID": "Emissor DID", + "subjectDID": "Subjecte DID", + "type": "Tipus", + "credentialExpired": "Credencial caducada", + "incorrectSignature": "Signatura incorrecta", + "revokedOrSuspendedCredential": "Credencial revocada o suspesa", + "display": "Mostrar", + "download": "Descarregar", + "successfullyDownloaded": "Descàrrega realitzada", + "advancedSecuritySettings": "Configuració de seguretat avançada", + "clientMetadata": "Metadades de la cartera", + "theIssuanceOfThisCredentialIsPending": "L’emissió d’aquesta credencial està pendent", + "clientId": "ID del client", + "clientSecret": "Client secret", + "walletProfiles": "Perfils de la cartera", + "walletProfilesDescription": "Escull un perfil SSI o personalitza el teu", + "profileCustom": "Personalitzar", + "profileEbsiV3": "Infraestructura de serveis blockchain europea", + "decentralizedIdentityInteropProfile": "Perfil d’interop d’identitat descentralizada", + "protectYourWallet": "Protegeix la teva cartera", + "protectYourWalletMessage": "Utilitza l’empremta digital, la cara o el PIN del dispositiu per protegir i desbloquejar la teva cartera. Dades xifrades i segures en aquest dispositiu.", + "pinUnlock": "Desbloqueig PIN", + "secureWithDevicePINOnly": "Protegir només amb PIN del dispositiu", + "biometricUnlock": "Desbloqueig biomètric", + "secureWithFingerprint": "Protegir amb empremta digital", + "pinUnlockAndBiometric2FA": "Desbloqueig PIN + biomètric (2FA)", + "secureWithFingerprintAndPINBackup": "Protegir amb empremta digital + PIN de seguretat", + "secureYourWalletWithPINCodeAndBiometrics": "Protegeix la cartera amb codi PIN i biomètrica", + "twoFactorAuthenticationHasBeenEnabled": "Autenticació de dos factors activada.", + "createAnProfessionalWallet": "Crear cartera d’empresa", + "initialization": "Inicialització", + "login": "Iniciar sessió", + "password": "Contrasenya", + "pleaseEnterYourEmailAndYourCompanyPasswordToCreateYourAccount": "Indica el correu electrònic i la contrasenya de la teva empresa per crear el compte", + "enterTheSecurityCodeThatWeSentYouByEmail": "Indica el codi de seguretat que t’hem enviat", + "enterTheSecurityCode": "Indica el codi de seguretat", + "yourEmail": "El teu correu electrònic", + "publicKeyOfWalletInstance": "Clau pública de la instància de la cartera", + "walletInstanceKey": "Clau d’instància de la cartera", + "protocoleStandardRelease": "Llançament estàndard del protocol", + "organizationProfile": "Perfil de l’organització", + "profileName": "Nom del perfil", + "companyName": "Nom de l’empresa", + "configFileIdentifier": "Identificador de l’arxiu de config", + "clientCredentials": "Credencials del client", + "updateYourWalletConfigNow": "Actualitzar ara config de cartera", + "updateConfigurationNow": "Actualitza la configuració ara", + "pleaseEnterYourEmailAndPasswordToUpdateYourOrganizationWalletConfiguration": "Indica el correu electrònic i la contrasenya per actualitzar la configuració de la cartera de la teva organització.", + "congrats": "Felicitats!", + "yourWalletConfigurationHasBeenSuccessfullyUpdated": "La configuració de la cartera s’ha actualitzat correctament", + "continueString": "Continuar", + "walletProvider": "Proveïdor de cartera" +} \ No newline at end of file diff --git a/lib/l10n/arb/app_de.arb b/lib/l10n/arb/app_de.arb deleted file mode 100644 index 1422ebce5..000000000 --- a/lib/l10n/arb/app_de.arb +++ /dev/null @@ -1,3 +0,0 @@ -{ - "@@locale": "de" -} \ No newline at end of file diff --git a/lib/l10n/arb/app_en.arb b/lib/l10n/arb/app_en.arb index 067868373..1ebd52f27 100644 --- a/lib/l10n/arb/app_en.arb +++ b/lib/l10n/arb/app_en.arb @@ -3,7 +3,6 @@ "genericError": "An error has occurred!", "@genericError": { "description": "Generic error message", - "@@locale": "en", "type": "text", "placeholders": {} }, @@ -222,7 +221,6 @@ } }, "selfIssuedCreatedSuccessfully": "Self issued credential created successfully", - "companyName": "Company Name", "companyWebsite": "Company Website", "submit": "Submit", "insertYourDIDKey": "Insert your DID", @@ -304,8 +302,7 @@ "delete": "Delete", "enterNewPinCode": "Create a PIN Code\nto protect your wallet", "confirmYourPinCode": "Confirm your pin code", - "walletAltme": "Wallet Altme", - "createPersonalWallet": "Create Personal Wallet", + "walletAltme": "Wallet Altme", "createTitle": "Create or import a wallet", "createSubtitle": "Would you like to create a new wallet or import an existing one?", "enterYourPinCode": "Enter your pin code", @@ -349,7 +346,6 @@ "trustFramework": "Trust Framework", "network": "Network", "issuerRegistry": "Issuer Registry", - "about": "About", "termsOfUse": "Terms of Use & Confidentiality", "scanFingerprintToAuthenticate": "Scan Fingerprint to Authenticate", "biometricsNotSupported": "Biometrics not supported", @@ -689,7 +685,7 @@ "decline": "Decline", "yotiCameraAppbarTitle": "Please, position your face in the center", "cameraSubtitle": "You have 5 seconds to take your photo.\nMake sure there’s enough light before starting.", - "todoImportant": "TODO(all): update the text of below keys","walletSecurity": "Wallet Security", + "walletSecurity": "Wallet Security", "walletSecurityDescription": "Protect your wallet with Pin Code and Biometrics Authentication", "blockchainSettings": "Blockchain Settings", "blockchainSettingsDescription": "Manage accounts, Recovery Phrase, Connected dApps and Networks", @@ -968,8 +964,6 @@ "jwkDecentralizedIDP256": "JWK Decentralized ID P-256", "defaultDid": "Default DID", "selectOneOfTheDid": "Select one of the DIDs", - "clientTypeTitle": "OIDC4VCI Client Type", - "clientTypeSubtitle": "Default: DID\nSwitch to change the client type", "cryptographicHolderBinding": "Cryptographic Holder Binding", "cryptographicHolderBindingSubtitle": "Default : On\nDisable cryptographic binding for claim based binding credentials.", "scopeParameters": "Scope Parameters", @@ -978,8 +972,6 @@ "clientAuthenticationMethodsSubtitle": "Default: Client id as DID or JWK\nSelect to other authentication methods if needed.", "vcFormatType": "VC Format", "vcFormatTypeSubtitle": "Default: ldp_vc\nSelect one of the VC formats.", - "proofHeader": "Proof of Possession Header", - "proofHeaderSubtitle": "Default: kid\nSwitch if jwk is needed in header.", "theServiceIsNotAvailable": "The service is not available", "issuerDID": "Issuer DID", "subjectDID": "Subject DID", @@ -1010,7 +1002,6 @@ "secureWithFingerprintAndPINBackup": "Secure with Fingerprint + PIN backup", "secureYourWalletWithPINCodeAndBiometrics": "Secure your wallet with PIN code and Biometrics", "twoFactorAuthenticationHasBeenEnabled": "Two factor authentication has been enabled.", - "createAnProfessionalWallet": "Create Enterprise Wallet", "initialization": "Initialization", "login": "Login", "password": "Password", @@ -1033,10 +1024,18 @@ "yourWalletConfigurationHasBeenSuccessfullyUpdated": "Your wallet configuration has been successfully updated", "continueString": "Continue", "walletProvider": "Wallet Provider", + "clientTypeTitle": "OIDC4VCI Client Type", + "clientTypeSubtitle": "Default: DID\nSwitch to change the client type", + "proofHeader": "Proof of Possession Header", + "proofHeaderSubtitle": "Default: kid\nSwitch if jwk is needed in header.", "theLdpFormatIsNotSupportedByThisDIDMethod": "The ldp_format is not supported by this DID method.", "switchOffCryptoHolderBindingForThatDIDMethod": "Switch off Crypto Holder Binding for that DID Method.", "thisTypeProofCannotBeUsedWithThisVCFormat": "This type proof cannot be used with this VC Format.", "enterprise": "Enterprise", "oWFBaselineProfile": "OWF Baseline Profile", - "defaultProfile":"Default" + "defaultProfile":"Default", + "blockchainCardsDiscoverTitle": "Get a proof of crypto account ownership", + "blockchainCardsDiscoverSubtitle": "Get a proof of crypto account ownership.", + "successfullyAddedEnterpriseAccount": "Successfully added enterprise account!", + "successfullyUpdatedEnterpriseAccount": "Successfully updated enterprise account!" } diff --git a/lib/l10n/arb/app_es.arb b/lib/l10n/arb/app_es.arb index c94736f51..1e874f867 100644 --- a/lib/l10n/arb/app_es.arb +++ b/lib/l10n/arb/app_es.arb @@ -1,3 +1,1031 @@ { - "@@locale": "es" + "@@locale": "es", + "genericError": "¡Se ha producido un error!", + "@genericError": { + "description": "Mensaje de error genérico", + "type": "text", + "placeholders": {} + }, + "credentialListTitle": "Credenciales", + "@credentialListTitle": { + "description": "Título de la página de lista de credenciales", + "type": "text", + "placeholders": {} + }, + "credentialDetailIssuedBy": "Emitido por {issuer}", + "@credentialDetailIssuedBy": { + "description": "Emisor de credenciales en la página de detalles", + "type": "text", + "placeholders": { + "issuer": {} + } + }, + "listActionRefresh": "Actualizar", + "@listActionRefresh": { + "description": "Botón de acción de lista para actualizar el contenido", + "type": "text", + "placeholders": {} + }, + "listActionViewList": "Ver como lista", + "@listActionViewList": { + "description": "Botón de acción de lista para establecer la vista en el modo de lista", + "type": "text", + "placeholders": {} + }, + "listActionViewGrid": "Ver como cuadrícula", + "@listActionViewGrid": { + "description": "Botón de acción de lista para establecer la vista en el modo de cuadrícula", + "type": "text", + "placeholders": {} + }, + "listActionFilter": "Filtro", + "@listActionFilter": { + "description": "Botón de acción de lista para abrir opciones de filtro", + "type": "text", + "placeholders": {} + }, + "listActionSort": "Ordenar", + "@listActionSort": { + "description": "Botón de acción de lista para abrir opciones de ordenación", + "type": "text", + "placeholders": {} + }, + "onBoardingStartSubtitle": "Lorem ipsum dolor sit ame", + "onBoardingTosTitle": "Términos y condiciones", + "onBoardingTosText": "Al tocar Aceptar, \"Acepto los términos y condiciones, y la divulgación de esta información.\"", + "onBoardingTosButton": "Aceptar", + "onBoardingRecoveryTitle": "Recuperación de clave", + "onBoardingRecoveryButton": "Recuperar", + "onBoardingGenPhraseTitle": "Frase de recuperación", + "onBoardingGenPhraseButton": "Continuar", + "onBoardingGenTitle": "Generación de clave privada", + "onBoardingGenButton": "Generar", + "onBoardingSuccessTitle": "Identificador creado", + "onBoardingSuccessButton": "Continuar", + "credentialDetailShare": "Compartir por código QR", + "credentialAddedMessage": "¡Se ha añadido una nueva credencial!", + "credentialDetailDeleteCard": "Eliminar esta tarjeta", + "credentialDetailDeleteConfirmationDialog": "¿Seguro que desea eliminar esta credencial?", + "credentialDetailDeleteConfirmationDialogYes": "Sí", + "credentialDetailDeleteConfirmationDialogNo": "No", + "credentialDetailDeleteSuccessMessage": "Eliminación realizada.", + "credentialDetailEditConfirmationDialog": "¿Seguro que desea editar esta credencial?", + "credentialDetailEditConfirmationDialogYes": "Guardar", + "credentialDetailEditConfirmationDialogNo": "Cancelar", + "credentialDetailEditSuccessMessage": "Edición realizada.", + "credentialDetailCopyFieldValue": "¡Valor de campo copiado en el portapapeles!", + "credentialDetailStatus": "Estado de verificación", + "credentialPresentTitle": "Seleccionar credencial(es)", + "credentialPresentTitleDIDAuth": "Solicitud de DIDAuth", + "credentialPresentRequiredCredential": "Alguien pide su(s)", + "credentialPresentConfirm": "Seleccionar credencial(es)", + "credentialPresentCancel": "Rechazar", + "credentialPickPresent": "Presentar", + "credentialPickTitle": "Seleccionar credencial(es)", + "selectYourTezosAssociatedWallet": "Seleccione su cartera asociada a Tezos", + "credentialPickSelect": "Seleccione su credencial", + "siopV2credentialPickSelect": "Elija solo una credencial que presentar de su cartera", + "credentialPickAlertMessage": "¿Quiere poner un alias a esta credencial?", + "credentialReceiveTitle": "Oferta de credenciales", + "credentialReceiveHost": "desea enviarle una credencial", + "credentialAddThisCard": "Añadir esta tarjeta", + "credentialReceiveCancel": "Cancelar esta tarjeta", + "credentialDetailListTitle": "Mi cartera", + "communicationHostAllow": "Permitir", + "communicationHostDeny": "Denegar", + "scanTitle": "Escanear código QR", + "scanPromptHost": "¿Confía en este host?", + "scanRefuseHost": "La comunicación solicitada se ha denegado.", + "scanUnsupportedMessage": "La URL extraída no es válida.", + "qrCodeSharing": "Ahora comparte", + "qrCodeNoValidMessage": "Este código QR no contiene un mensaje válido.", + "profileTitle": "Perfil", + "personalTitle": "Personal", + "termsTitle": "Términos y condiciones", + "recoveryKeyTitle": "Frase de recuperación", + "showRecoveryPhrase": "Mostrar frase de recuperación", + "warningDialogTitle": "Cuidado", + "warningDialogSubtitle": "La página de recuperación contiene información sensible, por lo que su identificador podría caer en malas manos. No debe abrir esta página en un lugar público ni compartirla con nadie.", + "recoveryText": "Introduzca su frase de recuperación", + "recoveryMnemonicHintText": "Escriba aquí su frase de recuperación.\nUna vez que escriba sus 12 palabras,\ntoque Importar.", + "recoveryMnemonicError": "Introduzca una frase mnemotécnica válida", + "showDialogYes": "Continuar", + "showDialogNo": "Cancelar", + "supportTitle": "Asistencia", + "noticesTitle": "Avisos", + "resetWalletButton": "Restablecer Cartera", + "resetWalletConfirmationText": "¿Seguro que desea restablecer su cartera?", + "selectThemeText": "Seleccione el tema", + "lightThemeText": "Tema claro", + "darkThemeText": "Tema oscuro", + "systemThemeText": "Tema del sistema", + "genPhraseInstruction": "Escriba las palabras, descargue el archivo de copia de respaldo y guárdelo seguro", + "genPhraseExplanation": "Si pierde el acceso a la cartera, las necesitará en orden correcto y el archivo de respaldo para recuperar certificados.", + "errorGeneratingKey": "Error al generar la clave, vuelva a intentarlo", + "documentHeaderTooltipName": "Juan Pérez", + "documentHeaderTooltipJob": "Operador de criptomonedas", + "documentHeaderTooltipLabel": "Estado:", + "documentHeaderTooltipValue": "Válido", + "didDisplayId": "DID", + "blockChainDisplayMethod": "Blockchain", + "blockChainAdress": "Dirección", + "didDisplayCopy": "Copiar DID en el portapapeles", + "adressDisplayCopy": "Copiar dirección en el portapapeles", + "personalSave": "Guardar", + "personalSubtitle": "La información de su perfil puede usarse para completar un certificado si es necesario", + "personalFirstName": "Nombre", + "personalLastName": "Apellidos", + "personalPhone": "Teléfono", + "personalAddress": "Dirección", + "personalMail": "Email", + "lastName": "Apellidos", + "firstName": "Nombre", + "gender": "sexo", + "birthdate": "Fecha de nacimiento", + "birthplace": "Lugar de nacimiento", + "address": "Dirección", + "maritalStatus": "Estado civil", + "nationality": "Nacionalidad", + "identifier": "Identificador", + "issuer": "Emitido por", + "workFor": "Trabaja en", + "startDate": "Desde", + "endDate": "Hasta", + "employmentType": "Tipo de empleo", + "jobTitle": "Cargo", + "baseSalary": "Salario", + "expires": "Caducidad", + "generalInformationLabel": "Información general", + "learningAchievement": "Logro", + "signedBy": "Firmado por", + "from": "De", + "to": "A", + "credential": "Credencial", + "issuanceDate": "Fecha de emisión", + "appContactWebsite": "Sitio web", + "trustFrameworkDescription": "El marco de confianza es un conjunto de registros que ofrecen una base segura y fiable para que las entidades del sistema confíen e interactúen entre sí.", + "confimrDIDAuth": "¿Desea iniciar sesión en el sitio?", + "evidenceLabel": "Evidencia", + "networkErrorBadRequest": "Solicitud errónea", + "networkErrorConflict": "Error debido a un conflicto", + "networkErrorPreconditionFailed": "El servidor no cumple una de las condiciones previas.", + "networkErrorCreated": "", + "networkErrorGatewayTimeout": "Tiempo de espera de puerta de enlace alcanzado", + "networkErrorInternalServerError": "Este es un error interno del servidor. Contacte con el administrador del servidor", + "networkErrorMethodNotAllowed": "El usuario no tiene derechos de acceso al contenido", + "networkErrorNoInternetConnection": "Sin conexión a Internet", + "networkErrorNotAcceptable": "No aceptable", + "networkErrorNotImplemented": "No implementado", + "networkErrorOk": "", + "networkErrorRequestCancelled": "Solicitud cancelada", + "networkErrorRequestTimeout": "Tiempo de espera de solicitud", + "networkErrorSendTimeout": "Enviar tiempo de espera en conexión con servidor API", + "networkErrorServiceUnavailable": "Servicio no disponible", + "networkErrorTooManyRequests": "El usuario ha enviado demasiadas solicitudes en un tiempo dado", + "networkErrorUnableToProcess": "No se pueden procesar los datos", + "networkErrorUnauthenticated": "El usuario debe autenticarse para obtener la respuesta solicitada", + "networkErrorUnauthorizedRequest": "Solicitud no autorizada", + "networkErrorUnexpectedError": "Ha habido un error inesperado", + "networkErrorNotFound": "No encontrado", + "active": "Activo", + "expired": "Caducado", + "revoked": "Revocado", + "ok": "ACEPTAR", + "unavailable_feature_title": "Función no disponible", + "unavailable_feature_message": "Función no disponible en el navegador", + "personalSkip": "OMITIR", + "restoreCredential": "Restablecer credenciales", + "backupCredential": "Hacer copia de respaldo de credenciales", + "backupCredentialPhrase": "Escriba las palabras, descargue el archivo de copia de respaldo y guárdelo seguro", + "backupCredentialPhraseExplanation": "Para hacer una copia de respaldo de credenciales, escriba su frase de recuperación y guárdela segura.", + "backupCredentialButtonTitle": "Guardar el archivo", + "backupPolygonIdCredentialEmptyError": "No tiene ninguna credencial de Polygon ID en su cartera.", + "needStoragePermission": "Necesita permiso de almacenamiento para descargar el archivo.", + "backupCredentialNotificationTitle": "Sin errores", + "backupCredentialNotificationMessage": "Archivo descargado. Toque para abrir el archivo.", + "backupCredentialError": "Ha habido un problema. Inténtelo más tarde.", + "backupCredentialSuccessMessage": "Archivo descargado.", + "restorationCredentialWarningDialogSubtitle": "Si restablece, se borrarán todas las credenciales que tiene en la cartera.", + "recoveryCredentialPhrase": "Escriba las palabras y cargue el archivo de copia de respaldo si lo ha guardado", + "recoveryCredentialPhraseExplanation": "Si pierde sus credenciales, necesitará ambas palabras en orden correcto y un archivo de copia de respaldo cifrado para recuperarlas", + "recoveryCredentialButtonTitle": "Cargar archivo de copia de respaldo", + "recoveryCredentialSuccessMessage": "Se ha(n) recuperado {postfix}.", + "recoveryCredentialJSONFormatErrorMessage": "Cargue el archivo válido.", + "recoveryCredentialAuthErrorMessage": "Frase mnemotécnica incorrecta o archivo cargado dañado.", + "recoveryCredentialDefaultErrorMessage": "Ha habido un problema. Inténtelo más tarde.", + "@recoveryCredentialSuccessMessage": { + "description": "Número de mensajes sin errores", + "type": "text", + "placeholders": { + "postfix": {} + } + }, + "selfIssuedCreatedSuccessfully": "Credencial autoemitida creada", + "companyWebsite": "Sitio web de la empresa", + "submit": "Enviar", + "insertYourDIDKey": "Inserte su DID", + "importYourRSAKeyJsonFile": "Importe su archivo json de clave RSA", + "didKeyAndRSAKeyVerifiedSuccessfully": "Las claves DID y RSA se han verificado", + "pleaseEnterYourDIDKey": "Escriba su DID", + "pleaseImportYourRSAKey": "Importe su clave RSA", + "confirm": "Confirmar", + "pleaseSelectRSAKeyFileWithJsonExtension": "Seleccione el archivo de clave RSA (extensión json)", + "rsaNotMatchedWithDIDKey": "La clave RSA no coincide con el DID", + "didKeyNotResolved": "DID no resuelto", + "anUnknownErrorHappened": "Ha habido un error inesperado", + "walletType": "Tipo de cartera", + "chooseYourWalletType": "Elija el tipo de cartera", + "proceed": "Continuar", + "enterpriseWallet": "Cartera de empresa", + "personalWallet": "Cartera personal", + "failedToVerifySelfIssuedCredential": "Error al verificar la credencial autoemitida", + "failedToCreateSelfIssuedCredential": "Error al crear la credencial autoemitida", + "credentialVerificationReturnWarning": "Al verificar la credencial, se han activado avisos. ", + "failedToVerifyCredential": "Error al verificar la credencial.", + "somethingsWentWrongTryAgainLater": "Ha habido un problema, inténtelo más tarde. ", + "successfullyPresentedYourCredential": "¡Se han presentado su(s) credencial(es)!", + "successfullyPresentedYourDID": "¡Se ha presentado su DID!", + "thisQRCodeIsNotSupported": "Este código QR no es compatible.", + "thisUrlDoseNotContainAValidMessage": "Esta URL no contiene un mensaje válido.", + "anErrorOccurredWhileConnectingToTheServer": "Ha habido un error al conectar con el servidor.", + "failedToSaveMnemonicPleaseTryAgain": "Error al guardar la frase mnemotécnica, reinténtelo", + "failedToLoadProfile": "Error al cargar el perfil. ", + "failedToSaveProfile": "Error al guardar el perfil. ", + "failedToLoadDID": "Error al cargar el DID. ", + "personalOpenIdRestrictionMessage": "Cartera personal sin acceso.", + "credentialEmptyError": "No tiene ninguna credencial en su cartera.", + "credentialPresentTitleSiopV2": "Presentar credencial", + "confirmSiopV2": "Confirme la credencial presentada", + "storagePermissionRequired": "Permiso de almacenamiento requerido", + "storagePermissionDeniedMessage": "Conceda acceso de almacenamiento para cargar el archivo.", + "storagePermissionPermanentlyDeniedMessage": "Permiso de almacenamiento necesario para cargar el archivo. Permita el acceso de almacenamiento en configuración de la aplicación.", + "cancel": "Cancelar", + "loading": "Espere un momento...", + "issuerWebsitesTitle": "Obtener credenciales", + "getCredentialTitle": "Obtener credenciales", + "participantCredential": "Pase Gaia-X", + "phonePassCredential": "Prueba de teléfono", + "emailPassCredential": "Prueba de email", + "needEmailPass": "Primero necesita obtener una prueba de email", + "signature": "Firma", + "proof": "Prueba", + "verifyMe": "Verificarme", + "yes": "Sí", + "no": "No", + "credentialAlias": "Alias de credencial", + "verificationStatus": "Estado de verificación", + "cardsPending": "Tarjeta pendiente", + "cardsActive": "Tarjeta activa", + "cardsProblem": "Problema de tarjeta", + "unableToProcessTheData": "No se pueden procesar los datos", + "unimplementedQueryType": "Tipo de consulta no implementado", + "onSubmittedPassBasePopUp": "Recibirá un email", + "myCollection": "Mi colección", + "items": "elementos", + "succesfullyUpdated": "Actualizado.", + "generate": "Generar", + "myAssets": "Mis activos", + "search": "Buscar", + "professional": "Profesional", + "splashSubtitle": "Tenga su propia identidad digital y activos digitales.", + "poweredBy": "Con tecnología de", + "splashLoading": "Cargando...", + "version": "Versión", + "cards": "Tarjetas", + "nfts": "NFT", + "coins": "Monedas", + "getCards": "Obtener credenciales", + "close": "Cerrar", + "profile": "Perfil", + "infos": "Información", + "save": "Guardar", + "delete": "Eliminar", + "enterNewPinCode": "Cree un código PIN\npara proteger su cartera", + "confirmYourPinCode": "Confirme su código PIN", + "walletAltme": "Cartera Altme", + "createPersonalWallet": "Crear cartera personal", + "createTitle": "Crear o importar una cartera", + "createSubtitle": "¿Desea crear una nueva cartera o importar una existente?", + "enterYourPinCode": "Escriba su código PIN", + "changePinCode": "Cambiar código PIN", + "tryAgain": "Intentarlo de nuevo", + "credentialSelectionListEmptyError": "No tiene la credencial requerida para continuar.", + "trustedIssuer": "El emisor está aprobado por EBSI.", + "yourPinCodeChangedSuccessfully": "Se ha cambiado su código PIN", + "advantagesCards": "Tarjetas de ventajas", + "advantagesDiscoverCards": "Reciba recompensas exclusivas", + "identityCards": "Tarjetas de identidad", + "identityDiscoverCards": "Simplificar verificación de ID", + "contactInfoCredentials": "Datos de contacto", + "contactInfoDiscoverCredentials": "Verificar sus datos de contacto", + "myProfessionalCards": "Tarjetas profesionales", + "otherCards": "Otras tarjetas", + "inMyWallet": "En mi cartera", + "details": "Detalles", + "getIt": "Obtener", + "getItNow": "Obtener ahora", + "getThisCard": "Obtener esta tarjeta", + "drawerBiometrics": "Autenticación biométrica", + "drawerTalaoCommunityCard": "Tarjeta de Comunidad de Talao", + "drawerTalaoCommunityCardTitle": "Importe su dirección de Ethereum y reciba su Tarjeta de Comunidad.", + "drawerTalaoCommunityCardSubtitle": "Acceda a los mejores descuentos, programas de afiliación y tarjetas de vales de nuestro ecosistema de socios.", + "drawerTalaoCommunityCardTextBoxMessage": "Tras escribir su clave privada, toque Importar.\nAsegúrese de escribir la clave privada de Ethereum con su token de Talao.", + "drawerTalaoCommunityCardSubtitle2": "La cartera es de autocustodia. Nunca accedemos a sus claves privadas o fondos.", + "drawerTalaoCommunityCardKeyError": "Escriba una clave privada válida", + "loginWithBiometricsMessage": "Desbloquee rápido su cartera sin contraseña ni código PIN", + "manage": "Administrar", + "wallet": "Cartera", + "manageAccounts": "Administrar cuentas de blockchain", + "blockchainAccounts": "Cuentas de blockchain", + "educationCredentials": "Credenciales de formación", + "educationDiscoverCredentials": "Verifique su trayectoria académica", + "educationCredentialsDiscoverSubtitle": "Obtenga su diploma digital (EBSI)", + "security": "Seguridad", + "networkAndRegistries": "Red y registros", + "chooseNetwork": "Elegir red", + "chooseRegistry": "Elegir registro", + "trustFramework": "Marco de confianza", + "network": "Red", + "issuerRegistry": "Registro de emisor", + "termsOfUse": "Términos de uso y confidencialidad", + "scanFingerprintToAuthenticate": "Escanear huella dactilar para autenticarse", + "biometricsNotSupported": "Biometría no compatible", + "deviceDoNotSupportBiometricsAuthentication": "Su dispositivo no admite autenticación biométrica", + "biometricsEnabledMessage": "Ya puede desbloquear la aplicación con sus biometría.", + "biometricsDisabledMessage": "Se ha desactivado su biometría.", + "exportSecretKey": "Exportar clave secreta", + "secretKey": "Clave secreta", + "chooseNetWork": "Elegir red", + "nftEmptyMessage": "¡Su galería digital está vacía!", + "myAccount": "Mi cuenta", + "cryptoAccounts": "Cuentas", + "cryptoAccount": "Cuenta", + "cryptoAddAccount": "Añadir cuenta", + "cryptoAddedMessage": "Su cuenta de criptomonedas se ha añadido.", + "cryptoEditConfirmationDialog": "¿Confirma editar el nombre de cuenta de criptomonedas?", + "cryptoEditConfirmationDialogYes": "Guardar", + "cryptoEditConfirmationDialogNo": "Cancelar", + "cryptoEditLabel": "Nombre de cuenta", + "onBoardingFirstTitle": "Descubra 3 ofertas web exclusivas en su cartera.", + "onBoardingFirstSubtitle": "Obtenga tarjetas de afiliación y fidelización, vales y muchas ventajas de sus aplicaciones y juegos favoritos.", + "onBoardingSecondTitle": "Nuestra cartera es mucho más que una cartera digital.", + "onBoardingSecondSubtitle": "Almacene y administre datos personales y acceda a cualquier aplicación de la web 3.0.", + "onBoardingThirdTitle": "Gestione sus datos con autonomía, seguridad y privacidad.", + "onBoardingThirdSubtitle": "La cartera usa criptografía SSI para ofrecerle un control de datos total. Nada saldrá fuera de su teléfono.", + "onBoardingStart": "Empezar", + "learnMoreAboutAltme": "Descubra más sobre nuestra cartera", + "scroll": "Desplazarse", + "agreeTermsAndConditionCheckBox": "Acepto los términos y condiciones.", + "readTermsOfUseCheckBox": "He leído los términos de uso.", + "createOrImportNewAccount": "Crear o importar una nueva cuenta.", + "selectAccount": "Seleccionar cuenta", + "onbordingSeedPhrase": "Frase semilla", + "onboardingPleaseStoreMessage": "Escriba su frase de recuperación", + "onboardingVerifyPhraseMessage": "Confirmar palabras de recuperación", + "onboardingVerifyPhraseMessageDetails": "Para comprobar que su frase de recuperación esté bien, seleccione las palabras en orden correcto.", + "onboardingAltmeMessage": "La cartera es sin custodia. La frase de recuperación es la única forma de recuperar su cuenta.", + "onboardingWroteDownMessage": "He escrito una frase de recuperación", + "copyToClipboard": "Copiar en el portapapeles", + "pinCodeMessage": "El código PIN impide el acceso no autorizado a su cartera. Puede cambiarlo en cualquier momento.", + "enterNameForYourNewAccount": "Escriba un nombre para su nueva cuenta", + "create": "Crear", + "import": "Importar", + "accountName": "Nombre de cuenta", + "importWalletText": "Escriba aquí su frase de recuperación o clave privada.", + "importWalletTextRecoveryPhraseOnly": "Escriba aquí su frase de recuperación.", + "recoveryPhraseDescriptions": "Una frase de recuperación (o frase semilla, clave privada o frase de copia de respaldo) es una lista de 12 palabras generadas por su cartera de criptomonedas para acceder a sus fondos", + "importEasilyFrom": "Importar su contraseña desde:", + "templeWallet": "Cartera de Temple", + "temple": "Temple", + "metaMaskWallet": "Cartera de Metamask", + "metaMask": "Metamask", + "kukai": "Kukai", + "kukaiWallet": "Cartera de Kukai", + "other": "Otra", + "otherWalletApp": "Otra aplicación de cartera", + "importWalletHintText": "Tras escribir sus 12 palabras (frase de recuperación) o {numberCharacters} caracteres privados (clave privada), toque Importar.", + "@importWalletHintText": { + "description": "texto de sugerencia al importar una cuenta adicional", + "type": "text", + "placeholders": { + "numberCharacters": {} + } + }, + "importWalletHintTextRecoveryPhraseOnly": "Tras escribir sus 12 palabras (frase de recuperación), toque Importar.", + "kycDialogTitle": "Para obtener esta tarjeta y otras tarjetas de identidad, verifique su ID", + "idVerificationProcess": "Proceso de verificación de ID", + "idCheck": "Comprobación de ID", + "facialRecognition": "Reconocimiento facial", + "kycDialogButton": "Iniciar verificación de ID", + "kycDialogFooter": "Conforme al RGPD y la CCPA + nivel de seguridad SOC2", + "finishedVerificationTitle": "Verificación de ID en\ncurso", + "finishedVerificationDescription": "Recibirá un email para confirmar que su ID se ha verificado", + "verificationPendingTitle": "Su verificación de ID\nestá pendiente", + "verificationPendingDescription": "En general, tarda menos de 5 minutos en verificarse. Recibirá un email una vez terminada la verificación.", + "verificationDeclinedTitle": "Se ha rechazado su verificación", + "restartVerification": "Reiniciar verificación de ID", + "verificationDeclinedDescription": "Se ha rechazado su verificación. Reinicie su verificación de ID.", + "verifiedTitle": "¡Excelente! La verificación se ha realizado.", + "verifiedDescription": "Ya puede empezar a añadir su tarjeta 'over18'. Vamos a empezar.", + "verfiedButton": "Añadiendo la tarjeta de más de 18 años", + "verifiedNotificationTitle": "¡Verificación completada!", + "verifiedNotificationDescription": "¡Enhorabuena! Verificación realizada.", + "showDecentralizedID": "Mostrar identidad descentralizada", + "manageDecentralizedID": "Administrar identidad descentralizada", + "addressBook": "Libreta de direcciones", + "home": "Mi cartera", + "discover": "Descubrir", + "settings": "Configuración", + "privateKeyDescriptions": "La clave privada es un número secreto para firmar transacciones y demostrar que es titular de una dirección de blockchain. En Tezos, las claves privadas suelen tener 54 caracteres.", + "importAccount": "Importar cuenta", + "imported": "Importada", + "cardDetails": "Detalles de tarjeta", + "publicAddress": "Dirección pública", + "didKey": "Clave DID", + "export": "Exportar", + "copy": "Copiar", + "didPrivateKey": "Clave privada DID", + "reveal": "Mostrar", + "didPrivateKeyDescription": "Tenga mucho cuidado con sus claves privadas: controlan el acceso a sus datos de credenciales.", + "didPrivateKeyDescriptionAlert": "No comparta su clave privada con nadie. Esta cartera es sin custodia. Nunca se la pediremos.", + "iReadTheMessageCorrectly": "Leo bien el mensaje", + "beCareful": "Cuidado", + "decentralizedIDKey": "Clave de identidad descentralizada", + "copySecretKeyToClipboard": "¡Clave secreta copiada en el portapapeles!", + "copyDIDKeyToClipboard": "¡Clave DID copiada en el portapapeles!", + "seeAddress": "Ver dirección", + "revealPrivateKey": "Mostrar clave privada", + "share": "Compartir", + "shareWith": "Compartir con", + "copiedToClipboard": "¡Se ha copiado en el portapapeles!", + "privateKey": "Clave privada", + "decentralizedID": "Identificador descentralizado", + "did": "DID", + "accountPrivateKeyAlert": "No comparta su frase de recuperación con nadie. Esta cartera es sin custodia. Nunca se la pediremos. Si comparte su frase de recuperación, podría perder sus fondos", + "sameAccountNameError": "Este nombre de cuenta se ha usado antes, escriba uno distinto", + "unknown": "Desconocido", + "credentialManifestDescription": "Descripción", + "credentialManifestInformations": "Información", + "credentialDetailsActivity": "Actividad", + "credentialDetailsOrganisation": "Organización", + "credentialDetailsPresented": "Presentado", + "credentialDetailsOrganisationDetail": "Detalles de la organización:", + "credentialDetailsInWalletSince": "En la cartera desde", + "termsOfUseAndLicenses": "Términos de uso y licencias", + "licenses": "Licencias", + "sendTo": "Enviar a", + "next": "Siguiente", + "withdrawalInputHint": "Copiar dirección o escanear", + "amount": "Cantidad", + "amountSent": "Cantidad enviada", + "max": "Máx.", + "edit": "Editar", + "networkFee": "Tarifa de gas estimada", + "totalAmount": "Cantidad total", + "selectToken": "Seleccionar token", + "insufficientBalance": "Saldo insuficiente", + "slow": "Lento", + "average": "Medio", + "fast": "Rápido", + "changeFee": "Cambiar tarifa", + "sent": "Enviado", + "done": "Listo", + "link": "Haga clic para acceder", + "myTokens": "Mis tokens", + "tezosMainNetwork": "Red principal de Tezos", + "send": "Enviar", + "receive": "Recibir", + "recentTransactions": "Transacciones recientes", + "sendOnlyToThisAddressDescription": "Envíe únicamente {symbol} a esta dirección. Si envía otros tokens, podría perderlos para siempre.", + "@sendOnlyToThisAddressDescription": { + "description": "nombre de símbolo al mostrar la dirección en página de recepción", + "type": "text", + "placeholders": { + "symbol": {} + } + }, + "addTokens": "Añadir tokens", + "providedBy": "Suministrado por", + "issuedOn": "Emitido el", + "expirationDate": "Periodo de validez", + "connect": "Conectar", + "connection": "Conexión", + "selectAccountToGrantAccess": "Seleccione una cuenta para conceder acceso:", + "requestPersmissionTo": "Solicitar permiso para:", + "viewAccountBalanceAndNFTs": "Ver el saldo de la cuenta y los NFT", + "requestApprovalForTransaction": "Solicitar aprobación para la transacción", + "connectedWithBeacon": "Conexión con dApp realizada", + "failedToConnectWithBeacon": "Error al conectar con dApp", + "tezosNetwork": "Red de Tezos", + "confirm_sign": "Confirmar firma", + "sign": "Firmar", + "payload_to_sign": "Carga para firmar", + "signedPayload": "La carga se ha firmado.", + "failedToSignPayload": "Error al firmar la carga", + "voucher": "Vale", + "tezotopia": "Tezotopia", + "operationCompleted": "La operación solicitada ha finalizado. La transacción puede tardar unos minutos en aparecer en la cartera.", + "operationFailed": "Error al realizar la operación solicitada", + "membership": "Afiliación", + "switchNetworkMessage": "Cambie a su red a", + "fee": "Tarifa", + "addCards": "Añadir tarjetas", + "gaming": "Videojuegos", + "identity": "Identidad", + "payment": "Pago", + "socialMedia": "Redes sociales", + "advanceSettings": "Configuración avanzada", + "categories": "Categorías", + "selectCredentialCategoryWhichYouWantToShowInCredentialList": "Seleccione categorías de credenciales para mostrar en la lista de credenciales:", + "community": "Comunidad", + "tezos": "Tezos", + "rights": "Derechos", + "disconnectAndRevokeRights": "Desconectar y revocar derechos", + "revokeAllRights": "Revocar todos los derechos", + "revokeSubtitleMessage": "¿Seguro que desea revocar todos los derechos?", + "revokeAll": "Revocar todos", + "succesfullyDisconnected": "Desconexión de dApp realizada.", + "connectedApps": "dApps conectadas", + "manageConnectedApps": "Administrar dApps conectadas", + "noDappConnected": "Aún no hay ninguna dApp conectada", + "nftDetails": "Detalles de NFT", + "failedToDoOperation": "Error al realizar la operación", + "nft": "NFT", + "receiveNft": "Recibir NFT", + "sendOnlyNftToThisAddressDescription": "Envíe únicamente NFT de Tezos a esta dirección. Si envía NFT de otra red, podría perderlos para siempre.", + "beaconShareMessage": "Envíe solo Tezos (XTZ) y NFT de Tezos (estándar FA2) a esta dirección. Si envía Tezos y NFT de otras redes, podría perderlos para siempre", + "advantagesCredentialHomeSubtitle": "Disfrute de ventajas exclusivas en Web3", + "advantagesCredentialDiscoverSubtitle": "Descubra tarjetas de fidelización y pases exclusivos", + "identityCredentialHomeSubtitle": "Demuestre cosas sobre sí mismo protegiendo sus datos", + "identityCredentialDiscoverSubtitle": "Reciba KYC reutilizables y credenciales de verificación de edad", + "myProfessionalCredentialDiscoverSubtitle": "Use sus tarjetas profesionales de forma segura", + "blockchainAccountsCredentialHomeSubtitle": "Demuestre que es titular de sus cuentas de blockchain", + "educationCredentialHomeSubtitle": "Demuestre su trayectoria académica al instante", + "passCredentialHomeSubtitle": "Utilice pases exclusivos: Equipe su experiencia Web3 con todo lo necesario", + "financeCardsCredentialHomeSubtitle": "Acceda a nuevas oportunidades de inversión en Web3", + "financeCardsCredentialDiscoverSubtitle": "Reciba ventajas exclusivas de comunidades que le gustan", + "contactInfoCredentialHomeSubtitle": "Comparta sus datos de contacto al instante", + "contactInfoCredentialDiscoverSubtitle": "Obtenga credenciales fáciles de compartir", + "otherCredentialHomeSubtitle": "Otros tipos de tarjetas en su cartera", + "otherCredentialDiscoverSubtitle": "Otros tipos de tarjetas que puede añadir", + "showMore": "... Mostrar más", + "showLess": "Mostrar menos...", + "youHaveReceivedARewardOf": "Ha recibido una recompensa de", + "gotIt": "De acuerdo", + "transactionErrorBalanceTooLow": "Una operación ha intentado gastar más tokens que los del contrato", + "transactionErrorCannotPayStorageFee": "El coste de almacenamiento supera el saldo del contrato", + "transactionErrorFeeTooLow": "Costes de operación demasiado bajos", + "transactionErrorFeeTooLowForMempool": "Costes de operación demasiado bajos para mempool lleno", + "transactionErrorTxRollupBalanceTooLow": "Se ha intentado gastar un índice de ticket de un índice sin el saldo necesario", + "transactionErrorTxRollupInvalidZeroTransfer": "El importe de una transferencia debe ser superior a cero.", + "transactionErrorTxRollupUnknownAddress": "La dirección debe estar en el contexto al firmar una transferencia con ella.", + "transactionErrorInactiveChain": "Se ha intentado validar un bloque de una cadena inactiva.", + "website": "Sitio web", + "whyGetThisCard": "Por qué esta tarjeta", + "howToGetIt": "Cómo conseguirla", + "emailPassWhyGetThisCard": "Prueba que pueden requerir algunas aplicaciones/sitios web 3.0 para acceder a su servicio o sus ventajas: Tarjeta de afiliación o fidelización, recompensas, etc.", + "emailPassExpirationDate": "Esta tarjeta seguirá activa y reutilizable durante 1 AÑO.", + "emailPassHowToGetIt": "Es realmente fácil. Altme verificará que es titular de esa dirección enviándole un código por email.", + "tezotopiaMembershipWhyGetThisCard": "Esta tarjeta de afiliación ofrece reembolsos del 25 % en TODAS las transacciones de juegos de Tezotopia al comprar un Drops en tienda o emitir un NFT en Starbase.", + "tezotopiaMembershipExpirationDate": "Esta tarjeta seguirá activa y reutilizable durante 1 AÑO.", + "tezotopiaMembershipLongDescription": "Tezotopia es un juego de NFT de metaverso en tiempo real en Tezos para cosechar Tezotops, luchar por recompensas y conquistar tierras en una aventura espacial de blockchain inmersiva. Explore el metaverso, gane NFT y conquiste Tezotopia.", + "chainbornMembershipHowToGetIt": "Para obtener esta tarjeta, necesita un “Héroe” en Chainborn y una prueba de email. La tarjeta “Prueba de email” está en la sección “Discover” de Altme.", + "chainbornMembershipWhyGetThisCard": "¡Acceda en primicia a contenido exclusivo de la tienda, airdrops y más ventajas solo para miembros de Chainborn!", + "chainbornMembershipExpirationDate": "Esta tarjeta seguirá activa y reutilizable durante 1 AÑO.", + "chainbornMembershipLongDescription": "Chainborn es un juego de lucha de NFT. Use sus propios NFT como héroes y compita por botines y la gloria. Luche, gane puntos de experiencia para mejorar la fuerza y salud de su héroe y aumente el valor de sus NFT en esta cautivadora aventura en Tezos.", + "twitterHowToGetIt": "Siga los pasos en TezosProfiles https://tzprofiles.com/connect. A continuación, solicite la tarjeta “Cuenta de Twitter” en Altme. Asegúrese de firmar la transacción en TZPROFILES con la misma cuenta que usa en Altme.", + "twitterWhyGetThisCard": "La tarjeta demuestra que es titular de su cuenta de Twitter. Úsela siempre que tenga que demostrar que es titular de su cuenta de Twitter.", + "twitterExpirationDate": "Esta tarjeta seguirá activa durante 1 año.", + "twitterDummyDesc": "Demuestre que es titular de su cuenta de Twitter.", + "linkedinCardHowToGetIt": "Puede solicitar esta tarjeta tras la verificación KYC de Altme. En su perfil de LinkedIn solo se podrá acceder a información sobre su nombre y apellidos, nacionalidad y año de nacimiento.", + "linkedinCardWhyGetThisCard": "La tarjeta demuestra su identidad para su perfil de LinkedIn. Permite exportar un código QR que mostrar en el banner de su cuenta de LinkedIn. Al escanear el código QR con su cartera de Altme, cualquier persona podrá verificar que su identidad coincide con la URL de su perfil de LinkedIn y consultar su nacionalidad y año de nacimiento.", + "linkedinCardExpirationDate": "Esta tarjeta seguirá activa y reutilizable durante 1 AÑO.", + "tezotopiaMembershipHowToGetIt": "Debe presentar una prueba de que es mayor de 13 años y otra para su email.", + "over18WhyGetThisCard": "Prueba que pueden requerir algunas aplicaciones/sitios web 3.0 para acceder a su servicio o sus ventajas: Tarjeta de afiliación o fidelización, recompensas, etc.", + "over18ExpirationDate": "Esta tarjeta seguirá activa y reutilizable durante 1 AÑO.", + "over18HowToGetIt": "Puede solicitar esta tarjeta tras la verificación KYC de Altme.", + "over13WhyGetThisCard": "Prueba que pueden requerir algunas aplicaciones/sitios web 3.0 para acceder a su servicio o sus ventajas: Tarjeta de afiliación o fidelización, recompensas, etc.", + "over13ExpirationDate": "Esta tarjeta seguirá activa y reutilizable durante 1 AÑO.", + "over13HowToGetIt": "Puede solicitar esta tarjeta tras la verificación KYC de Altme.", + "over15WhyGetThisCard": "Prueba que pueden requerir algunas aplicaciones/sitios web 3.0 para acceder a su servicio o sus ventajas: Tarjeta de afiliación o fidelización, recompensas, etc.", + "over15ExpirationDate": "Esta tarjeta seguirá activa y reutilizable durante 1 AÑO.", + "over15HowToGetIt": "Puede solicitar esta tarjeta tras la verificación KYC de Altme.", + "passportFootprintWhyGetThisCard": "Prueba que pueden requerir algunas aplicaciones/sitios web 3.0 para acceder a su servicio o sus ventajas: Tarjeta de afiliación o fidelización, recompensas, etc.", + "passportFootprintExpirationDate": "Esta tarjeta seguirá activa y reutilizable durante 1 AÑO.", + "passportFootprintHowToGetIt": "Puede solicitar esta tarjeta tras la verificación KYC de Altme.", + "verifiableIdCardWhyGetThisCard": "Esta tarjeta de identidad digital contiene la misma información que su carné de identidad físico. Ej.: Puede usarla en Web 3 para una verificación KYC.", + "verifiableIdCardExpirationDate": "Esta tarjeta seguirá activa y reutilizable durante 1 AÑO.", + "verifiableIdCardHowToGetIt": "Puede solicitar esta tarjeta tras la verificación KYC de Altme.", + "verifiableIdCardDummyDesc": "Consiga su documento de identidad digital.", + "phoneProofWhyGetThisCard": "Prueba que pueden requerir algunas aplicaciones/sitios web 3.0 para acceder a su servicio o sus ventajas: Tarjeta de afiliación o fidelización, recompensas, etc.", + "phoneProofExpirationDate": "Esta tarjeta seguirá activa y reutilizable durante 1 AÑO.", + "phoneProofHowToGetIt": "Es realmente fácil. Altme verificará que es titular de ese n.º de teléfono con un código por sms.", + "tezVoucherWhyGetThisCard": "La tarjeta de vales le ofrece reembolsos del 10 % en TODAS las transacciones de juegos de Tezotopia al comprar un Drops en tienda o emitir un NFT en Starbase.", + "tezVoucherExpirationDate": "Esta tarjeta seguirá activa y reutilizable durante 30 días.", + "tezVoucherHowToGetIt": " Es realmente fácil. Puede solicitarla gratis ahora.", + "genderWhyGetThisCard": "Esta prueba de género demuestra su género (masculino/femenino) sin revelar ningún dato personal más. Puede usarse en una encuesta de usuario, etc.", + "genderExpirationDate": "Esta tarjeta seguirá activa y reutilizable durante 1 AÑO.", + "genderHowToGetIt": "Puede solicitar esta tarjeta tras la verificación KYC de Altme.", + "nationalityWhyGetThisCard": "Esta credencial es útil para demostrar su nacionalidad sin revelar ningún dato personal más. Pueden requerirla aplicaciones Web 3 en encuesta de usuario, etc.", + "nationalityExpirationDate": "Esta tarjeta seguirá activa y reutilizable durante 1 AÑO.", + "nationalityHowToGetIt": "Puede solicitar esta tarjeta tras la verificación KYC de Altme.", + "ageRangeWhyGetThisCard": "Esta credencial demuestra su grupo de edad sin revelar ningún dato personal más. Pueden requerirla aplicaciones Web 3 en encuesta de usuario para solicitar ventajas: Tarjeta de afiliación, etc.", + "ageRangeExpirationDate": "Esta tarjeta seguirá activa y reutilizable durante 1 AÑO.", + "ageRangeHowToGetIt": "Puede solicitar esta tarjeta tras la verificación KYC de Altme.", + "defiComplianceWhyGetThisCard": "Obtenga pruebas verificables de cumplimiento de KYC/AML para protocolos DeFi y dApps Web 3 conformes. Tras su obtención, puede emitir un NFT intransferible y que proteja la privacidad para verificación en cadena sin revelar datos personales.", + "defiComplianceExpirationDate": "Esta credencial sigue activa durante 3 meses. La renovación requiere una verificación de cumplimiento sencilla, sin un nuevo KYC.", + "defiComplianceHowToGetIt": "¡Es fácil! Haga una verificación KYC única en la cartera de Altme (ID360) y solicite su credencial de cumplimiento DeFi.", + "rewardDialogTitle": "¡Fantástico 🥳!", + "rewardDialogDescPart1": "Acaba de recibir", + "rewardDialogDescPart2": "en su cuenta", + "origin": "Origen", + "nftTooBigToLoad": "El NFT es demasiado grande para cargarse", + "seeTransaction": "Ver transacción", + "nftListSubtitle": "Estos son todos los NFT y coleccionables de su cuenta.", + "tokenListSubtitle": "Estos son todos los tokens de su cuenta.", + "my": "Mi", + "get": "Obtener", + "seeMoreNFTInformationOn": "Ver más información de NFT sobre", + "credentialStatus": "Estado", + "pass": "Pase", + "payloadFormatErrorMessage": "El formato de carga es incorrecto.", + "thisFeatureIsNotSupportedMessage": "La función no es compatible aún", + "myWallet": "Mi cartera", + "ethereumNetwork": "Red Ethereum", + "fantomNetwork": "Red Fantom", + "polygonNetwork": "Red Polygon", + "binanceNetwork": "Red BNB Chain", + "step": "Paso", + "activateBiometricsTitle": "Activar biometría\npara añadir una capa de seguridad", + "loginWithBiometricsOnBoarding": "Iniciar sesión con biometría", + "option": "Opción", + "start": "Empezar", + "iAgreeToThe": "Acepto los ", + "termsAndConditions": "Términos y condiciones", + "walletReadyTitle": "¡Su cartera está lista!", + "walletReadySubtitle": "Vamos a descubrir todo lo que \nofrece la Web 3.", + "failedToInitCamera": "¡Error al inicializar la cámara!", + "chooseMethodPageOver18Title": "Elija un método para obtener su prueba Mayor de 18 años", + "chooseMethodPageOver13Title": "Elija un método para obtener su prueba Mayor de 13 años", + "chooseMethodPageOver15Title": "Elija un método para obtener su prueba Mayor de 15 años", + "chooseMethodPageOver21Title": "Elija un método para obtener su prueba Mayor de 21 años", + "chooseMethodPageOver50Title": "Elija un método para obtener su prueba Mayor de 50 años", + "chooseMethodPageOver65Title": "Elija un método para obtener su prueba Mayor de 65 años", + "chooseMethodPageAgeRangeTitle": "Elija un método para obtener su prueba de grupo de edad", + "chooseMethodPageVerifiableIdTitle": "Elija un método para obtener su prueba de ID verificable", + "chooseMethodPageDefiComplianceTitle": "Elija un método para obtener su prueba de cumplimiento DeFi", + "chooseMethodPageSubtitle": "Verifíquese con una foto en tiempo real o una comprobación de carné de identidad clásica.", + "kycTitle": "Foto rápida personal (1 min)", + "kycSubtitle": "Verifíquese al instante con una foto.", + "passbaseTitle": "Comprobación de carné de identidad completa", + "passbaseSubtitle": "Verifíquese con el pasaporte o su carné de identidad o de conducir", + "verifyYourAge": "Verifique su edad", + "verifyYourAgeSubtitle": "Este proceso de verificación de edad es muy sencillo. Solo necesita una foto en tiempo real.", + "verifyYourAgeDescription": "Al aceptar, nos autoriza a usar una imagen para estimar su edad. Nuestro socio Yoti hará la estimación. Solo usará su imagen para ello y la eliminará justo después.\n\nPara descubrir más, lea nuestra Política de privacidad.", + "accept": "Aceptar", + "decline": "Rechazar", + "yotiCameraAppbarTitle": "Sitúe el rostro en el centro.", + "cameraSubtitle": "Tiene 5 segundos para hacerse la foto.\nAntes de comenzar, asegúrese de que hay suficiente luz.", + "walletSecurity": "Wallet Security", + "walletSecurityDescription": "Proteja su cartera con código PIN y autenticación biométrica", + "blockchainSettings": "Configuración de blockchain", + "blockchainSettingsDescription": "Administrar cuentas, frase de recuperación, dApps y redes conectadas", + "ssi": "Identidad autosoberana (DID)", + "ssiDescription": "Gestione su identidad descentralizada, haga una copia de respaldo o restablezca sus credenciales", + "helpCenter": "Centro de ayuda", + "helpCenterDescription": "Contacte con nosotros y solicite ayuda para nuestra cartera si lo necesita", + "about": "Acerca de", + "aboutDescription": "Lea sobre términos de uso, confidencialidad y licencias", + "resetWallet": "Restablecer Cartera", + "resetWalletDescription": "Borre todos los datos de su teléfono y reinicie su cartera.", + "showWalletRecoveryPhrase": "Mostrar frase de recuperación de cartera", + "showWalletRecoveryPhraseSubtitle": "La frase de recuperación sirve de clave de copia de respaldo para recuperar el acceso a su cartera.", + "blockchainNetwork": "Red de blockchain (de forma predeterminada)", + "contactUs": "Póngase en contacto con nosotros", + "officialWebsite": "Sitio web oficial", + "yourAppVersion": "Su versión de la aplicación", + "resetWalletTitle": "¿Seguro que desea restablecer su cartera?", + "resetWalletSubtitle": "A hacerlo, se borrarán todos sus datos. Guarde su frase de recuperación y el archivo de copia de respaldo de credenciales antes de eliminar.", + "resetWalletSubtitle2": "Esta cartera es de autocustodia; no podemos recuperar sus fondos o credenciales por usted.", + "resetWalletCheckBox1": "He escrito una frase de recuperación", + "resetWalletCheckBox2": "Guardé el archivo de copia de respaldo de credenciales", + "email": "Email", + "fillingThisFieldIsMandatory": "Es obligatorio rellenar este campo.", + "yourMessage": "Su mensaje", + "message": "Mensaje", + "subject": "Asunto", + "enterAValidEmail": "Escriba un email válido.", + "failedToSendEmail": "Error al enviar el email.", + "selectAMethodToAddAccount": "Seleccione un método para añadir la cuenta", + "createAccount": "Crear cuenta", + "createAccountDescription": "Crear una cuenta protegida por su frase de recuperación", + "importAccountDescription": "Importar una cuenta desde una cartera existente", + "chooseABlockchainForAccountCreation": "Elija la blockchain en la que desea crear una nueva cuenta.", + "tezosAccount": "Cuenta de Tezos", + "tezosAccountDescription": "Crear una nueva dirección de blockchain de Tezos", + "ethereumAccount": "Cuenta de Ethereum", + "ethereumAccountDescription": "Crear una nueva dirección de blockchain de Ethereum", + "fantomAccount": "Cuenta de Fantom", + "fantomAccountDescription": "Crear una nueva dirección de blockchain de Fantom", + "polygonAccount": "Cuenta de Polygon", + "polygonAccountDescription": "Crear una nueva dirección de blockchain de Polygon", + "binanceAccount": "Cuenta de BNB Chain", + "binanceAccountDescription": "Crear una nueva dirección de blockchain de BNB Chain", + "setAccountNameDescription": "¿Quiere ponerle un nombre a esta nueva cuenta? Esto resulta útil si tiene varias.", + "letsGo": "¡Vamos allá!", + "congratulations": "¡Enhorabuena!", + "tezosAccountCreationCongratulations": "Su nueva cuenta de Tezos se ha creado.", + "ethereumAccountCreationCongratulations": "Su nueva cuenta de Ethereum se ha creado.", + "fantomAccountCreationCongratulations": "Su nueva cuenta de Fantom se ha creado.", + "polygonAccountCreationCongratulations": "Su nueva cuenta de Polygon se ha creado.", + "binanceAccountCreationCongratulations": "Su nueva cuenta de BNB Chain se ha creado.", + "accountImportCongratulations": "Su cuenta se ha importado.", + "saveBackupCredentialTitle": "Descargue el archivo de copia de respaldo.\nGuárdelo en un lugar seguro.", + "saveBackupCredentialSubtitle": "Para recuperar todas sus credenciales, necesita la frase de recuperación Y este archivo de copia de respaldo.", + "saveBackupPolygonCredentialSubtitle": "Para recuperar todas sus credenciales de Polygon ID, necesita la frase de recuperación Y el archivo de copia de respaldo.", + "restoreCredentialStep1Title": "Paso 1: Escriba las 12 palabras de su frase de recuperación", + "restorePhraseTextFieldHint": "Escriba su frase de recuperación (o frase mnemotécnica)...", + "restoreCredentialStep2Title": "Paso 2: Cargue su archivo de copia de respaldo de credenciales", + "loadFile": "Cargar archivo", + "uploadFile": "Cargar archivo", + "creators": "Creadores", + "publishers": "Editores", + "creationDate": "Fecha de creación", + "myProfessionalrCards": "tarjetas profesionales", + "myProfessionalrCardsSubtitle": "Use sus tarjetas profesionales de forma segura.", + "guardaWallet": "Cartera Guarda", + "exodusWallet": "Cartera Exodus", + "trustWallet": "Cartera Trust", + "myetherwallet": "Cartera MyEther", + "skip": "Omitir", + "userNotFitErrorMessage": "No puede obtener esta tarjeta: no se cumplen algunas condiciones.", + "youAreMissing": "Le faltan", + "credentialsRequestedBy": "credenciales solicitadas por", + "transactionIsLikelyToFail": "Es probable que falle la transacción.", + "buy": "Comprar", + "thisFeatureIsNotSupportedYetForFantom": "Esta función no es compatible aún para Fantom.", + "thisFeatureIsNotSupportedYetForBinance": "Esta función no es compatible aún para BNB Chain.", + "faqs": "Preguntas frecuentes (P+F)", + "softwareLicenses": "Licencias de software", + "notAValidWalletAddress": "¡No es una dirección de cartera válida!", + "otherAccount": "Otra cuenta", + "thereIsNoAccountInYourWallet": "No hay ninguna cuenta en su cartera", + "exportToLinkedIn": "Exportar a LinkedIn", + "addLinkedInInfo": "Añadir información de LinkedIn", + "whatsYourLinkedinProfileUrl": "¿Cuál es la URL de su perfil de LinkedIn?", + "invalidUrlError": "Escriba una URL de LinkedIn válida", + "linkedInBannerSuccessfullyExported": "Su banner de LinkedIn se ha exportado.", + "credentialSuccessfullyExported": "Su credencial se ha exportado.", + "linkedInBanner": "Banner de LinkedIn", + "linkedInProfile": "Perfil de LinkedIn", + "checkLinkedinProfile": "Comprobar un perfil de LinkedIn", + "scanAndDisplay": "Escanear y mostrar", + "whatsNew": "Novedades", + "okGotIt": "¡DE ACUERDO!", + "support": "asistencia", + "transactionDoneDialogDescription": "La transferencia puede tardar unos minutos en realizarse", + "withdrawalFailedMessage": "No ha sido posible efectuar la retirada de la cuenta", + "credentialRequiredMessage": "Necesita esas credenciales en su cartera para adquirir esta tarjeta:", + "keyDecentralizedIdEdSA": "Identidad descentralizada de llave EdDSA", + "keyDecentralizedIDSecp256k1": "Identidad descentralizada de llave Secp256k1", + "polygonIdDecentralizedId": "Identidad descentralizada de Polygon", + "ebsiV3DecentralizedId": "Identidad descentralizada de EBSI V3", + "requiredCredentialNotFoundTitle": "No se encuentra la credencial\nque necesita en su cartera.", + "requiredCredentialNotFoundSubTitle": "La credencial requerida no está en su cartera", + "requiredCredentialNotFoundDescription": "Póngase en contacto con nosotros en:", + "backToHome": "Volver al inicio", + "help": "Ayuda", + "searchCredentials": "Buscar credenciales", + "supportChatWelcomeMessage": "¡Bienvenido/a a nuestra asistencia por chat! Estamos aquí para ayudarle con cualquier duda o problema sobre nuestra cartera.", + "cardChatWelcomeMessage": "¡Bienvenido/a a nuestra asistencia por chat! Estamos aquí para ayudarle con cualquier duda o problema.", + "creator": "Creador", + "contractAddress": "Dirección de contrato", + "lastMetadataSync": "Última sincronización de metadatos", + "e2eEncyptedChat": "El chat está cifrado de extremo a extremo.", + "pincodeAttemptMessage": "Ha introducido un código PIN incorrecto tres veces. Por motivos de seguridad, espere un minuto antes de volverlo a intentar.", + "verifyNow": "Verificar ahora", + "verifyLater": "Verificar más tarde", + "welDone": "¡Excelente!", + "mnemonicsVerifiedMessage": "Su frase de recuperación se ha guardado.", + "chatWith": "Chatear con", + "sendAnEmail": "Enviar un email", + "livenessCardHowToGetIt": "¡Es fácil! Haga una verificación KYC única en la cartera de Altme (ID360) y solicite su credencial de Liveness.", + "livenessCardExpirationDate": "Esta credencial seguirá activa durante 1 año. La renovación es sencilla.", + "livenessCardWhyGetThisCard": "Obtenga pruebas verificables de humanidad para la mayoría de DeFi, protocolos GameFi y dApps Web3. Tras su obtención, puede emitir un NFT intransferible y que proteja la privacidad para verificación en cadena sin revelar datos personales.", + "livenessCardLongDescription": "La credencial es una prueba verificable de humanidad. Permite demostrar que no es un bot en protocolos DeFi, juegos en cadena o dApps Web3.", + "chat": "Chatear", + "polygonDecentralizedID": "Identidad descentralizada de Polygon", + "needMnemonicVerificatinoDescription": "¡Verifique las frases semilla de su cartera para proteger sus activos!", + "succesfullyAuthenticated": "Se ha autenticado.", + "authenticationFailed": "Error al autenticar.", + "documentType": "Tipo de documento", + "countryCode": "Código de país", + "deviceIncompatibilityMessage": "Su dispositivo no es compatible con esta función.", + "tezosProofMessage": "", + "ethereumProofMessage": "", + "fantomProofMessage": "", + "polygonProofMessage": "", + "binanceProofMessage": "", + "yearsOld": "años", + "youAreOver13": "Tiene más de 13 años", + "youAreOver15": "Tiene más de 15 años", + "youAreOver18": "Tiene más de 18 años", + "youAreOver21": "Tiene más de 21 años", + "youAreOver50": "Tiene más de 50 años", + "youAreOver65": "Tiene más de 65 años", + "polygon": "Polygon", + "ebsi": "EBSI", + "backupPolygonIdIdentity": "Hacer copia de respaldo de ID de Polygon ID", + "restorePolygonIdCredentials": "Restablecer credenciales de Polygon ID", + "comingSoon": "Próximamente", + "financeCredentialsHomeTitle": "Mis credenciales financieras", + "financeCredentialsDiscoverTitle": "Obtener credenciales financieras verificadas", + "financeCredentialsDiscoverSubtitle": "Acceda a nuevas oportunidades de inversión en web3.", + "financeCredentialsHomeSubtitle": "Acceda a nuevas oportunidades de inversión en Web3", + "hummanityProofCredentialsHomeTitle": "Mi prueba de humanidad", + "hummanityProofCredentialsHomeSubtitle": "Demuestra fácilmente que es un humano y no un bot.", + "hummanityProofCredentialsDiscoverTitle": "Demuestre que no es un bot ni una IA", + "hummanityProofCredentialsDiscoverSubtitle": "Obtenga una prueba de humanidad reutilizable para compartir", + "socialMediaCredentialsHomeTitle": "Mis cuentas de redes sociales", + "socialMediaCredentialsHomeSubtitle": "Demuestre titularidad al instante en sus cuentas con la prueba de humanidad", + "socialMediaCredentialsDiscoverTitle": "Verificar sus cuentas de redes sociales", + "socialMediaCredentialsDiscoverSubtitle": "Demuestre titularidad al instante en sus cuentas cuando lo necesite", + "walletIntegrityCredentialsHomeTitle": "Integridad de cartera", + "walletIntegrityCredentialsHomeSubtitle": "TBD", + "walletIntegrityCredentialsDiscoverTitle": "Integridad de cartera", + "walletIntegrityCredentialsDiscoverSubtitle": "TBD", + "polygonCredentialsHomeTitle": "Mis credenciales de Polygon ID", + "polygonCredentialsHomeSubtitle": "Demuestre derechos de acceso en ecosistema de Polygon", + "polygonCredentialsDiscoverTitle": "Obtener credenciales de Polygon ID", + "polygonCredentialsDiscoverSubtitle": "Demuestre derechos de acceso en ecosistema de Polygon", + "pendingCredentialsHomeTitle": "Mis credenciales pendientes", + "pendingCredentialsHomeSubtitle": "Demuestre sus derechos de acceso.", + "restore": "Restablecer", + "backup": "Hacer una copia de respaldo", + "takePicture": "Hacer una foto", + "kyc": "KYC", + "aiSystemWasNotAbleToEstimateYourAge": "El sistema de IA no pudo estimar su edad", + "youGotAgeCredentials": "Ha obtenido su credencial {credential}.", + "@youGotAgeCredentials": { + "description": "la descripción para obtener las credenciales", + "placeholders": { + "credential": {} + } + }, + "yourAgeEstimationIs": "La estimación de su edad de IA es {ageEstimate} años", + "@yourAgeEstimationIs": { + "description": "", + "placeholders": { + "ageEstimate": {} + } + }, + "credentialNotFound": "Credencial no encontrada", + "cryptographicProof": "Prueba criptográfica", + "downloadingCircuitLoadingMessage": "Descargando circuitos. Esto puede tardar un poco. Espere.", + "cryptoAccountAlreadyExistMessage": "Parece haber una cuenta con esta información criptográfica", + "errorGeneratingProof": "Error al generar la prueba", + "createWalletMessage": "Primero cree su cartera.", + "successfullyGeneratingProof": "Prueba generada", + "wouldYouLikeToAcceptThisCredentialsFromThisOrganisation": "¿Desea aceptar esta(s) credencial(es) de esta organización?", + "thisOrganisationRequestsThisInformation": "Esta organización solicita esta información", + "iS": "es", + "isSmallerThan": "es menor que", + "isBiggerThan": "es mayor que", + "isOneOfTheFollowingValues": "es uno de los siguientes valores", + "isNotOneOfTheFollowingValues": "no es uno de los siguientes valores", + "isNot": "no es", + "approve": "Aprobar", + "noInformationWillBeSharedFromThisCredentialMessage": "No se compartirá información de esta credencial (Prueba de Conocimiento Cero).", + "burn": "Retirar", + "wouldYouLikeToConfirmThatYouIntendToBurnThisNFT": "¿Seguro que desea retirar este NFT?", + "pleaseAddXtoConnectToTheDapp": "Añada la cuenta {chain} para conectarse a la dApp.", + "@pleaseAddXtoConnectToTheDapp": { + "description": "", + "placeholders": { + "chain": {} + } + }, + "pleaseSwitchPolygonNetwork": "Cambie a {networkType} de Polygon para ejecutar esta acción.", + "@pleaseSwitchPolygonNetwork": { + "description": "", + "placeholders": { + "networkType": {} + } + }, + "oidc4vcProfile": "Perfil de OIDC4VC", + "pleaseSwitchToCorrectOIDC4VCProfile": "Cambie al perfil de OIDC4VC correcto.", + "authenticationSuccess": "Autenticación correcta", + "format": "Formato", + "pleaseInsertTheSecredCodeReceived": "Inserte el código secreto recibido.", + "verifyIssuerWebsiteIdentity": "Verificar la identidad del sitio web del emisor", + "verifyIssuerWebsiteIdentitySubtitle": "Predeterminado: Desactivado\nActívelo para verificar la identidad del sitio web antes de acceder.", + "developerMode": "Modo de desarrollador", + "developerModeSubtitle": "Active el modo de desarrollador para depuración avanzada", + "confirmVerifierAccess": "Confirmar acceso de verificador", + "confirmVerifierAccessSubtitle": "Predeterminado: Activado\nDesactívelo para omitir la confirmación al compartir credenciales verificables.", + "credentialManifestSupport": "Asistencia de manifiesto de credenciales", + "credentialManifestSupportSubtitle": "Predeterminado: Desactivado\nUse la sintaxis de representación de cartera de DIF en vez del atributo 'display'.", + "secureAuthenticationWithPINCode": "Proteger autenticación con código PIN", + "secureAuthenticationWithPINCodeSubtitle": "Predeterminado: Activado\nDesactívelo para omitir código PIN para autenticación del sitio web (no recomendado).", + "youcanSelectOnlyXCredential": "Solo puede seleccionar {count} credencial(es).", + "@youcanSelectOnlyXCredential": { + "description": "", + "placeholders": { + "count": {} + } + }, + "theCredentialIsNotReady": "La credencial no está lista.", + "theCredentialIsNoMoreReady": "La credencial ya no está disponible.", + "lowSecurity": "Seguridad baja", + "highSecurity": "Seguridad alta", + "theRequestIsRejected": "Se ha rechazado la solicitud.", + "userPinIsIncorrect": "El PIN de usuario es incorrecto", + "security_level": "Nivel de seguridad", + "oidc4vc_settings": "Configuración de OIDC4VC", + "userPinTitle": "Flujo de dígitos del PIN de usuario pre-authorized_code", + "userPinSubtitle": "Predeterminado: 6 dígitos\nActivar para administrar el código PIN de 4 dígitos", + "securityLevelTitle": "Nivel de cartera", + "securityLevelSubTitle": "Predeterminado: Permisivo\nDefina Estricto para fortalecer controles para emisores y verificadores.", + "responseTypeNotSupported": "El tipo de respuesta no es compatible", + "invalidRequest": "La solicitud no es válida", + "subjectSyntaxTypeNotSupported": "El tipo de sintaxis de sujeto no es compatible.", + "accessDenied": "Acceso rechazado", + "thisRequestIsNotSupported": "Esta solicitud no es compatible", + "unsupportedCredential": "Credencial no compatible", + "aloginIsRequired": "Nombre de usuario requerido", + "userConsentIsRequired": "Consentimiento de usuario requerido", + "theWalletIsNotRegistered": "La cartera no está registrada", + "credentialIssuanceDenied": "Emisión de credencial rechazada", + "thisCredentialFormatIsNotSupported": "Formato de credencial no compatible", + "thisFormatIsNotSupported": "Formato no compatible", + "moreDetails": "Más detalles", + "theCredentialOfferIsInvalid": "La oferta de credencial no es válida", + "dateOfRequest": "Fecha de solicitud", + "keyDecentralizedIDP256": "Identidad descentralizada de llave P-256", + "jwkDecentralizedIDP256": "Identidad descentralizada de JWK P-256", + "defaultDid": "DID predeterminado", + "selectOneOfTheDid": "Seleccione uno de los DID", + "subjectSyntaxType": "Tipo de sintaxis de sujeto", + "enableToUseTheJWKThumprintOfTheKey": "Predeterminado: DID\nActívelo para utilizar la huella digital JWK de la llave", + "cryptographicHolderBinding": "Enlace de titular criptográfico", + "cryptographicHolderBindingSubtitle": "Predeterminado: Activado\nDesactívelo para aceptar credenciales de portador como tickets de seguridad baja.", + "scopeParameters": "Parámetros de ámbito", + "scopeParametersSubtitle": "Predeterminado: Desactivado\nActívelo para que la cartera utilice el ámbito en vez de authorization_details.", + "clientAuthenticationMethods": "Métodos de autenticación de cliente", + "clientAuthenticationMethodsSubtitle": "Predeterminado: ID de cliente como DID o JWK\nSeleccione otros métodos de autenticación si es necesario.", + "vcFormatType": "Formato VC", + "vcFormatTypeSubtitle": "Predeterminado: ldp_vc\nSeleccione uno de los formatos VC.", + "theServiceIsNotAvailable": "Este servicio no está disponible", + "issuerDID": "DID de emisor", + "subjectDID": "DID de sujeto", + "type": "Tipo", + "credentialExpired": "Credencial caducada", + "incorrectSignature": "Firma incorrecta", + "revokedOrSuspendedCredential": "Credencial revocada o suspendida", + "display": "Mostrar", + "download": "Descargar", + "successfullyDownloaded": "Descarga correcta", + "advancedSecuritySettings": "Configuración de seguridad avanzada", + "clientMetadata": "Metadatos de cartera", + "theIssuanceOfThisCredentialIsPending": "Emisión de credencial pendiente", + "clientId": "ID de cliente", + "clientSecret": "Secreto de cliente", + "walletProfiles": "Perfiles de cartera", + "walletProfilesDescription": "Elija su perfil SSI o personalice el suyo propio", + "profileCustom": "Personalizado", + "profileEbsiV3": "European Blockchain Services Infrastructure", + "decentralizedIdentityInteropProfile": "Perfil de interoperabilidad de identidad descentralizada", + "protectYourWallet": "Proteja su cartera", + "protectYourWalletMessage": "Proteja y desbloquee su cartera con su huella dactilar, rostro o el PIN de su dispositivo. Datos cifrados de forma segura en este dispositivo.", + "pinUnlock": "Desbloqueo con PIN", + "secureWithDevicePINOnly": "Proteger solo con el PIN del dispositivo", + "biometricUnlock": "Desbloqueo con biometría", + "secureWithFingerprint": "Proteger con huella dactilar", + "pinUnlockAndBiometric2FA": "Desbloqueo con PIN + biometría (2FA)", + "secureWithFingerprintAndPINBackup": "Proteger con huella dactilar y copia de respaldo PIN", + "secureYourWalletWithPINCodeAndBiometrics": "Proteger su cartera con código PIN y biometría", + "twoFactorAuthenticationHasBeenEnabled": "Autenticación en dos pasos activada.", + "createAnProfessionalWallet": "Crear cartera de empresa", + "initialization": "Inicialización", + "login": "Nombre de usuario", + "password": "Contraseña", + "pleaseEnterYourEmailAndYourCompanyPasswordToCreateYourAccount": "Escriba su email y la contraseña de su empresa para crear su cuenta", + "enterTheSecurityCodeThatWeSentYouByEmail": "Escriba el código de seguridad que le enviamos por email", + "enterTheSecurityCode": "Escriba el código de seguridad", + "yourEmail": "Su email", + "publicKeyOfWalletInstance": "Clave pública de instancia de cartera", + "walletInstanceKey": "Clave de instancia de cartera", + "protocoleStandardRelease": "Versión estándar de protocolo", + "organizationProfile": "Perfil de organización", + "profileName": "Nombre de perfil", + "companyName": "Nombre de la empresa", + "configFileIdentifier": "Identificador de archivo de configuración", + "clientCredentials": "Credenciales de cliente", + "updateYourWalletConfigNow": "Actualizar la configuración de cartera ahora", + "updateConfigurationNow": "Actualizar la configuración ahora", + "pleaseEnterYourEmailAndPasswordToUpdateYourOrganizationWalletConfiguration": "Escriba su email y contraseña para actualizar la configuración de cartera de su organización", + "congrats": "¡Enhorabuena!", + "yourWalletConfigurationHasBeenSuccessfullyUpdated": "Configuración de cartera actualizada", + "continueString": "Continuar", + "walletProvider": "Proveedor de cartera" } \ No newline at end of file diff --git a/lib/l10n/arb/app_fr.arb b/lib/l10n/arb/app_fr.arb index fac41546d..af9274421 100644 --- a/lib/l10n/arb/app_fr.arb +++ b/lib/l10n/arb/app_fr.arb @@ -3,19 +3,18 @@ "genericError": "Une erreur est survenue!", "@genericError": { "description": "Message d'erreur générique", - "@@locale": "fr", "type": "text", "placeholders": {} }, "credentialListTitle": "Identifiants", "@credentialListTitle": { - "description": "Titre de la page Liste des informations d'identification", + "description": "Titre de la page Liste des documents numériques", "type": "text", "placeholders": {} }, "credentialDetailIssuedBy": "Émis par {issuer}", "@credentialDetailIssuedBy": { - "description": "Émetteur d'informations d'identification sur la page de détail", + "description": "Détail de l'émetteur du document numérique", "type": "text", "placeholders": { "issuer": {} @@ -23,19 +22,19 @@ }, "listActionRefresh": "Rafraîchir", "@listActionRefresh": { - "description": "Bouton d'action de liste pour actualiser le contenu", + "description": "Bouton d'actualisation du contenu de la liste", "type": "text", "placeholders": {} }, "listActionViewList": "Afficher sous forme de liste", "@listActionViewList": { - "description": "Bouton d'action de liste pour définir l'affichage en mode liste", + "description": "Bouton d'affichage de la page en mode liste", "type": "text", "placeholders": {} }, "listActionViewGrid": "Afficher sous forme de grille", "@listActionViewGrid": { - "description": "Bouton d'action de liste pour définir la vue en mode grille", + "description": "Bouton d'affichage de la page en mode grille", "type": "text", "placeholders": {} }, @@ -53,7 +52,7 @@ }, "onBoardingStartSubtitle": "Lorem ipsum dolor sit ame", "onBoardingTosTitle": "Conditions générales", - "onBoardingTosText": "En appuyant sur accepter \"J'accepte les termes et conditions ainsi que la divulgation de ces informations.\"", + "onBoardingTosText": "En appuyant sur accepter \"J'accepte les termes et conditions.\"", "onBoardingTosButton": "Accepter", "onBoardingRecoveryTitle": "Récupération de clé", "onBoardingRecoveryButton": "Récupérer", @@ -63,39 +62,39 @@ "onBoardingGenButton": "Générer", "onBoardingSuccessTitle": "Identifiant créé", "onBoardingSuccessButton": "Continuer", - "credentialDetailShare": "Partager par code QR", - "credentialAddedMessage": "Un nouvel identifiant a été ajouté avec succès !", + "credentialDetailShare": "Partager par QR code", + "credentialAddedMessage": "Votre nouveau document a bien été ajouté !", "credentialDetailDeleteCard": "Supprimer cette carte", - "credentialDetailDeleteConfirmationDialog": "Voulez-vous vraiment supprimer cet identifiant ?", + "credentialDetailDeleteConfirmationDialog": "Voulez-vous vraiment supprimer ce document ?", "credentialDetailDeleteConfirmationDialogYes": "Oui", "credentialDetailDeleteConfirmationDialogNo": "Non", "credentialDetailDeleteSuccessMessage": "Supprimé avec succès.", - "credentialDetailEditConfirmationDialog": "Voulez-vous vraiment modifier cet identifiant ?", + "credentialDetailEditConfirmationDialog": "Voulez-vous vraiment modifier ce document ?", "credentialDetailEditConfirmationDialogYes": "Enregistrer", "credentialDetailEditConfirmationDialogNo": "Annuler", "credentialDetailEditSuccessMessage": "Modification réussie.", "credentialDetailCopyFieldValue": "Valeur du champ copiée dans le presse-papier !", "credentialDetailStatus": "Statut de vérification", - "credentialPresentTitle": "Sélectionnez les identifiants", + "credentialPresentTitle": "Sélectionnez les documents", "credentialPresentTitleDIDAuth": "Requête DIDAuth", "credentialPresentRequiredCredential": "Quelqu'un demande votre", - "credentialPresentConfirm": "Sélectionnez les identifiants", + "credentialPresentConfirm": "Sélectionnez les documents", "credentialPresentCancel": "Rejeter", "credentialPickPresent": "Présent", - "credentialPickTitle": "Sélectionnez les identifiants", + "credentialPickTitle": "Sélectionnez les documents", "selectYourTezosAssociatedWallet": "Sélectionnez votre portefeuille associé Tezos", "credentialPickSelect": "Sélectionnez votre identifiant", - "siopV2credentialPickSelect": "Choisissez un seul identifiant de votre portefeuille à présenter", - "credentialPickAlertMessage": "Voulez-vous donner un alias à cet identifiant ?", - "credentialReceiveTitle": "Offre d'identification", - "credentialReceiveHost": "veut vous envoyer un identifiant", + "siopV2credentialPickSelect": "Choisissez un seul document à présenter", + "credentialPickAlertMessage": "Voulez-vous donner un alias à ce document ?", + "credentialReceiveTitle": "Offre de document", + "credentialReceiveHost": "veut vous envoyer un document", "credentialAddThisCard": "Ajouter cette carte", "credentialReceiveCancel": "Annuler cette carte", "credentialDetailListTitle": "Mon portefeuille", "communicationHostAllow": "Autoriser", "communicationHostDeny": "Refuser", - "scanTitle": "Scanner le code QR", - "scanPromptHost": "Avez-vous confiance en cet hôte ?", + "scanTitle": "Scanner le QR code", + "scanPromptHost": "Faites-vous confiance à ce domaine ?", "scanRefuseHost": "La demande de communication a été refusée.", "scanUnsupportedMessage": "L'URL extraite n'est pas valide.", "qrCodeSharing": "Vous partagez maintenant", @@ -103,10 +102,10 @@ "profileTitle": "Profil", "personalTitle": "Personnel", "termsTitle": "Conditions d'utilisation", - "recoveryKeyTitle": "Expression de récupération", + "recoveryKeyTitle": "Clé de récupération", "showRecoveryPhrase": "Afficher la phrase de récupération", "warningDialogTitle": "Soyez prudent", - "warningDialogSubtitle": "La page de récupération contient des informations sensibles qui pourraient compromettre votre identifiant entre de mauvaises mains. Vous ne devez pas ouvrir cette page en public ni la partager avec qui que ce soit.", + "warningDialogSubtitle": "La page de récupération contient des informations sensibles qui pourraient compromettre vos informations entre de mauvaises mains. Vous ne devez pas ouvrir cette page en public ni la partager avec qui que ce soit.", "recoveryText": "Veuillez entrer votre phrase de récupération", "recoveryMnemonicHintText": "Saisissez votre phrase de récupération ici. Une fois que vous avez saisi vos 12 mots, appuyez sur Importer.", "recoveryMnemonicError": "Veuillez entrer une phrase mnémonique valide", @@ -121,7 +120,7 @@ "darkThemeText": "Thème sombre", "systemThemeText": "Thème système", "genPhraseInstruction": "Écrivez ces mots, téléchargez le fichier de sauvegarde et conservez-les en lieu sûr", - "genPhraseExplanation": "Vous avez besoin des mots dans le bon ordre et du fichier de sauvegarde pour récupérer vos certificats, si vous perdez l'accès à ce portefeuille.", + "genPhraseExplanation": "Vous avez besoin des mots dans le bon ordre et du fichier de sauvegarde pour récupérer vos documents, si vous perdez l'accès à ce portefeuille.", "errorGeneratingKey": "Échec de la génération de la clé, veuillez réessayer", "documentHeaderTooltipName": "Jean Doe", "documentHeaderTooltipJob": "Cryptocommerçant", @@ -133,7 +132,7 @@ "didDisplayCopy": "Copier DID dans le presse-papiers", "adressDisplayCopy": "Copier l'adresse dans le presse-papiers", "personalSave": "Enregistrer", - "personalSubtitle": "Les informations de votre profil peuvent être utilisées pour compléter un certificat si nécessaire", + "personalSubtitle": "Les informations de votre profil peuvent être utilisées", "personalFirstName": "Prénom", "personalLastName": "Nom de famille", "personalPhone": "Téléphone", @@ -141,7 +140,7 @@ "personalMail": "E-mail", "lastName": "Nom de famille", "firstName": "Prenom", - "gender": "sexe H/F", + "gender": "Sexe H/F", "birthdate": "Date de naissance", "birthplace": "Lieu de naissance", "address": "Adresse", @@ -161,17 +160,17 @@ "signedBy": "Signé par", "from": "De", "to": "À", - "credential": "informations d'identification", + "credential": "Document numérique vérifiable", "issuanceDate": "Date d'émission", "appContactWebsite": "Site web", - "trustFrameworkDescription": "The trust framework is formed by a set of registries that provide a secure and reliable basis for entities within the system to trust and interact with each other.", - "confimrDIDAuth": "Voulez-vous vous connecter au site ?", + "trustFrameworkDescription": "Le cadre de confiance repose sur un ensemble de registres fiables qui permettent aux entités du système de se faire confiance et d'interagir ensemble.", + "confimrDIDAuth": "Voulez-vous vous connecter à ce site ?", "evidenceLabel": "Preuve", "networkErrorBadRequest": "Mauvaise requête", "networkErrorConflict": "Erreur due à un conflit", "networkErrorPreconditionFailed": "Le serveur ne remplit pas l'une des conditions préalables.", "networkErrorCreated": "", - "networkErrorGatewayTimeout": "La passerelle a rencontré un délai d'attente", + "networkErrorGatewayTimeout": "Délai d'attente trop long", "networkErrorInternalServerError": "Il s'agit d'une erreur interne du serveur. Contactez l'administrateur du serveur", "networkErrorMethodNotAllowed": "L'utilisateur n'a pas les droits d'accès au contenu", "networkErrorNoInternetConnection": "Pas de connexion Internet", @@ -194,21 +193,21 @@ "ok": "OK", "unavailable_feature_title": "Fonctionnalité non disponible", "unavailable_feature_message": "Cette fonctionnalité n'est pas disponible sur le navigateur", - "personalSkip": "SAUTER", - "restoreCredential": "Restaurer les identifiants", - "backupCredential": "Identifiants de sauvegarde", + "personalSkip": "Passer", + "restoreCredential": "Restaurer mes documents numériques", + "backupCredential": "Sauvegarder mes documents numériques", "backupCredentialPhrase": "Écrivez ces mots, téléchargez le fichier de sauvegarde et conservez-les en lieu sûr", "backupCredentialPhraseExplanation": "Pour sauvegarder vos informations d'identification, notez votre phrase de récupération et conservez-la en lieu sûr.", "backupCredentialButtonTitle": "Enregistrer le fichier", - "backupPolygonIdCredentialEmptyError": "You do not have any polygon id credential in your wallet.", - "needStoragePermission": "Sorry, You need storage permission to download this file.", + "backupPolygonIdCredentialEmptyError": "Vous n'avez pas de preuve d'identité PolygonID dans votre portefeuille.", + "needStoragePermission": "Désolé, vous avez besoin d'une autorisation pour télécharger ce fichier.", "backupCredentialNotificationTitle": "Succès", "backupCredentialNotificationMessage": "Le fichier a été téléchargé avec succès. Appuyez pour ouvrir le fichier.", "backupCredentialError": "Une erreur s'est produite. Veuillez réessayer plus tard.", "backupCredentialSuccessMessage": "Le fichier a été téléchargé avec succès.", - "restorationCredentialWarningDialogSubtitle": "La restauration effacera tous les identifiants que vous avez déjà dans votre portefeuille.", + "restorationCredentialWarningDialogSubtitle": "La restauration effacera tous les documents vérifiables que vous avez déjà dans votre portefeuille.", "recoveryCredentialPhrase": "Écrivez les mots et téléchargez le fichier de sauvegarde si vous l'avez enregistré auparavant", - "recoveryCredentialPhraseExplanation": "Vous avez besoin des deux mots dans le bon ordre et d'un fichier de sauvegarde crypté pour récupérer vos informations d'identification si vous les avez perdues d'une manière ou d'une autre", + "recoveryCredentialPhraseExplanation": "Vous avez besoin des deux mots dans le bon ordre et d'un fichier de sauvegarde crypté pour récupérer vos documents numériques", "recoveryCredentialButtonTitle": "Télécharger le fichier de sauvegarde", "recoveryCredentialSuccessMessage": "Récupération réussie de {postfix}.", "recoveryCredentialJSONFormatErrorMessage": "Veuillez télécharger le fichier valide.", @@ -222,7 +221,6 @@ } }, "selfIssuedCreatedSuccessfully": "Identifiant auto-émis créé avec succès", - "companyName": "Nom de l'entreprise", "companyWebsite": "Site Web de l'entreprise", "submit": "Envoyer", "insertYourDIDKey": "Insérez votre DID", @@ -245,9 +243,9 @@ "credentialVerificationReturnWarning": "La vérification des identifiants a renvoyé des avertissements. ", "failedToVerifyCredential": "Échec de la vérification des informations d'identification.", "somethingsWentWrongTryAgainLater": "Une erreur s'est produite, veuillez réessayer plus tard.", - "successfullyPresentedYourCredential": "Votre identifiant a été présenté avec succès !", + "successfullyPresentedYourCredential": "Votre document a été présenté avec succès !", "successfullyPresentedYourDID": "Votre DID a été présenté avec succès !", - "thisQRCodeIsNotSupported": "Ce code QR n'est pas pris en charge.", + "thisQRCodeIsNotSupported": "Ce QR code n'est pas pris en charge.", "thisUrlDoseNotContainAValidMessage": "Cette URL ne contient pas de message valide.", "anErrorOccurredWhileConnectingToTheServer": "Une erreur s'est produite lors de la connexion au serveur.", "failedToSaveMnemonicPleaseTryAgain": "Échec de l'enregistrement du mnémonique, veuillez réessayer", @@ -255,16 +253,16 @@ "failedToSaveProfile": "Échec de l'enregistrement du profil. ", "failedToLoadDID": "Échec du chargement du DID. ", "personalOpenIdRestrictionMessage": "Le portefeuille personnel n'a pas accès.", - "credentialEmptyError": "Vous n'avez aucun identifiant dans votre portefeuille.", - "credentialPresentTitleSiopV2": "Présenter l'identifiant", - "confirmSiopV2": "Veuillez confirmer l'identifiant présenté", + "credentialEmptyError": "Vous n'avez aucun justificatif vérifiable dans votre portefeuille.", + "credentialPresentTitleSiopV2": "Présenter le document", + "confirmSiopV2": "Veuillez confirmer le document présenté", "storagePermissionRequired": "Autorisation de stockage requise", "storagePermissionDeniedMessage": "Veuillez autoriser l'accès au stockage afin de télécharger le fichier.", "storagePermissionPermanentlyDeniedMessage": "Vous avez besoin d'une autorisation de stockage pour télécharger un fichier. Veuillez accéder aux paramètres de l'application et accorder l'accès à l'autorisation de stockage.", "cancel": "Annuler", "loading": "Veuillez patienter un instant...", - "issuerWebsitesTitle": "Obtenir les identifiants", - "getCredentialTitle": "Obtenir les identifiants", + "issuerWebsitesTitle": "Obtenir les documents", + "getCredentialTitle": "Obtenir les documents", "participantCredential": "Pass GaiaX", "phonePassCredential": "Preuve de téléphone", "emailPassCredential": "Preuve d'e-mail", @@ -274,7 +272,7 @@ "verifyMe": "Vérifiez-moi", "yes": "Oui", "no": "Non", - "credentialAlias": "Alias d'identifiant", + "credentialAlias": "Alias pour documents", "verificationStatus": "État de la vérification", "cardsPending": "Carte en attente", "cardsActive": "Carte active", @@ -288,14 +286,14 @@ "generate": "générer", "myAssets": "Mes actifs", "search": "Rechercher", - "professional": "Professional", + "professional": "Professionnel", "splashSubtitle": "Prenez le contrôle de vos données", "poweredBy": "Powered By", "splashLoading": "Chargement...", "version": "Version", "cards": "Cartes", "nfts": "NFTs", - "coins": "Coins", + "coins": "Cryptos", "getCards": "Obtenir", "close": "Fermer", "profile": "Profil", @@ -305,61 +303,60 @@ "enterNewPinCode": "Créez un code PIN pour protéger votre portefeuille", "confirmYourPinCode": "Confirmez votre code PIN", "walletAltme": "Portefeuille Altme", - "createPersonalWallet": "Create Personal Wallet", + "createPersonalWallet": "Créer un portefeuille personnel", "createTitle": "Créez ou importez votre adresse de portefeuille", - "createSubtitle": "Altme n'a jamais accès à vos fonds ou à votre phase de récupération. Rien ne sort de votre téléphone.", + "createSubtitle": "Altme n'a jamais accès à vos actifs ou à votre phase de récupération. Rien ne sort de votre téléphone.", "enterYourPinCode": "Entrez votre code PIN", "changePinCode": "Modifier le code PIN", "tryAgain": "Réessayez", - "credentialSelectionListEmptyError": "Vous n'avez pas les informations d'identification demandées pour poursuivre.", - "trustedIssuer": "Cet émetteur est approuvé par EBSI.", + "credentialSelectionListEmptyError": "Il vous manque un ou plusieurs documents numériques pour poursuivre.", + "trustedIssuer": "Cet émetteur est approuvé par l'EBSI.", "yourPinCodeChangedSuccessfully": "Votre code PIN a bien été modifié", - "advantagesCards": "Cartes de jeu", - "advantagesDiscoverCards": "Unlock exclusive rewards", - "identityCards": "Cartes d'identité", - "identityDiscoverCards": "Simplify ID verification", - "contactInfoCredentials": "Cartes communautaires", - "contactInfoDiscoverCredentials": "Verify your contact information", - "myProfessionalCards": "Cartes professionnelles", - "otherCards": "Autres cartes", + "advantagesCards": "Cartes avantages", + "advantagesDiscoverCards": "Débloquer des récompenses uniques", + "identityCards": "Cartes d'identités", + "identityDiscoverCards": "Simplifiez la vérification d'identité", + "contactInfoCredentials": "Cartes de communauté", + "contactInfoDiscoverCredentials": "Vérifiez vos informations de contact", + "myProfessionalCards": "Justificatifs professionnels", + "otherCards": "Autres cartes / justifs", "inMyWallet": "Dans mon portefeuille", "details": "Détails", "getIt": "Obtenir", - "getItNow": "Obtenez-le maintenant", + "getItNow": "Obtenir maintenant", "getThisCard": "Obtenir maintenant", "drawerBiometrics": "Authentification biométrique", "drawerTalaoCommunityCard": "Carte de communauté Talao", - "drawerTalaoCommunityCardTitle": "Importez votre adresse Ethereum et obtenez votre carte communautaire.", - "drawerTalaoCommunityCardSubtitle": "Elle vous donnera accès aux meilleures réductions, adhésions et cartes de bons d'achat de notre écosystème de partenaires.", - "drawerTalaoCommunityCardTextBoxMessage": "Une fois que vous avez entré votre clé privée, appuyez sur Importer. Veuillez vous assurer d'entrer la clé privée Ethereum qui contient votre cryptomonnaie Talao.", - "drawerTalaoCommunityCardSubtitle2": "Le portefeuille Altme est auto-dépositaire. Nous n'avons jamais accès à vos clés privées ou à vos fonds.", + "drawerTalaoCommunityCardTitle": "Importez votre adresse Ethereum et obtenez votre carte de membre.", + "drawerTalaoCommunityCardSubtitle": "Elle vous donnera accès aux meilleures réductions, adhésions et bons d'achat de notre écosystème de partenaires.", + "drawerTalaoCommunityCardTextBoxMessage": "Une fois que vous avez entré votre clé privée, appuyez sur Importer. Veuillez vous assurer d'entrer la clé privée Ethereum qui contient vos tokens Talao.", + "drawerTalaoCommunityCardSubtitle2": "Le portefeuille Altme est 100% décentralisé. Nous n'avons jamais accès à vos clés privées ou à vos fonds.", "drawerTalaoCommunityCardKeyError": "Veuillez saisir une clé privée valide", "loginWithBiometricsMessage": "Déverrouillez rapidement votre portefeuille sans avoir à saisir de mot de passe ou de code PIN", "manage": "Gérer", "wallet": "Portefeuille", - "manageAccounts": "Gérer les comptes blockchain", + "manageAccounts": "Gérer vos comptes blockchain", "blockchainAccounts": "Comptes blockchain", - "educationCredentials": "Education credentials", - "educationDiscoverCredentials": "Verify your education background", - "educationCredentialsDiscoverSubtitle": "Get your digital diploma (EBSI)", + "educationCredentials": "Justificatifs académiques", + "educationDiscoverCredentials": "Vérifiez votre parcours académique", + "educationCredentialsDiscoverSubtitle": "Obtenez vos diplôme numérique (EBSI)", "security": "Sécurité", "networkAndRegistries": "Réseau et registres", "chooseNetwork": "Choisir un réseau", "chooseRegistry": "Choisir le registre", - "trustFramework": "Trust Framework", + "trustFramework": "Cadre de confiance", "network": "Réseau", "issuerRegistry": "Registre des émetteurs", - "about": "À propos", - "termsOfUse": "Conditions d'utilisation et confidentialité", + "termsOfUse": "Conditions d'utilisation et de confidentialité", "scanFingerprintToAuthenticate": "Scanner l'empreinte digitale pour s'authentifier", "biometricsNotSupported": "La biométrie n'est pas prise en charge", "deviceDoNotSupportBiometricsAuthentication": "Votre appareil ne prend pas en charge l'authentification biométrique", "biometricsEnabledMessage": "Vous pouvez maintenant déverrouiller l'application avec vos données biométriques.", - "biometricsDisabledMessage": "Votre biométrie a été désactivée.", + "biometricsDisabledMessage": "L'identification biométrique a été désactivée.", "exportSecretKey": "Exporter la clé secrète", "secretKey": "Clé secrète", "chooseNetWork": "Choisir un réseau", - "nftEmptyMessage": "Votre galerie numérique est vide !", + "nftEmptyMessage": "Votre collection NFT est vide !", "myAccount": "Mon compte", "cryptoAccounts": "Comptes", "cryptoAccount": "Compte", @@ -369,12 +366,12 @@ "cryptoEditConfirmationDialogYes": "Enregistrer", "cryptoEditConfirmationDialogNo": "Annuler", "cryptoEditLabel": "Nom du compte", - "onBoardingFirstTitle": "Découvrez des offres exclusives Web 3 directement dans votre portefeuille.", - "onBoardingFirstSubtitle": "Obtenez des cartes de membre, des cartes de fidélité, des bons et bien d'autres avantages de vos applications et jeux préférés.", - "onBoardingSecondTitle": "AltMe est bien plus qu'un simple portefeuille numérique.", - "onBoardingSecondSubtitle": "Stockez et gérez vos données personnelles et accédez à toutes les applications Web 3.0.", + "onBoardingFirstTitle": "Découvrez des offres uniques directement dans votre portefeuille.", + "onBoardingFirstSubtitle": "Obtenez des cartes de membre, des cartes de fidélité et bien d'autres avantages.", + "onBoardingSecondTitle": "Altme est bien plus qu'un simple portefeuille numérique.", + "onBoardingSecondSubtitle": "Stockez et gérez vos données personnelles et accédez aux applications Web3.", "onBoardingThirdTitle": "Gérez vos données en toute autonomie, sécurité et confidentialité.", - "onBoardingThirdSubtitle": "Altme utilise la cryptographie SSI pour vous donner un contrôle total sur vos données. Rien ne sort de votre téléphone.", + "onBoardingThirdSubtitle": "Altme utilise la cryptographie pour vous donner un contrôle total sur vos données. Rien ne sort de votre téléphone.", "onBoardingStart": "Démarrer", "learnMoreAboutAltme": "En savoir plus sur Altme", "scroll": "Défilement", @@ -382,11 +379,11 @@ "readTermsOfUseCheckBox": "J'ai lu les conditions d'utilisation.", "createOrImportNewAccount": "Créer ou importer un nouveau compte.", "selectAccount": "Sélectionner un compte", - "onbordingSeedPhrase": "Phrase de départ", + "onbordingSeedPhrase": "Phrase de récupération", "onboardingPleaseStoreMessage": "Veuillez noter votre phrase de récupération", - "onboardingVerifyPhraseMessage": "Confirm Recovery Words", - "onboardingVerifyPhraseMessageDetails": "To ensure your Recovery Phrase is written correctly, select the words in correct order.", - "onboardingAltmeMessage": "Altme n'est pas dépositaire. Votre phrase de récupération est le seul moyen de récupérer votre compte.", + "onboardingVerifyPhraseMessage": "Confirmez votre phrase de récupération", + "onboardingVerifyPhraseMessageDetails": "Pour vous assurer que votre phrase de récupération est écrite correctement, sélectionnez les mots dans l'ordre.", + "onboardingAltmeMessage": "Altme est 100% décentralisé (non custodial). Votre phrase de récupération est le seul moyen de récupérer votre compte.", "onboardingWroteDownMessage": "J'ai écrit ma phrase de récupération", "copyToClipboard": "Copier dans le presse-papiers", "pinCodeMessage": "Le code PIN empêche l'accès non autorisé à votre portefeuille Altme. Vous pouvez le modifier à tout moment.", @@ -395,35 +392,35 @@ "import": "Importer", "accountName": "Nom du compte", "importWalletText": "Entrez ici votre phrase de récupération ou votre clé privée.", - "importWalletTextRecoveryPhraseOnly": "Enter your recovery phrase here.", - "recoveryPhraseDescriptions": "Une phrase de récupération (parfois appelée phrase de départ, clé privée ou phrase de sauvegarde) est une liste de 12 mots générés par votre portefeuille de crypto-monnaie qui vous donne accès à vos fonds", + "importWalletTextRecoveryPhraseOnly": "Saisissez votre phrase de récupération ici.", + "recoveryPhraseDescriptions": "Une phrase de récupération (parfois appelée phrase de départ ou clé privée) est une liste de 12 mots générés par votre portefeuille crypto donnant accès à vos actifs", "importEasilyFrom": "Importez votre compte depuis :", - "templeWallet": "Portefeuille du temple", + "templeWallet": "Portefeuille Temple", "temple": "Temple", "metaMaskWallet": "Portefeuille Metamask", - "metaMask": "Métamasque", + "metaMask": "Metamask", "kukai": "Kukai", "kukaiWallet": "Portefeuille Kukai", "other": "Autre", - "otherWalletApp": "Autre application de portefeuille", + "otherWalletApp": "Autre portefeuille", "importWalletHintText": "Une fois que vous avez saisi vos 12 mots (phrase de récupération) ou {numberCharacters} caractères privés (clé privée), appuyez sur Importer.", "@importWalletHintText": { - "description": "Texte d'astuce lors de l'importation d'un compte supplémentaire", + "description": "Astuce lors de l'importation d'un compte supplémentaire", "type": "text", "placeholders": { "numberCharacters": {} } }, - "importWalletHintTextRecoveryPhraseOnly": "Once you have entered your 12 words (recovery phrase), tap Import.", - "kycDialogTitle": "Pour obtenir ce justificatif d'identité numérique, vous devez vérifier votre identité", + "importWalletHintTextRecoveryPhraseOnly": "Une fois que vous avez entré vos 12 mots (phrase de récupération), appuyez sur Importer.", + "kycDialogTitle": "Pour obtenir ce document d'identité numérique, vous devez vérifier votre identité", "idVerificationProcess": "Processus de vérification d'identité", "idCheck": "Vérification d'identité", "facialRecognition": "Reconnaissance faciale", - "kycDialogButton": "Démarrer la vérification de l'ID", - "kycDialogFooter": "Conforme GDPR et CCPA + Niveau de sécurité SOC2", + "kycDialogButton": "Démarrer la vérification d'identité", + "kycDialogFooter": "Conforme RGPD + Niveau de sécurité SOC2", "finishedVerificationTitle": "Vérification d'identité en cours", "finishedVerificationDescription": "Vous recevrez un e-mail une fois que votre identité aura été vérifiée", - "verificationPendingTitle": "Votre vérification d'identité est en attente", + "verificationPendingTitle": "Votre vérification d'identité est en cours", "verificationPendingDescription": "En général, la vérification prend moins de 5 minutes. Vous recevrez un e-mail une fois la vérification terminée.", "verificationDeclinedTitle": "La vérification n'a pas abouti", "restartVerification": "Redémarrer la vérification d'identité", @@ -433,13 +430,13 @@ "verfiedButton": "Ajout de la preuve d'âge : + de 18 ans", "verifiedNotificationTitle": "Vérification terminée !", "verifiedNotificationDescription": "Félicitations ! Vous avez été vérifié avec succès.", - "showDecentralizedID": "Afficher l'ID décentralisé", - "manageDecentralizedID": "Gérer l'ID décentralisé", + "showDecentralizedID": "Afficher l'ID décentralisé (DID)", + "manageDecentralizedID": "Gérer l'ID décentralisé (DID)", "addressBook": "Carnet d'adresses", "home": "Mon portefeuille", "discover": "Découvrez", "settings": "Paramètres", - "privateKeyDescriptions": "Une clé privée est un numéro secret utilisé pour signer des transactions et prouver la propriété d'une adresse blockchain. Sur Tezos, la clé privée comporte généralement 54 caractères.", + "privateKeyDescriptions": "Une clé privée est un numéro secret utilisé pour signer des transactions et prouver la propriété d'un compte blockchain. Sur Tezos, la clé privée comporte généralement 54 caractères.", "importAccount": "Importer un compte", "imported": "Importé", "cardDetails": "Détails", @@ -449,11 +446,11 @@ "copy": "Copier", "didPrivateKey": "Clé privée SDA", "reveal": "Révéler", - "didPrivateKeyDescription": "Soyez prudent avec vos clés privées, car elles contrôlent l'accès à vos informations d'identification.", - "didPrivateKeyDescriptionAlert": "Ne partagez votre clé privée avec personne.", + "didPrivateKeyDescription": "Soyez prudent avec vos clés privées, car elles contrôlent l'accès à vos informations personnelles.", + "didPrivateKeyDescriptionAlert": "Ne partagez votre clé privée sous aucun prétexte.", "iReadTheMessageCorrectly": "J'ai bien lu le message", "beCareful": "Soyez prudent", - "decentralizedIDKey": "Clé d'identification décentralisée", + "decentralizedIDKey": "Clé DID décentralisée", "copySecretKeyToClipboard": "Clé secrète copiée dans le presse-papier !", "copyDIDKeyToClipboard": "Clé DID copiée dans le presse-papier !", "seeAddress": "Voir l'adresse", @@ -462,10 +459,10 @@ "shareWith": "Partager avec", "copiedToClipboard": "Copié dans le presse-papier !", "privateKey": "Clé privée", - "decentralizedID": "Identifiant décentralisé", + "decentralizedID": "ID décentralisé (DID)", "did": "DID", "accountPrivateKeyAlert": "Ne partagez jamais votre phrase de récupération. Le partage de votre phrase de récupération peut entraîner une perte de vos fonds.", - "sameAccountNameError": "Ce nom de compte a déjà été utilisé ; entrez un nom de compte différent, s'il vous plaît", + "sameAccountNameError": "Ce nom de compte a déjà été utilisé ; entrez un nom de compte différent, svp", "unknown": "Inconnu", "credentialManifestDescription": "Description", "credentialManifestInformations": "Informations", @@ -478,18 +475,18 @@ "licenses": "Licences", "sendTo": "Envoyer à", "next": "Suivant", - "withdrawalInputHint": "Copier l'adresse, scanner ou liste blanche", + "withdrawalInputHint": "Copier l'adresse, scanner ou rechercher", "amount": "Montant", - "amountSent": "Amount sent", + "amountSent": "Montant envoyé", "max": "Max", - "edit": "Editer", + "edit": "Éditer", "networkFee": "Frais de réseau", "totalAmount": "Montant total", "selectToken": "Sélectionner le token", "insufficientBalance": "Solde insuffisant", "slow": "Lent", - "average": "Moyenne", - "fast": "rapide", + "average": "Moyen", + "fast": "Rapide", "changeFee": "Modifier les frais", "sent": "Envoyé", "done": "fait", @@ -499,7 +496,7 @@ "send": "Envoyer", "receive": "Recevoir", "recentTransactions": "Transactions récentes", - "sendOnlyToThisAddressDescription": "Envoyez uniquement {symbol} à cette adresse. L'envoi d'autres cryptomonnaie peut entraîner une perte permanente.", + "sendOnlyToThisAddressDescription": "Envoyez uniquement {symbol} à cette adresse. L'envoi d'autres cryptos peut entraîner une perte.", "@sendOnlyToThisAddressDescription": { "description": "Nom du symbole lors de l'affichage de l'adresse dans la page de réception", "type": "text", @@ -521,16 +518,16 @@ "failedToConnectWithBeacon": "Échec de la connexion", "tezosNetwork": "Réseau Tezos", "confirm_sign": "Confirmer la signature", - "sign": "Signe", + "sign": "Signer", "payload_to_sign": "Transaction à signer", "signedPayload": "Transaction signée avec succès", "failedToSignPayload": "Échec de la signature", - "voucher": "Voucher", + "voucher": "Bon", "tezotopia": "Tezotopia", - "operationCompleted": "Votre demande a été prise en compte. La transaction peut mettre quelques minutes à s'afficher dans le portefeuille.", + "operationCompleted": "Votre demande a été prise en compte. La transaction peut mettre quelques minutes à s'afficher.", "operationFailed": "L'opération a échoué", "membership": "Adhésion", - "switchNetworkMessage": "Veuillez basculer votre réseau vers", + "switchNetworkMessage": "Veuillez changer de réseau", "fee": "Frais", "addCards": "Ajouter des cartes", "gaming": "Jeux", @@ -539,7 +536,7 @@ "socialMedia": "Réseaux sociaux", "advanceSettings": "Paramètres avancés", "categories": "Catégories", - "selectCredentialCategoryWhichYouWantToShowInCredentialList": "Sélectionnez les types de justificatifs numériques que vous souhaitez afficher dans la liste :", + "selectCredentialCategoryWhichYouWantToShowInCredentialList": "Sélectionnez les types de documents que vous souhaitez afficher dans la liste :", "community": "Communauté", "tezos": "Tezos", "rights": "Droits", @@ -565,12 +562,12 @@ "blockchainAccountsCredentialHomeSubtitle": "Utilisez vos comptes blockchains en toute sécurité.", "educationCredentialHomeSubtitle": "Prove your education background instantly", "passCredentialHomeSubtitle": "Utilisez des pass exclusifs : améliorez votre expérience Web3.", - "financeCardsCredentialHomeSubtitle": "Access new investment opportunities in web3", - "financeCardsCredentialDiscoverSubtitle": "Get exclusive advantages offered by Communities you like", - "contactInfoCredentialHomeSubtitle": "Share your contact information instantly", - "contactInfoCredentialDiscoverSubtitle": "Obtain easy-to-share credentials", - "otherCredentialHomeSubtitle": "Autres types de justificatifs numériques dans votre portefeuille", - "otherCredentialDiscoverSubtitle": "Autres types de justificatifs numériques que vous pouvez ajouter", + "financeCardsCredentialHomeSubtitle": "Accédez à de nouvelles opportunités d'investissement dans le web3", + "financeCardsCredentialDiscoverSubtitle": "Obtenez des avantages uniques offerts par les communautés que vous aimez", + "contactInfoCredentialHomeSubtitle": "Partagez instantanément vos infos de contact", + "contactInfoCredentialDiscoverSubtitle": "Obtenez des preuves vérifiables et faciles à partager", + "otherCredentialHomeSubtitle": "Autres types de documents numériques dans votre portefeuille", + "otherCredentialDiscoverSubtitle": "Autres types de documents numériques que vous pouvez ajouter", "showMore": "...Afficher plus", "showLess": "Afficher moins...", "youHaveReceivedARewardOf": "Vous avez reçu une récompense de", @@ -586,41 +583,41 @@ "website": "Website", "whyGetThisCard": "Description", "howToGetIt": "Comment l'obtenir", - "emailPassWhyGetThisCard": "Ce justificatif peut être exigé par certaines Apps / Sites Web 3 pour accéder à leur service ou obtenir des avantages : Carte de membre, Carte de fidélité, Rewards, etc.", + "emailPassWhyGetThisCard": "Cette preuve peut être exigé par certaines Apps / Sites Web 3 pour accéder à leur service ou obtenir des avantages : Carte de membre, Carte de fidélité, Rewards, etc.", "emailPassExpirationDate": "Cette carte restera active et réutilisable pendant 1 an.", "emailPassHowToGetIt": "C'est facile. Altme vérifiera que vous possédez cet email en envoyant un code sur votre email.", "tezotopiaMembershipWhyGetThisCard": "Cette carte de membre vous donnera 25 % de remise sur TOUTES les transactions du jeu Tezotopia lorsque vous achetez un Drops sur le marché ou mintez un NFT sur starbase.", "tezotopiaMembershipExpirationDate": "Cette carte restera active et réutilisable pendant 1 AN.", - "tezotopiaMembershipLongDescription": "Tezotopia is a real-time metaverse NFT game on Tezos, where players yield farm with Tezotops, engage in battles for rewards, and claim land in an immersive blockchain space adventure. Explore the metaverse, collect NFTs and conquer Tezotopia.", + "tezotopiaMembershipLongDescription": "Tezotopia est un jeu NFT en temps réel sur Tezos, où les joueurs participent à des batailles pour des récompenses et revendiquent des terres dans une aventure immersive. Explorez le métaverse, collectez des NFTs et conquérez Tezotopia.", "chainbornMembershipHowToGetIt": "Pour obtenir cette carte, vous devez invoquer un \"héros\" dans le jeu Chainborn et partager une preuve d'e-mail. Vous pouvez trouver la carte \"preuve d'email\" dans la section \"Découvrir\".", "chainbornMembershipWhyGetThisCard": "Soyez parmi les premiers à accéder au contenu exclusif de la boutique Chainborn, aux airdrops et aux autres avantages réservés aux membres !", "chainbornMembershipExpirationDate": "Cette carte restera active et réutilisable pendant 1 AN.", - "chainbornMembershipLongDescription": "Chainborn is an exciting NFT battle game where players use their own NFTs as heroes, competing for loot and glory. Engage in thrilling fights, gain experience points to boost your hero's strength and health, and enhance the value of your NFTs in this captivating Tezos-based adventure.", + "chainbornMembershipLongDescription": "Chainborn est un jeu de bataille NFT où les joueurs utilisent leurs propres NFT comme héros. Participez à des combats palpitants, gagnez des points d'expérience pour renforcer la force et la santé de votre héros, et augmentez la valeur de vos NFT dans cette captivante aventure Tezos.", "twitterHowToGetIt": "Suivez les étapes sur TezosProfiles https://tzprofiles.com/connect. Ensuite, obtenez la carte \"compte Twitter\" dans Altme. Assurez-vous de signer la transaction sur TZPROFILES avec le même compte que vous utilisez dans Altme. ", "twitterWhyGetThisCard": "Cette carte est une preuve que vous possédez votre compte Twitter. Utilisez-la pour prouver la propriété de votre compte Twitter chaque fois que vous en avez besoin.", "twitterExpirationDate": "Cette carte sera active pendant 1 an.", "twitterDummyDesc": "Prouvez la propriété de votre compte Twitter", - "linkedinCardHowToGetIt": "Vous pouvez obtenir ce justificatif en suivant une vérification d'identité. Seules les informations relatives à votre prénom, nom, nationalité et année de naissance seront accessibles depuis votre profil LinkedIn.", + "linkedinCardHowToGetIt": "Vous pouvez obtenir cette preuve en suivant une vérification d'identité. Seules les informations relatives à votre prénom, nom, nationalité et année de naissance seront accessibles depuis votre profil LinkedIn.", "linkedinCardWhyGetThisCard": "Cette carte est une preuve de votre identité pour votre profil LinkedIn. A partir de cette carte, vous pouvez exporter un QR code et l'afficher dans la bannière de votre compte LinkedIn. En scannant le QR code avec son portefeuille Altme, n'importe qui pourra vérifier que votre identité correspond à l'URL de votre profil LinkedIn, et pourra également accéder à 2 informations complémentaires : votre nationalité et votre année de naissance.", "linkedinCardExpirationDate": "Cette carte restera active et réutilisable pendant 1 AN.", "tezotopiaMembershipHowToGetIt": "Vous devez présenter une preuve de nationalité et une preuve de tranche d'âge. Obtenez-les en suivant le KYC d'Altme.", - "over18WhyGetThisCard": "Ce justificatif peut être exigé par certaines Applications / Sites Web du Web 3 pour accéder à leur service ou obtenir des avantages : Carte de membre, Carte de fidélité, Rewards, etc.", + "over18WhyGetThisCard": "Cette preuve peut être exigée par certaines Applications / Sites Web du Web 3 pour accéder à leur service ou obtenir des avantages : Carte de membre, Carte de fidélité, Rewards, etc.", "over18ExpirationDate": "Cette carte restera active et réutilisable pendant 1 AN.", "over18HowToGetIt": "Vous pouvez obtenir cette carte en suivant la vérification KYC d'Altme.", - "over13WhyGetThisCard": "Ce justificatif peut être exigé par certaines Applications / Sites Web du Web 3 pour accéder à leur service ou obtenir des avantages : Carte de membre, Carte de fidélité, Rewards, etc.", + "over13WhyGetThisCard": "Cette preuve peut être exigée par certaines Applications / Sites Web du Web 3 pour accéder à leur service ou obtenir des avantages : Carte de membre, Carte de fidélité, Rewards, etc.", "over13ExpirationDate": "Cette carte restera active et réutilisable pendant 1 AN.", "over13HowToGetIt": "Vous pouvez obtenir cette carte en suivant la vérification KYC d'Altme.", - "over15WhyGetThisCard": "This proof may be required by some Web 3 Apps / Websites to access their service or claim benefits : Membership card, Loyalty card, Rewards, etc.", + "over15WhyGetThisCard": "Cette preuve peut être exigée par certaines Applications / Sites Web du Web 3 pour accéder à leur service ou obtenir des avantages : Carte de membre, fidélité, Rewards, etc.", "over15ExpirationDate": "Cette carte restera active et réutilisable pendant 1 AN.", "over15HowToGetIt": "Vous pouvez obtenir cette carte en suivant la vérification KYC d'Altme.", - "passportFootprintWhyGetThisCard": "Ce justificatif peut être exigé par certaines Web 3 Apps / Sites Internet pour accéder à leur service ou obtenir des avantages : Carte de membre, Carte de fidélité, Rewards, etc.", + "passportFootprintWhyGetThisCard": "Cette preuve peut être exigée par certaines Web 3 Apps / Sites Internet pour accéder à leur service ou obtenir des avantages : Carte de membre, Carte de fidélité, Rewards, etc.", "passportFootprintExpirationDate": "Cette carte restera active et réutilisable pendant 1 AN.", "passportFootprintHowToGetIt": "Vous pouvez obtenir cette carte en suivant la vérification KYC d'Altme.", "verifiableIdCardWhyGetThisCard": "Cette carte d'identité numérique contient les mêmes informations que votre carte d'identité physique. Vous pouvez l'utiliser dans le Web 3 pour prouver votre identité.", "verifiableIdCardExpirationDate": "Cette carte restera active et réutilisable pendant 1 AN.", "verifiableIdCardHowToGetIt": "Vous pouvez obtenir cette carte en suivant la vérification KYC d'Altme.", "verifiableIdCardDummyDesc": "Obtenez votre carte d'identité numérique.", - "phoneProofWhyGetThisCard": "Ce justificatif peut être exigé par certaines Applications / Sites Web Web 3 pour accéder à leur service ou obtenir des avantages : Carte de membre, Carte de fidélité, Rewards, etc.", + "phoneProofWhyGetThisCard": "Cette preuve peut être exigée par certaines Applications / Sites Web Web 3 pour accéder à leur service ou obtenir des avantages : Carte de membre, Carte de fidélité, Rewards, etc.", "phoneProofExpirationDate": "Cette carte restera active et réutilisable pendant 1 AN.", "phoneProofHowToGetIt": "C'est simple. Altme vérifiera la propriété de votre numéro de téléphone en envoyant un code par SMS.", "tezVoucherWhyGetThisCard": "Cette carte vous donnera 10 % de remise en argent sur TOUTES les transactions du jeu Tezotopia lorsque vous achetez un Drops sur le marché ou frappez un NFT sur starbase.", @@ -635,20 +632,20 @@ "ageRangeWhyGetThisCard": "Cet identifiant est utile pour prouver votre tranche d'âge sans révéler aucune autre information vous concernant. Il peut être requis par certains sites ou apps Web 3 ou pour obtenir des avantages : carte de membre, etc.", "ageRangeExpirationDate": "Cette carte restera active et réutilisable pendant 1 AN.", "ageRangeHowToGetIt": "Vous pouvez obtenir cette carte en suivant la vérification KYC d'Altme.", - "defiComplianceWhyGetThisCard": "Obtain verifiable proof of KYC/AML compliance, requested by compliant DeFi protocols and Web3 dApps. Once obtained, you can mint a privacy-preserving, non-transferable NFT for on-chain verification without revealing personal data.", - "defiComplianceExpirationDate": "This credential remains active for 3 months. Renewal requires a straightforward compliance check, without new KYC.", - "defiComplianceHowToGetIt": "It's easy! Complete a one-time KYC check in Altme wallet (powered by ID360) and request your DeFi compliance credential.", - "rewardDialogTitle": "Bravo 🥳", + "defiComplianceWhyGetThisCard": "Obtenez une preuve de conformité KYC/AML, souvent demandée par les protocoles DeFi conformes et les applications Web3. Une fois obtenue, vous pourrez obtenir un NFT non transférable pour être vérifiée directement on-chain sans révéler vos données personnelles.", + "defiComplianceExpirationDate": "Cette preuve restera active pendant 3 mois. Le renouvellement nécessite une vérification simple, sans nouveau KYC.", + "defiComplianceHowToGetIt": "C'est facile ! Effectuez une vérification KYC dans le portefeuille Altme (par ID360) et demandez votre attestation de conformité DeFi.", + "rewardDialogTitle": "Félicitations 🥳", "rewardDialogDescPart1": "Vous venez de recevoir", - "rewardDialogDescPart2": "sur votre compte", + "rewardDialogDescPart2": "Sur votre compte", "origin": "Origine", - "nftTooBigToLoad": "Chargement en cours", + "nftTooBigToLoad": "En cours de chargement", "seeTransaction": "Voir la transaction", - "nftListSubtitle": "Voici tous les NFT et objets de collection de votre compte.", - "tokenListSubtitle": "Voici toutes les cryptomonnaies de votre compte.", - "my": "Mon", + "nftListSubtitle": "Voici tous les NFTs de votre collection.", + "tokenListSubtitle": "Voici toutes les cryptos de votre compte.", + "my": "Mes", "get": "Obtenir", - "seeMoreNFTInformationOn": "See more NFT information on", + "seeMoreNFTInformationOn": "Voir plus d'informations sur les NFT sur", "credentialStatus": "Status", "pass": "passe", "payloadFormatErrorMessage": "Le format est incorrect.", @@ -658,67 +655,67 @@ "fantomNetwork": "Réseau Fantom", "polygonNetwork": "Réseau Polygon", "binanceNetwork": "Réseau BNB Chain", - "step": "Etape", - "activateBiometricsTitle": "Activer la biométrie pour renforer la sécurité", - "loginWithBiometricsOnBoarding": "Se connecter avec la biométrie", + "step": "Étape", + "activateBiometricsTitle": "Activer votre emprunte digitale pour renforer la sécurité", + "loginWithBiometricsOnBoarding": "Se connecter avec votre emprunte digitale", "option": "Option", "start": "Démarrer", "iAgreeToThe": "J'accepte les ", "termsAndConditions": "Termes et conditions", "walletReadyTitle": "Votre portefeuille est prêt !", - "walletReadySubtitle": "Découvrez l'univers Web3.", + "walletReadySubtitle": "Explorez l'univers Web3.", "failedToInitCamera": "L'initialisation de la caméra a échoué !", - "chooseMethodPageOver18Title": "Choisissez une méthode pour vérifier que vous avez + de 18 ans", - "chooseMethodPageOver13Title": "Choisissez une méthode pour vérifier que vous avez + de 13 ans", - "chooseMethodPageOver15Title": "Choose a method to get your Over 15 Proof", - "chooseMethodPageOver21Title": "Choose a method to get your Over 21 Proof", - "chooseMethodPageOver50Title": "Choose a method to get your Over 50 Proof", - "chooseMethodPageOver65Title": "Choose a method to get your Over 65 Proof", - "chooseMethodPageAgeRangeTitle": "Choose a method to get your Age Range Proof", - "chooseMethodPageVerifiableIdTitle": "Choose a method to get your Verifiable Id Proof", - "chooseMethodPageDefiComplianceTitle": "Choose a method to get your Defi Compliance Proof", - "chooseMethodPageSubtitle": "Faites-vous vérifier en prenant une photo ou par une vérification de document .", - "kycTitle": "Quick photo of you (1min)", - "kycSubtitle": "Get instantly verified by taking a photo of yourself.", - "passbaseTitle": "Full ID document check", - "passbaseSubtitle": "Get verified with an ID card, passport or driving license.", + "chooseMethodPageOver18Title": "Choisissez une méthode pour vérifier que vous avez + de 18 ans", + "chooseMethodPageOver13Title": "Choisissez une méthode pour vérifier que vous avez + de 13 ans", + "chooseMethodPageOver15Title": "Choisissez une méthode pour obtenir votre preuve de + de 15 ans", + "chooseMethodPageOver21Title": "Choisissez une méthode pour obtenir votre preuve de + de 21 ans", + "chooseMethodPageOver50Title": "Choisissez une méthode pour obtenir votre preuve de + de 50 ans", + "chooseMethodPageOver65Title": "Choisissez une méthode pour obtenir votre preuve de + de 65 ans", + "chooseMethodPageAgeRangeTitle": "Choisissez une méthode pour obtenir une preuve de tranche d'âge", + "chooseMethodPageVerifiableIdTitle": "Choisissez une méthode pour obtenir une preuve d'identité vérifiable", + "chooseMethodPageDefiComplianceTitle": "Choisissez une méthode pour obtenir une preuve de conformité DeFi", + "chooseMethodPageSubtitle": "Faites-vous vérifier en prenant une photo ou en partageant un document.", + "kycTitle": "Selfie / Photo (1 min)", + "kycSubtitle": "Obtenez une vérification instantanée en prenant une photo de vous-même.", + "passbaseTitle": "Vérification avec document d'identité", + "passbaseSubtitle": "Obtenez une vérification avec une carte d'identité, un passeport ou un permis de conduire.", "verifyYourAge": "Vérifiez votre âge", "verifyYourAgeSubtitle": "Ce processus de vérification de l'âge est très simple. Il suffit d'une photo selfie.", - "verifyYourAgeDescription": "En acceptant, vous acceptez que nous utilisions votre photo pour estimer votre âge. L'estimation est effectuée par notre partenaire Yoti qui utilise votre photo uniquement à cette fin et la supprime immédiatement après. Pour plus d'informations, consultez notre Politique de confidentialité.", + "verifyYourAgeDescription": "En acceptant, vous acceptez que nous utilisions votre photo pour estimer votre âge. L'estimation est effectuée par notre partenaire Yoti qui utilise votre photo uniquement à cette fin et la supprime immédiatement après. Pour plus d'infos, consultez notre Politique de confidentialité.", "accept": "Accepter", "decline": "Refuser", - "yotiCameraAppbarTitle": "Please, position your face in the center", - "cameraSubtitle": "Vous avez 5 secondes pour prendre votre photo. Assurez-vous qu'il y a suffisamment de lumière avant de commencer.", - "todoImportant": "TODO(all): update the text of below keys","walletSecurity": "Wallet Security", + "yotiCameraAppbarTitle": "Rapprochez votre visage au maximum avant de prendre la photo", + "cameraSubtitle": "Vous avez 5 secondes pour prendre votre photo. Rapprochez votre visage au maximum avant de commencer.", + "walletSecurity": "Sécurité du portefeuille", "walletSecurityDescription": "Protégez votre portefeuille avec le code PIN et l'authentification biométrique", "blockchainSettings": "Paramètres de la blockchain", "blockchainSettingsDescription": "Gérer vos comptes, votre phrase de récupération, et les dApps", "ssi": "Identité auto-souveraine (DID)", - "ssiDescription": "Gérez votre identifiant décentralisé et sauvegardez ou restaurez vos identifiants", + "ssiDescription": "Gérez votre identité décentralisée et sauvegardez ou restaurez vos documents numériques", "helpCenter": "Centre d'aide", - "helpCenterDescription": "Contactez-nous et obtenez de l'aide si vous avez besoin d'aide pour utiliser Altme", + "helpCenterDescription": "Contactez-nous et obtenez de l'aide", "about": "À propos", "aboutDescription": "En savoir plus sur les conditions d'utilisation, la confidentialité et les licences d'Altme", "resetWallet": "Réinitialiser le portefeuille", "resetWalletDescription": "Effacez toutes les données stockées sur votre téléphone et réinitialisez le portefeuille Altme.", "showWalletRecoveryPhrase": "Afficher la phrase de récupération du portefeuille", - "showWalletRecoveryPhraseSubtitle": "The recovery phrase acts as a backup key to restore access to a your wallet.", + "showWalletRecoveryPhraseSubtitle": "La phrase de récupération est nécessaire pour accéder à votre portefeuille.", "blockchainNetwork": "Réseau Blockchain (par défaut)", "contactUs": "Contactez-nous", "officialWebsite": "Site officiel", "yourAppVersion": "La version de votre application Altme", "resetWalletTitle": "Êtes-vous sûr de vouloir réinitialiser votre portefeuille ?", "resetWalletSubtitle": "Cette action effacera vos données. Veuillez vous assurer d'avoir enregistré votre phrase de récupération et le fichier de sauvegarde de vos justifs numériques avant de les supprimer.", - "resetWalletSubtitle2": "Altme est 100% décentralisé, nous ne sommes donc pas en mesure de récupérer vos fonds ou vos justificatifs numériques à votre place.", + "resetWalletSubtitle2": "Altme est 100% décentralisé, nous ne sommes donc pas en mesure de récupérer vos fonds ou vos documents numériques à votre place.", "resetWalletCheckBox1": "J'ai noté ma phrase de récupération", - "resetWalletCheckBox2": "J'ai enregistré le fichier contenant mes justifs numériques", + "resetWalletCheckBox2": "J'ai enregistré le fichier contenant mes documents numériques", "email": "E-mail", "fillingThisFieldIsMandatory": "Remplir ce champ est obligatoire.", "yourMessage": "Votre message", - "message": "message", + "message": "Message", "subject": "Sujet", "enterAValidEmail": "Entrez un email valide.", - "failedToSendEmail": "Échec de l'envoi de l'email.", + "failedToSendEmail": "Échec de l'envoi d'email.", "selectAMethodToAddAccount": "Sélectionnez une méthode pour ajouter un compte", "createAccount": "Créer un compte", "createAccountDescription": "Créez un compte protégé par votre phrase de récupération", @@ -743,29 +740,29 @@ "polygonAccountCreationCongratulations": "Votre nouveau compte Polygon a été créé avec succès.", "binanceAccountCreationCongratulations": "Votre nouveau compte BNB Chain a été créé avec succès.", "accountImportCongratulations": "Votre compte a été importé avec succès.", - "saveBackupCredentialTitle": "Téléchargez le fichier de sauvegarde. Conservez-le en lieu sûr.", - "saveBackupCredentialSubtitle": "Pour récupérer tous vos justificatifs numériques, vous aurez besoin de votre phrase de récupération ET de ce fichier de sauvegarde.", - "saveBackupPolygonCredentialSubtitle": "To recover all your polygon id credentials you will need the Recovery Phrase AND this backup file.", - "restoreCredentialStep1Title": "Etape 1 : Entrez vos 12 mots de phrase de récupération", + "saveBackupCredentialTitle": "Téléchargez le fichier de sauvegarde. Conservez-le en lieu sûr.", + "saveBackupCredentialSubtitle": "Pour récupérer vos documents numériques, vous aurez besoin de votre phrase de récupération ET de ce fichier de sauvegarde.", + "saveBackupPolygonCredentialSubtitle": "Pour récupérer vos documents d'identité PolygonID, vous aurez besoin de votre phrase de récupération ET de ce fichier de sauvegarde.", + "restoreCredentialStep1Title": "Etape 1 : Entrez les 12 mots de votre phrase de récupération", "restorePhraseTextFieldHint": "Entrez votre phrase de récupération (ou phrase mnémonique) ici...", - "restoreCredentialStep2Title": "Etape 2 : Téléchargez votre fichier de sauvegarde contenant vos justificatifs numériques", + "restoreCredentialStep2Title": "Etape 2 : Téléchargez le fichier de sauvegarde contenant vos attestations numériques", "loadFile": "Charger le fichier", "uploadFile": "Télécharger le fichier", "creators": "Créateurs", "publishers": "Éditeurs", "creationDate": "Créer une date", - "myProfessionalrCards": "Justificatifs professionnelles", - "myProfessionalrCardsSubtitle": "Utilisez vos justificatifs professionnelles facilement.", + "myProfessionalrCards": "Justifs professionnels", + "myProfessionalrCardsSubtitle": "Partager vos justifs professionnelles en 1 clic.", "guardaWallet": "Portefeuille Guarda", "exodusWallet": "Portefeuille Exodus", "trustWallet": "Portefeuille de confiance", "myetherwallet": "Mon portefeuille Ether", "skip": "Ignorer", - "userNotFitErrorMessage": "Vous ne pouvez pas obtenir cette carte car certaines conditions ne sont pas remplies.", + "userNotFitErrorMessage": "Vous ne pouvez pas obtenir ce document car certaines conditions ne sont pas remplies.", "youAreMissing": "Vous êtes absent", "credentialsRequestedBy": "informations demandées par", "transactionIsLikelyToFail": "La transaction est susceptible d'échouer.", - "buy": "acheter", + "buy": "Acheter", "thisFeatureIsNotSupportedYetForFantom": "Cette fonctionnalité n'est pas encore prise en charge pour Fantom.", "thisFeatureIsNotSupportedYetForBinance": "Cette fonctionnalité n'est pas encore prise en charge pour BNB Chain.", "faqs": "FAQ", @@ -776,267 +773,272 @@ "exportToLinkedIn": "Exporter vers LinkedIn", "addLinkedInInfo": "Ajouter des informations LinkedIn", "whatsYourLinkedinProfileUrl": "Quelle est l'URL de votre profil linkedIn ?", - "invalidUrlError": "Veuillez saisir une URL linkdin valide", + "invalidUrlError": "Veuillez saisir une URL LinkedIn valide", "linkedInBannerSuccessfullyExported": "Votre bannière LinkedIn a été exportée avec succès.", "credentialSuccessfullyExported": "Votre identifiant a été exporté avec succès.", "linkedInBanner": "Bannière Linkedin", "linkedInProfile": "Profil Linkedin", - "checkLinkedinProfile": "Vérifier un profil Linkedin", + "checkLinkedinProfile": "Vérifier votre profil Linkedin", "scanAndDisplay": "Numériser et afficher", "whatsNew": "Nouveautés", "okGotIt": "Ok, compris !", "support": "support", "transactionDoneDialogDescription": "Cela peut prendre quelques minutes", "withdrawalFailedMessage": "Le retrait a échoué", - "credentialRequiredMessage": "Vous devez d'abord posséder ces justificatifs pour acquérir cette carte :", - "keyDecentralizedIdEdSA": "Key Decentralized ID EdDSA", - "keyDecentralizedIDSecp256k1": "Key Decentralized ID Secp256k1", - "polygonIdDecentralizedId": "Polygon Decentralized ID", - "ebsiV3DecentralizedId": "EBSI V3 Decentralized ID", - "requiredCredentialNotFoundTitle": "We are unable to find the credential\nyou need in your wallet.", - "requiredCredentialNotFoundSubTitle": "The required credential is not in your wallet", - "requiredCredentialNotFoundDescription": "Please contact us on :", - "backToHome": "Back to home", - "help": "Help", - "searchCredentials": "Search credentials", - "supportChatWelcomeMessage": "Welcome to our chat support! We're here to assist you with any questions or concerns you may have about our wallet.", - "cardChatWelcomeMessage": "Welcome to our chat support! We're here to assist you with any questions or concerns.", - "creator": "Creator", - "contractAddress": "Contract address", - "lastMetadataSync": "Last metadata sync", - "e2eEncyptedChat": "Chat is encrypted from end to end.", - "pincodeAttemptMessage": "You have entered an incorrect PIN code three times. For security reasons, please wait for one minute before trying again.", - "verifyNow": "Verify Now", - "verifyLater": "Verify Later", - "welDone": "Well done!", - "mnemonicsVerifiedMessage": "Your revovery phrase is saved correctly.", - "chatWith": "Chat with", - "sendAnEmail": "Send an email", - "livenessCardHowToGetIt": "It's easy! Complete a one-time KYC check in Altme wallet (powered by ID360) and request a Liveness credential.", - "livenessCardExpirationDate": "This credential will remain active for 1 year. Renewal is straightforward.", - "livenessCardWhyGetThisCard": "Obtain verifiable proof of humanity, requested by most DeFi, GameFi protocols and Web3 dApps. Once obtained, you can mint a privacy-preserving, non-transferable NFT for on-chain verification without revealing personal data.", - "livenessCardLongDescription": "This credential is a verifiable proof of humanity. Use it to prove you are not a bot when requested by DeFi protocols, Onchain games or Web3 dApps.", + "credentialRequiredMessage": "Vous devez d'abord posséder ces documents pour obtenir cette carte :", + "keyDecentralizedIdEdSA": "Clé d'Identité Décentralisée EdDSA", + "keyDecentralizedIDSecp256k1": "Clé d'Identité Décentralisée Secp256k1", + "polygonIdDecentralizedId": "Identité Décentralisée Polygon", + "ebsiV3DecentralizedId": "Identité Décentralisée EBSI V3", + "requiredCredentialNotFoundTitle": "Nous ne parvenons pas à trouver le document\ndont vous avez besoin dans votre portefeuille.", + "requiredCredentialNotFoundSubTitle": "Le document demandé n'est pas dans votre portefeuille", + "requiredCredentialNotFoundDescription": "Veuillez nous contacter sur :", + "backToHome": "Retour à l'accueil", + "help": "Aide", + "searchCredentials": "Rechercher des documents", + "supportChatWelcomeMessage": "Bienvenue sur notre chat ! Nous sommes là pour répondre à vos questions.", + "cardChatWelcomeMessage": "Bienvenue sur notre chat ! Nous sommes là pour répondre à vos questions.", + "creator": "Créateur", + "contractAddress": "Adresse du contrat", + "lastMetadataSync": "Dernière synchronisation des métadonnées", + "e2eEncyptedChat": "Les échanges sont chiffrés de bout en bout.", + "pincodeAttemptMessage": "Vous avez saisi un code PIN incorrect trois fois. Pour des raisons de sécurité, veuillez attendre une minute avant de réessayer.", + "verifyNow": "Vérifier maintenant", + "verifyLater": "Vérifier plus tard", + "welDone": "Bien joué !", + "mnemonicsVerifiedMessage": "Votre phrase de récupération est enregistrée correctement.", + "chatWith": "Discuter avec", + "sendAnEmail": "Envoyer un email", + "livenessCardHowToGetIt": "C'est facile ! Effectuez une vérification KYC (solution ID360) et obtenez votre preuve d'humanité.", + "livenessCardExpirationDate": "Ce document restera valable pendant 1 an. Son renouvellement est simple.", + "livenessCardWhyGetThisCard": "Obtenez une preuve d'humanité, demandée par la plupart des protocoles DeFi ou dApps Web3. Une fois obtenue, vous pourrez demander un NFT non transférable pour prouver votre humanité onchain.", + "livenessCardLongDescription": "Ce document est une preuve d'humanité. Utilisez-le pour prouver que vous n'êtes pas un robot lorsque cela est nécessaire.", "chat": "Chat", - "polygonDecentralizedID": "Polygon Decentralized ID", - "needMnemonicVerificatinoDescription": "You need to verify your wallet seed phrases to protect your assets!", - "succesfullyAuthenticated": "Successfully Authenticated.", - "authenticationFailed": "Authentication Failed.", - "documentType": "Document Type", - "countryCode": "Country Code", - "deviceIncompatibilityMessage": "Sorry, your device is not compatible for this feature.", + "polygonDecentralizedID": "Identité décentralisée Polygon", + "needMnemonicVerificatinoDescription": "Vous devez vérifier les phrases de récupération de votre portefeuille pour protéger vos actifs !", + "succesfullyAuthenticated": "Authentification réussie.", + "authenticationFailed": "Échec de l'authentification.", + "documentType": "Type de Document", + "countryCode": "Code Pays", + "deviceIncompatibilityMessage": "Désolé, votre appareil n'est pas compatible avec cette fonctionnalité.", "tezosProofMessage": "", "ethereumProofMessage": "", "fantomProofMessage": "", "polygonProofMessage": "", "binanceProofMessage": "", - "yearsOld": "years old", - "youAreOver13": "You are over 13 years old", - "youAreOver15": "You are over 15 years old", - "youAreOver18": "You are over 18 years old", - "youAreOver21": "You are over 21 years old", - "youAreOver50": "You are over 50 years old", - "youAreOver65": "You are over 65 years old", + "yearsOld": "ans", + "youAreOver13": "Vous avez + de 13 ans", + "youAreOver15": "Vous avez + de 15 ans", + "youAreOver18": "Vous avez + de 18 ans", + "youAreOver21": "Vous avez + de 21 ans", + "youAreOver50": "Vous avez + de 50 ans", + "youAreOver65": "Vous avez + de 65 ans", "polygon": "Polygon", "ebsi": "EBSI", - "backupPolygonIdIdentity": "Backup PolygonId Identity", - "restorePolygonIdCredentials": "Restore PolygonId Credentials", - "comingSoon": "Coming Soon", - "financeCredentialsHomeTitle": "My financial credentials", - "financeCredentialsDiscoverTitle": "Get verified financial credentials", - "financeCredentialsDiscoverSubtitle": "Access new investment opportunities in web3.", - "financeCredentialsHomeSubtitle": "Access new investment opportunities in web3", - "hummanityProofCredentialsHomeTitle": "My proof of humanity", - "hummanityProofCredentialsHomeSubtitle": "Easily prove you are a human and not a bot.", - "hummanityProofCredentialsDiscoverTitle": "Prove you are not a bot or AI", - "hummanityProofCredentialsDiscoverSubtitle": "Get a reusable proof of humanity to share", - "socialMediaCredentialsHomeTitle": "My social media accounts", - "socialMediaCredentialsHomeSubtitle": "Prove your accounts ownership instantly Proof of humanity", - "socialMediaCredentialsDiscoverTitle": "Verify your social media accounts", - "socialMediaCredentialsDiscoverSubtitle": "Prove your accounts ownership when required", - "walletIntegrityCredentialsHomeTitle": "Wallet integrity", + "backupPolygonIdIdentity": "Sauvegarder vos informations d'identité PolygonId", + "restorePolygonIdCredentials": "Restaurer vos preuves d'identité PolygonId", + "comingSoon": "Bientôt disponible", + "financeCredentialsHomeTitle": "Mes justifs financiers", + "financeCredentialsDiscoverTitle": "Obtenez des justifs financiers vérifiés", + "financeCredentialsDiscoverSubtitle": "Accédez à de nouvelles opportunités d'investissement dans le web3.", + "financeCredentialsHomeSubtitle": "Accédez à de nouvelles opportunités d'investissement dans le web3", + "hummanityProofCredentialsHomeTitle": "Ma preuve d'humanité", + "hummanityProofCredentialsHomeSubtitle": "Prouvez facilement que vous êtes humain et non un robot.", + "hummanityProofCredentialsDiscoverTitle": "Prouvez que vous n'êtes pas un robot ou une IA", + "hummanityProofCredentialsDiscoverSubtitle": "Obtenez une preuve d'humanité à partager", + "socialMediaCredentialsHomeTitle": "Mes réseaux sociaux", + "socialMediaCredentialsHomeSubtitle": "Prouvez instantanément la propriété de vos comptes", + "socialMediaCredentialsDiscoverTitle": "Vérifiez vos comptes de réseaux sociaux", + "socialMediaCredentialsDiscoverSubtitle": "Prouvez la propriété de vos réseaux sociaux", + "walletIntegrityCredentialsHomeTitle": "Intégrité du portefeuille", "walletIntegrityCredentialsHomeSubtitle": "TBD", - "walletIntegrityCredentialsDiscoverTitle": "WAllet integrity", + "walletIntegrityCredentialsDiscoverTitle": "Intégrité du portefeuille", "walletIntegrityCredentialsDiscoverSubtitle": "TBD", - "polygonCredentialsHomeTitle": "My PolygonID credentials", - "polygonCredentialsHomeSubtitle": "Prove your access rights in the Polygon ecosystem", - "polygonCredentialsDiscoverTitle": "Get PolygonID credentials", - "polygonCredentialsDiscoverSubtitle": "Prove your access rights in the Polygon ecosystem", - "pendingCredentialsHomeTitle": "My Pending credentials", - "pendingCredentialsHomeSubtitle": "Prove your access rights.", - "restore": "Restore", - "backup": "Backup", - "takePicture": "Take a picture", + "polygonCredentialsHomeTitle": "Mes preuves PolygonID", + "polygonCredentialsHomeSubtitle": "Prouvez votre identité dans l'écosystème Polygon", + "polygonCredentialsDiscoverTitle": "Obtenez des références PolygonID", + "polygonCredentialsDiscoverSubtitle": "Prouvez vos droits d'accès dans l'écosystème Polygon", + "pendingCredentialsHomeTitle": "Mes références en attente", + "pendingCredentialsHomeSubtitle": "Prouvez vos droits d'accès.", + "restore": "Restaurer", + "backup": "Sauvegarder", + "takePicture": "Prendre une photo", "kyc": "KYC", - "aiSystemWasNotAbleToEstimateYourAge": "AI system was not able to estimate your age", - "youGotAgeCredentials": "You got your {credential} credential.", + "aiSystemWasNotAbleToEstimateYourAge": "L'IA de YOTI n'a pas pu estimer votre âge", + "youGotAgeCredentials": "Vous avez votre preuve {credential}.", "@youGotAgeCredentials": { - "description": "the description for the getting credentials", + "description": "la description pour l'obtention des preuves d'âge", "placeholders": { "credential": {} } }, - "yourAgeEstimationIs": "Your AI age estimation is {ageEstimate} years", + "yourAgeEstimationIs": "Votre estimation d'âge est de {ageEstimate} ans (YOTI)", "@yourAgeEstimationIs": { "description": "", "placeholders": { "ageEstimate": {} } }, - "credentialNotFound": "Credential Not Found", - "cryptographicProof": "Cryptographic Proof", - "downloadingCircuitLoadingMessage": "Downloading circuits. It may take some time. Please wait.", - "cryptoAccountAlreadyExistMessage": "It appears that an account with this crypto information already exists", - "errorGeneratingProof": "Error Generating Proof", - "createWalletMessage": "Please create your wallet first.", - "successfullyGeneratingProof": "Successfully Generated Proof", - "wouldYouLikeToAcceptThisCredentialsFromThisOrganisation": "Would you like to accept this credential(s) from this organisation?", - "thisOrganisationRequestsThisInformation": "This organisation requests this information", - "iS": "is", - "isSmallerThan": "is smaller than", - "isBiggerThan": "is bigger than", - "isOneOfTheFollowingValues": "is one of the following values", - "isNotOneOfTheFollowingValues": "is not one of the following values", - "isNot": "is not", - "approve": "Approve", - "noInformationWillBeSharedFromThisCredentialMessage": "No information will be shared from this credential (Zero Knowledge Proof).", - "burn": "Burn", - "wouldYouLikeToConfirmThatYouIntendToBurnThisNFT": "Do you really want to burn this NFT ?", - "pleaseAddXtoConnectToTheDapp": "Please add {chain} account to connect to the dapp.", + "credentialNotFound": "Référence non trouvée", + "cryptographicProof": "Preuve", + "downloadingCircuitLoadingMessage": "Téléchargement. Cela peut prendre un certain temps. Veuillez patienter.", + "cryptoAccountAlreadyExistMessage": "Il semble qu'un compte avec ces informations existe déjà", + "errorGeneratingProof": "Erreur lors de la génération de la preuve", + "createWalletMessage": "Veuillez d'abord créer votre portefeuille.", + "successfullyGeneratingProof": "Preuve générée avec Succès", + "wouldYouLikeToAcceptThisCredentialsFromThisOrganisation": "Souhaitez-vous accepter ce(s) document(s) ?", + "thisOrganisationRequestsThisInformation": "Cette organisation demande cette information", + "iS": "est", + "isSmallerThan": "est inférieur à", + "isBiggerThan": "est supérieur à", + "isOneOfTheFollowingValues": "est l'une des valeurs suivantes", + "isNotOneOfTheFollowingValues": "n'est pas l'une des valeurs suivantes", + "isNot": "n'est pas", + "approve": "Approuver", + "noInformationWillBeSharedFromThisCredentialMessage": "Aucune information personnelle ne sera partagée (ZKP).", + "burn": "Détruire", + "wouldYouLikeToConfirmThatYouIntendToBurnThisNFT": "Voulez-vous vraiment détruire / burn ce NFT ?", + "pleaseAddXtoConnectToTheDapp": "Veuillez ajouter un compte {chain} pour vous connecter à l'application.", "@pleaseAddXtoConnectToTheDapp": { "description": "", "placeholders": { "chain": {} } }, - "pleaseSwitchPolygonNetwork": "Please switch to polygon {networkType} to perform this action.", + "pleaseSwitchPolygonNetwork": "Veuillez passer au réseau polygon {networkType} pour effectuer cette action.", "@pleaseSwitchPolygonNetwork": { "description": "", "placeholders": { "networkType": {} } }, - "oidc4vcProfile": "OIDC4VC Profile", - "pleaseSwitchToCorrectOIDC4VCProfile": "Please switch to correct OIDC4VC profile.", - "authenticationSuccess": "Authentication Success", + "oidc4vcProfile": "Profil OIDC4VC", + "pleaseSwitchToCorrectOIDC4VCProfile": "Veuillez passer au bon profil OIDC4VC.", + "authenticationSuccess": "Authentification Réussie", "format": "Format", - "pleaseInsertTheSecredCodeReceived": "Please insert the secret code received.", - "verifyIssuerWebsiteIdentity": "Verify issuer website identity", - "verifyIssuerWebsiteIdentitySubtitle": "Default: Off\nEnable to verify website identity before access.", - "developerMode": "Developer Mode", - "developerModeSubtitle": "Enable developer mode to access advanced debugging tools", - "confirmVerifierAccess": "Confirm verifier access", - "confirmVerifierAccessSubtitle": "Default: On\nDisable to skip confirmation when you share your verifiable credentials.", + "pleaseInsertTheSecredCodeReceived": "Veuillez insérer le code secret reçu.", + "verifyIssuerWebsiteIdentity": "Vérifier l'identité du site Web de l'émetteur", + "verifyIssuerWebsiteIdentitySubtitle": "Par défaut : Désactivé\nActivez pour vérifier l'identité du site Web avant l'accès.", + "developerMode": "Mode Développeur", + "developerModeSubtitle": "Activez le mode développeur pour accéder à des outils de débug avancés", + "confirmVerifierAccess": "Confirmer le partage du document", + "confirmVerifierAccessSubtitle": "Par défaut : Activé\nDésactivez pour demander une confirmation lorsque vous partagez vos documents vérifiables.", "credentialManifestSupport": "Credential Manifest Support", "credentialManifestSupportSubtitle": "Default: Off\nUse DIF Wallet Rendering syntax instead of the 'display' attribute.", - "secureAuthenticationWithPINCode": "Secure Authentication with PIN Code", - "secureAuthenticationWithPINCodeSubtitle": "Default: On\nTurn off to skip PIN code for website authentication (not recommended).", - "youcanSelectOnlyXCredential": "You can select only {count} credential(s).", + "secureAuthenticationWithPINCode": "Authentification sécurisée avec Code PIN", + "secureAuthenticationWithPINCodeSubtitle": "Par défaut : Activé\nDésactivez pour ignorer le code PIN lors de l'authentification Web (non recommandé).", + "youcanSelectOnlyXCredential": "Vous pouvez sélectionner uniquement {count} document(s).", "@youcanSelectOnlyXCredential": { "description": "", "placeholders": { "count": {} } }, - "theCredentialIsNotReady": "The credential is not ready.", - "theCredentialIsNoMoreReady": "The ceredential is no more available.", - "lowSecurity": "Low Security", - "highSecurity": "High Security", - "theRequestIsRejected": "The request is rejected.", - "userPinIsIncorrect": "User pin is incorrect", - "security_level": "Security Level", - "oidc4vc_settings": "OIDC4VC Settings", + "theCredentialIsNotReady": "Le document n'est pas prêt.", + "theCredentialIsNoMoreReady": "Ce document n'est plus disponible.", + "lowSecurity": "Sécurité faible", + "highSecurity": "Sécurité élevée", + "theRequestIsRejected": "La demande est rejetée.", + "userPinIsIncorrect": "Le code PIN utilisateur est incorrect", + "security_level": "Niveau de Sécurité", + "oidc4vc_settings": "Paramètres OIDC4VC", "userPinTitle": "User PIN Digits pre-authorized_code Flow", - "userPinSubtitle": "Default: 6 digits\nEnable to manage 4 digits PIN code", - "securityLevelTitle": "Wallet Level", + "userPinSubtitle": "Par défaut : 6 chiffres\nActivez pour avoir un code PIN à 4 chiffres", + "securityLevelTitle": "Niveau du Portefeuille", "securityLevelSubTitle": "Default: Permissive\nSet to Strict to strengthen controls for issuers and verifiers", - "responseTypeNotSupported": "The response type is not supported", - "invalidRequest": "The request is invalid", - "subjectSyntaxTypeNotSupported": "The subject syntax type is not supported.", - "accessDenied": "Access denied", - "thisRequestIsNotSupported": "This request is not supported", - "unsupportedCredential": "Unsupported credential", - "aloginIsRequired": "A login is required", - "userConsentIsRequired": "User consent is required", - "theWalletIsNotRegistered": "The wallet is not registered", - "credentialIssuanceDenied": "Credential issuance denied", - "thisCredentialFormatIsNotSupported": "This credential format is not supported", - "thisFormatIsNotSupported": "This format is not supported", - "moreDetails": "More Details", - "theCredentialOfferIsInvalid": "The credential offer is invalid", - "dateOfRequest": "Date of Request", - "keyDecentralizedIDP256": "Key Decentralized ID P-256", - "jwkDecentralizedIDP256": "JWK Decentralized ID P-256", - "defaultDid": "Default DID", - "selectOneOfTheDid": "Select one of the DIDs", - "clientTypeTitle": "OIDC4VCI Client Type", - "clientTypeSubtitle": "Default: DID\nSwitch to change the client type", - "cryptographicHolderBinding": "Cryptographic Holder Binding", - "cryptographicHolderBindingSubtitle": "Default : On\nDisable cryptographic binding for claim based binding credentials.", - "scopeParameters": "Scope Parameters", - "scopeParametersSubtitle": "Default : Off\nEnable to force wallet to use scope instead of authorization_details.", - "clientAuthenticationMethods": "Client Authentication Methods", + "responseTypeNotSupported": "Le type de réponse n'est pas pris en charge", + "invalidRequest": "La demande n'est pas valide", + "subjectSyntaxTypeNotSupported": "Le type de syntaxe n'est pas pris en charge.", + "accessDenied": "Accès refusé", + "thisRequestIsNotSupported": "Cette demande n'est pas prise en charge", + "unsupportedCredential": "Référence non prise en charge", + "aloginIsRequired": "Une connexion est requise", + "userConsentIsRequired": "Le consentement de l'utilisateur est requis", + "theWalletIsNotRegistered": "Ce portefeuille n'est pas enregistré", + "credentialIssuanceDenied": "Émission du document refusé", + "thisCredentialFormatIsNotSupported": "Ce format n'est pas pris en charge", + "thisFormatIsNotSupported": "Ce format n'est pas pris en charge", + "moreDetails": "Plus de détails", + "theCredentialOfferIsInvalid": "Ce document n'est pas valide", + "dateOfRequest": "Date de la Demande", + "keyDecentralizedIDP256": "Clé d'Identité Décentralisée P-256", + "jwkDecentralizedIDP256": "JWK d'Identité Décentralisée P-256", + "defaultDid": "DID par Défaut", + "selectOneOfTheDid": "Sélectionnez l'un des DIDs", + "clientTypeTitle": "Type de Client OIDC4VCI", + "clientTypeSubtitle": "Par défaut : DID\nSwitch pour changer le type de client", + "cryptographicHolderBinding": "Liaison du Titulaire Cryptographique", + "cryptographicHolderBindingSubtitle": "Par défaut : On\nDisable cryptographic binding for claim based binding credentials.", + "scopeParameters": "Paramètres", + "scopeParametersSubtitle": "Off\nEnable to force wallet to use scope instead of authorization_details.", + "clientAuthenticationMethods": "Méthodes d'authentification", "clientAuthenticationMethodsSubtitle": "Default: Client id as DID or JWK\nSelect to other authentication methods if needed.", - "vcFormatType": "VC Format", - "vcFormatTypeSubtitle": "Default: ldp_vc\nSelect one of the VC formats.", - "proofHeader": "OIDC4VCI Jwt Proof Type", - "proofHeaderSubtitle": "Default: kid\nSwitch if jwk is needed in header.", - "theServiceIsNotAvailable": "The service is not available", - "issuerDID": "Issuer DID", - "subjectDID": "Subject DID", + "vcFormatType": "Type de Format de VC", + "vcFormatTypeSubtitle": "Par défaut : ldp_vc\nSélectionnez l'un des formats VC.", + "proofHeader": "Type de Preuve OIDC4VCI Jwt", + "proofHeaderSubtitle": "Par défaut : kid\nChangez si un JWK est nécessaire dans l'en-tête.", + "theServiceIsNotAvailable": "Le service n'est pas disponible", + "issuerDID": "DID de l'Émetteur", + "subjectDID": "DID du Sujet", "type": "Type", - "credentialExpired": "Credential Expired", - "incorrectSignature": "Incorrect Signature", - "revokedOrSuspendedCredential": "Revoked or Suspended Credential", - "display": "Display", - "download": "Download", - "successfullyDownloaded": "Successfully Downloaded", - "advancedSecuritySettings": "Advanced Security Settings", - "clientMetadata": "Wallet metadata", - "theIssuanceOfThisCredentialIsPending": "The issuance of this credential is pending", - "clientId": "Client Id", - "clientSecret": "Client Secret", - "walletProfiles": "Wallet Profiles", - "walletProfilesDescription": "Choose your SSI profile or customize your own", - "profileCustom": "Custom", - "profileEbsiV3": "European Blockchain Services Infrastructure", - "decentralizedIdentityInteropProfile": "Decentralized Identity Interop Profile", - "protectYourWallet": "Protect your wallet", - "protectYourWalletMessage": "Use your fingerprint, face, or device PIN to secure and unlock your wallet. Your data is securely encrypted on this device.", - "pinUnlock": "PIN unlock", - "secureWithDevicePINOnly": "Secure with Device PIN only", - "biometricUnlock": "Biometric unlock", - "secureWithFingerprint": "Secure with Fingerprint", - "pinUnlockAndBiometric2FA": "PIN unlock + Biometric (2FA)", - "secureWithFingerprintAndPINBackup": "Secure with Fingerprint + PIN backup", - "secureYourWalletWithPINCodeAndBiometrics": "Secure your wallet with PIN code and Biometrics", - "twoFactorAuthenticationHasBeenEnabled": "Two factor authentication has been enabled.", - "createAnProfessionalWallet": "Create Enterprise Wallet", - "initialization": "Initialization", - "login": "Login", - "password": "Password", - "pleaseEnterYourEmailAndYourCompanyPasswordToCreateYourAccount": "Please enter your email and your company password to create your account", - "enterTheSecurityCodeThatWeSentYouByEmail": "Enter the security code that we sent you by email", - "enterTheSecurityCode": "Enter the security code", - "yourEmail": "Your email", - "publicKeyOfWalletInstance": "Public Key of Wallet Instance", - "walletInstanceKey": "Wallet Instance Key", - "protocoleStandardRelease": "Protocole standard release", - "organizationProfile": "Organization Profile", - "profileName": "Profile Name", - "companyName": "Company Name", - "configFileIdentifier": "Config file identifier", - "clientCredentials": "Client Credentials", - "updateYourWalletConfigNow": "Update your wallet config now", - "updateConfigurationNow": "Update configuration now", - "pleaseEnterYourEmailAndPasswordToUpdateYourOrganizationWalletConfiguration": "Please enter your email and password to update your organization wallet configuration", - "congrats": "Congrats !", - "yourWalletConfigurationHasBeenSuccessfullyUpdated": "Your wallet configuration has been successfully updated", - "continueString": "Continue", - "walletProvider": "Wallet Provider", - "theLdpFormatIsNotSupportedByThisDIDMethod": "The ldp_format is not supported by this DID method.", - "switchOffCryptoHolderBindingForThatDIDMethod": "Switch off Crypto Holder Binding for that DID Method.", - "thisTypeProofCannotBeUsedWithThisVCFormat": "This type proof cannot be used with this VC Format.", - "enterprise": "Enterprise", - "oWFBaselineProfile": "OWF Baseline Profile", - "defaultProfile":"Default" + "credentialExpired": "Document expiré", + "incorrectSignature": "Signature incorrecte", + "revokedOrSuspendedCredential": "Document révoqué ou suspendu", + "display": "Affichage", + "download": "Télécharger", + "successfullyDownloaded": "Téléchargé avec succès", + "advancedSecuritySettings": "Paramètres de sécurité avancés", + "clientMetadata": "Métadonnées du portefeuille", + "theIssuanceOfThisCredentialIsPending": "L'émission de ce Document est en cours", + "clientId": "ID client", + "clientSecret": "Secret client", + "walletProfiles": "Profils de portefeuille", + "walletProfilesDescription": "Choisissez votre profil SSI", + "profileCustom": "Personnalisé", + "profileEbsiV3": "Blockchain Européenne EBSI", + "decentralizedIdentityInteropProfile": "Profil DIIP", + "protectYourWallet": "Protégez votre portefeuille", + "protectYourWalletMessage": "Utilisez votre empreinte digitale, votre visage ou le code PIN de votre appareil pour sécuriser et déverrouiller votre portefeuille.", + "pinUnlock": "Déverrouillage par PIN", + "secureWithDevicePINOnly": "Sécurisé uniquement avec le code PIN de l'appareil", + "biometricUnlock": "Déverrouillage biométrique", + "secureWithFingerprint": "Sécurisé avec empreinte digitale", + "pinUnlockAndBiometric2FA": "Déverrouillage par PIN + Empreinte digitale (2FA)", + "secureWithFingerprintAndPINBackup": "Sécurisé avec empreinte digitale + Sauvegarde du code PIN", + "secureYourWalletWithPINCodeAndBiometrics": "Sécurisez votre portefeuille avec un code PIN + Empreinte digitale", + "twoFactorAuthenticationHasBeenEnabled": "L'authentification à deux facteurs a été activée.", + "createAnProfessionalWallet": "Créer un portefeuille professionnel", + "initialization": "Initialisation", + "login": "Connexion", + "password": "Mot de Passe", + "pleaseEnterYourEmailAndYourCompanyPasswordToCreateYourAccount": "Veuillez entrer votre email et le mot de passe pour créer votre compte", + "enterTheSecurityCodeThatWeSentYouByEmail": "Entrez le code de sécurité que nous vous avons envoyé par email", + "enterTheSecurityCode": "Entrez le code de sécurité", + "yourEmail": "Votre email", + "publicKeyOfWalletInstance": "Clé Publique de l'Instance de Portefeuille", + "walletInstanceKey": "Clé d'instance du portefeuille", + "protocoleStandardRelease": "Publication standard du protocole", + "organizationProfile": "Profil de l'organisation", + "profileName": "Nom du profil", + "companyName": "Nom de l'entreprise", + "configFileIdentifier": "Identifiant du fichier de configuration", + "clientCredentials": "Informations d'Identification du Client", + "updateYourWalletConfigNow": "Mettez à jour votre configuration maintenant", + "updateConfigurationNow": "Mettre à jour la configuration maintenant", + "pleaseEnterYourEmailAndPasswordToUpdateYourOrganizationWalletConfiguration": "Veuillez entrer votre email et votre mot de passe pour mettre à jour votre portefeuille", + "congrats": "Félicitation !", + "yourWalletConfigurationHasBeenSuccessfullyUpdated": "La configuration de votre portefeuille a été mise à jour avec succès", + "continueString": "Continuer", + "walletProvider": "Fournisseur de Portefeuille", + "theLdpFormatIsNotSupportedByThisDIDMethod": "Le format LDP n'est pas pris en charge par cette méthode DID.", + "switchOffCryptoHolderBindingForThatDIDMethod": "Désactivez la fonctionnalité \"Crypto Holder Binding\" pour cette méthode DID.", + "thisTypeProofCannotBeUsedWithThisVCFormat": "Ce type de preuve ne peut pas être utilisé avec ce format de VC.", + "enterprise": "Entreprise", + "oWFBaselineProfile": "Profil de base OWF", + "defaultProfile":"Profil par défaut", + "blockchainCardsDiscoverTitle": "Prouvez que vous possédez un compte crypto.", + "blockchainCardsDiscoverSubtitle": "Prouvez que vous possédez un compte crypto.", + "successfullyAddedEnterpriseAccount": "Compte entreprise ajouté avec succès !", + "successfullyUpdatedEnterpriseAccount": "Compte entreprise mis à jour avec succès !" + } diff --git a/lib/l10n/arb/app_it.arb b/lib/l10n/arb/app_it.arb deleted file mode 100644 index 975eb2bf9..000000000 --- a/lib/l10n/arb/app_it.arb +++ /dev/null @@ -1,3 +0,0 @@ -{ - "@@locale": "it" -} \ No newline at end of file diff --git a/lib/l10n/untranslated.json b/lib/l10n/untranslated.json index 0c29c8d49..ac52f842d 100644 --- a/lib/l10n/untranslated.json +++ b/lib/l10n/untranslated.json @@ -1,2842 +1,35 @@ { - "de": [ - "genericError", - "credentialListTitle", - "credentialDetailIssuedBy", - "listActionRefresh", - "listActionViewList", - "listActionViewGrid", - "listActionFilter", - "listActionSort", - "onBoardingStartSubtitle", - "onBoardingTosTitle", - "onBoardingTosText", - "onBoardingTosButton", - "onBoardingRecoveryTitle", - "onBoardingRecoveryButton", - "onBoardingGenPhraseTitle", - "onBoardingGenPhraseButton", - "onBoardingGenTitle", - "onBoardingGenButton", - "onBoardingSuccessTitle", - "onBoardingSuccessButton", - "credentialDetailShare", - "credentialAddedMessage", - "credentialDetailDeleteCard", - "credentialDetailDeleteConfirmationDialog", - "credentialDetailDeleteConfirmationDialogYes", - "credentialDetailDeleteConfirmationDialogNo", - "credentialDetailDeleteSuccessMessage", - "credentialDetailEditConfirmationDialog", - "credentialDetailEditConfirmationDialogYes", - "credentialDetailEditConfirmationDialogNo", - "credentialDetailEditSuccessMessage", - "credentialDetailCopyFieldValue", - "credentialDetailStatus", - "credentialPresentTitle", - "credentialPresentTitleDIDAuth", - "credentialPresentRequiredCredential", - "credentialPresentConfirm", - "credentialPresentCancel", - "credentialPickPresent", - "credentialPickTitle", - "selectYourTezosAssociatedWallet", - "credentialPickSelect", - "siopV2credentialPickSelect", - "credentialPickAlertMessage", - "credentialReceiveTitle", - "credentialReceiveHost", - "credentialAddThisCard", - "credentialReceiveCancel", - "credentialDetailListTitle", - "communicationHostAllow", - "communicationHostDeny", - "scanTitle", - "scanPromptHost", - "scanRefuseHost", - "scanUnsupportedMessage", - "qrCodeSharing", - "qrCodeNoValidMessage", - "profileTitle", - "personalTitle", - "termsTitle", - "recoveryKeyTitle", - "showRecoveryPhrase", - "warningDialogTitle", - "warningDialogSubtitle", - "recoveryText", - "recoveryMnemonicHintText", - "recoveryMnemonicError", - "showDialogYes", - "showDialogNo", - "supportTitle", - "noticesTitle", - "resetWalletButton", - "resetWalletConfirmationText", - "selectThemeText", - "lightThemeText", - "darkThemeText", - "systemThemeText", - "genPhraseInstruction", - "genPhraseExplanation", - "errorGeneratingKey", - "documentHeaderTooltipName", - "documentHeaderTooltipJob", - "documentHeaderTooltipLabel", - "documentHeaderTooltipValue", - "didDisplayId", - "blockChainDisplayMethod", - "blockChainAdress", - "didDisplayCopy", - "adressDisplayCopy", - "personalSave", - "personalSubtitle", - "personalFirstName", - "personalLastName", - "personalPhone", - "personalAddress", - "personalMail", - "lastName", - "firstName", - "gender", - "birthdate", - "birthplace", - "address", - "maritalStatus", - "nationality", - "identifier", - "issuer", - "workFor", - "startDate", - "endDate", - "employmentType", - "jobTitle", - "baseSalary", - "expires", - "generalInformationLabel", - "learningAchievement", - "signedBy", - "from", - "to", - "credential", - "issuanceDate", - "appContactWebsite", - "trustFrameworkDescription", - "confimrDIDAuth", - "evidenceLabel", - "networkErrorBadRequest", - "networkErrorConflict", - "networkErrorPreconditionFailed", - "networkErrorCreated", - "networkErrorGatewayTimeout", - "networkErrorInternalServerError", - "networkErrorMethodNotAllowed", - "networkErrorNoInternetConnection", - "networkErrorNotAcceptable", - "networkErrorNotImplemented", - "networkErrorOk", - "networkErrorRequestCancelled", - "networkErrorRequestTimeout", - "networkErrorSendTimeout", - "networkErrorServiceUnavailable", - "networkErrorTooManyRequests", - "networkErrorUnableToProcess", - "networkErrorUnauthenticated", - "networkErrorUnauthorizedRequest", - "networkErrorUnexpectedError", - "networkErrorNotFound", - "active", - "expired", - "revoked", - "ok", - "unavailable_feature_title", - "unavailable_feature_message", - "personalSkip", - "restoreCredential", - "backupCredential", - "backupCredentialPhrase", - "backupCredentialPhraseExplanation", - "backupCredentialButtonTitle", - "backupPolygonIdCredentialEmptyError", - "needStoragePermission", - "backupCredentialNotificationTitle", - "backupCredentialNotificationMessage", - "backupCredentialError", - "backupCredentialSuccessMessage", - "restorationCredentialWarningDialogSubtitle", - "recoveryCredentialPhrase", - "recoveryCredentialPhraseExplanation", - "recoveryCredentialButtonTitle", - "recoveryCredentialSuccessMessage", - "recoveryCredentialJSONFormatErrorMessage", - "recoveryCredentialAuthErrorMessage", - "recoveryCredentialDefaultErrorMessage", - "selfIssuedCreatedSuccessfully", - "companyName", - "companyWebsite", - "submit", - "insertYourDIDKey", - "importYourRSAKeyJsonFile", - "didKeyAndRSAKeyVerifiedSuccessfully", - "pleaseEnterYourDIDKey", - "pleaseImportYourRSAKey", - "confirm", - "pleaseSelectRSAKeyFileWithJsonExtension", - "rsaNotMatchedWithDIDKey", - "didKeyNotResolved", - "anUnknownErrorHappened", - "walletType", - "chooseYourWalletType", - "proceed", - "enterpriseWallet", - "personalWallet", - "failedToVerifySelfIssuedCredential", - "failedToCreateSelfIssuedCredential", - "credentialVerificationReturnWarning", - "failedToVerifyCredential", - "somethingsWentWrongTryAgainLater", - "successfullyPresentedYourCredential", - "successfullyPresentedYourDID", - "thisQRCodeIsNotSupported", - "thisUrlDoseNotContainAValidMessage", - "anErrorOccurredWhileConnectingToTheServer", - "failedToSaveMnemonicPleaseTryAgain", - "failedToLoadProfile", - "failedToSaveProfile", - "failedToLoadDID", - "personalOpenIdRestrictionMessage", - "credentialEmptyError", - "credentialPresentTitleSiopV2", - "confirmSiopV2", - "storagePermissionRequired", - "storagePermissionDeniedMessage", - "storagePermissionPermanentlyDeniedMessage", - "cancel", - "loading", - "issuerWebsitesTitle", - "getCredentialTitle", - "participantCredential", - "phonePassCredential", - "emailPassCredential", - "needEmailPass", - "signature", - "proof", - "verifyMe", - "yes", - "no", - "credentialAlias", - "verificationStatus", - "cardsPending", - "cardsActive", - "cardsProblem", - "unableToProcessTheData", - "unimplementedQueryType", - "onSubmittedPassBasePopUp", - "myCollection", - "items", - "succesfullyUpdated", - "generate", - "myAssets", - "search", - "professional", - "splashSubtitle", - "poweredBy", - "splashLoading", - "version", - "cards", - "nfts", - "coins", - "getCards", - "close", - "profile", - "infos", - "save", - "delete", - "enterNewPinCode", - "confirmYourPinCode", - "walletAltme", - "createPersonalWallet", - "createTitle", - "createSubtitle", - "enterYourPinCode", - "changePinCode", - "tryAgain", - "credentialSelectionListEmptyError", - "trustedIssuer", - "yourPinCodeChangedSuccessfully", - "advantagesCards", - "advantagesDiscoverCards", - "identityCards", - "identityDiscoverCards", - "contactInfoCredentials", - "contactInfoDiscoverCredentials", - "myProfessionalCards", - "otherCards", - "inMyWallet", - "details", - "getIt", - "getItNow", - "getThisCard", - "drawerBiometrics", - "drawerTalaoCommunityCard", - "drawerTalaoCommunityCardTitle", - "drawerTalaoCommunityCardSubtitle", - "drawerTalaoCommunityCardTextBoxMessage", - "drawerTalaoCommunityCardSubtitle2", - "drawerTalaoCommunityCardKeyError", - "loginWithBiometricsMessage", - "manage", - "wallet", - "manageAccounts", - "blockchainAccounts", - "educationCredentials", - "educationDiscoverCredentials", - "educationCredentialsDiscoverSubtitle", - "security", - "networkAndRegistries", - "chooseNetwork", - "chooseRegistry", - "trustFramework", - "network", - "issuerRegistry", - "about", - "termsOfUse", - "scanFingerprintToAuthenticate", - "biometricsNotSupported", - "deviceDoNotSupportBiometricsAuthentication", - "biometricsEnabledMessage", - "biometricsDisabledMessage", - "exportSecretKey", - "secretKey", - "chooseNetWork", - "nftEmptyMessage", - "myAccount", - "cryptoAccounts", - "cryptoAccount", - "cryptoAddAccount", - "cryptoAddedMessage", - "cryptoEditConfirmationDialog", - "cryptoEditConfirmationDialogYes", - "cryptoEditConfirmationDialogNo", - "cryptoEditLabel", - "onBoardingFirstTitle", - "onBoardingFirstSubtitle", - "onBoardingSecondTitle", - "onBoardingSecondSubtitle", - "onBoardingThirdTitle", - "onBoardingThirdSubtitle", - "onBoardingStart", - "learnMoreAboutAltme", - "scroll", - "agreeTermsAndConditionCheckBox", - "readTermsOfUseCheckBox", - "createOrImportNewAccount", - "selectAccount", - "onbordingSeedPhrase", - "onboardingPleaseStoreMessage", - "onboardingVerifyPhraseMessage", - "onboardingVerifyPhraseMessageDetails", - "onboardingAltmeMessage", - "onboardingWroteDownMessage", - "copyToClipboard", - "pinCodeMessage", - "enterNameForYourNewAccount", - "create", - "import", - "accountName", - "importWalletText", - "importWalletTextRecoveryPhraseOnly", - "recoveryPhraseDescriptions", - "importEasilyFrom", - "templeWallet", - "temple", - "metaMaskWallet", - "metaMask", - "kukai", - "kukaiWallet", - "other", - "otherWalletApp", - "importWalletHintText", - "importWalletHintTextRecoveryPhraseOnly", - "kycDialogTitle", - "idVerificationProcess", - "idCheck", - "facialRecognition", - "kycDialogButton", - "kycDialogFooter", - "finishedVerificationTitle", - "finishedVerificationDescription", - "verificationPendingTitle", - "verificationPendingDescription", - "verificationDeclinedTitle", - "restartVerification", - "verificationDeclinedDescription", - "verifiedTitle", - "verifiedDescription", - "verfiedButton", - "verifiedNotificationTitle", - "verifiedNotificationDescription", - "showDecentralizedID", - "manageDecentralizedID", - "addressBook", - "home", - "discover", - "settings", - "privateKeyDescriptions", - "importAccount", - "imported", - "cardDetails", - "publicAddress", - "didKey", - "export", - "copy", - "didPrivateKey", - "reveal", - "didPrivateKeyDescription", - "didPrivateKeyDescriptionAlert", - "iReadTheMessageCorrectly", - "beCareful", - "decentralizedIDKey", - "copySecretKeyToClipboard", - "copyDIDKeyToClipboard", - "seeAddress", - "revealPrivateKey", - "share", - "shareWith", - "copiedToClipboard", - "privateKey", - "decentralizedID", - "did", - "accountPrivateKeyAlert", - "sameAccountNameError", - "unknown", - "credentialManifestDescription", - "credentialManifestInformations", - "credentialDetailsActivity", - "credentialDetailsOrganisation", - "credentialDetailsPresented", - "credentialDetailsOrganisationDetail", - "credentialDetailsInWalletSince", - "termsOfUseAndLicenses", - "licenses", - "sendTo", - "next", - "withdrawalInputHint", - "amount", - "amountSent", - "max", - "edit", - "networkFee", - "totalAmount", - "selectToken", - "insufficientBalance", - "slow", - "average", - "fast", - "changeFee", - "sent", - "done", - "link", - "myTokens", - "tezosMainNetwork", - "send", - "receive", - "recentTransactions", - "sendOnlyToThisAddressDescription", - "addTokens", - "providedBy", - "issuedOn", - "expirationDate", - "connect", - "connection", - "selectAccountToGrantAccess", - "requestPersmissionTo", - "viewAccountBalanceAndNFTs", - "requestApprovalForTransaction", - "connectedWithBeacon", - "failedToConnectWithBeacon", - "tezosNetwork", - "confirm_sign", - "sign", - "payload_to_sign", - "signedPayload", - "failedToSignPayload", - "voucher", - "tezotopia", - "operationCompleted", - "operationFailed", - "membership", - "switchNetworkMessage", - "fee", - "addCards", - "gaming", - "identity", - "payment", - "socialMedia", - "advanceSettings", - "categories", - "selectCredentialCategoryWhichYouWantToShowInCredentialList", - "community", - "tezos", - "rights", - "disconnectAndRevokeRights", - "revokeAllRights", - "revokeSubtitleMessage", - "revokeAll", - "succesfullyDisconnected", - "connectedApps", - "manageConnectedApps", - "noDappConnected", - "nftDetails", - "failedToDoOperation", - "nft", - "receiveNft", - "sendOnlyNftToThisAddressDescription", - "beaconShareMessage", - "advantagesCredentialHomeSubtitle", - "advantagesCredentialDiscoverSubtitle", - "identityCredentialHomeSubtitle", - "identityCredentialDiscoverSubtitle", - "myProfessionalCredentialDiscoverSubtitle", - "blockchainAccountsCredentialHomeSubtitle", - "educationCredentialHomeSubtitle", - "passCredentialHomeSubtitle", - "financeCardsCredentialHomeSubtitle", - "financeCardsCredentialDiscoverSubtitle", - "contactInfoCredentialHomeSubtitle", - "contactInfoCredentialDiscoverSubtitle", - "otherCredentialHomeSubtitle", - "otherCredentialDiscoverSubtitle", - "showMore", - "showLess", - "youHaveReceivedARewardOf", - "gotIt", - "transactionErrorBalanceTooLow", - "transactionErrorCannotPayStorageFee", - "transactionErrorFeeTooLow", - "transactionErrorFeeTooLowForMempool", - "transactionErrorTxRollupBalanceTooLow", - "transactionErrorTxRollupInvalidZeroTransfer", - "transactionErrorTxRollupUnknownAddress", - "transactionErrorInactiveChain", - "website", - "whyGetThisCard", - "howToGetIt", - "emailPassWhyGetThisCard", - "emailPassExpirationDate", - "emailPassHowToGetIt", - "tezotopiaMembershipWhyGetThisCard", - "tezotopiaMembershipExpirationDate", - "tezotopiaMembershipLongDescription", - "chainbornMembershipHowToGetIt", - "chainbornMembershipWhyGetThisCard", - "chainbornMembershipExpirationDate", - "chainbornMembershipLongDescription", - "twitterHowToGetIt", - "twitterWhyGetThisCard", - "twitterExpirationDate", - "twitterDummyDesc", - "linkedinCardHowToGetIt", - "linkedinCardWhyGetThisCard", - "linkedinCardExpirationDate", - "tezotopiaMembershipHowToGetIt", - "over18WhyGetThisCard", - "over18ExpirationDate", - "over18HowToGetIt", - "over13WhyGetThisCard", - "over13ExpirationDate", - "over13HowToGetIt", - "over15WhyGetThisCard", - "over15ExpirationDate", - "over15HowToGetIt", - "passportFootprintWhyGetThisCard", - "passportFootprintExpirationDate", - "passportFootprintHowToGetIt", - "verifiableIdCardWhyGetThisCard", - "verifiableIdCardExpirationDate", - "verifiableIdCardHowToGetIt", - "verifiableIdCardDummyDesc", - "phoneProofWhyGetThisCard", - "phoneProofExpirationDate", - "phoneProofHowToGetIt", - "tezVoucherWhyGetThisCard", - "tezVoucherExpirationDate", - "tezVoucherHowToGetIt", - "genderWhyGetThisCard", - "genderExpirationDate", - "genderHowToGetIt", - "nationalityWhyGetThisCard", - "nationalityExpirationDate", - "nationalityHowToGetIt", - "ageRangeWhyGetThisCard", - "ageRangeExpirationDate", - "ageRangeHowToGetIt", - "defiComplianceWhyGetThisCard", - "defiComplianceExpirationDate", - "defiComplianceHowToGetIt", - "rewardDialogTitle", - "rewardDialogDescPart1", - "rewardDialogDescPart2", - "origin", - "nftTooBigToLoad", - "seeTransaction", - "nftListSubtitle", - "tokenListSubtitle", - "my", - "get", - "seeMoreNFTInformationOn", - "credentialStatus", - "pass", - "payloadFormatErrorMessage", - "thisFeatureIsNotSupportedMessage", - "myWallet", - "ethereumNetwork", - "fantomNetwork", - "polygonNetwork", - "binanceNetwork", - "step", - "activateBiometricsTitle", - "loginWithBiometricsOnBoarding", - "option", - "start", - "iAgreeToThe", - "termsAndConditions", - "walletReadyTitle", - "walletReadySubtitle", - "failedToInitCamera", - "chooseMethodPageOver18Title", - "chooseMethodPageOver13Title", - "chooseMethodPageOver15Title", - "chooseMethodPageOver21Title", - "chooseMethodPageOver50Title", - "chooseMethodPageOver65Title", - "chooseMethodPageAgeRangeTitle", - "chooseMethodPageVerifiableIdTitle", - "chooseMethodPageDefiComplianceTitle", - "chooseMethodPageSubtitle", - "kycTitle", - "kycSubtitle", - "passbaseTitle", - "passbaseSubtitle", - "verifyYourAge", - "verifyYourAgeSubtitle", - "verifyYourAgeDescription", - "accept", - "decline", - "yotiCameraAppbarTitle", - "cameraSubtitle", - "todoImportant", - "walletSecurity", - "walletSecurityDescription", - "blockchainSettings", - "blockchainSettingsDescription", - "ssi", - "ssiDescription", - "helpCenter", - "helpCenterDescription", - "aboutDescription", - "resetWallet", - "resetWalletDescription", - "showWalletRecoveryPhrase", - "showWalletRecoveryPhraseSubtitle", - "blockchainNetwork", - "contactUs", - "officialWebsite", - "yourAppVersion", - "resetWalletTitle", - "resetWalletSubtitle", - "resetWalletSubtitle2", - "resetWalletCheckBox1", - "resetWalletCheckBox2", - "email", - "fillingThisFieldIsMandatory", - "yourMessage", - "message", - "subject", - "enterAValidEmail", - "failedToSendEmail", - "selectAMethodToAddAccount", - "createAccount", - "createAccountDescription", - "importAccountDescription", - "chooseABlockchainForAccountCreation", - "tezosAccount", - "tezosAccountDescription", - "ethereumAccount", - "ethereumAccountDescription", - "fantomAccount", - "fantomAccountDescription", - "polygonAccount", - "polygonAccountDescription", - "binanceAccount", - "binanceAccountDescription", - "setAccountNameDescription", - "letsGo", - "congratulations", - "tezosAccountCreationCongratulations", - "ethereumAccountCreationCongratulations", - "fantomAccountCreationCongratulations", - "polygonAccountCreationCongratulations", - "binanceAccountCreationCongratulations", - "accountImportCongratulations", - "saveBackupCredentialTitle", - "saveBackupCredentialSubtitle", - "saveBackupPolygonCredentialSubtitle", - "restoreCredentialStep1Title", - "restorePhraseTextFieldHint", - "restoreCredentialStep2Title", - "loadFile", - "uploadFile", - "creators", - "publishers", - "creationDate", - "myProfessionalrCards", - "myProfessionalrCardsSubtitle", - "guardaWallet", - "exodusWallet", - "trustWallet", - "myetherwallet", - "skip", - "userNotFitErrorMessage", - "youAreMissing", - "credentialsRequestedBy", - "transactionIsLikelyToFail", - "buy", - "thisFeatureIsNotSupportedYetForFantom", - "thisFeatureIsNotSupportedYetForBinance", - "faqs", - "softwareLicenses", - "notAValidWalletAddress", - "otherAccount", - "thereIsNoAccountInYourWallet", - "exportToLinkedIn", - "addLinkedInInfo", - "whatsYourLinkedinProfileUrl", - "invalidUrlError", - "linkedInBannerSuccessfullyExported", - "credentialSuccessfullyExported", - "linkedInBanner", - "linkedInProfile", - "checkLinkedinProfile", - "scanAndDisplay", - "whatsNew", - "okGotIt", - "support", - "transactionDoneDialogDescription", - "withdrawalFailedMessage", - "credentialRequiredMessage", - "keyDecentralizedIdEdSA", - "keyDecentralizedIDSecp256k1", - "polygonIdDecentralizedId", - "ebsiV3DecentralizedId", - "requiredCredentialNotFoundTitle", - "requiredCredentialNotFoundSubTitle", - "requiredCredentialNotFoundDescription", - "backToHome", - "help", - "searchCredentials", - "supportChatWelcomeMessage", - "cardChatWelcomeMessage", - "creator", - "contractAddress", - "lastMetadataSync", - "e2eEncyptedChat", - "pincodeAttemptMessage", - "verifyNow", - "verifyLater", - "welDone", - "mnemonicsVerifiedMessage", - "chatWith", - "sendAnEmail", - "livenessCardHowToGetIt", - "livenessCardExpirationDate", - "livenessCardWhyGetThisCard", - "livenessCardLongDescription", - "chat", - "polygonDecentralizedID", - "needMnemonicVerificatinoDescription", - "succesfullyAuthenticated", - "authenticationFailed", - "documentType", - "countryCode", - "deviceIncompatibilityMessage", - "tezosProofMessage", - "ethereumProofMessage", - "fantomProofMessage", - "polygonProofMessage", - "binanceProofMessage", - "yearsOld", - "youAreOver13", - "youAreOver15", - "youAreOver18", - "youAreOver21", - "youAreOver50", - "youAreOver65", - "polygon", - "ebsi", - "backupPolygonIdIdentity", - "restorePolygonIdCredentials", - "comingSoon", - "financeCredentialsHomeTitle", - "financeCredentialsDiscoverTitle", - "financeCredentialsDiscoverSubtitle", - "financeCredentialsHomeSubtitle", - "hummanityProofCredentialsHomeTitle", - "hummanityProofCredentialsHomeSubtitle", - "hummanityProofCredentialsDiscoverTitle", - "hummanityProofCredentialsDiscoverSubtitle", - "socialMediaCredentialsHomeTitle", - "socialMediaCredentialsHomeSubtitle", - "socialMediaCredentialsDiscoverTitle", - "socialMediaCredentialsDiscoverSubtitle", - "walletIntegrityCredentialsHomeTitle", - "walletIntegrityCredentialsHomeSubtitle", - "walletIntegrityCredentialsDiscoverTitle", - "walletIntegrityCredentialsDiscoverSubtitle", - "polygonCredentialsHomeTitle", - "polygonCredentialsHomeSubtitle", - "polygonCredentialsDiscoverTitle", - "polygonCredentialsDiscoverSubtitle", - "pendingCredentialsHomeTitle", - "pendingCredentialsHomeSubtitle", - "restore", - "backup", - "takePicture", - "kyc", - "aiSystemWasNotAbleToEstimateYourAge", - "youGotAgeCredentials", - "yourAgeEstimationIs", - "credentialNotFound", - "cryptographicProof", - "downloadingCircuitLoadingMessage", - "cryptoAccountAlreadyExistMessage", - "errorGeneratingProof", - "createWalletMessage", - "successfullyGeneratingProof", - "wouldYouLikeToAcceptThisCredentialsFromThisOrganisation", - "thisOrganisationRequestsThisInformation", - "iS", - "isSmallerThan", - "isBiggerThan", - "isOneOfTheFollowingValues", - "isNotOneOfTheFollowingValues", - "isNot", - "approve", - "noInformationWillBeSharedFromThisCredentialMessage", - "burn", - "wouldYouLikeToConfirmThatYouIntendToBurnThisNFT", - "pleaseAddXtoConnectToTheDapp", - "pleaseSwitchPolygonNetwork", - "oidc4vcProfile", - "pleaseSwitchToCorrectOIDC4VCProfile", - "authenticationSuccess", - "format", - "pleaseInsertTheSecredCodeReceived", - "verifyIssuerWebsiteIdentity", - "verifyIssuerWebsiteIdentitySubtitle", - "developerMode", - "developerModeSubtitle", - "confirmVerifierAccess", - "confirmVerifierAccessSubtitle", - "credentialManifestSupport", - "credentialManifestSupportSubtitle", - "secureAuthenticationWithPINCode", - "secureAuthenticationWithPINCodeSubtitle", - "youcanSelectOnlyXCredential", - "theCredentialIsNotReady", - "theCredentialIsNoMoreReady", - "lowSecurity", - "highSecurity", - "theRequestIsRejected", - "userPinIsIncorrect", - "security_level", - "oidc4vc_settings", - "userPinTitle", - "userPinSubtitle", - "securityLevelTitle", - "securityLevelSubTitle", - "responseTypeNotSupported", - "invalidRequest", - "subjectSyntaxTypeNotSupported", - "accessDenied", - "thisRequestIsNotSupported", - "unsupportedCredential", - "aloginIsRequired", - "userConsentIsRequired", - "theWalletIsNotRegistered", - "credentialIssuanceDenied", - "thisCredentialFormatIsNotSupported", - "thisFormatIsNotSupported", - "moreDetails", - "theCredentialOfferIsInvalid", - "dateOfRequest", - "keyDecentralizedIDP256", - "jwkDecentralizedIDP256", - "defaultDid", - "selectOneOfTheDid", + "ca": [ "clientTypeTitle", "clientTypeSubtitle", - "cryptographicHolderBinding", - "cryptographicHolderBindingSubtitle", - "scopeParameters", - "scopeParametersSubtitle", - "clientAuthenticationMethods", - "clientAuthenticationMethodsSubtitle", - "vcFormatType", - "vcFormatTypeSubtitle", "proofHeader", "proofHeaderSubtitle", - "theServiceIsNotAvailable", - "issuerDID", - "subjectDID", - "type", - "credentialExpired", - "incorrectSignature", - "revokedOrSuspendedCredential", - "display", - "download", - "successfullyDownloaded", - "advancedSecuritySettings", - "clientMetadata", - "theIssuanceOfThisCredentialIsPending", - "clientId", - "clientSecret", - "walletProfiles", - "walletProfilesDescription", - "profileCustom", - "profileEbsiV3", - "decentralizedIdentityInteropProfile", - "protectYourWallet", - "protectYourWalletMessage", - "pinUnlock", - "secureWithDevicePINOnly", - "biometricUnlock", - "secureWithFingerprint", - "pinUnlockAndBiometric2FA", - "secureWithFingerprintAndPINBackup", - "secureYourWalletWithPINCodeAndBiometrics", - "twoFactorAuthenticationHasBeenEnabled", - "createAnProfessionalWallet", - "initialization", - "login", - "password", - "pleaseEnterYourEmailAndYourCompanyPasswordToCreateYourAccount", - "enterTheSecurityCodeThatWeSentYouByEmail", - "enterTheSecurityCode", - "yourEmail", - "publicKeyOfWalletInstance", - "walletInstanceKey", - "protocoleStandardRelease", - "organizationProfile", - "profileName", - "configFileIdentifier", - "clientCredentials", - "updateYourWalletConfigNow", - "updateConfigurationNow", - "pleaseEnterYourEmailAndPasswordToUpdateYourOrganizationWalletConfiguration", - "congrats", - "yourWalletConfigurationHasBeenSuccessfullyUpdated", - "continueString", - "walletProvider", "theLdpFormatIsNotSupportedByThisDIDMethod", "switchOffCryptoHolderBindingForThatDIDMethod", "thisTypeProofCannotBeUsedWithThisVCFormat", "enterprise", "oWFBaselineProfile", - "defaultProfile" + "defaultProfile", + "blockchainCardsDiscoverTitle", + "blockchainCardsDiscoverSubtitle", + "successfullyAddedEnterpriseAccount", + "successfullyUpdatedEnterpriseAccount" ], "es": [ - "genericError", - "credentialListTitle", - "credentialDetailIssuedBy", - "listActionRefresh", - "listActionViewList", - "listActionViewGrid", - "listActionFilter", - "listActionSort", - "onBoardingStartSubtitle", - "onBoardingTosTitle", - "onBoardingTosText", - "onBoardingTosButton", - "onBoardingRecoveryTitle", - "onBoardingRecoveryButton", - "onBoardingGenPhraseTitle", - "onBoardingGenPhraseButton", - "onBoardingGenTitle", - "onBoardingGenButton", - "onBoardingSuccessTitle", - "onBoardingSuccessButton", - "credentialDetailShare", - "credentialAddedMessage", - "credentialDetailDeleteCard", - "credentialDetailDeleteConfirmationDialog", - "credentialDetailDeleteConfirmationDialogYes", - "credentialDetailDeleteConfirmationDialogNo", - "credentialDetailDeleteSuccessMessage", - "credentialDetailEditConfirmationDialog", - "credentialDetailEditConfirmationDialogYes", - "credentialDetailEditConfirmationDialogNo", - "credentialDetailEditSuccessMessage", - "credentialDetailCopyFieldValue", - "credentialDetailStatus", - "credentialPresentTitle", - "credentialPresentTitleDIDAuth", - "credentialPresentRequiredCredential", - "credentialPresentConfirm", - "credentialPresentCancel", - "credentialPickPresent", - "credentialPickTitle", - "selectYourTezosAssociatedWallet", - "credentialPickSelect", - "siopV2credentialPickSelect", - "credentialPickAlertMessage", - "credentialReceiveTitle", - "credentialReceiveHost", - "credentialAddThisCard", - "credentialReceiveCancel", - "credentialDetailListTitle", - "communicationHostAllow", - "communicationHostDeny", - "scanTitle", - "scanPromptHost", - "scanRefuseHost", - "scanUnsupportedMessage", - "qrCodeSharing", - "qrCodeNoValidMessage", - "profileTitle", - "personalTitle", - "termsTitle", - "recoveryKeyTitle", - "showRecoveryPhrase", - "warningDialogTitle", - "warningDialogSubtitle", - "recoveryText", - "recoveryMnemonicHintText", - "recoveryMnemonicError", - "showDialogYes", - "showDialogNo", - "supportTitle", - "noticesTitle", - "resetWalletButton", - "resetWalletConfirmationText", - "selectThemeText", - "lightThemeText", - "darkThemeText", - "systemThemeText", - "genPhraseInstruction", - "genPhraseExplanation", - "errorGeneratingKey", - "documentHeaderTooltipName", - "documentHeaderTooltipJob", - "documentHeaderTooltipLabel", - "documentHeaderTooltipValue", - "didDisplayId", - "blockChainDisplayMethod", - "blockChainAdress", - "didDisplayCopy", - "adressDisplayCopy", - "personalSave", - "personalSubtitle", - "personalFirstName", - "personalLastName", - "personalPhone", - "personalAddress", - "personalMail", - "lastName", - "firstName", - "gender", - "birthdate", - "birthplace", - "address", - "maritalStatus", - "nationality", - "identifier", - "issuer", - "workFor", - "startDate", - "endDate", - "employmentType", - "jobTitle", - "baseSalary", - "expires", - "generalInformationLabel", - "learningAchievement", - "signedBy", - "from", - "to", - "credential", - "issuanceDate", - "appContactWebsite", - "trustFrameworkDescription", - "confimrDIDAuth", - "evidenceLabel", - "networkErrorBadRequest", - "networkErrorConflict", - "networkErrorPreconditionFailed", - "networkErrorCreated", - "networkErrorGatewayTimeout", - "networkErrorInternalServerError", - "networkErrorMethodNotAllowed", - "networkErrorNoInternetConnection", - "networkErrorNotAcceptable", - "networkErrorNotImplemented", - "networkErrorOk", - "networkErrorRequestCancelled", - "networkErrorRequestTimeout", - "networkErrorSendTimeout", - "networkErrorServiceUnavailable", - "networkErrorTooManyRequests", - "networkErrorUnableToProcess", - "networkErrorUnauthenticated", - "networkErrorUnauthorizedRequest", - "networkErrorUnexpectedError", - "networkErrorNotFound", - "active", - "expired", - "revoked", - "ok", - "unavailable_feature_title", - "unavailable_feature_message", - "personalSkip", - "restoreCredential", - "backupCredential", - "backupCredentialPhrase", - "backupCredentialPhraseExplanation", - "backupCredentialButtonTitle", - "backupPolygonIdCredentialEmptyError", - "needStoragePermission", - "backupCredentialNotificationTitle", - "backupCredentialNotificationMessage", - "backupCredentialError", - "backupCredentialSuccessMessage", - "restorationCredentialWarningDialogSubtitle", - "recoveryCredentialPhrase", - "recoveryCredentialPhraseExplanation", - "recoveryCredentialButtonTitle", - "recoveryCredentialSuccessMessage", - "recoveryCredentialJSONFormatErrorMessage", - "recoveryCredentialAuthErrorMessage", - "recoveryCredentialDefaultErrorMessage", - "selfIssuedCreatedSuccessfully", - "companyName", - "companyWebsite", - "submit", - "insertYourDIDKey", - "importYourRSAKeyJsonFile", - "didKeyAndRSAKeyVerifiedSuccessfully", - "pleaseEnterYourDIDKey", - "pleaseImportYourRSAKey", - "confirm", - "pleaseSelectRSAKeyFileWithJsonExtension", - "rsaNotMatchedWithDIDKey", - "didKeyNotResolved", - "anUnknownErrorHappened", - "walletType", - "chooseYourWalletType", - "proceed", - "enterpriseWallet", - "personalWallet", - "failedToVerifySelfIssuedCredential", - "failedToCreateSelfIssuedCredential", - "credentialVerificationReturnWarning", - "failedToVerifyCredential", - "somethingsWentWrongTryAgainLater", - "successfullyPresentedYourCredential", - "successfullyPresentedYourDID", - "thisQRCodeIsNotSupported", - "thisUrlDoseNotContainAValidMessage", - "anErrorOccurredWhileConnectingToTheServer", - "failedToSaveMnemonicPleaseTryAgain", - "failedToLoadProfile", - "failedToSaveProfile", - "failedToLoadDID", - "personalOpenIdRestrictionMessage", - "credentialEmptyError", - "credentialPresentTitleSiopV2", - "confirmSiopV2", - "storagePermissionRequired", - "storagePermissionDeniedMessage", - "storagePermissionPermanentlyDeniedMessage", - "cancel", - "loading", - "issuerWebsitesTitle", - "getCredentialTitle", - "participantCredential", - "phonePassCredential", - "emailPassCredential", - "needEmailPass", - "signature", - "proof", - "verifyMe", - "yes", - "no", - "credentialAlias", - "verificationStatus", - "cardsPending", - "cardsActive", - "cardsProblem", - "unableToProcessTheData", - "unimplementedQueryType", - "onSubmittedPassBasePopUp", - "myCollection", - "items", - "succesfullyUpdated", - "generate", - "myAssets", - "search", - "professional", - "splashSubtitle", - "poweredBy", - "splashLoading", - "version", - "cards", - "nfts", - "coins", - "getCards", - "close", - "profile", - "infos", - "save", - "delete", - "enterNewPinCode", - "confirmYourPinCode", - "walletAltme", - "createPersonalWallet", - "createTitle", - "createSubtitle", - "enterYourPinCode", - "changePinCode", - "tryAgain", - "credentialSelectionListEmptyError", - "trustedIssuer", - "yourPinCodeChangedSuccessfully", - "advantagesCards", - "advantagesDiscoverCards", - "identityCards", - "identityDiscoverCards", - "contactInfoCredentials", - "contactInfoDiscoverCredentials", - "myProfessionalCards", - "otherCards", - "inMyWallet", - "details", - "getIt", - "getItNow", - "getThisCard", - "drawerBiometrics", - "drawerTalaoCommunityCard", - "drawerTalaoCommunityCardTitle", - "drawerTalaoCommunityCardSubtitle", - "drawerTalaoCommunityCardTextBoxMessage", - "drawerTalaoCommunityCardSubtitle2", - "drawerTalaoCommunityCardKeyError", - "loginWithBiometricsMessage", - "manage", - "wallet", - "manageAccounts", - "blockchainAccounts", - "educationCredentials", - "educationDiscoverCredentials", - "educationCredentialsDiscoverSubtitle", - "security", - "networkAndRegistries", - "chooseNetwork", - "chooseRegistry", - "trustFramework", - "network", - "issuerRegistry", - "about", - "termsOfUse", - "scanFingerprintToAuthenticate", - "biometricsNotSupported", - "deviceDoNotSupportBiometricsAuthentication", - "biometricsEnabledMessage", - "biometricsDisabledMessage", - "exportSecretKey", - "secretKey", - "chooseNetWork", - "nftEmptyMessage", - "myAccount", - "cryptoAccounts", - "cryptoAccount", - "cryptoAddAccount", - "cryptoAddedMessage", - "cryptoEditConfirmationDialog", - "cryptoEditConfirmationDialogYes", - "cryptoEditConfirmationDialogNo", - "cryptoEditLabel", - "onBoardingFirstTitle", - "onBoardingFirstSubtitle", - "onBoardingSecondTitle", - "onBoardingSecondSubtitle", - "onBoardingThirdTitle", - "onBoardingThirdSubtitle", - "onBoardingStart", - "learnMoreAboutAltme", - "scroll", - "agreeTermsAndConditionCheckBox", - "readTermsOfUseCheckBox", - "createOrImportNewAccount", - "selectAccount", - "onbordingSeedPhrase", - "onboardingPleaseStoreMessage", - "onboardingVerifyPhraseMessage", - "onboardingVerifyPhraseMessageDetails", - "onboardingAltmeMessage", - "onboardingWroteDownMessage", - "copyToClipboard", - "pinCodeMessage", - "enterNameForYourNewAccount", - "create", - "import", - "accountName", - "importWalletText", - "importWalletTextRecoveryPhraseOnly", - "recoveryPhraseDescriptions", - "importEasilyFrom", - "templeWallet", - "temple", - "metaMaskWallet", - "metaMask", - "kukai", - "kukaiWallet", - "other", - "otherWalletApp", - "importWalletHintText", - "importWalletHintTextRecoveryPhraseOnly", - "kycDialogTitle", - "idVerificationProcess", - "idCheck", - "facialRecognition", - "kycDialogButton", - "kycDialogFooter", - "finishedVerificationTitle", - "finishedVerificationDescription", - "verificationPendingTitle", - "verificationPendingDescription", - "verificationDeclinedTitle", - "restartVerification", - "verificationDeclinedDescription", - "verifiedTitle", - "verifiedDescription", - "verfiedButton", - "verifiedNotificationTitle", - "verifiedNotificationDescription", - "showDecentralizedID", - "manageDecentralizedID", - "addressBook", - "home", - "discover", - "settings", - "privateKeyDescriptions", - "importAccount", - "imported", - "cardDetails", - "publicAddress", - "didKey", - "export", - "copy", - "didPrivateKey", - "reveal", - "didPrivateKeyDescription", - "didPrivateKeyDescriptionAlert", - "iReadTheMessageCorrectly", - "beCareful", - "decentralizedIDKey", - "copySecretKeyToClipboard", - "copyDIDKeyToClipboard", - "seeAddress", - "revealPrivateKey", - "share", - "shareWith", - "copiedToClipboard", - "privateKey", - "decentralizedID", - "did", - "accountPrivateKeyAlert", - "sameAccountNameError", - "unknown", - "credentialManifestDescription", - "credentialManifestInformations", - "credentialDetailsActivity", - "credentialDetailsOrganisation", - "credentialDetailsPresented", - "credentialDetailsOrganisationDetail", - "credentialDetailsInWalletSince", - "termsOfUseAndLicenses", - "licenses", - "sendTo", - "next", - "withdrawalInputHint", - "amount", - "amountSent", - "max", - "edit", - "networkFee", - "totalAmount", - "selectToken", - "insufficientBalance", - "slow", - "average", - "fast", - "changeFee", - "sent", - "done", - "link", - "myTokens", - "tezosMainNetwork", - "send", - "receive", - "recentTransactions", - "sendOnlyToThisAddressDescription", - "addTokens", - "providedBy", - "issuedOn", - "expirationDate", - "connect", - "connection", - "selectAccountToGrantAccess", - "requestPersmissionTo", - "viewAccountBalanceAndNFTs", - "requestApprovalForTransaction", - "connectedWithBeacon", - "failedToConnectWithBeacon", - "tezosNetwork", - "confirm_sign", - "sign", - "payload_to_sign", - "signedPayload", - "failedToSignPayload", - "voucher", - "tezotopia", - "operationCompleted", - "operationFailed", - "membership", - "switchNetworkMessage", - "fee", - "addCards", - "gaming", - "identity", - "payment", - "socialMedia", - "advanceSettings", - "categories", - "selectCredentialCategoryWhichYouWantToShowInCredentialList", - "community", - "tezos", - "rights", - "disconnectAndRevokeRights", - "revokeAllRights", - "revokeSubtitleMessage", - "revokeAll", - "succesfullyDisconnected", - "connectedApps", - "manageConnectedApps", - "noDappConnected", - "nftDetails", - "failedToDoOperation", - "nft", - "receiveNft", - "sendOnlyNftToThisAddressDescription", - "beaconShareMessage", - "advantagesCredentialHomeSubtitle", - "advantagesCredentialDiscoverSubtitle", - "identityCredentialHomeSubtitle", - "identityCredentialDiscoverSubtitle", - "myProfessionalCredentialDiscoverSubtitle", - "blockchainAccountsCredentialHomeSubtitle", - "educationCredentialHomeSubtitle", - "passCredentialHomeSubtitle", - "financeCardsCredentialHomeSubtitle", - "financeCardsCredentialDiscoverSubtitle", - "contactInfoCredentialHomeSubtitle", - "contactInfoCredentialDiscoverSubtitle", - "otherCredentialHomeSubtitle", - "otherCredentialDiscoverSubtitle", - "showMore", - "showLess", - "youHaveReceivedARewardOf", - "gotIt", - "transactionErrorBalanceTooLow", - "transactionErrorCannotPayStorageFee", - "transactionErrorFeeTooLow", - "transactionErrorFeeTooLowForMempool", - "transactionErrorTxRollupBalanceTooLow", - "transactionErrorTxRollupInvalidZeroTransfer", - "transactionErrorTxRollupUnknownAddress", - "transactionErrorInactiveChain", - "website", - "whyGetThisCard", - "howToGetIt", - "emailPassWhyGetThisCard", - "emailPassExpirationDate", - "emailPassHowToGetIt", - "tezotopiaMembershipWhyGetThisCard", - "tezotopiaMembershipExpirationDate", - "tezotopiaMembershipLongDescription", - "chainbornMembershipHowToGetIt", - "chainbornMembershipWhyGetThisCard", - "chainbornMembershipExpirationDate", - "chainbornMembershipLongDescription", - "twitterHowToGetIt", - "twitterWhyGetThisCard", - "twitterExpirationDate", - "twitterDummyDesc", - "linkedinCardHowToGetIt", - "linkedinCardWhyGetThisCard", - "linkedinCardExpirationDate", - "tezotopiaMembershipHowToGetIt", - "over18WhyGetThisCard", - "over18ExpirationDate", - "over18HowToGetIt", - "over13WhyGetThisCard", - "over13ExpirationDate", - "over13HowToGetIt", - "over15WhyGetThisCard", - "over15ExpirationDate", - "over15HowToGetIt", - "passportFootprintWhyGetThisCard", - "passportFootprintExpirationDate", - "passportFootprintHowToGetIt", - "verifiableIdCardWhyGetThisCard", - "verifiableIdCardExpirationDate", - "verifiableIdCardHowToGetIt", - "verifiableIdCardDummyDesc", - "phoneProofWhyGetThisCard", - "phoneProofExpirationDate", - "phoneProofHowToGetIt", - "tezVoucherWhyGetThisCard", - "tezVoucherExpirationDate", - "tezVoucherHowToGetIt", - "genderWhyGetThisCard", - "genderExpirationDate", - "genderHowToGetIt", - "nationalityWhyGetThisCard", - "nationalityExpirationDate", - "nationalityHowToGetIt", - "ageRangeWhyGetThisCard", - "ageRangeExpirationDate", - "ageRangeHowToGetIt", - "defiComplianceWhyGetThisCard", - "defiComplianceExpirationDate", - "defiComplianceHowToGetIt", - "rewardDialogTitle", - "rewardDialogDescPart1", - "rewardDialogDescPart2", - "origin", - "nftTooBigToLoad", - "seeTransaction", - "nftListSubtitle", - "tokenListSubtitle", - "my", - "get", - "seeMoreNFTInformationOn", - "credentialStatus", - "pass", - "payloadFormatErrorMessage", - "thisFeatureIsNotSupportedMessage", - "myWallet", - "ethereumNetwork", - "fantomNetwork", - "polygonNetwork", - "binanceNetwork", - "step", - "activateBiometricsTitle", - "loginWithBiometricsOnBoarding", - "option", - "start", - "iAgreeToThe", - "termsAndConditions", - "walletReadyTitle", - "walletReadySubtitle", - "failedToInitCamera", - "chooseMethodPageOver18Title", - "chooseMethodPageOver13Title", - "chooseMethodPageOver15Title", - "chooseMethodPageOver21Title", - "chooseMethodPageOver50Title", - "chooseMethodPageOver65Title", - "chooseMethodPageAgeRangeTitle", - "chooseMethodPageVerifiableIdTitle", - "chooseMethodPageDefiComplianceTitle", - "chooseMethodPageSubtitle", - "kycTitle", - "kycSubtitle", - "passbaseTitle", - "passbaseSubtitle", - "verifyYourAge", - "verifyYourAgeSubtitle", - "verifyYourAgeDescription", - "accept", - "decline", - "yotiCameraAppbarTitle", - "cameraSubtitle", - "todoImportant", - "walletSecurity", - "walletSecurityDescription", - "blockchainSettings", - "blockchainSettingsDescription", - "ssi", - "ssiDescription", - "helpCenter", - "helpCenterDescription", - "aboutDescription", - "resetWallet", - "resetWalletDescription", - "showWalletRecoveryPhrase", - "showWalletRecoveryPhraseSubtitle", - "blockchainNetwork", - "contactUs", - "officialWebsite", - "yourAppVersion", - "resetWalletTitle", - "resetWalletSubtitle", - "resetWalletSubtitle2", - "resetWalletCheckBox1", - "resetWalletCheckBox2", - "email", - "fillingThisFieldIsMandatory", - "yourMessage", - "message", - "subject", - "enterAValidEmail", - "failedToSendEmail", - "selectAMethodToAddAccount", - "createAccount", - "createAccountDescription", - "importAccountDescription", - "chooseABlockchainForAccountCreation", - "tezosAccount", - "tezosAccountDescription", - "ethereumAccount", - "ethereumAccountDescription", - "fantomAccount", - "fantomAccountDescription", - "polygonAccount", - "polygonAccountDescription", - "binanceAccount", - "binanceAccountDescription", - "setAccountNameDescription", - "letsGo", - "congratulations", - "tezosAccountCreationCongratulations", - "ethereumAccountCreationCongratulations", - "fantomAccountCreationCongratulations", - "polygonAccountCreationCongratulations", - "binanceAccountCreationCongratulations", - "accountImportCongratulations", - "saveBackupCredentialTitle", - "saveBackupCredentialSubtitle", - "saveBackupPolygonCredentialSubtitle", - "restoreCredentialStep1Title", - "restorePhraseTextFieldHint", - "restoreCredentialStep2Title", - "loadFile", - "uploadFile", - "creators", - "publishers", - "creationDate", - "myProfessionalrCards", - "myProfessionalrCardsSubtitle", - "guardaWallet", - "exodusWallet", - "trustWallet", - "myetherwallet", - "skip", - "userNotFitErrorMessage", - "youAreMissing", - "credentialsRequestedBy", - "transactionIsLikelyToFail", - "buy", - "thisFeatureIsNotSupportedYetForFantom", - "thisFeatureIsNotSupportedYetForBinance", - "faqs", - "softwareLicenses", - "notAValidWalletAddress", - "otherAccount", - "thereIsNoAccountInYourWallet", - "exportToLinkedIn", - "addLinkedInInfo", - "whatsYourLinkedinProfileUrl", - "invalidUrlError", - "linkedInBannerSuccessfullyExported", - "credentialSuccessfullyExported", - "linkedInBanner", - "linkedInProfile", - "checkLinkedinProfile", - "scanAndDisplay", - "whatsNew", - "okGotIt", - "support", - "transactionDoneDialogDescription", - "withdrawalFailedMessage", - "credentialRequiredMessage", - "keyDecentralizedIdEdSA", - "keyDecentralizedIDSecp256k1", - "polygonIdDecentralizedId", - "ebsiV3DecentralizedId", - "requiredCredentialNotFoundTitle", - "requiredCredentialNotFoundSubTitle", - "requiredCredentialNotFoundDescription", - "backToHome", - "help", - "searchCredentials", - "supportChatWelcomeMessage", - "cardChatWelcomeMessage", - "creator", - "contractAddress", - "lastMetadataSync", - "e2eEncyptedChat", - "pincodeAttemptMessage", - "verifyNow", - "verifyLater", - "welDone", - "mnemonicsVerifiedMessage", - "chatWith", - "sendAnEmail", - "livenessCardHowToGetIt", - "livenessCardExpirationDate", - "livenessCardWhyGetThisCard", - "livenessCardLongDescription", - "chat", - "polygonDecentralizedID", - "needMnemonicVerificatinoDescription", - "succesfullyAuthenticated", - "authenticationFailed", - "documentType", - "countryCode", - "deviceIncompatibilityMessage", - "tezosProofMessage", - "ethereumProofMessage", - "fantomProofMessage", - "polygonProofMessage", - "binanceProofMessage", - "yearsOld", - "youAreOver13", - "youAreOver15", - "youAreOver18", - "youAreOver21", - "youAreOver50", - "youAreOver65", - "polygon", - "ebsi", - "backupPolygonIdIdentity", - "restorePolygonIdCredentials", - "comingSoon", - "financeCredentialsHomeTitle", - "financeCredentialsDiscoverTitle", - "financeCredentialsDiscoverSubtitle", - "financeCredentialsHomeSubtitle", - "hummanityProofCredentialsHomeTitle", - "hummanityProofCredentialsHomeSubtitle", - "hummanityProofCredentialsDiscoverTitle", - "hummanityProofCredentialsDiscoverSubtitle", - "socialMediaCredentialsHomeTitle", - "socialMediaCredentialsHomeSubtitle", - "socialMediaCredentialsDiscoverTitle", - "socialMediaCredentialsDiscoverSubtitle", - "walletIntegrityCredentialsHomeTitle", - "walletIntegrityCredentialsHomeSubtitle", - "walletIntegrityCredentialsDiscoverTitle", - "walletIntegrityCredentialsDiscoverSubtitle", - "polygonCredentialsHomeTitle", - "polygonCredentialsHomeSubtitle", - "polygonCredentialsDiscoverTitle", - "polygonCredentialsDiscoverSubtitle", - "pendingCredentialsHomeTitle", - "pendingCredentialsHomeSubtitle", - "restore", - "backup", - "takePicture", - "kyc", - "aiSystemWasNotAbleToEstimateYourAge", - "youGotAgeCredentials", - "yourAgeEstimationIs", - "credentialNotFound", - "cryptographicProof", - "downloadingCircuitLoadingMessage", - "cryptoAccountAlreadyExistMessage", - "errorGeneratingProof", - "createWalletMessage", - "successfullyGeneratingProof", - "wouldYouLikeToAcceptThisCredentialsFromThisOrganisation", - "thisOrganisationRequestsThisInformation", - "iS", - "isSmallerThan", - "isBiggerThan", - "isOneOfTheFollowingValues", - "isNotOneOfTheFollowingValues", - "isNot", - "approve", - "noInformationWillBeSharedFromThisCredentialMessage", - "burn", - "wouldYouLikeToConfirmThatYouIntendToBurnThisNFT", - "pleaseAddXtoConnectToTheDapp", - "pleaseSwitchPolygonNetwork", - "oidc4vcProfile", - "pleaseSwitchToCorrectOIDC4VCProfile", - "authenticationSuccess", - "format", - "pleaseInsertTheSecredCodeReceived", - "verifyIssuerWebsiteIdentity", - "verifyIssuerWebsiteIdentitySubtitle", - "developerMode", - "developerModeSubtitle", - "confirmVerifierAccess", - "confirmVerifierAccessSubtitle", - "credentialManifestSupport", - "credentialManifestSupportSubtitle", - "secureAuthenticationWithPINCode", - "secureAuthenticationWithPINCodeSubtitle", - "youcanSelectOnlyXCredential", - "theCredentialIsNotReady", - "theCredentialIsNoMoreReady", - "lowSecurity", - "highSecurity", - "theRequestIsRejected", - "userPinIsIncorrect", - "security_level", - "oidc4vc_settings", - "userPinTitle", - "userPinSubtitle", - "securityLevelTitle", - "securityLevelSubTitle", - "responseTypeNotSupported", - "invalidRequest", - "subjectSyntaxTypeNotSupported", - "accessDenied", - "thisRequestIsNotSupported", - "unsupportedCredential", - "aloginIsRequired", - "userConsentIsRequired", - "theWalletIsNotRegistered", - "credentialIssuanceDenied", - "thisCredentialFormatIsNotSupported", - "thisFormatIsNotSupported", - "moreDetails", - "theCredentialOfferIsInvalid", - "dateOfRequest", - "keyDecentralizedIDP256", - "jwkDecentralizedIDP256", - "defaultDid", - "selectOneOfTheDid", "clientTypeTitle", "clientTypeSubtitle", - "cryptographicHolderBinding", - "cryptographicHolderBindingSubtitle", - "scopeParameters", - "scopeParametersSubtitle", - "clientAuthenticationMethods", - "clientAuthenticationMethodsSubtitle", - "vcFormatType", - "vcFormatTypeSubtitle", "proofHeader", "proofHeaderSubtitle", - "theServiceIsNotAvailable", - "issuerDID", - "subjectDID", - "type", - "credentialExpired", - "incorrectSignature", - "revokedOrSuspendedCredential", - "display", - "download", - "successfullyDownloaded", - "advancedSecuritySettings", - "clientMetadata", - "theIssuanceOfThisCredentialIsPending", - "clientId", - "clientSecret", - "walletProfiles", - "walletProfilesDescription", - "profileCustom", - "profileEbsiV3", - "decentralizedIdentityInteropProfile", - "protectYourWallet", - "protectYourWalletMessage", - "pinUnlock", - "secureWithDevicePINOnly", - "biometricUnlock", - "secureWithFingerprint", - "pinUnlockAndBiometric2FA", - "secureWithFingerprintAndPINBackup", - "secureYourWalletWithPINCodeAndBiometrics", - "twoFactorAuthenticationHasBeenEnabled", - "createAnProfessionalWallet", - "initialization", - "login", - "password", - "pleaseEnterYourEmailAndYourCompanyPasswordToCreateYourAccount", - "enterTheSecurityCodeThatWeSentYouByEmail", - "enterTheSecurityCode", - "yourEmail", - "publicKeyOfWalletInstance", - "walletInstanceKey", - "protocoleStandardRelease", - "organizationProfile", - "profileName", - "configFileIdentifier", - "clientCredentials", - "updateYourWalletConfigNow", - "updateConfigurationNow", - "pleaseEnterYourEmailAndPasswordToUpdateYourOrganizationWalletConfiguration", - "congrats", - "yourWalletConfigurationHasBeenSuccessfullyUpdated", - "continueString", - "walletProvider", "theLdpFormatIsNotSupportedByThisDIDMethod", "switchOffCryptoHolderBindingForThatDIDMethod", "thisTypeProofCannotBeUsedWithThisVCFormat", "enterprise", "oWFBaselineProfile", - "defaultProfile" - ], - - "it": [ - "genericError", - "credentialListTitle", - "credentialDetailIssuedBy", - "listActionRefresh", - "listActionViewList", - "listActionViewGrid", - "listActionFilter", - "listActionSort", - "onBoardingStartSubtitle", - "onBoardingTosTitle", - "onBoardingTosText", - "onBoardingTosButton", - "onBoardingRecoveryTitle", - "onBoardingRecoveryButton", - "onBoardingGenPhraseTitle", - "onBoardingGenPhraseButton", - "onBoardingGenTitle", - "onBoardingGenButton", - "onBoardingSuccessTitle", - "onBoardingSuccessButton", - "credentialDetailShare", - "credentialAddedMessage", - "credentialDetailDeleteCard", - "credentialDetailDeleteConfirmationDialog", - "credentialDetailDeleteConfirmationDialogYes", - "credentialDetailDeleteConfirmationDialogNo", - "credentialDetailDeleteSuccessMessage", - "credentialDetailEditConfirmationDialog", - "credentialDetailEditConfirmationDialogYes", - "credentialDetailEditConfirmationDialogNo", - "credentialDetailEditSuccessMessage", - "credentialDetailCopyFieldValue", - "credentialDetailStatus", - "credentialPresentTitle", - "credentialPresentTitleDIDAuth", - "credentialPresentRequiredCredential", - "credentialPresentConfirm", - "credentialPresentCancel", - "credentialPickPresent", - "credentialPickTitle", - "selectYourTezosAssociatedWallet", - "credentialPickSelect", - "siopV2credentialPickSelect", - "credentialPickAlertMessage", - "credentialReceiveTitle", - "credentialReceiveHost", - "credentialAddThisCard", - "credentialReceiveCancel", - "credentialDetailListTitle", - "communicationHostAllow", - "communicationHostDeny", - "scanTitle", - "scanPromptHost", - "scanRefuseHost", - "scanUnsupportedMessage", - "qrCodeSharing", - "qrCodeNoValidMessage", - "profileTitle", - "personalTitle", - "termsTitle", - "recoveryKeyTitle", - "showRecoveryPhrase", - "warningDialogTitle", - "warningDialogSubtitle", - "recoveryText", - "recoveryMnemonicHintText", - "recoveryMnemonicError", - "showDialogYes", - "showDialogNo", - "supportTitle", - "noticesTitle", - "resetWalletButton", - "resetWalletConfirmationText", - "selectThemeText", - "lightThemeText", - "darkThemeText", - "systemThemeText", - "genPhraseInstruction", - "genPhraseExplanation", - "errorGeneratingKey", - "documentHeaderTooltipName", - "documentHeaderTooltipJob", - "documentHeaderTooltipLabel", - "documentHeaderTooltipValue", - "didDisplayId", - "blockChainDisplayMethod", - "blockChainAdress", - "didDisplayCopy", - "adressDisplayCopy", - "personalSave", - "personalSubtitle", - "personalFirstName", - "personalLastName", - "personalPhone", - "personalAddress", - "personalMail", - "lastName", - "firstName", - "gender", - "birthdate", - "birthplace", - "address", - "maritalStatus", - "nationality", - "identifier", - "issuer", - "workFor", - "startDate", - "endDate", - "employmentType", - "jobTitle", - "baseSalary", - "expires", - "generalInformationLabel", - "learningAchievement", - "signedBy", - "from", - "to", - "credential", - "issuanceDate", - "appContactWebsite", - "trustFrameworkDescription", - "confimrDIDAuth", - "evidenceLabel", - "networkErrorBadRequest", - "networkErrorConflict", - "networkErrorPreconditionFailed", - "networkErrorCreated", - "networkErrorGatewayTimeout", - "networkErrorInternalServerError", - "networkErrorMethodNotAllowed", - "networkErrorNoInternetConnection", - "networkErrorNotAcceptable", - "networkErrorNotImplemented", - "networkErrorOk", - "networkErrorRequestCancelled", - "networkErrorRequestTimeout", - "networkErrorSendTimeout", - "networkErrorServiceUnavailable", - "networkErrorTooManyRequests", - "networkErrorUnableToProcess", - "networkErrorUnauthenticated", - "networkErrorUnauthorizedRequest", - "networkErrorUnexpectedError", - "networkErrorNotFound", - "active", - "expired", - "revoked", - "ok", - "unavailable_feature_title", - "unavailable_feature_message", - "personalSkip", - "restoreCredential", - "backupCredential", - "backupCredentialPhrase", - "backupCredentialPhraseExplanation", - "backupCredentialButtonTitle", - "backupPolygonIdCredentialEmptyError", - "needStoragePermission", - "backupCredentialNotificationTitle", - "backupCredentialNotificationMessage", - "backupCredentialError", - "backupCredentialSuccessMessage", - "restorationCredentialWarningDialogSubtitle", - "recoveryCredentialPhrase", - "recoveryCredentialPhraseExplanation", - "recoveryCredentialButtonTitle", - "recoveryCredentialSuccessMessage", - "recoveryCredentialJSONFormatErrorMessage", - "recoveryCredentialAuthErrorMessage", - "recoveryCredentialDefaultErrorMessage", - "selfIssuedCreatedSuccessfully", - "companyName", - "companyWebsite", - "submit", - "insertYourDIDKey", - "importYourRSAKeyJsonFile", - "didKeyAndRSAKeyVerifiedSuccessfully", - "pleaseEnterYourDIDKey", - "pleaseImportYourRSAKey", - "confirm", - "pleaseSelectRSAKeyFileWithJsonExtension", - "rsaNotMatchedWithDIDKey", - "didKeyNotResolved", - "anUnknownErrorHappened", - "walletType", - "chooseYourWalletType", - "proceed", - "enterpriseWallet", - "personalWallet", - "failedToVerifySelfIssuedCredential", - "failedToCreateSelfIssuedCredential", - "credentialVerificationReturnWarning", - "failedToVerifyCredential", - "somethingsWentWrongTryAgainLater", - "successfullyPresentedYourCredential", - "successfullyPresentedYourDID", - "thisQRCodeIsNotSupported", - "thisUrlDoseNotContainAValidMessage", - "anErrorOccurredWhileConnectingToTheServer", - "failedToSaveMnemonicPleaseTryAgain", - "failedToLoadProfile", - "failedToSaveProfile", - "failedToLoadDID", - "personalOpenIdRestrictionMessage", - "credentialEmptyError", - "credentialPresentTitleSiopV2", - "confirmSiopV2", - "storagePermissionRequired", - "storagePermissionDeniedMessage", - "storagePermissionPermanentlyDeniedMessage", - "cancel", - "loading", - "issuerWebsitesTitle", - "getCredentialTitle", - "participantCredential", - "phonePassCredential", - "emailPassCredential", - "needEmailPass", - "signature", - "proof", - "verifyMe", - "yes", - "no", - "credentialAlias", - "verificationStatus", - "cardsPending", - "cardsActive", - "cardsProblem", - "unableToProcessTheData", - "unimplementedQueryType", - "onSubmittedPassBasePopUp", - "myCollection", - "items", - "succesfullyUpdated", - "generate", - "myAssets", - "search", - "professional", - "splashSubtitle", - "poweredBy", - "splashLoading", - "version", - "cards", - "nfts", - "coins", - "getCards", - "close", - "profile", - "infos", - "save", - "delete", - "enterNewPinCode", - "confirmYourPinCode", - "walletAltme", - "createPersonalWallet", - "createTitle", - "createSubtitle", - "enterYourPinCode", - "changePinCode", - "tryAgain", - "credentialSelectionListEmptyError", - "trustedIssuer", - "yourPinCodeChangedSuccessfully", - "advantagesCards", - "advantagesDiscoverCards", - "identityCards", - "identityDiscoverCards", - "contactInfoCredentials", - "contactInfoDiscoverCredentials", - "myProfessionalCards", - "otherCards", - "inMyWallet", - "details", - "getIt", - "getItNow", - "getThisCard", - "drawerBiometrics", - "drawerTalaoCommunityCard", - "drawerTalaoCommunityCardTitle", - "drawerTalaoCommunityCardSubtitle", - "drawerTalaoCommunityCardTextBoxMessage", - "drawerTalaoCommunityCardSubtitle2", - "drawerTalaoCommunityCardKeyError", - "loginWithBiometricsMessage", - "manage", - "wallet", - "manageAccounts", - "blockchainAccounts", - "educationCredentials", - "educationDiscoverCredentials", - "educationCredentialsDiscoverSubtitle", - "security", - "networkAndRegistries", - "chooseNetwork", - "chooseRegistry", - "trustFramework", - "network", - "issuerRegistry", - "about", - "termsOfUse", - "scanFingerprintToAuthenticate", - "biometricsNotSupported", - "deviceDoNotSupportBiometricsAuthentication", - "biometricsEnabledMessage", - "biometricsDisabledMessage", - "exportSecretKey", - "secretKey", - "chooseNetWork", - "nftEmptyMessage", - "myAccount", - "cryptoAccounts", - "cryptoAccount", - "cryptoAddAccount", - "cryptoAddedMessage", - "cryptoEditConfirmationDialog", - "cryptoEditConfirmationDialogYes", - "cryptoEditConfirmationDialogNo", - "cryptoEditLabel", - "onBoardingFirstTitle", - "onBoardingFirstSubtitle", - "onBoardingSecondTitle", - "onBoardingSecondSubtitle", - "onBoardingThirdTitle", - "onBoardingThirdSubtitle", - "onBoardingStart", - "learnMoreAboutAltme", - "scroll", - "agreeTermsAndConditionCheckBox", - "readTermsOfUseCheckBox", - "createOrImportNewAccount", - "selectAccount", - "onbordingSeedPhrase", - "onboardingPleaseStoreMessage", - "onboardingVerifyPhraseMessage", - "onboardingVerifyPhraseMessageDetails", - "onboardingAltmeMessage", - "onboardingWroteDownMessage", - "copyToClipboard", - "pinCodeMessage", - "enterNameForYourNewAccount", - "create", - "import", - "accountName", - "importWalletText", - "importWalletTextRecoveryPhraseOnly", - "recoveryPhraseDescriptions", - "importEasilyFrom", - "templeWallet", - "temple", - "metaMaskWallet", - "metaMask", - "kukai", - "kukaiWallet", - "other", - "otherWalletApp", - "importWalletHintText", - "importWalletHintTextRecoveryPhraseOnly", - "kycDialogTitle", - "idVerificationProcess", - "idCheck", - "facialRecognition", - "kycDialogButton", - "kycDialogFooter", - "finishedVerificationTitle", - "finishedVerificationDescription", - "verificationPendingTitle", - "verificationPendingDescription", - "verificationDeclinedTitle", - "restartVerification", - "verificationDeclinedDescription", - "verifiedTitle", - "verifiedDescription", - "verfiedButton", - "verifiedNotificationTitle", - "verifiedNotificationDescription", - "showDecentralizedID", - "manageDecentralizedID", - "addressBook", - "home", - "discover", - "settings", - "privateKeyDescriptions", - "importAccount", - "imported", - "cardDetails", - "publicAddress", - "didKey", - "export", - "copy", - "didPrivateKey", - "reveal", - "didPrivateKeyDescription", - "didPrivateKeyDescriptionAlert", - "iReadTheMessageCorrectly", - "beCareful", - "decentralizedIDKey", - "copySecretKeyToClipboard", - "copyDIDKeyToClipboard", - "seeAddress", - "revealPrivateKey", - "share", - "shareWith", - "copiedToClipboard", - "privateKey", - "decentralizedID", - "did", - "accountPrivateKeyAlert", - "sameAccountNameError", - "unknown", - "credentialManifestDescription", - "credentialManifestInformations", - "credentialDetailsActivity", - "credentialDetailsOrganisation", - "credentialDetailsPresented", - "credentialDetailsOrganisationDetail", - "credentialDetailsInWalletSince", - "termsOfUseAndLicenses", - "licenses", - "sendTo", - "next", - "withdrawalInputHint", - "amount", - "amountSent", - "max", - "edit", - "networkFee", - "totalAmount", - "selectToken", - "insufficientBalance", - "slow", - "average", - "fast", - "changeFee", - "sent", - "done", - "link", - "myTokens", - "tezosMainNetwork", - "send", - "receive", - "recentTransactions", - "sendOnlyToThisAddressDescription", - "addTokens", - "providedBy", - "issuedOn", - "expirationDate", - "connect", - "connection", - "selectAccountToGrantAccess", - "requestPersmissionTo", - "viewAccountBalanceAndNFTs", - "requestApprovalForTransaction", - "connectedWithBeacon", - "failedToConnectWithBeacon", - "tezosNetwork", - "confirm_sign", - "sign", - "payload_to_sign", - "signedPayload", - "failedToSignPayload", - "voucher", - "tezotopia", - "operationCompleted", - "operationFailed", - "membership", - "switchNetworkMessage", - "fee", - "addCards", - "gaming", - "identity", - "payment", - "socialMedia", - "advanceSettings", - "categories", - "selectCredentialCategoryWhichYouWantToShowInCredentialList", - "community", - "tezos", - "rights", - "disconnectAndRevokeRights", - "revokeAllRights", - "revokeSubtitleMessage", - "revokeAll", - "succesfullyDisconnected", - "connectedApps", - "manageConnectedApps", - "noDappConnected", - "nftDetails", - "failedToDoOperation", - "nft", - "receiveNft", - "sendOnlyNftToThisAddressDescription", - "beaconShareMessage", - "advantagesCredentialHomeSubtitle", - "advantagesCredentialDiscoverSubtitle", - "identityCredentialHomeSubtitle", - "identityCredentialDiscoverSubtitle", - "myProfessionalCredentialDiscoverSubtitle", - "blockchainAccountsCredentialHomeSubtitle", - "educationCredentialHomeSubtitle", - "passCredentialHomeSubtitle", - "financeCardsCredentialHomeSubtitle", - "financeCardsCredentialDiscoverSubtitle", - "contactInfoCredentialHomeSubtitle", - "contactInfoCredentialDiscoverSubtitle", - "otherCredentialHomeSubtitle", - "otherCredentialDiscoverSubtitle", - "showMore", - "showLess", - "youHaveReceivedARewardOf", - "gotIt", - "transactionErrorBalanceTooLow", - "transactionErrorCannotPayStorageFee", - "transactionErrorFeeTooLow", - "transactionErrorFeeTooLowForMempool", - "transactionErrorTxRollupBalanceTooLow", - "transactionErrorTxRollupInvalidZeroTransfer", - "transactionErrorTxRollupUnknownAddress", - "transactionErrorInactiveChain", - "website", - "whyGetThisCard", - "howToGetIt", - "emailPassWhyGetThisCard", - "emailPassExpirationDate", - "emailPassHowToGetIt", - "tezotopiaMembershipWhyGetThisCard", - "tezotopiaMembershipExpirationDate", - "tezotopiaMembershipLongDescription", - "chainbornMembershipHowToGetIt", - "chainbornMembershipWhyGetThisCard", - "chainbornMembershipExpirationDate", - "chainbornMembershipLongDescription", - "twitterHowToGetIt", - "twitterWhyGetThisCard", - "twitterExpirationDate", - "twitterDummyDesc", - "linkedinCardHowToGetIt", - "linkedinCardWhyGetThisCard", - "linkedinCardExpirationDate", - "tezotopiaMembershipHowToGetIt", - "over18WhyGetThisCard", - "over18ExpirationDate", - "over18HowToGetIt", - "over13WhyGetThisCard", - "over13ExpirationDate", - "over13HowToGetIt", - "over15WhyGetThisCard", - "over15ExpirationDate", - "over15HowToGetIt", - "passportFootprintWhyGetThisCard", - "passportFootprintExpirationDate", - "passportFootprintHowToGetIt", - "verifiableIdCardWhyGetThisCard", - "verifiableIdCardExpirationDate", - "verifiableIdCardHowToGetIt", - "verifiableIdCardDummyDesc", - "phoneProofWhyGetThisCard", - "phoneProofExpirationDate", - "phoneProofHowToGetIt", - "tezVoucherWhyGetThisCard", - "tezVoucherExpirationDate", - "tezVoucherHowToGetIt", - "genderWhyGetThisCard", - "genderExpirationDate", - "genderHowToGetIt", - "nationalityWhyGetThisCard", - "nationalityExpirationDate", - "nationalityHowToGetIt", - "ageRangeWhyGetThisCard", - "ageRangeExpirationDate", - "ageRangeHowToGetIt", - "defiComplianceWhyGetThisCard", - "defiComplianceExpirationDate", - "defiComplianceHowToGetIt", - "rewardDialogTitle", - "rewardDialogDescPart1", - "rewardDialogDescPart2", - "origin", - "nftTooBigToLoad", - "seeTransaction", - "nftListSubtitle", - "tokenListSubtitle", - "my", - "get", - "seeMoreNFTInformationOn", - "credentialStatus", - "pass", - "payloadFormatErrorMessage", - "thisFeatureIsNotSupportedMessage", - "myWallet", - "ethereumNetwork", - "fantomNetwork", - "polygonNetwork", - "binanceNetwork", - "step", - "activateBiometricsTitle", - "loginWithBiometricsOnBoarding", - "option", - "start", - "iAgreeToThe", - "termsAndConditions", - "walletReadyTitle", - "walletReadySubtitle", - "failedToInitCamera", - "chooseMethodPageOver18Title", - "chooseMethodPageOver13Title", - "chooseMethodPageOver15Title", - "chooseMethodPageOver21Title", - "chooseMethodPageOver50Title", - "chooseMethodPageOver65Title", - "chooseMethodPageAgeRangeTitle", - "chooseMethodPageVerifiableIdTitle", - "chooseMethodPageDefiComplianceTitle", - "chooseMethodPageSubtitle", - "kycTitle", - "kycSubtitle", - "passbaseTitle", - "passbaseSubtitle", - "verifyYourAge", - "verifyYourAgeSubtitle", - "verifyYourAgeDescription", - "accept", - "decline", - "yotiCameraAppbarTitle", - "cameraSubtitle", - "todoImportant", - "walletSecurity", - "walletSecurityDescription", - "blockchainSettings", - "blockchainSettingsDescription", - "ssi", - "ssiDescription", - "helpCenter", - "helpCenterDescription", - "aboutDescription", - "resetWallet", - "resetWalletDescription", - "showWalletRecoveryPhrase", - "showWalletRecoveryPhraseSubtitle", - "blockchainNetwork", - "contactUs", - "officialWebsite", - "yourAppVersion", - "resetWalletTitle", - "resetWalletSubtitle", - "resetWalletSubtitle2", - "resetWalletCheckBox1", - "resetWalletCheckBox2", - "email", - "fillingThisFieldIsMandatory", - "yourMessage", - "message", - "subject", - "enterAValidEmail", - "failedToSendEmail", - "selectAMethodToAddAccount", - "createAccount", - "createAccountDescription", - "importAccountDescription", - "chooseABlockchainForAccountCreation", - "tezosAccount", - "tezosAccountDescription", - "ethereumAccount", - "ethereumAccountDescription", - "fantomAccount", - "fantomAccountDescription", - "polygonAccount", - "polygonAccountDescription", - "binanceAccount", - "binanceAccountDescription", - "setAccountNameDescription", - "letsGo", - "congratulations", - "tezosAccountCreationCongratulations", - "ethereumAccountCreationCongratulations", - "fantomAccountCreationCongratulations", - "polygonAccountCreationCongratulations", - "binanceAccountCreationCongratulations", - "accountImportCongratulations", - "saveBackupCredentialTitle", - "saveBackupCredentialSubtitle", - "saveBackupPolygonCredentialSubtitle", - "restoreCredentialStep1Title", - "restorePhraseTextFieldHint", - "restoreCredentialStep2Title", - "loadFile", - "uploadFile", - "creators", - "publishers", - "creationDate", - "myProfessionalrCards", - "myProfessionalrCardsSubtitle", - "guardaWallet", - "exodusWallet", - "trustWallet", - "myetherwallet", - "skip", - "userNotFitErrorMessage", - "youAreMissing", - "credentialsRequestedBy", - "transactionIsLikelyToFail", - "buy", - "thisFeatureIsNotSupportedYetForFantom", - "thisFeatureIsNotSupportedYetForBinance", - "faqs", - "softwareLicenses", - "notAValidWalletAddress", - "otherAccount", - "thereIsNoAccountInYourWallet", - "exportToLinkedIn", - "addLinkedInInfo", - "whatsYourLinkedinProfileUrl", - "invalidUrlError", - "linkedInBannerSuccessfullyExported", - "credentialSuccessfullyExported", - "linkedInBanner", - "linkedInProfile", - "checkLinkedinProfile", - "scanAndDisplay", - "whatsNew", - "okGotIt", - "support", - "transactionDoneDialogDescription", - "withdrawalFailedMessage", - "credentialRequiredMessage", - "keyDecentralizedIdEdSA", - "keyDecentralizedIDSecp256k1", - "polygonIdDecentralizedId", - "ebsiV3DecentralizedId", - "requiredCredentialNotFoundTitle", - "requiredCredentialNotFoundSubTitle", - "requiredCredentialNotFoundDescription", - "backToHome", - "help", - "searchCredentials", - "supportChatWelcomeMessage", - "cardChatWelcomeMessage", - "creator", - "contractAddress", - "lastMetadataSync", - "e2eEncyptedChat", - "pincodeAttemptMessage", - "verifyNow", - "verifyLater", - "welDone", - "mnemonicsVerifiedMessage", - "chatWith", - "sendAnEmail", - "livenessCardHowToGetIt", - "livenessCardExpirationDate", - "livenessCardWhyGetThisCard", - "livenessCardLongDescription", - "chat", - "polygonDecentralizedID", - "needMnemonicVerificatinoDescription", - "succesfullyAuthenticated", - "authenticationFailed", - "documentType", - "countryCode", - "deviceIncompatibilityMessage", - "tezosProofMessage", - "ethereumProofMessage", - "fantomProofMessage", - "polygonProofMessage", - "binanceProofMessage", - "yearsOld", - "youAreOver13", - "youAreOver15", - "youAreOver18", - "youAreOver21", - "youAreOver50", - "youAreOver65", - "polygon", - "ebsi", - "backupPolygonIdIdentity", - "restorePolygonIdCredentials", - "comingSoon", - "financeCredentialsHomeTitle", - "financeCredentialsDiscoverTitle", - "financeCredentialsDiscoverSubtitle", - "financeCredentialsHomeSubtitle", - "hummanityProofCredentialsHomeTitle", - "hummanityProofCredentialsHomeSubtitle", - "hummanityProofCredentialsDiscoverTitle", - "hummanityProofCredentialsDiscoverSubtitle", - "socialMediaCredentialsHomeTitle", - "socialMediaCredentialsHomeSubtitle", - "socialMediaCredentialsDiscoverTitle", - "socialMediaCredentialsDiscoverSubtitle", - "walletIntegrityCredentialsHomeTitle", - "walletIntegrityCredentialsHomeSubtitle", - "walletIntegrityCredentialsDiscoverTitle", - "walletIntegrityCredentialsDiscoverSubtitle", - "polygonCredentialsHomeTitle", - "polygonCredentialsHomeSubtitle", - "polygonCredentialsDiscoverTitle", - "polygonCredentialsDiscoverSubtitle", - "pendingCredentialsHomeTitle", - "pendingCredentialsHomeSubtitle", - "restore", - "backup", - "takePicture", - "kyc", - "aiSystemWasNotAbleToEstimateYourAge", - "youGotAgeCredentials", - "yourAgeEstimationIs", - "credentialNotFound", - "cryptographicProof", - "downloadingCircuitLoadingMessage", - "cryptoAccountAlreadyExistMessage", - "errorGeneratingProof", - "createWalletMessage", - "successfullyGeneratingProof", - "wouldYouLikeToAcceptThisCredentialsFromThisOrganisation", - "thisOrganisationRequestsThisInformation", - "iS", - "isSmallerThan", - "isBiggerThan", - "isOneOfTheFollowingValues", - "isNotOneOfTheFollowingValues", - "isNot", - "approve", - "noInformationWillBeSharedFromThisCredentialMessage", - "burn", - "wouldYouLikeToConfirmThatYouIntendToBurnThisNFT", - "pleaseAddXtoConnectToTheDapp", - "pleaseSwitchPolygonNetwork", - "oidc4vcProfile", - "pleaseSwitchToCorrectOIDC4VCProfile", - "authenticationSuccess", - "format", - "pleaseInsertTheSecredCodeReceived", - "verifyIssuerWebsiteIdentity", - "verifyIssuerWebsiteIdentitySubtitle", - "developerMode", - "developerModeSubtitle", - "confirmVerifierAccess", - "confirmVerifierAccessSubtitle", - "credentialManifestSupport", - "credentialManifestSupportSubtitle", - "secureAuthenticationWithPINCode", - "secureAuthenticationWithPINCodeSubtitle", - "youcanSelectOnlyXCredential", - "theCredentialIsNotReady", - "theCredentialIsNoMoreReady", - "lowSecurity", - "highSecurity", - "theRequestIsRejected", - "userPinIsIncorrect", - "security_level", - "oidc4vc_settings", - "userPinTitle", - "userPinSubtitle", - "securityLevelTitle", - "securityLevelSubTitle", - "responseTypeNotSupported", - "invalidRequest", - "subjectSyntaxTypeNotSupported", - "accessDenied", - "thisRequestIsNotSupported", - "unsupportedCredential", - "aloginIsRequired", - "userConsentIsRequired", - "theWalletIsNotRegistered", - "credentialIssuanceDenied", - "thisCredentialFormatIsNotSupported", - "thisFormatIsNotSupported", - "moreDetails", - "theCredentialOfferIsInvalid", - "dateOfRequest", - "keyDecentralizedIDP256", - "jwkDecentralizedIDP256", - "defaultDid", - "selectOneOfTheDid", - "clientTypeTitle", - "clientTypeSubtitle", - "cryptographicHolderBinding", - "cryptographicHolderBindingSubtitle", - "scopeParameters", - "scopeParametersSubtitle", - "clientAuthenticationMethods", - "clientAuthenticationMethodsSubtitle", - "vcFormatType", - "vcFormatTypeSubtitle", - "proofHeader", - "proofHeaderSubtitle", - "theServiceIsNotAvailable", - "issuerDID", - "subjectDID", - "type", - "credentialExpired", - "incorrectSignature", - "revokedOrSuspendedCredential", - "display", - "download", - "successfullyDownloaded", - "advancedSecuritySettings", - "clientMetadata", - "theIssuanceOfThisCredentialIsPending", - "clientId", - "clientSecret", - "walletProfiles", - "walletProfilesDescription", - "profileCustom", - "profileEbsiV3", - "decentralizedIdentityInteropProfile", - "protectYourWallet", - "protectYourWalletMessage", - "pinUnlock", - "secureWithDevicePINOnly", - "biometricUnlock", - "secureWithFingerprint", - "pinUnlockAndBiometric2FA", - "secureWithFingerprintAndPINBackup", - "secureYourWalletWithPINCodeAndBiometrics", - "twoFactorAuthenticationHasBeenEnabled", - "createAnProfessionalWallet", - "initialization", - "login", - "password", - "pleaseEnterYourEmailAndYourCompanyPasswordToCreateYourAccount", - "enterTheSecurityCodeThatWeSentYouByEmail", - "enterTheSecurityCode", - "yourEmail", - "publicKeyOfWalletInstance", - "walletInstanceKey", - "protocoleStandardRelease", - "organizationProfile", - "profileName", - "configFileIdentifier", - "clientCredentials", - "updateYourWalletConfigNow", - "updateConfigurationNow", - "pleaseEnterYourEmailAndPasswordToUpdateYourOrganizationWalletConfiguration", - "congrats", - "yourWalletConfigurationHasBeenSuccessfullyUpdated", - "continueString", - "walletProvider", - "theLdpFormatIsNotSupportedByThisDIDMethod", - "switchOffCryptoHolderBindingForThatDIDMethod", - "thisTypeProofCannotBeUsedWithThisVCFormat", - "enterprise", - "oWFBaselineProfile", - "defaultProfile" + "defaultProfile", + "blockchainCardsDiscoverTitle", + "blockchainCardsDiscoverSubtitle", + "successfullyAddedEnterpriseAccount", + "successfullyUpdatedEnterpriseAccount" ] } diff --git a/lib/lang/cubit/lang_cubit.dart b/lib/lang/cubit/lang_cubit.dart index 7367e5c06..2b509497b 100644 --- a/lib/lang/cubit/lang_cubit.dart +++ b/lib/lang/cubit/lang_cubit.dart @@ -2,16 +2,16 @@ import 'dart:async'; import 'package:altme/l10n/l10n.dart'; import 'package:bloc/bloc.dart'; -// import 'package:devicelocale/devicelocale.dart'; +import 'package:devicelocale/devicelocale.dart'; import 'package:flutter/material.dart'; class LangCubit extends Cubit { LangCubit() : super(const Locale('en', 'US')); Future fetchLocale() async { - const Locale locale = Locale('en', 'US'); + final Locale? locale = await Devicelocale.currentAsLocale; - final langauageCode = locale.languageCode; + final langauageCode = locale!.languageCode; if (AppLocalizations.supportedLocales.contains(Locale(langauageCode))) { setLocale(locale); diff --git a/lib/oidc4vc/add_credential_data.dart b/lib/oidc4vc/add_credential_data.dart new file mode 100644 index 000000000..8970bca09 --- /dev/null +++ b/lib/oidc4vc/add_credential_data.dart @@ -0,0 +1,96 @@ +import 'package:altme/app/app.dart'; +import 'package:altme/credentials/credentials.dart'; +import 'package:altme/dashboard/dashboard.dart'; + +import 'package:altme/oidc4vc/oidc4vc.dart'; +import 'package:jwt_decode/jwt_decode.dart'; +import 'package:oidc4vc/oidc4vc.dart'; +import 'package:secure_storage/secure_storage.dart'; +import 'package:uuid/uuid.dart'; + +Future addCredentialData({ + required List encodedCredentialOrFutureTokens, + required String? deferredCredentialEndpoint, + required String format, + required OpenIdConfiguration? openIdConfiguration, + required Map? tokenResponse, + required SecureStorageProvider secureStorageProvider, + required ProfileCubit profileCubit, + required CredentialsCubit credentialsCubit, + required String scannedResponse, + required dynamic credential, + required String issuer, + required bool isLastCall, + required JWTDecode jwtDecode, + required BlockchainType blockchainType, +}) async { + for (int i = 0; i < encodedCredentialOrFutureTokens.length; i++) { + final data = encodedCredentialOrFutureTokens[i]; + final String credentialName = getCredentialData(credential); + final acceptanceToken = data['acceptance_token']; + + if (acceptanceToken != null && deferredCredentialEndpoint != null) { + /// add deferred card + final id = const Uuid().v4(); + + final credentialModel = CredentialModel( + id: id, + credentialPreview: Credential( + 'dummy1', + ['dummy2'], + [credentialName], + 'dummy4', + 'dummy5', + '', + [Proof.dummy()], + CredentialSubjectModel( + id: 'dummy7', + type: 'dummy8', + issuedBy: const Author(''), + credentialCategory: CredentialCategory.pendingCards, + credentialSubjectType: CredentialSubjectType.defaultCredential, + ), + [Translation('en', '')], + [Translation('en', '')], + CredentialStatusField.emptyCredentialStatusField(), + [Evidence.emptyEvidence()], + ), + data: const {}, + jwt: null, + format: 'jwt_vc', + image: '', + shareLink: '', + pendingInfo: PendingInfo( + acceptanceToken: acceptanceToken.toString(), + deferredCredentialEndpoint: deferredCredentialEndpoint, + format: format, + url: scannedResponse, + issuer: issuer, + requestedAt: DateTime.now(), + ), + ); + // insert the credential in the wallet + await credentialsCubit.insertCredential( + credential: credentialModel, + showStatus: false, + showMessage: + isLastCall && i + 1 == encodedCredentialOrFutureTokens.length, + isPendingCredential: true, + blockchainType: blockchainType, + ); + } else { + await addOIDC4VCCredential( + encodedCredentialFromOIDC4VC: data, + credentialsCubit: credentialsCubit, + issuer: issuer, + credentialType: credentialName, + isLastCall: + isLastCall && i + 1 == encodedCredentialOrFutureTokens.length, + format: format, + openIdConfiguration: openIdConfiguration, + jwtDecode: jwtDecode, + blockchainType: blockchainType, + ); + } + } +} diff --git a/lib/oidc4vc/add_oidc4vc_credential.dart b/lib/oidc4vc/add_oidc4vc_credential.dart index f4e22efd6..b6627e0e7 100644 --- a/lib/oidc4vc/add_oidc4vc_credential.dart +++ b/lib/oidc4vc/add_oidc4vc_credential.dart @@ -12,6 +12,7 @@ import 'package:uuid/uuid.dart'; Future addOIDC4VCCredential({ required dynamic encodedCredentialFromOIDC4VC, required CredentialsCubit credentialsCubit, + required BlockchainType blockchainType, required String credentialType, required bool isLastCall, required String format, @@ -211,6 +212,7 @@ Future addOIDC4VCCredential({ await credentialsCubit.deleteById( id: credentialIdToBeDeleted, showMessage: false, + blockchainType: blockchainType, ); } @@ -219,5 +221,6 @@ Future addOIDC4VCCredential({ credential: credentialModel, showStatus: false, showMessage: isLastCall, + blockchainType: blockchainType, ); } diff --git a/lib/oidc4vc/get_and_add_credential.dart b/lib/oidc4vc/get_and_add_credential.dart deleted file mode 100644 index d0bbecff8..000000000 --- a/lib/oidc4vc/get_and_add_credential.dart +++ /dev/null @@ -1,162 +0,0 @@ -import 'package:altme/app/app.dart'; -import 'package:altme/credentials/credentials.dart'; -import 'package:altme/dashboard/dashboard.dart'; - -import 'package:altme/oidc4vc/oidc4vc.dart'; -import 'package:did_kit/did_kit.dart'; -import 'package:jwt_decode/jwt_decode.dart'; -import 'package:oidc4vc/oidc4vc.dart'; -import 'package:secure_storage/secure_storage.dart'; -import 'package:uuid/uuid.dart'; - -Future getAndAddCredential({ - required String scannedResponse, - required OIDC4VC oidc4vc, - required bool isEBSIV3, - required DIDKitProvider didKitProvider, - required CredentialsCubit credentialsCubit, - required dynamic credential, - required SecureStorageProvider secureStorageProvider, - required ProfileCubit profileCubit, - required bool isLastCall, - required DioClient dioClient, - required String? userPin, - required String? preAuthorizedCode, - required String issuer, - required String? codeForAuthorisedFlow, - required String? codeVerifier, - required bool cryptoHolderBinding, - required String? authorization, - required OIDC4VCIDraftType oidc4vciDraftType, - required DidKeyType didKeyType, - required String clientId, - required String? clientSecret, - required JWTDecode jwtDecode, -}) async { - final privateKey = await fetchPrivateKey( - isEBSIV3: isEBSIV3, - oidc4vc: oidc4vc, - secureStorage: getSecureStorage, - didKeyType: didKeyType, - ); - - final (did, kid) = await fetchDidAndKid( - isEBSIV3: isEBSIV3, - privateKey: privateKey, - didKitProvider: didKitProvider, - secureStorage: getSecureStorage, - didKeyType: didKeyType, - ); - - if (preAuthorizedCode != null || - (codeForAuthorisedFlow != null && codeVerifier != null)) { - /// codeForAuthorisedFlow != null - /// this is second phase flow for authorization_code - /// first phase is need for the authentication - /// - /// preAuthorizedCode != null - /// this is full phase flow for preAuthorizedCode - - final customOidc4vcProfile = profileCubit.state.model.profileSetting - .selfSovereignIdentityOptions.customOidc4vcProfile; - - final index = getIndexValue(isEBSIV3: isEBSIV3, didKeyType: didKeyType); - - final ( - List encodedCredentialOrFutureTokens, - String? deferredCredentialEndpoint, - String format, - OpenIdConfiguration? openIdConfiguration, - ) = await oidc4vc.getCredential( - preAuthorizedCode: preAuthorizedCode, - issuer: issuer, - credential: credential, - did: did, - kid: kid, - clientId: clientId, - clientSecret: clientSecret, - privateKey: privateKey, - indexValue: index, - userPin: userPin, - code: codeForAuthorisedFlow, - codeVerifier: codeVerifier, - cryptoHolderBinding: cryptoHolderBinding, - authorization: authorization, - oidc4vciDraftType: oidc4vciDraftType, - clientType: customOidc4vcProfile.clientType, - proofHeaderType: customOidc4vcProfile.proofHeader, - clientAuthentication: customOidc4vcProfile.clientAuthentication, - redirectUri: Parameters.oidc4vcUniversalLink, - ); - - for (int i = 0; i < encodedCredentialOrFutureTokens.length; i++) { - final data = encodedCredentialOrFutureTokens[i]; - final String credentialName = getCredentialData(credential); - final acceptanceToken = data['acceptance_token']; - - if (acceptanceToken != null && deferredCredentialEndpoint != null) { - /// add deferred card - final id = const Uuid().v4(); - - final credentialModel = CredentialModel( - id: id, - credentialPreview: Credential( - 'dummy1', - ['dummy2'], - [credentialName], - 'dummy4', - 'dummy5', - '', - [Proof.dummy()], - CredentialSubjectModel( - id: 'dummy7', - type: 'dummy8', - issuedBy: const Author(''), - credentialCategory: CredentialCategory.pendingCards, - credentialSubjectType: CredentialSubjectType.defaultCredential, - ), - [Translation('en', '')], - [Translation('en', '')], - CredentialStatusField.emptyCredentialStatusField(), - [Evidence.emptyEvidence()], - ), - data: const {}, - jwt: null, - format: 'jwt_vc', - image: '', - shareLink: '', - pendingInfo: PendingInfo( - acceptanceToken: acceptanceToken.toString(), - deferredCredentialEndpoint: deferredCredentialEndpoint, - format: format, - url: scannedResponse, - issuer: issuer, - requestedAt: DateTime.now(), - ), - ); - // insert the credential in the wallet - await credentialsCubit.insertCredential( - credential: credentialModel, - showStatus: false, - showMessage: - isLastCall && i + 1 == encodedCredentialOrFutureTokens.length, - isPendingCredential: true, - ); - } else { - await addOIDC4VCCredential( - encodedCredentialFromOIDC4VC: data, - credentialsCubit: credentialsCubit, - issuer: issuer, - credentialType: credentialName, - isLastCall: - isLastCall && i + 1 == encodedCredentialOrFutureTokens.length, - format: format, - openIdConfiguration: openIdConfiguration, - jwtDecode: jwtDecode, - ); - } - } - } else { - throw Exception(); - } -} diff --git a/lib/oidc4vc/get_and_add_deffered_credential.dart b/lib/oidc4vc/get_and_add_deffered_credential.dart index 80d36331d..2bca44c03 100644 --- a/lib/oidc4vc/get_and_add_deffered_credential.dart +++ b/lib/oidc4vc/get_and_add_deffered_credential.dart @@ -9,15 +9,11 @@ import 'package:oidc4vc/oidc4vc.dart'; Future getAndAddDefferedCredential({ required CredentialModel credentialModel, required CredentialsCubit credentialsCubit, - required DioClient dioClient, required OIDC4VC oidc4vc, required JWTDecode jwtDecode, + required BlockchainType blockchainType, + required String? issuer, }) async { - final (_, issuer) = await getIssuerAndPreAuthorizedCode( - scannedResponse: credentialModel.pendingInfo!.url, - dioClient: dioClient, - ); - final dynamic encodedCredentialOrFutureToken = await oidc4vc.getDeferredCredential( acceptanceToken: credentialModel.pendingInfo!.acceptanceToken, @@ -35,5 +31,6 @@ Future getAndAddDefferedCredential({ credentialIdToBeDeleted: credentialModel.id, openIdConfiguration: null, jwtDecode: jwtDecode, + blockchainType: blockchainType, ); } diff --git a/lib/oidc4vc/get_authorization_uri_for_issuer.dart b/lib/oidc4vc/get_authorization_uri_for_issuer.dart index 1ba743705..49015f548 100644 --- a/lib/oidc4vc/get_authorization_uri_for_issuer.dart +++ b/lib/oidc4vc/get_authorization_uri_for_issuer.dart @@ -73,7 +73,8 @@ Future getAuthorizationUriForIssuer({ authorizationEndPoint: Parameters.authorizeEndPoint, scope: scope, clientAuthentication: clientAuthentication, - oidc4vciDraftType: oidc4vciDraftType, vcFormatType: vcFormatType, + oidc4vciDraftType: oidc4vciDraftType, + vcFormatType: vcFormatType, ); await LaunchUrl.launchUri(oidc4vcAuthenticationUri); diff --git a/lib/oidc4vc/get_credential.dart b/lib/oidc4vc/get_credential.dart new file mode 100644 index 000000000..0bd582f48 --- /dev/null +++ b/lib/oidc4vc/get_credential.dart @@ -0,0 +1,91 @@ +import 'package:altme/app/app.dart'; +import 'package:altme/dashboard/dashboard.dart'; + +import 'package:did_kit/did_kit.dart'; +import 'package:oidc4vc/oidc4vc.dart'; +import 'package:secure_storage/secure_storage.dart'; + +/// Retreive credential_type from url +/// credentialResponseData, deferredCredentialEndpoint, format, +/// openIdConfiguration, tokenResponse +Future< + ( + List, + String?, + String, + OpenIdConfiguration?, + Map? + )> getCredential({ + required OIDC4VC oidc4vc, + required bool isEBSIV3, + required DIDKitProvider didKitProvider, + required dynamic credential, + required ProfileCubit profileCubit, + required String? userPin, + required String? preAuthorizedCode, + required String issuer, + required String? codeForAuthorisedFlow, + required String? codeVerifier, + required bool cryptoHolderBinding, + required String? authorization, + required OIDC4VCIDraftType oidc4vciDraftType, + required DidKeyType didKeyType, + required String? clientId, + required String? clientSecret, +}) async { + final privateKey = await fetchPrivateKey( + isEBSIV3: isEBSIV3, + oidc4vc: oidc4vc, + secureStorage: getSecureStorage, + didKeyType: didKeyType, + ); + + final (did, kid) = await fetchDidAndKid( + isEBSIV3: isEBSIV3, + privateKey: privateKey, + didKitProvider: didKitProvider, + secureStorage: getSecureStorage, + didKeyType: didKeyType, + ); + + final customOidc4vcProfile = profileCubit.state.model.profileSetting + .selfSovereignIdentityOptions.customOidc4vcProfile; + + final index = getIndexValue(isEBSIV3: isEBSIV3, didKeyType: didKeyType); + + final ( + List encodedCredentialOrFutureTokens, + String? deferredCredentialEndpoint, + String format, + OpenIdConfiguration? openIdConfiguration, + Map? tokenResponse, + ) = await oidc4vc.getCredential( + preAuthorizedCode: preAuthorizedCode, + issuer: issuer, + credential: credential, + did: did, + kid: kid, + clientId: clientId, + clientSecret: clientSecret, + privateKey: privateKey, + indexValue: index, + userPin: userPin, + code: codeForAuthorisedFlow, + codeVerifier: codeVerifier, + cryptoHolderBinding: cryptoHolderBinding, + authorization: authorization, + oidc4vciDraftType: oidc4vciDraftType, + clientType: customOidc4vcProfile.clientType, + proofHeaderType: customOidc4vcProfile.proofHeader, + clientAuthentication: customOidc4vcProfile.clientAuthentication, + redirectUri: Parameters.oidc4vcUniversalLink, + ); + + return ( + encodedCredentialOrFutureTokens, + deferredCredentialEndpoint, + format, + openIdConfiguration, + tokenResponse, + ); +} diff --git a/lib/oidc4vc/initiate_oidv4vc_credential_issuance.dart b/lib/oidc4vc/initiate_oidv4vc_credential_issuance.dart index e70fd2934..11f50b6ca 100644 --- a/lib/oidc4vc/initiate_oidv4vc_credential_issuance.dart +++ b/lib/oidc4vc/initiate_oidv4vc_credential_issuance.dart @@ -22,6 +22,9 @@ Future initiateOIDC4VCCredentialIssuance({ required String? userPin, required dynamic credentialOfferJson, required bool cryptoHolderBinding, + required OpenIdConfiguration? openIdConfiguration, + required String issuer, + required String? preAuthorizedCode, }) async { final Uri uriFromScannedResponse = Uri.parse(scannedResponse); @@ -62,11 +65,6 @@ Future initiateOIDC4VCCredentialIssuance({ } } - final (preAuthorizedCode, issuer) = await getIssuerAndPreAuthorizedCode( - scannedResponse: scannedResponse, - dioClient: dioClient, - ); - //cleared up to here if (credentials is List) { @@ -74,12 +72,14 @@ Future initiateOIDC4VCCredentialIssuance({ Uri.parse(scannedResponse).queryParameters['code']; final state = Uri.parse(scannedResponse).queryParameters['state']; - final OpenIdConfiguration openIdConfiguration = - await oidc4vc.getOpenIdConfig( - baseUrl: issuer!, - isAuthorizationServer: false, - oidc4vciDraftType: oidc4vciDraftType, - ); + if (openIdConfiguration == null) { + throw ResponseMessage( + data: { + 'error': 'invalid_issuer_metadata', + 'error_description': 'The open id configuration is invalid.', + }, + ); + } if (preAuthorizedCode != null) { /// full phase flow of preAuthorized @@ -131,7 +131,7 @@ Future initiateOIDC4VCCredentialIssuance({ codeForAuthorisedFlow: codeForAuthorisedFlow, codeVerifier: codeVerifier, authorization: authorization, - clientId: clientId ?? '', + clientId: clientId, clientSecret: clientSecret, ); } @@ -140,7 +140,7 @@ Future initiateOIDC4VCCredentialIssuance({ // full phase flow of preAuthorized await qrCodeScanCubit.processSelectedCredentials( userPin: userPin, - issuer: issuer!, + issuer: issuer, preAuthorizedCode: preAuthorizedCode, isEBSIV3: isEBSIV3, credentialOfferJson: credentialOfferJson, diff --git a/lib/oidc4vc/oidc4vc.dart b/lib/oidc4vc/oidc4vc.dart index 87bd0424b..8b1c2e8cf 100644 --- a/lib/oidc4vc/oidc4vc.dart +++ b/lib/oidc4vc/oidc4vc.dart @@ -1,7 +1,8 @@ +export 'add_credential_data.dart'; export 'add_oidc4vc_credential.dart'; -export 'get_and_add_credential.dart'; export 'get_and_add_deffered_credential.dart'; export 'get_authorization_uri_for_issuer.dart'; +export 'get_credential.dart'; export 'get_credential_offer_json.dart'; export 'initiate_oidv4vc_credential_issuance.dart'; export 'verify_encoded_data.dart'; diff --git a/lib/onboarding/enterprise/enterprise.dart b/lib/onboarding/enterprise/enterprise.dart deleted file mode 100644 index f32db9746..000000000 --- a/lib/onboarding/enterprise/enterprise.dart +++ /dev/null @@ -1,3 +0,0 @@ -export 'initialization/initialization.dart'; -export 'otp/otp.dart'; -export 'update/update.dart'; diff --git a/lib/onboarding/enterprise/initialization/cubit/initialization_cubit.dart b/lib/onboarding/enterprise/initialization/cubit/initialization_cubit.dart deleted file mode 100644 index d95d5e757..000000000 --- a/lib/onboarding/enterprise/initialization/cubit/initialization_cubit.dart +++ /dev/null @@ -1,309 +0,0 @@ -import 'dart:convert'; - -import 'package:altme/app/app.dart'; -import 'package:altme/dashboard/profile/profile.dart'; -import 'package:altme/oidc4vc/oidc4vc.dart'; -import 'package:equatable/equatable.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:json_annotation/json_annotation.dart'; -import 'package:jwt_decode/jwt_decode.dart'; -import 'package:oidc4vc/oidc4vc.dart'; -import 'package:secure_storage/secure_storage.dart'; -import 'package:uuid/uuid.dart'; - -part 'initialization_cubit.g.dart'; - -part 'initialization_state.dart'; - -class EnterpriseInitializationCubit - extends Cubit { - EnterpriseInitializationCubit({ - required this.client, - required this.secureStorageProvider, - required this.jwtDecode, - required this.oidc4vc, - required this.profileCubit, - }) : super(const EnterpriseInitializationState()); - - final DioClient client; - final SecureStorageProvider secureStorageProvider; - final JWTDecode jwtDecode; - final OIDC4VC oidc4vc; - final ProfileCubit profileCubit; - - void updateEmailFormat(String email) { - final regExpEmail = RegExp(AltMeStrings.emailPattern); - - final isValid = regExpEmail.hasMatch(email); - emit( - state.copyWith( - isEmailFormatCorrect: isValid, - message: null, - ), - ); - } - - void updatePasswordFormat(String password) { - emit( - state.copyWith( - isPasswordFormatCorrect: password.trim().length >= 3, - message: null, - ), - ); - } - - Future setWalletProviderType( - WalletProviderType walletProviderType, - ) async { - emit(state.loading()); - await secureStorageProvider.set( - SecureStorageKeys.walletProviderType, - walletProviderType.toString(), - ); - emit( - state.copyWith( - walletProviderType: walletProviderType, - message: null, - status: AppStatus.idle, - ), - ); - } - - void obscurePassword() { - emit( - state.copyWith( - obscurePassword: !state.obscurePassword, - message: null, - ), - ); - } - - String? jwtVc; - - Future requestTheConfiguration({ - required String email, - required String password, - }) async { - try { - emit(state.loading()); - final bool isDataEntered = - state.isEmailFormatCorrect && state.isPasswordFormatCorrect; - - if (jwtVc == null) { - /// GET nonce - final nonce = await getNonce(); - - /// get data to send to attestation request - final Map data = await getDataForRequest(nonce); - - /// get vc and store it in the wallet - await getJWTVc(data); - - if (!isDataEntered) { - return emit(state.copyWith(status: AppStatus.idle, message: null)); - } - } - - /// request the configuration and verify - await requestTheConfigurationAndVerify(email: email, password: password); - } catch (e) { - // TODO(bibash): need to remove this hardcode later - emit( - state.error( - message: const StateMessage.error( - stringMessage: - 'User not registered or email/password are incorrect', - showDialog: true, - ), - ), - ); - jwtVc = null; - } - } - - Future requestTheConfigurationAndVerify({ - required String email, - required String password, - }) async { - /// request the configuration - //final encodedData = utf8.encode('thierry@altme.io:talao'); - final encodedData = utf8.encode('$email:$password'); - final base64Encoded = base64UrlEncode(encodedData).replaceAll('=', ''); - - final headers = { - 'Content-Type': 'application/x-www-form-urlencoded', - 'Authorization': 'Basic $base64Encoded', - }; - - final data = { - 'grant_type': 'urn:ietf:params:oauth:grant-type:jwt-bearer', - 'assertion': jwtVc, - }; - - final response = await client.post( - '${state.walletProviderType.url}/configuration', - headers: headers, - data: data, - ); - - /// parse - final header = jwtDecode.parseJwtHeader(response as String); - final issuerKid = header['kid'].toString(); - final issuerDid = issuerKid.split('#')[0]; - - /// verify - final VerificationType isVerified = await verifyEncodedData( - issuerDid, - issuerKid, - response, - ); - - final profileSettingJson = jwtDecode.parseJwt(response); - - await secureStorageProvider.set( - SecureStorageKeys.enterpriseProfileSetting, - jsonEncode(profileSettingJson), - ); - - final profileSetting = ProfileSetting.fromJson(profileSettingJson); - - ///save to profileCubit - await profileCubit.setProfileSetting( - profileSetting: profileSetting, - profileType: ProfileType.enterprise, - ); - // if (isVerified == VerificationType.verified) { - // emit( - // state.copyWith( - // status: AppStatus.idle, - // message: const StateMessage.info( - // showDialog: true, - // stringMessage: 'Verfied', - // ), - // ), - // ); - // } else { - // emit( - // state.copyWith( - // status: AppStatus.idle, - // message: const StateMessage.info( - // showDialog: true, - // stringMessage: 'Not Verfied', - // ), - // ), - // ); - // } - - emit( - state.copyWith( - status: AppStatus.success, - message: null, - ), - ); - } - - Future getNonce() async { - final dynamic getRepsponse = - await client.get('${state.walletProviderType.url}/nonce'); - final nonce = getRepsponse['nonce'].toString(); - return nonce; - } - - Future> getDataForRequest(String nonce) async { - /// get private key - final p256KeyForWallet = await getWalletP256Key(secureStorageProvider); - final privateKey = jsonDecode(p256KeyForWallet) as Map; - - final customOidc4vcProfile = profileCubit.state.model.profileSetting - .selfSovereignIdentityOptions.customOidc4vcProfile; - - final tokenParameters = TokenParameters( - privateKey: privateKey, - did: '', - kid: null, - mediaType: MediaType.walletAttestation, - clientType: customOidc4vcProfile.clientType, - proofHeaderType: customOidc4vcProfile.proofHeader, - clientId: customOidc4vcProfile.clientId ?? '', - ); - - final thumbPrint = tokenParameters.thumbprint; - - final publicJWKString = sortedPublcJwk(p256KeyForWallet); - final publicJWK = jsonDecode(publicJWKString) as Map; - - final iat = (DateTime.now().millisecondsSinceEpoch / 1000).round(); - - final payload = { - 'iss': thumbPrint, - 'aud': 'https://wallet-provider.altme.io', - 'jti': const Uuid().v4(), - 'nonce': nonce, - 'cnf': { - 'jwk': { - ...publicJWK, - 'kid': thumbPrint, - }, - }, - 'iat': iat, - 'exp': iat + 1000, - }; - - /// sign and get token - final jwtToken = oidc4vc.generateToken( - payload: payload, - tokenParameters: tokenParameters, - ); - - final data = { - 'grant_type': 'urn:ietf:params:oauth:grant-type:jwt-bearer', - 'assertion': jwtToken, - }; - return data; - } - - Future getJWTVc(Map data) async { - /// get vc - final response = await client.post( - '${state.walletProviderType.url}/token', - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - }, - data: data, - ); - - jwtVc = response.toString(); - - /// parse - final header = jwtDecode.parseJwtHeader(jwtVc!); - final issuerKid = header['kid'].toString(); - final issuerDid = issuerKid.split('#')[0]; - - /// verify - final VerificationType isVerified = await verifyEncodedData( - issuerDid, - issuerKid, - jwtVc!, - ); - - await secureStorageProvider.set( - SecureStorageKeys.walletAttestationData, - jwtVc!, - ); - - return jwtVc!; - } - - void emitError(dynamic e) { - final messageHandler = getMessageHandler(e); - - emit( - state.error( - message: StateMessage.error( - messageHandler: messageHandler, - showDialog: true, - ), - ), - ); - } -} diff --git a/lib/onboarding/enterprise/initialization/cubit/initialization_state.dart b/lib/onboarding/enterprise/initialization/cubit/initialization_state.dart deleted file mode 100644 index a14b3198c..000000000 --- a/lib/onboarding/enterprise/initialization/cubit/initialization_state.dart +++ /dev/null @@ -1,68 +0,0 @@ -part of 'initialization_cubit.dart'; - -@JsonSerializable() -class EnterpriseInitializationState extends Equatable { - const EnterpriseInitializationState({ - this.status = AppStatus.init, - this.message, - this.isEmailFormatCorrect = false, - this.isPasswordFormatCorrect = false, - this.obscurePassword = true, - this.walletProviderType = WalletProviderType.Talao, - }); - - factory EnterpriseInitializationState.fromJson(Map json) => - _$EnterpriseInitializationStateFromJson(json); - - final AppStatus status; - final StateMessage? message; - final bool isEmailFormatCorrect; - final bool isPasswordFormatCorrect; - final bool obscurePassword; - final WalletProviderType walletProviderType; - - EnterpriseInitializationState loading() { - return copyWith( - status: AppStatus.loading, - message: null, - ); - } - - EnterpriseInitializationState error({required StateMessage message}) { - return copyWith( - status: AppStatus.error, - message: message, - ); - } - - EnterpriseInitializationState copyWith({ - required StateMessage? message, - AppStatus? status, - bool? isEmailFormatCorrect, - bool? isPasswordFormatCorrect, - bool? obscurePassword, - WalletProviderType? walletProviderType, - }) { - return EnterpriseInitializationState( - status: status ?? this.status, - message: message, - isEmailFormatCorrect: isEmailFormatCorrect ?? this.isEmailFormatCorrect, - isPasswordFormatCorrect: - isPasswordFormatCorrect ?? this.isPasswordFormatCorrect, - obscurePassword: obscurePassword ?? this.obscurePassword, - walletProviderType: walletProviderType ?? this.walletProviderType, - ); - } - - Map toJson() => _$EnterpriseInitializationStateToJson(this); - - @override - List get props => [ - status, - message, - isEmailFormatCorrect, - isPasswordFormatCorrect, - obscurePassword, - walletProviderType, - ]; -} diff --git a/lib/onboarding/enterprise/initialization/initialization.dart b/lib/onboarding/enterprise/initialization/initialization.dart deleted file mode 100644 index 7c252957f..000000000 --- a/lib/onboarding/enterprise/initialization/initialization.dart +++ /dev/null @@ -1,2 +0,0 @@ -export 'cubit/initialization_cubit.dart'; -export 'view/initialization_page.dart'; diff --git a/lib/onboarding/enterprise/initialization/view/initialization_page.dart b/lib/onboarding/enterprise/initialization/view/initialization_page.dart deleted file mode 100644 index c6dae7928..000000000 --- a/lib/onboarding/enterprise/initialization/view/initialization_page.dart +++ /dev/null @@ -1,236 +0,0 @@ -import 'package:altme/app/app.dart'; -import 'package:altme/dashboard/dashboard.dart'; -import 'package:altme/l10n/l10n.dart'; -import 'package:altme/onboarding/onboarding.dart'; -import 'package:altme/theme/theme.dart'; -import 'package:dio/dio.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:jwt_decode/jwt_decode.dart'; -import 'package:oidc4vc/oidc4vc.dart'; -import 'package:secure_storage/secure_storage.dart'; - -class EnterpriseInitializationPage extends StatelessWidget { - const EnterpriseInitializationPage({super.key}); - - static Route route() { - return MaterialPageRoute( - builder: (_) => const EnterpriseInitializationPage(), - settings: const RouteSettings(name: '/EnterpriseInitializationPage'), - ); - } - - @override - Widget build(BuildContext context) { - return BlocProvider( - create: (_) => EnterpriseInitializationCubit( - client: DioClient('', Dio()), - secureStorageProvider: getSecureStorage, - jwtDecode: JWTDecode(), - oidc4vc: OIDC4VC(), - profileCubit: context.read(), - ), - child: const EnterpriseInitializationView(), - ); - } -} - -class EnterpriseInitializationView extends StatefulWidget { - const EnterpriseInitializationView({ - super.key, - }); - - @override - State createState() => - _EnterpriseInitializationViewState(); -} - -class _EnterpriseInitializationViewState - extends State { - late TextEditingController emailController; - late TextEditingController passwordController; - - @override - void initState() { - emailController = TextEditingController(); - passwordController = TextEditingController(); - emailController.addListener(() { - context - .read() - .updateEmailFormat(emailController.text); - }); - passwordController.addListener(() { - context - .read() - .updatePasswordFormat(passwordController.text); - }); - - super.initState(); - } - - @override - Widget build(BuildContext context) { - final l10n = context.l10n; - return BlocConsumer( - listener: (context, state) { - if (state.status == AppStatus.loading) { - LoadingView().show(context: context); - } else { - LoadingView().hide(); - } - - if (state.status == AppStatus.success) { - Navigator.of(context).pushReplacement( - ProtectWalletPage.route(routeType: WalletRouteType.create), - ); - } - - if (state.message != null) { - AlertMessage.showStateMessage( - context: context, - stateMessage: state.message!, - ); - } - }, - builder: (context, state) { - return BasePage( - scrollView: true, - useSafeArea: true, - padding: const EdgeInsets.symmetric(horizontal: Sizes.spaceSmall), - titleLeading: const BackLeadingButton(), - backgroundColor: Theme.of(context).colorScheme.drawerBackground, - title: l10n.initialization, - titleAlignment: Alignment.topCenter, - body: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox(height: Sizes.space2XSmall), - Text( - l10n.pleaseEnterYourEmailAndYourCompanyPasswordToCreateYourAccount, - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.bodySmall3, - ), - const SizedBox(height: Sizes.spaceNormal), - Text( - l10n.walletProvider, - style: Theme.of(context).textTheme.textFieldTitle, - ), - const SizedBox(height: Sizes.spaceSmall), - Container( - padding: - const EdgeInsets.symmetric(vertical: 2, horizontal: 20), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(15), - color: Theme.of(context).highlightColor, - border: Border.all( - color: Theme.of(context).highlightColor, - width: 0, - ), - ), - child: DropdownButton( - value: state.walletProviderType, - underline: Container(), - dropdownColor: Theme.of(context).highlightColor, - isExpanded: true, - onChanged: (WalletProviderType? newValue) { - context - .read() - .setWalletProviderType(newValue!); - }, - items: WalletProviderType.values.map((type) { - return DropdownMenuItem( - value: type, - child: Text( - type.formattedString, - style: Theme.of(context).textTheme.normal, - ), - ); - }).toList(), - style: Theme.of(context).textTheme.normal, - ), - ), - const SizedBox(height: Sizes.spaceSmall), - Text( - l10n.email, - style: Theme.of(context).textTheme.textFieldTitle, - ), - const SizedBox(height: Sizes.spaceSmall), - BaseTextField( - hint: l10n.yourEmail, - fillColor: Theme.of(context).highlightColor, - hintStyle: Theme.of(context).textTheme.hintTextFieldStyle, - maxLines: 1, - borderRadius: Sizes.normalRadius, - controller: emailController, - type: TextInputType.emailAddress, - borderColor: Theme.of(context).colorScheme.background, - suffixIcon: state.isEmailFormatCorrect - ? const Icon(Icons.check_circle) - : null, - ), - const SizedBox(height: Sizes.spaceNormal), - Text( - l10n.password, - style: Theme.of(context).textTheme.textFieldTitle, - ), - const SizedBox(height: Sizes.spaceSmall), - BaseTextField( - hint: l10n.password, - fillColor: Theme.of(context).highlightColor, - hintStyle: Theme.of(context).textTheme.hintTextFieldStyle, - maxLines: 1, - borderRadius: Sizes.normalRadius, - controller: passwordController, - type: TextInputType.text, - obscureText: state.obscurePassword, - borderColor: Theme.of(context).colorScheme.background, - suffixIcon: Padding( - padding: const EdgeInsets.only(right: 10), - child: Wrap( - alignment: WrapAlignment.end, - children: [ - TransparentInkWell( - child: Icon( - state.obscurePassword - ? Icons.visibility_off - : Icons.visibility, - ), - onTap: () { - context - .read() - .obscurePassword(); - }, - ), - if (state.isPasswordFormatCorrect) ...[ - const SizedBox(width: 5), - const Icon(Icons.check_circle), - ], - ], - ), - ), - ), - ], - ), - navigation: Padding( - padding: const EdgeInsets.all(Sizes.spaceSmall), - child: MyElevatedButton( - text: l10n.next, - onPressed: - state.isEmailFormatCorrect && state.isPasswordFormatCorrect - ? () async { - await context - .read() - .requestTheConfiguration( - email: emailController.text.trim(), - password: passwordController.text.trim(), - ); - } - : null, - ), - ), - ); - }, - ); - } -} diff --git a/lib/onboarding/enterprise/otp/cubit/otp_cubit.dart b/lib/onboarding/enterprise/otp/cubit/otp_cubit.dart deleted file mode 100644 index 1fa8c5dd7..000000000 --- a/lib/onboarding/enterprise/otp/cubit/otp_cubit.dart +++ /dev/null @@ -1,16 +0,0 @@ -import 'package:altme/app/app.dart'; -import 'package:equatable/equatable.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:json_annotation/json_annotation.dart'; - -part 'otp_cubit.g.dart'; - -part 'otp_state.dart'; - -class EnterpriseOTPCubit extends Cubit { - EnterpriseOTPCubit() : super(const EnterpriseOTPState()); - - void updateOTPCorrectionStatus({required bool value}) { - emit(state.copyWith(isOTPCorrect: value)); - } -} diff --git a/lib/onboarding/enterprise/otp/cubit/otp_state.dart b/lib/onboarding/enterprise/otp/cubit/otp_state.dart deleted file mode 100644 index 2d1271060..000000000 --- a/lib/onboarding/enterprise/otp/cubit/otp_state.dart +++ /dev/null @@ -1,51 +0,0 @@ -part of 'otp_cubit.dart'; - -@JsonSerializable() -class EnterpriseOTPState extends Equatable { - const EnterpriseOTPState({ - this.status = AppStatus.init, - this.message, - this.isOTPCorrect = false, - }); - - factory EnterpriseOTPState.fromJson(Map json) => - _$EnterpriseOTPStateFromJson(json); - - final AppStatus status; - final StateMessage? message; - final bool isOTPCorrect; - - EnterpriseOTPState loading() { - return copyWith(status: AppStatus.loading); - } - - EnterpriseOTPState error({ - required MessageHandler messageHandler, - }) { - return copyWith( - status: AppStatus.error, - message: StateMessage.error(messageHandler: messageHandler), - ); - } - - EnterpriseOTPState copyWith({ - AppStatus? status, - StateMessage? message, - bool? isOTPCorrect, - }) { - return EnterpriseOTPState( - status: status ?? this.status, - message: message ?? this.message, - isOTPCorrect: isOTPCorrect ?? this.isOTPCorrect, - ); - } - - Map toJson() => _$EnterpriseOTPStateToJson(this); - - @override - List get props => [ - status, - message, - isOTPCorrect, - ]; -} diff --git a/lib/onboarding/enterprise/otp/login.dart b/lib/onboarding/enterprise/otp/login.dart deleted file mode 100644 index 783dc21a7..000000000 --- a/lib/onboarding/enterprise/otp/login.dart +++ /dev/null @@ -1,2 +0,0 @@ -export 'cubit/otp_cubit.dart'; -export 'view/otp_page.dart'; diff --git a/lib/onboarding/enterprise/otp/otp.dart b/lib/onboarding/enterprise/otp/otp.dart deleted file mode 100644 index 783dc21a7..000000000 --- a/lib/onboarding/enterprise/otp/otp.dart +++ /dev/null @@ -1,2 +0,0 @@ -export 'cubit/otp_cubit.dart'; -export 'view/otp_page.dart'; diff --git a/lib/onboarding/enterprise/otp/view/otp_page.dart b/lib/onboarding/enterprise/otp/view/otp_page.dart deleted file mode 100644 index 924e746d2..000000000 --- a/lib/onboarding/enterprise/otp/view/otp_page.dart +++ /dev/null @@ -1,118 +0,0 @@ -import 'package:altme/app/app.dart'; -import 'package:altme/l10n/l10n.dart'; -import 'package:altme/onboarding/onboarding.dart'; -import 'package:altme/theme/theme.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; - -class EnterpriseOTPPage extends StatelessWidget { - const EnterpriseOTPPage({super.key}); - - static Route route() { - return MaterialPageRoute( - builder: (_) => const EnterpriseOTPPage(), - settings: const RouteSettings(name: '/EnterpriseOTPPage'), - ); - } - - @override - Widget build(BuildContext context) { - return BlocProvider( - create: (_) => EnterpriseOTPCubit(), - child: EnterpriseOTPView(), - ); - } -} - -class EnterpriseOTPView extends StatelessWidget { - EnterpriseOTPView({super.key}); - - final List _controllers = [ - TextEditingController(), - TextEditingController(), - TextEditingController(), - TextEditingController(), - ]; - - @override - Widget build(BuildContext context) { - final l10n = context.l10n; - return BlocConsumer( - listener: (context, state) async { - if (state.status == AppStatus.loading) { - LoadingView().show(context: context); - } else { - LoadingView().hide(); - } - - if (state.message != null) { - AlertMessage.showStateMessage( - context: context, - stateMessage: state.message!, - ); - } - }, - builder: (context, state) { - return BasePage( - scrollView: true, - useSafeArea: true, - padding: const EdgeInsets.symmetric(horizontal: Sizes.spaceSmall), - titleLeading: const BackLeadingButton(), - backgroundColor: Theme.of(context).colorScheme.drawerBackground, - title: l10n.login, - titleAlignment: Alignment.topCenter, - body: Column( - children: [ - const SizedBox(height: Sizes.space2XSmall), - const MStepper(step: 1, totalStep: 2), - const SizedBox(height: Sizes.spaceNormal), - Text( - l10n.enterTheSecurityCodeThatWeSentYouByEmail, - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.bodySmall3, - ), - const SizedBox(height: Sizes.spaceNormal), - const SizedBox(height: Sizes.spaceNormal), - - ///OTP Box - Center( - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - OtpTextField( - index: 0, - controllers: _controllers, - autoFocus: true, - ), - const SizedBox(width: 15), - OtpTextField( - index: 1, - controllers: _controllers, - ), - const SizedBox(width: 15), - OtpTextField( - index: 2, - controllers: _controllers, - ), - const SizedBox(width: 15), - OtpTextField( - index: 3, - controllers: _controllers, - ), - ], - ), - ), - ], - ), - navigation: Padding( - padding: const EdgeInsets.all(Sizes.spaceSmall), - child: MyElevatedButton( - text: l10n.next, - onPressed: null, - ), - ), - ); - }, - ); - } -} diff --git a/lib/onboarding/enterprise/update/cubit/update_cubit.dart b/lib/onboarding/enterprise/update/cubit/update_cubit.dart deleted file mode 100644 index 73f3124f7..000000000 --- a/lib/onboarding/enterprise/update/cubit/update_cubit.dart +++ /dev/null @@ -1,182 +0,0 @@ -import 'dart:convert'; - -import 'package:altme/app/app.dart'; -import 'package:altme/dashboard/profile/profile.dart'; -import 'package:altme/oidc4vc/oidc4vc.dart'; -import 'package:equatable/equatable.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:json_annotation/json_annotation.dart'; -import 'package:jwt_decode/jwt_decode.dart'; -import 'package:oidc4vc/oidc4vc.dart'; -import 'package:secure_storage/secure_storage.dart'; - -part 'update_cubit.g.dart'; - -part 'update_state.dart'; - -class EnterpriseUpdateCubit extends Cubit { - EnterpriseUpdateCubit({ - required this.client, - required this.secureStorageProvider, - required this.jwtDecode, - required this.profileCubit, - }) : super(const EnterpriseUpdateState()); - - final DioClient client; - final SecureStorageProvider secureStorageProvider; - final JWTDecode jwtDecode; - - final ProfileCubit profileCubit; - - void updateEmailFormat(String email) { - final regExpEmail = RegExp(AltMeStrings.emailPattern); - - final isValid = regExpEmail.hasMatch(email); - emit( - state.copyWith( - isEmailFormatCorrect: isValid, - message: null, - ), - ); - } - - void updatePasswordFormat(String password) { - emit( - state.copyWith( - isPasswordFormatCorrect: password.trim().length >= 3, - message: null, - ), - ); - } - - void obscurePassword() { - emit( - state.copyWith( - obscurePassword: !state.obscurePassword, - message: null, - ), - ); - } - - Future updateTheConfiguration({ - required String email, - required String password, - }) async { - try { - emit(state.loading()); - final encodedData = utf8.encode('$email:$password'); - final base64Encoded = base64UrlEncode(encodedData).replaceAll('=', ''); - - final walletAttestationData = await secureStorageProvider.get( - SecureStorageKeys.walletAttestationData, - ); - - final headers = { - 'Content-Type': 'application/x-www-form-urlencoded', - 'Authorization': 'Basic $base64Encoded', - }; - - final data = { - 'grant_type': 'urn:ietf:params:oauth:grant-type:jwt-bearer', - 'assertion': walletAttestationData, - }; - - final walletProviderTypeString = await secureStorageProvider.get( - SecureStorageKeys.walletProviderType, - ); - - final walletProviderType = walletProviderTypeString != null - ? WalletProviderType.values.firstWhereOrNull( - (type) => type.toString() == walletProviderTypeString, - ) - : WalletProviderType.Talao; - - if (walletProviderType == null) throw Exception(); - - final response = await client.post( - '${walletProviderType.url}/update', - headers: headers, - data: data, - ); - - /// parse - final header = jwtDecode.parseJwtHeader(response as String); - final issuerKid = header['kid'].toString(); - final issuerDid = issuerKid.split('#')[0]; - - /// verify - final VerificationType isVerified = await verifyEncodedData( - issuerDid, - issuerKid, - response, - ); - - final profileSettingJson = jwtDecode.parseJwt(response); - - await secureStorageProvider.set( - SecureStorageKeys.enterpriseProfileSetting, - jsonEncode(profileSettingJson), - ); - - final profileSetting = ProfileSetting.fromJson(profileSettingJson); - - ///save to profileCubit - await profileCubit.setProfileSetting( - profileSetting: profileSetting, - profileType: ProfileType.enterprise, - ); - // if (isVerified == VerificationType.verified) { - // emit( - // state.copyWith( - // status: AppStatus.idle, - // message: const StateMessage.info( - // showDialog: true, - // stringMessage: 'Verfied', - // ), - // ), - // ); - // } else { - // emit( - // state.copyWith( - // status: AppStatus.idle, - // message: const StateMessage.info( - // showDialog: true, - // stringMessage: 'Not Verfied', - // ), - // ), - // ); - // } - - emit( - state.copyWith( - status: AppStatus.success, - message: null, - ), - ); - } catch (e) { - // TODO(bibash): need to remove this hardcode later - emit( - state.error( - message: const StateMessage.error( - stringMessage: - 'User not registered or email/password are incorrect', - showDialog: true, - ), - ), - ); - } - } - - void emitError(dynamic e) { - final messageHandler = getMessageHandler(e); - - emit( - state.error( - message: StateMessage.error( - messageHandler: messageHandler, - showDialog: true, - ), - ), - ); - } -} diff --git a/lib/onboarding/enterprise/update/cubit/update_state.dart b/lib/onboarding/enterprise/update/cubit/update_state.dart deleted file mode 100644 index 241551c18..000000000 --- a/lib/onboarding/enterprise/update/cubit/update_state.dart +++ /dev/null @@ -1,63 +0,0 @@ -part of 'update_cubit.dart'; - -@JsonSerializable() -class EnterpriseUpdateState extends Equatable { - const EnterpriseUpdateState({ - this.status = AppStatus.init, - this.message, - this.isEmailFormatCorrect = false, - this.isPasswordFormatCorrect = false, - this.obscurePassword = true, - }); - - factory EnterpriseUpdateState.fromJson(Map json) => - _$EnterpriseUpdateStateFromJson(json); - - final AppStatus status; - final StateMessage? message; - final bool isEmailFormatCorrect; - final bool isPasswordFormatCorrect; - final bool obscurePassword; - - EnterpriseUpdateState loading() { - return copyWith( - status: AppStatus.loading, - message: null, - ); - } - - EnterpriseUpdateState error({required StateMessage message}) { - return copyWith( - status: AppStatus.error, - message: message, - ); - } - - EnterpriseUpdateState copyWith({ - required StateMessage? message, - AppStatus? status, - bool? isEmailFormatCorrect, - bool? isPasswordFormatCorrect, - bool? obscurePassword, - }) { - return EnterpriseUpdateState( - status: status ?? this.status, - message: message, - isEmailFormatCorrect: isEmailFormatCorrect ?? this.isEmailFormatCorrect, - isPasswordFormatCorrect: - isPasswordFormatCorrect ?? this.isPasswordFormatCorrect, - obscurePassword: obscurePassword ?? this.obscurePassword, - ); - } - - Map toJson() => _$EnterpriseUpdateStateToJson(this); - - @override - List get props => [ - status, - message, - isEmailFormatCorrect, - isPasswordFormatCorrect, - obscurePassword - ]; -} diff --git a/lib/onboarding/enterprise/update/update.dart b/lib/onboarding/enterprise/update/update.dart deleted file mode 100644 index bacaef6b2..000000000 --- a/lib/onboarding/enterprise/update/update.dart +++ /dev/null @@ -1,2 +0,0 @@ -export 'cubit/update_cubit.dart'; -export 'view/update_page.dart'; diff --git a/lib/onboarding/enterprise/update/view/update_page.dart b/lib/onboarding/enterprise/update/view/update_page.dart deleted file mode 100644 index cd07a9df4..000000000 --- a/lib/onboarding/enterprise/update/view/update_page.dart +++ /dev/null @@ -1,205 +0,0 @@ -import 'package:altme/app/app.dart'; -import 'package:altme/credentials/cubit/credentials_cubit.dart'; -import 'package:altme/dashboard/dashboard.dart'; -import 'package:altme/l10n/l10n.dart'; -import 'package:altme/onboarding/onboarding.dart'; -import 'package:altme/theme/theme.dart'; -import 'package:dio/dio.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:jwt_decode/jwt_decode.dart'; -import 'package:secure_storage/secure_storage.dart'; - -class EnterpriseUpdatePage extends StatelessWidget { - const EnterpriseUpdatePage({super.key}); - - static Route route() { - return MaterialPageRoute( - builder: (_) => const EnterpriseUpdatePage(), - settings: const RouteSettings(name: '/EnterpriseUpdatePage'), - ); - } - - @override - Widget build(BuildContext context) { - return BlocProvider( - create: (_) => EnterpriseUpdateCubit( - client: DioClient('', Dio()), - secureStorageProvider: getSecureStorage, - jwtDecode: JWTDecode(), - profileCubit: context.read(), - ), - child: const EnterpriseUpdateView(), - ); - } -} - -class EnterpriseUpdateView extends StatefulWidget { - const EnterpriseUpdateView({ - super.key, - }); - - @override - State createState() => _EnterpriseUpdateViewState(); -} - -class _EnterpriseUpdateViewState extends State { - late TextEditingController emailController; - late TextEditingController passwordController; - - @override - void initState() { - emailController = TextEditingController(); - passwordController = TextEditingController(); - emailController.addListener(() { - context - .read() - .updateEmailFormat(emailController.text); - }); - passwordController.addListener(() { - context - .read() - .updatePasswordFormat(passwordController.text); - }); - super.initState(); - } - - @override - Widget build(BuildContext context) { - final l10n = context.l10n; - return BlocConsumer( - listener: (context, state) { - if (state.status == AppStatus.loading) { - LoadingView().show(context: context); - } else { - LoadingView().hide(); - } - - if (state.status == AppStatus.success) { - Navigator.popUntil(context, (route) { - return route.settings.name == AltMeStrings.dashBoardPage; - }); - showDialog( - context: context, - barrierDismissible: false, - builder: (context) => ConfirmDialog( - title: l10n.congrats, - subtitle: l10n.yourWalletConfigurationHasBeenSuccessfullyUpdated, - yes: l10n.continueString, - showNoButton: false, - icon: IconStrings.tickCircle, - ), - ); - } - - if (state.message != null) { - AlertMessage.showStateMessage( - context: context, - stateMessage: state.message!, - ); - } - }, - builder: (context, state) { - return BasePage( - scrollView: true, - useSafeArea: true, - padding: const EdgeInsets.symmetric(horizontal: Sizes.spaceSmall), - titleLeading: const BackLeadingButton(), - backgroundColor: Theme.of(context).colorScheme.drawerBackground, - title: l10n.updateConfigurationNow, - titleAlignment: Alignment.topCenter, - body: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - l10n.pleaseEnterYourEmailAndPasswordToUpdateYourOrganizationWalletConfiguration, - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.bodySmall3, - ), - const SizedBox(height: Sizes.spaceNormal), - Text( - l10n.email, - style: Theme.of(context).textTheme.textFieldTitle, - ), - const SizedBox(height: Sizes.spaceSmall), - BaseTextField( - hint: l10n.yourEmail, - fillColor: Theme.of(context).highlightColor, - hintStyle: Theme.of(context).textTheme.hintTextFieldStyle, - maxLines: 1, - borderRadius: Sizes.normalRadius, - controller: emailController, - type: TextInputType.emailAddress, - borderColor: Theme.of(context).colorScheme.background, - suffixIcon: state.isEmailFormatCorrect - ? const Icon(Icons.check_circle) - : null, - ), - const SizedBox(height: Sizes.spaceNormal), - Text( - l10n.password, - style: Theme.of(context).textTheme.textFieldTitle, - ), - const SizedBox(height: Sizes.spaceSmall), - BaseTextField( - hint: l10n.password, - fillColor: Theme.of(context).highlightColor, - hintStyle: Theme.of(context).textTheme.hintTextFieldStyle, - maxLines: 1, - borderRadius: Sizes.normalRadius, - controller: passwordController, - type: TextInputType.text, - obscureText: state.obscurePassword, - borderColor: Theme.of(context).colorScheme.background, - suffixIcon: Padding( - padding: const EdgeInsets.only(right: 10), - child: Wrap( - alignment: WrapAlignment.end, - children: [ - TransparentInkWell( - child: Icon( - state.obscurePassword - ? Icons.visibility_off - : Icons.visibility, - ), - onTap: () { - context - .read() - .obscurePassword(); - }, - ), - if (state.isPasswordFormatCorrect) ...[ - const SizedBox(width: 5), - const Icon(Icons.check_circle), - ], - ], - ), - ), - ), - ], - ), - navigation: Padding( - padding: const EdgeInsets.all(Sizes.spaceSmall), - child: MyElevatedButton( - text: l10n.next, - onPressed: - state.isEmailFormatCorrect && state.isPasswordFormatCorrect - ? () async { - await context - .read() - .updateTheConfiguration( - email: emailController.text.trim(), - password: passwordController.text.trim(), - ); - await context - .read() - .loadAllCredentials(); - } - : null, - ), - ), - ); - }, - ); - } -} diff --git a/lib/onboarding/onboarding.dart b/lib/onboarding/onboarding.dart index 066ebc461..4a305b9fa 100644 --- a/lib/onboarding/onboarding.dart +++ b/lib/onboarding/onboarding.dart @@ -1,5 +1,4 @@ export 'activate_biometircs/activate_biometrics.dart'; -export 'enterprise/enterprise.dart'; export 'gen_phrase/onboarding_gen_phrase.dart'; export 'helper_function/helper_function.dart'; export 'protect_wallet/protect_wallet.dart'; diff --git a/lib/onboarding/starter/view/starter_page.dart b/lib/onboarding/starter/view/starter_page.dart index 502cfe51a..bc79732c1 100644 --- a/lib/onboarding/starter/view/starter_page.dart +++ b/lib/onboarding/starter/view/starter_page.dart @@ -61,7 +61,7 @@ class StarterPage extends StatelessWidget { SubTitle(profileModel: state.model), const Spacer(flex: 4), MyGradientButton( - text: l10n.createPersonalWallet, + text: l10n.createAccount, verticalSpacing: 15, onPressed: () async { await profileCubit.setWalletType( @@ -71,25 +71,32 @@ class StarterPage extends StatelessWidget { profileSetting: ProfileSetting.initial(), profileType: ProfileType.defaultOne, ); - await showDialog( - context: context, - builder: (_) => const WalletDialog(), + await Navigator.of(context).push( + ProtectWalletPage.route( + routeType: WalletRouteType.create, + ), ); }, ), const Spacer(flex: 1), MyOutlinedButton( - text: l10n.createAnProfessionalWallet, + text: l10n.importAccount, textColor: Theme.of(context).colorScheme.lightPurple, borderColor: Theme.of(context).colorScheme.lightPurple, backgroundColor: Colors.transparent, onPressed: () async { await profileCubit.setWalletType( - walletType: WalletType.enterprise, + walletType: WalletType.personal, + ); + await profileCubit.setProfileSetting( + profileSetting: ProfileSetting.initial(), + profileType: ProfileType.defaultOne, ); await Navigator.of(context).push( - EnterpriseInitializationPage.route(), + ProtectWalletPage.route( + routeType: WalletRouteType.import, + ), ); }, ), diff --git a/lib/polygon_id/cubit/polygon_id_cubit.dart b/lib/polygon_id/cubit/polygon_id_cubit.dart index bc4775ed7..95710f687 100644 --- a/lib/polygon_id/cubit/polygon_id_cubit.dart +++ b/lib/polygon_id/cubit/polygon_id_cubit.dart @@ -4,6 +4,7 @@ import 'package:altme/app/app.dart'; import 'package:altme/credentials/credentials.dart'; import 'package:altme/dashboard/dashboard.dart'; import 'package:altme/dashboard/home/tab_bar/credentials/models/activity/activity.dart'; +import 'package:altme/wallet/wallet.dart'; import 'package:bloc/bloc.dart'; import 'package:credential_manifest/credential_manifest.dart'; import 'package:equatable/equatable.dart'; @@ -24,6 +25,7 @@ class PolygonIdCubit extends Cubit { required this.credentialsCubit, required this.client, required this.profileCubit, + required this.walletCubit, }) : super(const PolygonIdState()); final SecureStorageProvider secureStorageProvider; @@ -31,6 +33,7 @@ class PolygonIdCubit extends Cubit { final CredentialsCubit credentialsCubit; final DioClient client; final ProfileCubit profileCubit; + final WalletCubit walletCubit; final log = getLogger('PolygonIdCubit'); @@ -530,7 +533,10 @@ class PolygonIdCubit extends Cubit { activities: [Activity(acquisitionAt: DateTime.now())], ); // insert the credential in the wallet - await credentialsCubit.insertCredential(credential: credentialModel); + await credentialsCubit.insertCredential( + credential: credentialModel, + blockchainType: walletCubit.state.currentAccount!.blockchainType, + ); } /// getSchemas diff --git a/lib/scan/cubit/scan_cubit.dart b/lib/scan/cubit/scan_cubit.dart index c20037791..4d38da1b8 100644 --- a/lib/scan/cubit/scan_cubit.dart +++ b/lib/scan/cubit/scan_cubit.dart @@ -4,6 +4,7 @@ import 'package:altme/app/app.dart'; import 'package:altme/credentials/cubit/credentials_cubit.dart'; import 'package:altme/dashboard/dashboard.dart'; import 'package:altme/dashboard/home/tab_bar/credentials/models/activity/activity.dart'; +import 'package:altme/wallet/wallet.dart'; import 'package:bloc/bloc.dart'; import 'package:credential_manifest/credential_manifest.dart'; @@ -37,6 +38,7 @@ class ScanCubit extends Cubit { required this.didKitProvider, required this.secureStorageProvider, required this.profileCubit, + required this.walletCubit, required this.oidc4vc, }) : super(const ScanState()); @@ -45,6 +47,7 @@ class ScanCubit extends Cubit { final DIDKitProvider didKitProvider; final SecureStorageProvider secureStorageProvider; final ProfileCubit profileCubit; + final WalletCubit walletCubit; final OIDC4VC oidc4vc; Future credentialOfferOrPresent({ @@ -272,6 +275,7 @@ class ScanCubit extends Cubit { CredentialManifest? credentialManifest; await credentialsCubit.insertCredential( + blockchainType: walletCubit.state.currentAccount!.blockchainType, credential: CredentialModel.copyWithData( oldCredentialModel: credentialModel, newData: jsonCredential as Map, diff --git a/lib/splash/bloclisteners/blocklisteners.dart b/lib/splash/bloclisteners/blocklisteners.dart index de1114934..02a8c9753 100644 --- a/lib/splash/bloclisteners/blocklisteners.dart +++ b/lib/splash/bloclisteners/blocklisteners.dart @@ -4,6 +4,7 @@ import 'package:altme/app/app.dart'; import 'package:altme/connection_bridge/connection_bridge.dart'; import 'package:altme/credentials/cubit/credentials_cubit.dart'; import 'package:altme/dashboard/dashboard.dart'; +import 'package:altme/enterprise/enterprise.dart'; import 'package:altme/l10n/l10n.dart'; import 'package:altme/onboarding/cubit/onboarding_cubit.dart'; import 'package:altme/onboarding/onboarding.dart'; @@ -206,12 +207,16 @@ final qrCodeBlocListener = BlocListener( LoadingView().show(context: context); if (state.uri != null) { final profileCubit = context.read(); + final oidc4vc = OIDC4VC(); var acceptHost = true; final approvedIssuer = Issuer.emptyIssuer(state.uri!.host); - final walletSecurityOptions = - profileCubit.state.model.profileSetting.walletSecurityOptions; + final profileSetting = profileCubit.state.model.profileSetting; + final customOidc4vcProfile = + profileSetting.selfSovereignIdentityOptions.customOidc4vcProfile; + + final walletSecurityOptions = profileSetting.walletSecurityOptions; final bool verifySecurityIssuerWebsiteIdentity = walletSecurityOptions.verifySecurityIssuerWebsiteIdentity; @@ -228,6 +233,10 @@ final qrCodeBlocListener = BlocListener( state.uri.toString().startsWith(Parameters.oidc4vcUniversalLink); OIDC4VCType? oidc4vcTypeForIssuance; + dynamic credentialOfferJsonForIssuance; + OpenIdConfiguration? openIdConfigurationForIssuance; + String? issuerForIssuance; + String? preAuthorizedCodeForIssuance; if (isOpenIDUrl || isFromDeeplink) { final ( @@ -235,32 +244,50 @@ final qrCodeBlocListener = BlocListener( OpenIdConfiguration? openIdConfiguration, OpenIdConfiguration? authorizationServerConfiguration, dynamic credentialOfferJson, + String? issuer, + String? preAuthorizedCode, ) = await getIssuanceData( url: state.uri.toString(), client: client, - oidc4vc: OIDC4VC(), - oidc4vciDraftType: profileCubit - .state - .model - .profileSetting - .selfSovereignIdentityOptions - .customOidc4vcProfile - .oidc4vciDraft, + oidc4vc: oidc4vc, + oidc4vciDraftType: profileSetting.selfSovereignIdentityOptions + .customOidc4vcProfile.oidc4vciDraft, ); oidc4vcTypeForIssuance = oidc4vcType; + credentialOfferJsonForIssuance = credentialOfferJson; + openIdConfigurationForIssuance = openIdConfiguration; + issuerForIssuance = issuer; + preAuthorizedCodeForIssuance = preAuthorizedCode; /// if dev mode is ON show some dialog to show data if (profileCubit.state.model.isDeveloperMode) { late String formattedData; if (oidc4vcTypeForIssuance != null) { /// issuance case + + var tokenEndPoint = 'None'; + var credentialEndpoint = 'None'; + + if (openIdConfiguration != null && issuer != null) { + tokenEndPoint = await oidc4vc.readTokenEndPoint( + openIdConfiguration: openIdConfiguration, + issuer: issuer, + oidc4vciDraftType: customOidc4vcProfile.oidc4vciDraft, + ); + + credentialEndpoint = + oidc4vc.readCredentialEndpoint(openIdConfiguration); + } + formattedData = getFormattedStringOIDC4VCI( url: state.uri.toString(), authorizationServerConfiguration: authorizationServerConfiguration, credentialOfferJson: credentialOfferJson, openIdConfiguration: openIdConfiguration, + tokenEndpoint: tokenEndPoint, + credentialEndpoint: credentialEndpoint, ); } else { var url = state.uri!.toString(); @@ -307,9 +334,8 @@ final qrCodeBlocListener = BlocListener( context: context, builder: (_) { return DeveloperModeDialog( - onDisplay: () async { - Navigator.of(context).pop(false); - await Navigator.of(context).push( + onDisplay: () { + Navigator.of(context).push( JsonViewerPage.route( title: l10n.display, data: formattedData, @@ -318,8 +344,6 @@ final qrCodeBlocListener = BlocListener( return; }, onDownload: () { - Navigator.of(context).pop(false); - final box = context.findRenderObject() as RenderBox?; final subject = l10n.shareWith; @@ -329,6 +353,7 @@ final qrCodeBlocListener = BlocListener( sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size, ); + return; }, onSkip: () { Navigator.of(context).pop(true); @@ -399,9 +424,13 @@ final qrCodeBlocListener = BlocListener( LoadingView().hide(); if (acceptHost) { await context.read().accept( - issuer: approvedIssuer, + approvedIssuer: approvedIssuer, qrCodeScanCubit: context.read(), oidcType: oidc4vcTypeForIssuance, + credentialOfferJson: credentialOfferJsonForIssuance, + openIdConfiguration: openIdConfigurationForIssuance, + issuer: issuerForIssuance, + preAuthorizedCode: preAuthorizedCodeForIssuance, ); } else { context.read().emitError( @@ -547,6 +576,48 @@ final qrCodeBlocListener = BlocListener( await context.read().completeSiopV2Flow(); } + if (state.status == QrScanStatus.pauseForDialog) { + LoadingView().hide(); + + final data = state.dialogData ?? ''; + + final bool moveAhead = await showDialog( + context: context, + builder: (_) { + return DeveloperModeDialog( + onDisplay: () { + Navigator.of(context).push( + JsonViewerPage.route( + title: l10n.display, + data: data, + ), + ); + return; + }, + onDownload: () { + final box = context.findRenderObject() as RenderBox?; + final subject = l10n.shareWith; + + Share.share( + data, + subject: subject, + sharePositionOrigin: + box!.localToGlobal(Offset.zero) & box.size, + ); + return; + }, + onSkip: () { + Navigator.of(context).pop(true); + }, + ); + }, + ) ?? + true; + + context.read().completer!.complete(moveAhead); + LoadingView().show(context: context); + } + if (state.status == QrScanStatus.success) { if (state.route != null) { await Navigator.of(context).push(state.route!); @@ -840,3 +911,24 @@ final polygonIdBlocListener = BlocListener( } }, ); + +final enterpriseBlocListener = BlocListener( + listener: (BuildContext context, EnterpriseState state) { + if (state.status == AppStatus.loading) { + LoadingView().show(context: context); + } else { + LoadingView().hide(); + } + + if (state.status == AppStatus.goBack) { + Navigator.of(context).pop(); + } + + if (state.message != null) { + AlertMessage.showStateMessage( + context: context, + stateMessage: state.message!, + ); + } + }, +); diff --git a/lib/splash/helper_function/is_wallet_created.dart b/lib/splash/helper_function/is_wallet_created.dart index 96718b9ba..a9c503a7e 100644 --- a/lib/splash/helper_function/is_wallet_created.dart +++ b/lib/splash/helper_function/is_wallet_created.dart @@ -27,9 +27,6 @@ Future isWalletCreated({ return false; } - log.i('wallet initialisation'); - await credentialsCubit.loadAllCredentials(); - log.i('blockchain initialisation'); await blockchainInitialize( walletCubit: walletCubit, @@ -37,6 +34,11 @@ Future isWalletCreated({ secureStorageProvider: secureStorageProvider, ); + log.i('wallet initialisation'); + await credentialsCubit.loadAllCredentials( + blockchainType: walletCubit.state.currentAccount!.blockchainType, + ); + return true; } diff --git a/lib/splash/view/splash_page.dart b/lib/splash/view/splash_page.dart index 1f013fcd9..b6d8f12c7 100644 --- a/lib/splash/view/splash_page.dart +++ b/lib/splash/view/splash_page.dart @@ -5,6 +5,7 @@ import 'package:altme/app/app.dart'; import 'package:altme/connection_bridge/connection_bridge.dart'; import 'package:altme/dashboard/dashboard.dart'; import 'package:altme/deep_link/deep_link.dart'; +import 'package:altme/enterprise/enterprise.dart'; import 'package:altme/l10n/l10n.dart'; import 'package:altme/polygon_id/polygon_id.dart'; import 'package:altme/splash/splash.dart'; @@ -96,6 +97,11 @@ class _SplashViewState extends State { return; } + if (uri.toString().startsWith('configuration://?')) { + await context.read().requestTheConfiguration(uri!); + return; + } + if (uri.toString().startsWith(Parameters.authorizeEndPoint)) { context.read().addDeepLink(uri!.toString()); await context.read().deepLink(); @@ -223,6 +229,7 @@ class _SplashViewState extends State { beaconBlocListener, walletConnectBlocListener, polygonIdBlocListener, + enterpriseBlocListener, ], child: BlocBuilder( builder: (context, state) { diff --git a/lib/wallet/cubit/wallet_cubit.dart b/lib/wallet/cubit/wallet_cubit.dart index 82439b810..974badd8b 100644 --- a/lib/wallet/cubit/wallet_cubit.dart +++ b/lib/wallet/cubit/wallet_cubit.dart @@ -60,10 +60,12 @@ class WalletCubit extends Cubit { required MessageHandler messageHandler, })? onComplete, }) async { - if (isFromOnboarding) { - // if enterprise and walletAttestation data is available and added - await credentialsCubit.addWalletCredential(); - } + // if (isFromOnboarding) { + // // if enterprise and walletAttestation data is available and added + // await credentialsCubit.addWalletCredential( + // blockchainType: state.currentAccount?.blockchainType, + // ); + // } /// tracking added accounts final String totalAccountsYet = await secureStorageProvider.get( @@ -80,7 +82,7 @@ class WalletCubit extends Cubit { if (blockchainType != null) { /// Here, we create temporary accounts and check for their /// existence beforehand. - final newAcc = await _generateAccount( + final newAcc = await generateAccount( mnemonicOrKey: mnemonicOrKey, isImported: isImported, isSecretKey: isSecretKey, @@ -344,22 +346,15 @@ class WalletCubit extends Cubit { log.i('$blockchainType created'); + /// disable associated wallet account creation at start /// If we are not using crypto in the wallet we are not generating /// AssociatedAddress credentials. - final credential = Parameters.walletHandlesCrypto - ? await credentialsCubit.createOrUpdateAssociatedWalletCredential( - blockchainType: blockchainType, - cryptoAccountData: cryptoAccountData, - ) - : null; - - if (credential != null) { - await credentialsCubit.insertCredential( - credential: credential, - showMessage: false, - showStatus: showStatus, - ); - } + // if (Parameters.walletHandlesCrypto) { + // await credentialsCubit.insertAssociatedWalletCredential( + // blockchainType: blockchainType, + // cryptoAccountData: cryptoAccountData, + // ); + // } return cryptoAccountData; } @@ -376,7 +371,7 @@ class WalletCubit extends Cubit { ); } - Future _generateAccount({ + Future generateAccount({ String? accountName, required String mnemonicOrKey, required bool isImported, @@ -465,7 +460,10 @@ class WalletCubit extends Cubit { cryptoAccountString, ); - await credentialsCubit.insertOrUpdateAssociatedWalletCredential( + /// check if associated wallet credential is available for + /// blockchain type + + await credentialsCubit.updateAssociatedWalletCredential( blockchainType: blockchainType, cryptoAccountData: cryptoAccountData, ); diff --git a/packages/oidc4vc/lib/src/oidc4vc.dart b/packages/oidc4vc/lib/src/oidc4vc.dart index dab9a422e..880b6d3b1 100644 --- a/packages/oidc4vc/lib/src/oidc4vc.dart +++ b/packages/oidc4vc/lib/src/oidc4vc.dart @@ -386,11 +386,20 @@ class OIDC4VC { List? authorizationDetails; /// Retreive credential_type from url - Future<(List, String?, String, OpenIdConfiguration?)> getCredential({ + /// credentialResponseData, deferredCredentialEndpoint, format, + /// openIdConfiguration, tokenResponse + Future< + ( + List, + String?, + String, + OpenIdConfiguration?, + Map? + )> getCredential({ required String issuer, required dynamic credential, required String did, - required String clientId, + required String? clientId, required String? clientSecret, required String kid, required int indexValue, @@ -419,6 +428,8 @@ class OIDC4VC { oidc4vciDraftType: oidc4vciDraftType, ); + Map? tokenResponse; + if (accessToken == null) { final tokenData = buildTokenData( preAuthorizedCode: preAuthorizedCode, @@ -431,19 +442,19 @@ class OIDC4VC { redirectUri: redirectUri, ); - final response = await getToken( + tokenResponse = await getToken( tokenEndPoint: tokenEndPoint, tokenData: tokenData, authorization: authorization, ); - if (response is Map && response.containsKey('c_nonce')) { - cnonce = response['c_nonce'] as String; + if (tokenResponse.containsKey('c_nonce')) { + cnonce = tokenResponse['c_nonce'] as String; } - accessToken = response['access_token'] as String; + accessToken = tokenResponse['access_token'] as String; authorizationDetails = - response['authorization_details'] as List?; + tokenResponse['authorization_details'] as List?; } final issuerTokenParameters = IssuerTokenParameters( @@ -454,7 +465,7 @@ class OIDC4VC { mediaType: MediaType.proofOfOwnership, clientType: clientType, proofHeaderType: proofHeaderType, - clientId: clientId, + clientId: clientId ?? '', ); String? deferredCredentialEndpoint; @@ -533,6 +544,7 @@ class OIDC4VC { deferredCredentialEndpoint, format, openIdConfiguration, + tokenResponse, ); } @@ -839,9 +851,9 @@ class OIDC4VC { } switch (oidc4vciDraftType) { - case OIDC4VCIDraftType.draft8: - credentialData['type'] = credentialType; - credentialData['format'] = format; + // case OIDC4VCIDraftType.draft8: + // credentialData['type'] = credentialType; + // credentialData['format'] = format; case OIDC4VCIDraftType.draft11: if (types == null) { @@ -1065,24 +1077,6 @@ class OIDC4VC { return result; } - Future getSignedJwt({ - required Map payload, - required Map p256Key, - }) async { - // Create a JsonWebSignatureBuilder - final builder = JsonWebSignatureBuilder() - ..jsonContent = payload - ..setProtectedHeader('alg', 'ES256') - ..addRecipient( - JsonWebKey.fromJson(p256Key), - algorithm: 'ES256', - ); - // build the jws - final jws = builder.build(); - - return jws.toCompactSerialization(); - } - String readCredentialEndpoint( OpenIdConfiguration openIdConfiguration, ) { @@ -1131,7 +1125,7 @@ class OIDC4VC { } @visibleForTesting - Future getToken({ + Future> getToken({ required String tokenEndPoint, required Map tokenData, required String? authorization, @@ -1150,7 +1144,7 @@ class OIDC4VC { options: Options(headers: tokenHeaders), data: tokenData, ); - return tokenResponse.data; + return tokenResponse.data as Map; } Future extractVpToken({ @@ -1310,8 +1304,9 @@ class OIDC4VC { return verifierVpJwt; } + /// getSignedJwt String generateToken({ - required Map payload, + required Map payload, required TokenParameters tokenParameters, }) { final vpVerifierClaims = JsonWebTokenClaims.fromJson(payload); diff --git a/packages/oidc4vc/lib/src/oidc4vci_draft_type.dart b/packages/oidc4vc/lib/src/oidc4vci_draft_type.dart index 9ce1132d3..07d8da253 100644 --- a/packages/oidc4vc/lib/src/oidc4vci_draft_type.dart +++ b/packages/oidc4vc/lib/src/oidc4vci_draft_type.dart @@ -1,8 +1,6 @@ import 'package:json_annotation/json_annotation.dart'; enum OIDC4VCIDraftType { - @JsonValue('8') - draft8, @JsonValue('11') draft11, @JsonValue('12') @@ -14,8 +12,6 @@ enum OIDC4VCIDraftType { extension OIDC4VCIDraftTypeX on OIDC4VCIDraftType { String get formattedString { switch (this) { - case OIDC4VCIDraftType.draft8: - return 'Draft 8'; case OIDC4VCIDraftType.draft11: return 'Draft 11'; case OIDC4VCIDraftType.draft12: @@ -24,4 +20,15 @@ extension OIDC4VCIDraftTypeX on OIDC4VCIDraftType { return 'Draft 13'; } } + + String get numbering { + switch (this) { + case OIDC4VCIDraftType.draft11: + return '11'; + case OIDC4VCIDraftType.draft12: + return '12'; + case OIDC4VCIDraftType.draft13: + return '13'; + } + } } diff --git a/packages/oidc4vc/lib/src/vc_format_type.dart b/packages/oidc4vc/lib/src/vc_format_type.dart index 1654f1099..c594a6f8d 100644 --- a/packages/oidc4vc/lib/src/vc_format_type.dart +++ b/packages/oidc4vc/lib/src/vc_format_type.dart @@ -43,4 +43,31 @@ extension VCFormatTypeX on VCFormatType { return 'vc+sd-jwt'; } } + + String get urlValue { + switch (this) { + case VCFormatType.ldpVc: + return 'ldp_vc'; + case VCFormatType.jwtVc: + return 'jwt_vc'; + case VCFormatType.jwtVcJson: + return 'jwt_vc_json'; + case VCFormatType.jwtVcJsonLd: + return 'jwt_vc_json-ld'; + case VCFormatType.vcSdJWT: + return 'vcsd-jwt'; + } + } + + bool get supportCryptoCredential { + switch (this) { + case VCFormatType.ldpVc: + case VCFormatType.jwtVcJson: + return true; + case VCFormatType.jwtVc: + case VCFormatType.jwtVcJsonLd: + case VCFormatType.vcSdJWT: + return false; + } + } } diff --git a/pubspec.lock b/pubspec.lock index 4ba83d667..777395cc2 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,10 +5,10 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: eb376e9acf6938204f90eb3b1f00b578640d3188b4c8a8ec054f9f479af8d051 + sha256: "0b2f2bd91ba804e53a61d757b986f89f1f9eaed5b11e4b2f5a2468d86d6c9fc7" url: "https://pub.dev" source: hosted - version: "64.0.0" + version: "67.0.0" adaptive_number: dependency: transitive description: @@ -21,10 +21,10 @@ packages: dependency: transitive description: name: analyzer - sha256: "69f54f967773f6c26c7dcb13e93d7ccee8b17a641689da39e878d5cf13b06893" + sha256: "37577842a27e4338429a1cbc32679d508836510b056f1eedf0c8d20e39c1383d" url: "https://pub.dev" source: hosted - version: "6.2.0" + version: "6.4.1" android_intent_plus: dependency: transitive description: @@ -310,18 +310,18 @@ packages: dependency: transitive description: name: camera_avfoundation - sha256: "608b56b0880722f703871329c4d7d4c2f379c8e2936940851df7fc041abc6f51" + sha256: "7d0763dfcbf060f56aa254a68c103210280bee9e97bbe4fdef23e257a4f70ab9" url: "https://pub.dev" source: hosted - version: "0.9.13+10" + version: "0.9.14" camera_platform_interface: dependency: transitive description: name: camera_platform_interface - sha256: fceb2c36038b6392317b1d5790c6ba9e6ca9f1da3031181b8bea03882bf9387a + sha256: a250314a48ea337b35909a4c9d5416a208d736dcb01d0b02c6af122be66660b0 url: "https://pub.dev" source: hosted - version: "2.7.3" + version: "2.7.4" camera_web: dependency: transitive description: @@ -437,10 +437,10 @@ packages: dependency: transitive description: name: cross_file - sha256: fedaadfa3a6996f75211d835aaeb8fede285dae94262485698afd832371b9a5e + sha256: "55d7b444feb71301ef6b8838dbc1ae02e63dd48c8773f3810ff53bb1e2945b32" url: "https://pub.dev" source: hosted - version: "0.3.3+8" + version: "0.3.4+1" crypto: dependency: "direct main" description: @@ -500,10 +500,10 @@ packages: dependency: transitive description: name: dart_style - sha256: "40ae61a5d43feea6d24bd22c0537a6629db858963b99b4bc1c3db80676f32368" + sha256: "25b4624c231844a7a70a3817a729a6190a751ef1c07ded256e126a3b72261444" url: "https://pub.dev" source: hosted - version: "2.3.4" + version: "2.3.5" dart_web3: dependency: transitive description: @@ -779,10 +779,10 @@ packages: dependency: "direct main" description: name: file_saver - sha256: f66e1732f6dbbef256171a18b8e493cd360c4fd53b2098eb48d47a6fd676f9ee + sha256: eb16c32d3eb5e4b6318ab9fa97138d6ea0b2d47a25c0af6540263e46979e1c57 url: "https://pub.dev" source: hosted - version: "0.2.10" + version: "0.2.11" file_selector_linux: dependency: transitive description: @@ -973,10 +973,10 @@ packages: dependency: "direct main" description: name: flutter_markdown - sha256: "5b24061317f850af858ef7151dadbb6eb77c1c449c954c7bb064e8a5e0e7d81f" + sha256: a64c5323ac83ed2b7940d2b6288d160aa1753ff271ba9d9b2a86770414aa3eab url: "https://pub.dev" source: hosted - version: "0.6.20" + version: "0.6.20+1" flutter_native_timezone: dependency: "direct main" description: @@ -1077,10 +1077,10 @@ packages: dependency: "direct main" description: name: flutter_svg - sha256: d39e7f95621fc84376bc0f7d504f05c3a41488c562f4a8ad410569127507402c + sha256: "7b4ca6cf3304575fe9c8ec64813c8d02ee41d2afe60bcfe0678bcb5375d596a2" url: "https://pub.dev" source: hosted - version: "2.0.9" + version: "2.0.10+1" flutter_test: dependency: "direct dev" description: flutter @@ -1199,10 +1199,10 @@ packages: dependency: "direct overridden" description: name: http - sha256: a2bbf9d017fcced29139daa8ed2bba4ece450ab222871df93ca9eec6f80c34ba + sha256: "761a297c042deedc1ffbb156d6e2af13886bb305c2a343a4d972504cd67dd938" url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.2.1" http_mock_adapter: dependency: "direct dev" description: @@ -1287,10 +1287,10 @@ packages: dependency: transitive description: name: image_picker_platform_interface - sha256: fa4e815e6fcada50e35718727d83ba1c92f1edf95c0b4436554cec301b56233b + sha256: "3d2c323daea9d60608f1caf30be32a938916f4975434b8352e6f73dae496da38" url: "https://pub.dev" source: hosted - version: "2.9.3" + version: "2.9.4" image_picker_windows: dependency: transitive description: @@ -1429,10 +1429,10 @@ packages: dependency: "direct main" description: name: local_auth - sha256: "27679ed8e0d7daab2357db6bb7076359e083a56b295c0c59723845301da6aed9" + sha256: "280421b416b32de31405b0a25c3bd42dfcef2538dfbb20c03019e02a5ed55ed0" url: "https://pub.dev" source: hosted - version: "2.1.8" + version: "2.2.0" local_auth_android: dependency: transitive description: @@ -1441,14 +1441,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.37" - local_auth_ios: + local_auth_darwin: dependency: transitive description: - name: local_auth_ios - sha256: eb283b530029b334698918f1e282d4483737cbca972ff21b9193be3d6de8e2b8 + name: local_auth_darwin + sha256: "33381a15b0de2279523eca694089393bb146baebdce72a404555d03174ebc1e9" url: "https://pub.dev" source: hosted - version: "1.1.6" + version: "1.2.2" local_auth_platform_interface: dependency: transitive description: @@ -1509,10 +1509,10 @@ packages: dependency: "direct main" description: name: matrix - sha256: "90e8743a3836414751400ecb24c9b41a20472b316f77010dc4ddcf300d511906" + sha256: "64b71793b689f57521f24d5412dadd090a61762084971ff13c7b8870b3cebeb7" url: "https://pub.dev" source: hosted - version: "0.25.9" + version: "0.25.11" matrix_api_lite: dependency: transitive description: @@ -1940,10 +1940,10 @@ packages: dependency: transitive description: name: provider - sha256: "9a96a0a19b594dbc5bf0f1f27d2bc67d5f95957359b461cd9feb44ed6ae75096" + sha256: c8a055ee5ce3fd98d6fc872478b03823ffdb448699c6ebdbbc71d59b596fd48c url: "https://pub.dev" source: hosted - version: "6.1.1" + version: "6.1.2" pub_semver: dependency: transitive description: @@ -2139,10 +2139,10 @@ packages: dependency: transitive description: name: shared_preferences_web - sha256: "7b15ffb9387ea3e237bb7a66b8a23d2147663d391cafc5c8f37b2e7b4bde5d21" + sha256: "9aee1089b36bd2aafe06582b7d7817fd317ef05fc30e6ba14bff247d0933042a" url: "https://pub.dev" source: hosted - version: "2.2.2" + version: "2.3.0" shared_preferences_windows: dependency: transitive description: @@ -2425,10 +2425,10 @@ packages: dependency: "direct main" description: name: url_launcher - sha256: c512655380d241a337521703af62d2c122bf7b77a46ff7dd750092aa9433499c + sha256: "0ecc004c62fd3ed36a2ffcbe0dd9700aee63bd7532d0b642a488b1ec310f492e" url: "https://pub.dev" source: hosted - version: "6.2.4" + version: "6.2.5" url_launcher_android: dependency: transitive description: @@ -2441,10 +2441,10 @@ packages: dependency: transitive description: name: url_launcher_ios - sha256: "75bb6fe3f60070407704282a2d295630cab232991eb52542b18347a8a941df03" + sha256: "9149d493b075ed740901f3ee844a38a00b33116c7c5c10d7fb27df8987fb51d5" url: "https://pub.dev" source: hosted - version: "6.2.4" + version: "6.2.5" url_launcher_linux: dependency: transitive description: @@ -2473,10 +2473,10 @@ packages: dependency: transitive description: name: url_launcher_web - sha256: fff0932192afeedf63cdd50ecbb1bc825d31aed259f02bb8dba0f3b729a5e88b + sha256: "3692a459204a33e04bc94f5fb91158faf4f2c8903281ddd82915adecdb1a901d" url: "https://pub.dev" source: hosted - version: "2.2.3" + version: "2.3.0" url_launcher_windows: dependency: transitive description: @@ -2497,26 +2497,26 @@ packages: dependency: transitive description: name: vector_graphics - sha256: "4ac59808bbfca6da38c99f415ff2d3a5d7ca0a6b4809c71d9cf30fba5daf9752" + sha256: "32c3c684e02f9bc0afb0ae0aa653337a2fe022e8ab064bcd7ffda27a74e288e3" url: "https://pub.dev" source: hosted - version: "1.1.10+1" + version: "1.1.11+1" vector_graphics_codec: dependency: transitive description: name: vector_graphics_codec - sha256: f3247e7ab0ec77dc759263e68394990edc608fb2b480b80db8aa86ed09279e33 + sha256: c86987475f162fadff579e7320c7ddda04cd2fdeffbe1129227a85d9ac9e03da url: "https://pub.dev" source: hosted - version: "1.1.10+1" + version: "1.1.11+1" vector_graphics_compiler: dependency: transitive description: name: vector_graphics_compiler - sha256: "18489bdd8850de3dd7ca8a34e0c446f719ec63e2bab2e7a8cc66a9028dd76c5a" + sha256: "12faff3f73b1741a36ca7e31b292ddeb629af819ca9efe9953b70bd63fc8cd81" url: "https://pub.dev" source: hosted - version: "1.1.10+1" + version: "1.1.11+1" vector_math: dependency: transitive description: @@ -2577,10 +2577,10 @@ packages: dependency: transitive description: name: web - sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 + sha256: "1d9158c616048c38f712a6646e317a3426da10e884447626167240d45209cbad" url: "https://pub.dev" source: hosted - version: "0.3.0" + version: "0.5.0" web3dart: dependency: transitive description: @@ -2593,10 +2593,10 @@ packages: dependency: transitive description: name: web_socket_channel - sha256: d88238e5eac9a42bb43ca4e721edba3c08c6354d4a53063afaa568516217621b + sha256: "1d8e795e2a8b3730c41b8a98a2dff2e0fb57ae6f0764a1c46ec5915387d257b2" url: "https://pub.dev" source: hosted - version: "2.4.0" + version: "2.4.4" webkit_inspection_protocol: dependency: transitive description: @@ -2617,10 +2617,10 @@ packages: dependency: "direct main" description: name: webview_flutter - sha256: d81b68e88cc353e546afb93fb38958e3717282c5ac6e5d3be4a4aef9fc3c1413 + sha256: "25e1b6e839e8cbfbd708abc6f85ed09d1727e24e08e08c6b8590d7c65c9a8932" url: "https://pub.dev" source: hosted - version: "4.5.0" + version: "4.7.0" webview_flutter_android: dependency: "direct main" description: @@ -2641,10 +2641,10 @@ packages: dependency: "direct main" description: name: webview_flutter_wkwebview - sha256: "4d062ad505390ecef1c4bfb6001cd857a51e00912cc9dfb66edb1886a9ebd80c" + sha256: "9bf168bccdf179ce90450b5f37e36fe263f591c9338828d6bf09b6f8d0f57f86" url: "https://pub.dev" source: hosted - version: "3.10.2" + version: "3.12.0" win32: dependency: transitive description: @@ -2705,10 +2705,10 @@ packages: dependency: transitive description: name: yaml_edit - sha256: "1579d4a0340a83cf9e4d580ea51a16329c916973bffd5bd4b45e911b25d46bfd" + sha256: c566f4f804215d84a7a2c377667f546c6033d5b34b4f9e60dfb09d17c4e97826 url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.2.0" sdks: - dart: ">=3.2.0 <4.0.0" - flutter: ">=3.16.0" + dart: ">=3.3.0 <4.0.0" + flutter: ">=3.19.0" diff --git a/pubspec.yaml b/pubspec.yaml index 8b0b36fd1..bb612d5c2 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: altme description: AltMe Flutter App -version: 2.3.5+395 +version: 2.3.12+402 environment: sdk: ">=3.1.0 <4.0.0" From a0a37f294c0bfd88ccf25b1f672e5cb95bffb7a4 Mon Sep 17 00:00:00 2001 From: hawkbee1 Date: Fri, 1 Mar 2024 10:44:00 +0000 Subject: [PATCH 02/45] if credentialManifest!.issuedBy?.name is null use '' as issuer value --- .../missing_creentials/view/missing_credentials_page.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/dashboard/missing_creentials/view/missing_credentials_page.dart b/lib/dashboard/missing_creentials/view/missing_credentials_page.dart index fe8fa89b5..bbe47121a 100644 --- a/lib/dashboard/missing_creentials/view/missing_credentials_page.dart +++ b/lib/dashboard/missing_creentials/view/missing_credentials_page.dart @@ -65,7 +65,7 @@ class MissingCredentialsView extends StatelessWidget { String issuerName = ''; if (credentialManifest != null) { - issuerName = credentialManifest!.issuedBy!.name; + issuerName = credentialManifest!.issuedBy?.name ?? ''; } if (query != null) { From 1cb94490937472f48936c3a386632b98226b098b Mon Sep 17 00:00:00 2001 From: hawkbee1 Date: Fri, 1 Mar 2024 10:44:22 +0000 Subject: [PATCH 03/45] alllow deletion of blockchainAccountsCards --- .../models/credential_model/credential_model.dart | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/lib/dashboard/home/tab_bar/credentials/models/credential_model/credential_model.dart b/lib/dashboard/home/tab_bar/credentials/models/credential_model/credential_model.dart index 80417c9c4..ae92fb1be 100644 --- a/lib/dashboard/home/tab_bar/credentials/models/credential_model/credential_model.dart +++ b/lib/dashboard/home/tab_bar/credentials/models/credential_model/credential_model.dart @@ -236,11 +236,7 @@ class CredentialModel extends Equatable { bool get disAllowDelete => credentialPreview.credentialSubjectModel.credentialSubjectType == - CredentialSubjectType.walletCredential || - (credentialPreview.credentialSubjectModel.credentialCategory == - CredentialCategory.blockchainAccountsCards && - credentialPreview.credentialSubjectModel.issuedBy?.name == - 'My wallet'); + CredentialSubjectType.walletCredential; String get getFormat => format != null ? format! From b510b5f38f87c22197b9f4b1d8ac1a060604b58e Mon Sep 17 00:00:00 2001 From: Bibash Shrestha Date: Tue, 20 Feb 2024 15:11:20 +0545 Subject: [PATCH 04/45] Add account ownership manually #2291 --- .../credential_subject_type_extension.dart | 10 +++++----- lib/app/shared/enum/type/profile/profile_type.dart | 13 +++++++++++++ lib/l10n/arb/app_en.arb | 2 ++ lib/l10n/untranslated.json | 8 ++++---- 4 files changed, 24 insertions(+), 9 deletions(-) diff --git a/lib/app/shared/enum/type/credential_subject_type/credential_subject_type_extension.dart b/lib/app/shared/enum/type/credential_subject_type/credential_subject_type_extension.dart index 7f2631af7..db6b0a9c4 100644 --- a/lib/app/shared/enum/type/credential_subject_type/credential_subject_type_extension.dart +++ b/lib/app/shared/enum/type/credential_subject_type/credential_subject_type_extension.dart @@ -640,6 +640,11 @@ extension CredentialSubjectTypeExtension on CredentialSubjectType { case CredentialSubjectType.over65: case CredentialSubjectType.gender: case CredentialSubjectType.ageRange: + case CredentialSubjectType.tezosPooAddress: + case CredentialSubjectType.ethereumPooAddress: + case CredentialSubjectType.fantomPooAddress: + case CredentialSubjectType.polygonPooAddress: + case CredentialSubjectType.binancePooAddress: case CredentialSubjectType.defiCompliance: case CredentialSubjectType.tezotopiaMembership: case CredentialSubjectType.chainbornMembership: @@ -670,11 +675,6 @@ extension CredentialSubjectTypeExtension on CredentialSubjectType { case CredentialSubjectType.diplomaCard: case CredentialSubjectType.twitterCard: case CredentialSubjectType.walletCredential: - case CredentialSubjectType.tezosPooAddress: - case CredentialSubjectType.ethereumPooAddress: - case CredentialSubjectType.fantomPooAddress: - case CredentialSubjectType.polygonPooAddress: - case CredentialSubjectType.binancePooAddress: case CredentialSubjectType.certificateOfEmployment: case CredentialSubjectType.defaultCredential: case CredentialSubjectType.linkedInCard: diff --git a/lib/app/shared/enum/type/profile/profile_type.dart b/lib/app/shared/enum/type/profile/profile_type.dart index cff571896..a1e72e90b 100644 --- a/lib/app/shared/enum/type/profile/profile_type.dart +++ b/lib/app/shared/enum/type/profile/profile_type.dart @@ -42,4 +42,17 @@ extension ProfileTypeX on ProfileType { return true; } } + + bool get supportAssociatedCredential { + switch (this) { + case ProfileType.custom: + case ProfileType.owfBaselineProfile: + return false; + case ProfileType.defaultOne: + case ProfileType.dutch: + case ProfileType.ebsiV3: + case ProfileType.enterprise: + return true; + } + } } diff --git a/lib/l10n/arb/app_en.arb b/lib/l10n/arb/app_en.arb index 1ebd52f27..fe8614abd 100644 --- a/lib/l10n/arb/app_en.arb +++ b/lib/l10n/arb/app_en.arb @@ -840,6 +840,8 @@ "financeCredentialsHomeTitle": "My financial credentials", "financeCredentialsDiscoverTitle": "Get verified financial credentials", "financeCredentialsDiscoverSubtitle": "Access new investment opportunities in web3.", + "blockchainCardsDiscoverTitle": "Get a proof of crypto account ownership", + "blockchainCardsDiscoverSubtitle": "Get a proof of crypto account ownership.", "financeCredentialsHomeSubtitle": "Access new investment opportunities in web3", "hummanityProofCredentialsHomeTitle": "My proof of humanity", "hummanityProofCredentialsHomeSubtitle": "Easily prove you are a human and not a bot.", diff --git a/lib/l10n/untranslated.json b/lib/l10n/untranslated.json index ac52f842d..cdf1bef29 100644 --- a/lib/l10n/untranslated.json +++ b/lib/l10n/untranslated.json @@ -1,5 +1,7 @@ { "ca": [ + "blockchainCardsDiscoverTitle", + "blockchainCardsDiscoverSubtitle", "clientTypeTitle", "clientTypeSubtitle", "proofHeader", @@ -10,13 +12,13 @@ "enterprise", "oWFBaselineProfile", "defaultProfile", - "blockchainCardsDiscoverTitle", - "blockchainCardsDiscoverSubtitle", "successfullyAddedEnterpriseAccount", "successfullyUpdatedEnterpriseAccount" ], "es": [ + "blockchainCardsDiscoverTitle", + "blockchainCardsDiscoverSubtitle", "clientTypeTitle", "clientTypeSubtitle", "proofHeader", @@ -27,8 +29,6 @@ "enterprise", "oWFBaselineProfile", "defaultProfile", - "blockchainCardsDiscoverTitle", - "blockchainCardsDiscoverSubtitle", "successfullyAddedEnterpriseAccount", "successfullyUpdatedEnterpriseAccount" ] From bc5ee3cdba2e3cdc3fcf25622147599984008923 Mon Sep 17 00:00:00 2001 From: Bibash Shrestha Date: Thu, 22 Feb 2024 18:05:27 +0545 Subject: [PATCH 05/45] Account ownership cards : logic change --- lib/oidc4vc/get_authorization_uri_for_issuer.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/oidc4vc/get_authorization_uri_for_issuer.dart b/lib/oidc4vc/get_authorization_uri_for_issuer.dart index 49015f548..afe8fb4b6 100644 --- a/lib/oidc4vc/get_authorization_uri_for_issuer.dart +++ b/lib/oidc4vc/get_authorization_uri_for_issuer.dart @@ -7,6 +7,7 @@ import 'package:did_kit/did_kit.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:oidc4vc/oidc4vc.dart'; import 'package:uuid/uuid.dart'; +import 'package:dart_jsonwebtoken/dart_jsonwebtoken.dart'; Future getAuthorizationUriForIssuer({ required String scannedResponse, From 5b8e1a84f76bca0c0f83fbcb490bfb10c459db06 Mon Sep 17 00:00:00 2001 From: Bibash Shrestha Date: Fri, 23 Feb 2024 18:48:41 +0545 Subject: [PATCH 06/45] feat: Support qr to add enterprise account #2433 --- ios/Runner.xcodeproj/project.pbxproj | 2 +- .../xcshareddata/xcschemes/Runner.xcscheme | 2 +- lib/app/shared/constants/urls.dart | 16 ++++++++-------- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 9ef5f3487..4747bcb98 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -169,7 +169,7 @@ 97C146E61CF9000F007C117D /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 1430; + LastUpgradeCheck = 1510; ORGANIZATIONNAME = ""; TargetAttributes = { 97C146ED1CF9000F007C117D = { diff --git a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index a6b826db2..5e31d3d34 100644 --- a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ '$cryptoCompareBaseUrl/data/price?fsym=$symbol&tsyms=USD'; - // TZKT + /// TZKT static const tzktMainnetUrl = 'https://api.tzkt.io'; static const tzktGhostnetUrl = 'https://api.ghostnet.tzkt.io'; - //Moralis + /// Moralis static const moralisBaseUrl = 'https://deep-index.moralis.io/api/v2'; - //Infura + /// Infura static const infuraBaseUrl = 'https://mainnet.infura.io/v3/'; static const objktUrl = 'https://objkt.com/'; @@ -103,24 +103,24 @@ class Urls { static const over65AIValidationUrl = 'https://issuer.talao.co/ai/over65'; static const ageRangeAIValidationUrl = 'https://issuer.talao.co/ai/agerange'; - //Matrix home server + /// Matrix home server static const matrixHomeServer = 'https://matrix.talao.co'; static const getNonce = 'https://talao.co/matrix/nonce'; static const registerToMatrix = 'https://talao.co/matrix/register'; - //deeplink + /// deeplink static const appDeepLink = 'https://app.altme.io/app/download'; - //ID360 + /// ID360 static const getCodeForId360 = 'https://talao.co/id360/get_code'; static const authenticateForId360 = 'https://talao.co/id360/authenticate'; - //Discover + /// Discover static const discoverCoinsWebView = 'https://discover-coins-part.webflow.io/'; static const discoverNftsWebView = 'https://discover-coins-part.webflow.io/prod-nota-available/nft-noir'; - // wallet provider + /// wallet provider static const walletProvider = 'https://wallet-provider.talao.co'; static const walletTestProvider = 'https://preprod.wallet-provider.talao.co'; } From a841b0f3eaa49ef75994de88bde75ba5ee0f06b8 Mon Sep 17 00:00:00 2001 From: Bibash Shrestha Date: Mon, 26 Feb 2024 14:15:33 +0545 Subject: [PATCH 07/45] feat: Remove enterprise from onboarding #2433 --- pubspec.lock | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index 777395cc2..94317c479 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,10 +5,10 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: "0b2f2bd91ba804e53a61d757b986f89f1f9eaed5b11e4b2f5a2468d86d6c9fc7" + sha256: eb376e9acf6938204f90eb3b1f00b578640d3188b4c8a8ec054f9f479af8d051 url: "https://pub.dev" source: hosted - version: "67.0.0" + version: "64.0.0" adaptive_number: dependency: transitive description: @@ -21,10 +21,10 @@ packages: dependency: transitive description: name: analyzer - sha256: "37577842a27e4338429a1cbc32679d508836510b056f1eedf0c8d20e39c1383d" + sha256: "69f54f967773f6c26c7dcb13e93d7ccee8b17a641689da39e878d5cf13b06893" url: "https://pub.dev" source: hosted - version: "6.4.1" + version: "6.2.0" android_intent_plus: dependency: transitive description: @@ -437,10 +437,10 @@ packages: dependency: transitive description: name: cross_file - sha256: "55d7b444feb71301ef6b8838dbc1ae02e63dd48c8773f3810ff53bb1e2945b32" + sha256: fedaadfa3a6996f75211d835aaeb8fede285dae94262485698afd832371b9a5e url: "https://pub.dev" source: hosted - version: "0.3.4+1" + version: "0.3.3+8" crypto: dependency: "direct main" description: @@ -973,10 +973,10 @@ packages: dependency: "direct main" description: name: flutter_markdown - sha256: a64c5323ac83ed2b7940d2b6288d160aa1753ff271ba9d9b2a86770414aa3eab + sha256: "5b24061317f850af858ef7151dadbb6eb77c1c449c954c7bb064e8a5e0e7d81f" url: "https://pub.dev" source: hosted - version: "0.6.20+1" + version: "0.6.20" flutter_native_timezone: dependency: "direct main" description: @@ -1199,10 +1199,10 @@ packages: dependency: "direct overridden" description: name: http - sha256: "761a297c042deedc1ffbb156d6e2af13886bb305c2a343a4d972504cd67dd938" + sha256: a2bbf9d017fcced29139daa8ed2bba4ece450ab222871df93ca9eec6f80c34ba url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.2.0" http_mock_adapter: dependency: "direct dev" description: @@ -1287,10 +1287,10 @@ packages: dependency: transitive description: name: image_picker_platform_interface - sha256: "3d2c323daea9d60608f1caf30be32a938916f4975434b8352e6f73dae496da38" + sha256: fa4e815e6fcada50e35718727d83ba1c92f1edf95c0b4436554cec301b56233b url: "https://pub.dev" source: hosted - version: "2.9.4" + version: "2.9.3" image_picker_windows: dependency: transitive description: @@ -2139,10 +2139,10 @@ packages: dependency: transitive description: name: shared_preferences_web - sha256: "9aee1089b36bd2aafe06582b7d7817fd317ef05fc30e6ba14bff247d0933042a" + sha256: "7b15ffb9387ea3e237bb7a66b8a23d2147663d391cafc5c8f37b2e7b4bde5d21" url: "https://pub.dev" source: hosted - version: "2.3.0" + version: "2.2.2" shared_preferences_windows: dependency: transitive description: @@ -2473,10 +2473,10 @@ packages: dependency: transitive description: name: url_launcher_web - sha256: "3692a459204a33e04bc94f5fb91158faf4f2c8903281ddd82915adecdb1a901d" + sha256: fff0932192afeedf63cdd50ecbb1bc825d31aed259f02bb8dba0f3b729a5e88b url: "https://pub.dev" source: hosted - version: "2.3.0" + version: "2.2.3" url_launcher_windows: dependency: transitive description: @@ -2577,10 +2577,10 @@ packages: dependency: transitive description: name: web - sha256: "1d9158c616048c38f712a6646e317a3426da10e884447626167240d45209cbad" + sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 url: "https://pub.dev" source: hosted - version: "0.5.0" + version: "0.3.0" web3dart: dependency: transitive description: @@ -2593,10 +2593,10 @@ packages: dependency: transitive description: name: web_socket_channel - sha256: "1d8e795e2a8b3730c41b8a98a2dff2e0fb57ae6f0764a1c46ec5915387d257b2" + sha256: d88238e5eac9a42bb43ca4e721edba3c08c6354d4a53063afaa568516217621b url: "https://pub.dev" source: hosted - version: "2.4.4" + version: "2.4.0" webkit_inspection_protocol: dependency: transitive description: @@ -2710,5 +2710,5 @@ packages: source: hosted version: "2.2.0" sdks: - dart: ">=3.3.0 <4.0.0" - flutter: ">=3.19.0" + dart: ">=3.2.3 <4.0.0" + flutter: ">=3.16.6" From 213d4eab3b694d11e4d73442c4e64f7590e74f9c Mon Sep 17 00:00:00 2001 From: Bibash Shrestha Date: Mon, 26 Feb 2024 14:35:59 +0545 Subject: [PATCH 08/45] feat: Remove draft 8 #2436 --- pubspec.lock | 40 ++++++++-------------------------------- 1 file changed, 8 insertions(+), 32 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index 94317c479..8159322d1 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1385,30 +1385,6 @@ packages: relative: true source: path version: "1.0.0+1" - leak_tracker: - dependency: transitive - description: - name: leak_tracker - sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" - url: "https://pub.dev" - source: hosted - version: "10.0.0" - leak_tracker_flutter_testing: - dependency: transitive - description: - name: leak_tracker_flutter_testing - sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 - url: "https://pub.dev" - source: hosted - version: "2.0.1" - leak_tracker_testing: - dependency: transitive - description: - name: leak_tracker_testing - sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 - url: "https://pub.dev" - source: hosted - version: "2.0.1" linkify: dependency: transitive description: @@ -1493,18 +1469,18 @@ packages: dependency: transitive description: name: matcher - sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb + sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" url: "https://pub.dev" source: hosted - version: "0.12.16+1" + version: "0.12.16" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" + sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" url: "https://pub.dev" source: hosted - version: "0.8.0" + version: "0.5.0" matrix: dependency: "direct main" description: @@ -1533,10 +1509,10 @@ packages: dependency: transitive description: name: meta - sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 + sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e url: "https://pub.dev" source: hosted - version: "1.11.0" + version: "1.10.0" mime: dependency: "direct main" description: @@ -1684,10 +1660,10 @@ packages: dependency: "direct main" description: name: path - sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" + sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" url: "https://pub.dev" source: hosted - version: "1.9.0" + version: "1.8.3" path_drawing: dependency: transitive description: From ceb39ad680be0fe54d05f3871fc0165fdd24aca3 Mon Sep 17 00:00:00 2001 From: Bibash Shrestha Date: Mon, 26 Feb 2024 15:37:27 +0545 Subject: [PATCH 09/45] update email and phonepass url #2438 #2439 --- lib/app/shared/constants/urls.dart | 16 ++++---- .../credential_subject_type_extension.dart | 26 ++++++------ pubspec.lock | 40 +++++++++++++++---- 3 files changed, 52 insertions(+), 30 deletions(-) diff --git a/lib/app/shared/constants/urls.dart b/lib/app/shared/constants/urls.dart index 7aa529f54..a37da92d3 100644 --- a/lib/app/shared/constants/urls.dart +++ b/lib/app/shared/constants/urls.dart @@ -82,14 +82,14 @@ class Urls { static String ethPrice(String symbol) => '$cryptoCompareBaseUrl/data/price?fsym=$symbol&tsyms=USD'; - /// TZKT + // TZKT static const tzktMainnetUrl = 'https://api.tzkt.io'; static const tzktGhostnetUrl = 'https://api.ghostnet.tzkt.io'; - /// Moralis + //Moralis static const moralisBaseUrl = 'https://deep-index.moralis.io/api/v2'; - /// Infura + //Infura static const infuraBaseUrl = 'https://mainnet.infura.io/v3/'; static const objktUrl = 'https://objkt.com/'; @@ -103,24 +103,24 @@ class Urls { static const over65AIValidationUrl = 'https://issuer.talao.co/ai/over65'; static const ageRangeAIValidationUrl = 'https://issuer.talao.co/ai/agerange'; - /// Matrix home server + //Matrix home server static const matrixHomeServer = 'https://matrix.talao.co'; static const getNonce = 'https://talao.co/matrix/nonce'; static const registerToMatrix = 'https://talao.co/matrix/register'; - /// deeplink + //deeplink static const appDeepLink = 'https://app.altme.io/app/download'; - /// ID360 + //ID360 static const getCodeForId360 = 'https://talao.co/id360/get_code'; static const authenticateForId360 = 'https://talao.co/id360/authenticate'; - /// Discover + //Discover static const discoverCoinsWebView = 'https://discover-coins-part.webflow.io/'; static const discoverNftsWebView = 'https://discover-coins-part.webflow.io/prod-nota-available/nft-noir'; - /// wallet provider + // wallet provider static const walletProvider = 'https://wallet-provider.talao.co'; static const walletTestProvider = 'https://preprod.wallet-provider.talao.co'; } diff --git a/lib/app/shared/enum/type/credential_subject_type/credential_subject_type_extension.dart b/lib/app/shared/enum/type/credential_subject_type/credential_subject_type_extension.dart index db6b0a9c4..1cf7e531d 100644 --- a/lib/app/shared/enum/type/credential_subject_type/credential_subject_type_extension.dart +++ b/lib/app/shared/enum/type/credential_subject_type/credential_subject_type_extension.dart @@ -583,13 +583,13 @@ extension CredentialSubjectTypeExtension on CredentialSubjectType { case CredentialSubjectType.tezVoucher: case CredentialSubjectType.diplomaCard: case CredentialSubjectType.twitterCard: + return true; + case CredentialSubjectType.walletCredential: case CredentialSubjectType.tezosAssociatedWallet: case CredentialSubjectType.ethereumAssociatedWallet: case CredentialSubjectType.fantomAssociatedWallet: case CredentialSubjectType.polygonAssociatedWallet: case CredentialSubjectType.binanceAssociatedWallet: - return true; - case CredentialSubjectType.walletCredential: case CredentialSubjectType.tezosPooAddress: case CredentialSubjectType.ethereumPooAddress: case CredentialSubjectType.fantomPooAddress: @@ -626,13 +626,6 @@ extension CredentialSubjectTypeExtension on CredentialSubjectType { List get getVCFormatType { switch (this) { - case CredentialSubjectType.ethereumAssociatedWallet: - case CredentialSubjectType.fantomAssociatedWallet: - case CredentialSubjectType.polygonAssociatedWallet: - case CredentialSubjectType.binanceAssociatedWallet: - case CredentialSubjectType.tezosAssociatedWallet: - return VCFormatType.values; - case CredentialSubjectType.over13: case CredentialSubjectType.over15: case CredentialSubjectType.over21: @@ -640,11 +633,11 @@ extension CredentialSubjectTypeExtension on CredentialSubjectType { case CredentialSubjectType.over65: case CredentialSubjectType.gender: case CredentialSubjectType.ageRange: - case CredentialSubjectType.tezosPooAddress: - case CredentialSubjectType.ethereumPooAddress: - case CredentialSubjectType.fantomPooAddress: - case CredentialSubjectType.polygonPooAddress: - case CredentialSubjectType.binancePooAddress: + case CredentialSubjectType.ethereumAssociatedWallet: + case CredentialSubjectType.fantomAssociatedWallet: + case CredentialSubjectType.polygonAssociatedWallet: + case CredentialSubjectType.binanceAssociatedWallet: + case CredentialSubjectType.tezosAssociatedWallet: case CredentialSubjectType.defiCompliance: case CredentialSubjectType.tezotopiaMembership: case CredentialSubjectType.chainbornMembership: @@ -675,6 +668,11 @@ extension CredentialSubjectTypeExtension on CredentialSubjectType { case CredentialSubjectType.diplomaCard: case CredentialSubjectType.twitterCard: case CredentialSubjectType.walletCredential: + case CredentialSubjectType.tezosPooAddress: + case CredentialSubjectType.ethereumPooAddress: + case CredentialSubjectType.fantomPooAddress: + case CredentialSubjectType.polygonPooAddress: + case CredentialSubjectType.binancePooAddress: case CredentialSubjectType.certificateOfEmployment: case CredentialSubjectType.defaultCredential: case CredentialSubjectType.linkedInCard: diff --git a/pubspec.lock b/pubspec.lock index 8159322d1..94317c479 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1385,6 +1385,30 @@ packages: relative: true source: path version: "1.0.0+1" + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" + url: "https://pub.dev" + source: hosted + version: "10.0.0" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 + url: "https://pub.dev" + source: hosted + version: "2.0.1" + leak_tracker_testing: + dependency: transitive + description: + name: leak_tracker_testing + sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 + url: "https://pub.dev" + source: hosted + version: "2.0.1" linkify: dependency: transitive description: @@ -1469,18 +1493,18 @@ packages: dependency: transitive description: name: matcher - sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb url: "https://pub.dev" source: hosted - version: "0.12.16" + version: "0.12.16+1" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" + sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" url: "https://pub.dev" source: hosted - version: "0.5.0" + version: "0.8.0" matrix: dependency: "direct main" description: @@ -1509,10 +1533,10 @@ packages: dependency: transitive description: name: meta - sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e + sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.11.0" mime: dependency: "direct main" description: @@ -1660,10 +1684,10 @@ packages: dependency: "direct main" description: name: path - sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.dev" source: hosted - version: "1.8.3" + version: "1.9.0" path_drawing: dependency: transitive description: From 464bbc3923bb80845b378e6ded9a86763bac3ac2 Mon Sep 17 00:00:00 2001 From: Bibash Shrestha Date: Mon, 26 Feb 2024 16:49:37 +0545 Subject: [PATCH 10/45] Do not support scan for enterprise login #2442 and add over 18 for diip #2431 --- lib/splash/view/splash_page.dart | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/splash/view/splash_page.dart b/lib/splash/view/splash_page.dart index b6d8f12c7..1e273ed4a 100644 --- a/lib/splash/view/splash_page.dart +++ b/lib/splash/view/splash_page.dart @@ -93,6 +93,11 @@ class _SplashViewState extends State { } if (uri.toString().startsWith(Parameters.oidc4vcUniversalLink)) { + await context.read().requestTheConfiguration(uri!); + return; + } + + if (uri.toString().startsWith('configuration://?')) { await context.read().authorizedFlowStart(uri!); return; } From 284c04aaedf6ce80dfc259cfe1e31c76cde3150b Mon Sep 17 00:00:00 2001 From: Bibash Shrestha Date: Tue, 27 Feb 2024 11:13:45 +0545 Subject: [PATCH 11/45] feat: Re-support enterpise login with scan --- ios/Runner.xcodeproj/project.pbxproj | 2 +- .../xcshareddata/xcschemes/Runner.xcscheme | 2 +- pubspec.lock | 40 ++++--------------- 3 files changed, 10 insertions(+), 34 deletions(-) diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 4747bcb98..9ef5f3487 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -169,7 +169,7 @@ 97C146E61CF9000F007C117D /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 1510; + LastUpgradeCheck = 1430; ORGANIZATIONNAME = ""; TargetAttributes = { 97C146ED1CF9000F007C117D = { diff --git a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index 5e31d3d34..a6b826db2 100644 --- a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ Date: Tue, 27 Feb 2024 13:09:23 +0545 Subject: [PATCH 12/45] enterprise call bug fix --- lib/splash/view/splash_page.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/splash/view/splash_page.dart b/lib/splash/view/splash_page.dart index 1e273ed4a..2d6b5d862 100644 --- a/lib/splash/view/splash_page.dart +++ b/lib/splash/view/splash_page.dart @@ -93,12 +93,12 @@ class _SplashViewState extends State { } if (uri.toString().startsWith(Parameters.oidc4vcUniversalLink)) { - await context.read().requestTheConfiguration(uri!); + await context.read().authorizedFlowStart(uri!); return; } if (uri.toString().startsWith('configuration://?')) { - await context.read().authorizedFlowStart(uri!); + await context.read().requestTheConfiguration(uri!); return; } From f9b6ab7fb2bf9ce96e4f3fad8d1aee2678534fcb Mon Sep 17 00:00:00 2001 From: Bibash Shrestha Date: Tue, 27 Feb 2024 15:10:38 +0545 Subject: [PATCH 13/45] linter update and class update --- lib/oidc4vc/get_authorization_uri_for_issuer.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/oidc4vc/get_authorization_uri_for_issuer.dart b/lib/oidc4vc/get_authorization_uri_for_issuer.dart index afe8fb4b6..49015f548 100644 --- a/lib/oidc4vc/get_authorization_uri_for_issuer.dart +++ b/lib/oidc4vc/get_authorization_uri_for_issuer.dart @@ -7,7 +7,6 @@ import 'package:did_kit/did_kit.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:oidc4vc/oidc4vc.dart'; import 'package:uuid/uuid.dart'; -import 'package:dart_jsonwebtoken/dart_jsonwebtoken.dart'; Future getAuthorizationUriForIssuer({ required String scannedResponse, From 3e5ecdedfbf9a420e655f98cbd0f103db2a3807f Mon Sep 17 00:00:00 2001 From: Bibash Shrestha Date: Tue, 27 Feb 2024 16:59:42 +0545 Subject: [PATCH 14/45] Show crypto associated credential based on vcformat and didkey type --- .../credential_subject_type_extension.dart | 12 +++++++----- lib/app/shared/enum/type/profile/profile_type.dart | 13 ------------- 2 files changed, 7 insertions(+), 18 deletions(-) diff --git a/lib/app/shared/enum/type/credential_subject_type/credential_subject_type_extension.dart b/lib/app/shared/enum/type/credential_subject_type/credential_subject_type_extension.dart index 1cf7e531d..79b577a16 100644 --- a/lib/app/shared/enum/type/credential_subject_type/credential_subject_type_extension.dart +++ b/lib/app/shared/enum/type/credential_subject_type/credential_subject_type_extension.dart @@ -626,6 +626,13 @@ extension CredentialSubjectTypeExtension on CredentialSubjectType { List get getVCFormatType { switch (this) { + case CredentialSubjectType.ethereumAssociatedWallet: + case CredentialSubjectType.fantomAssociatedWallet: + case CredentialSubjectType.polygonAssociatedWallet: + case CredentialSubjectType.binanceAssociatedWallet: + case CredentialSubjectType.tezosAssociatedWallet: + return VCFormatType.values; + case CredentialSubjectType.over13: case CredentialSubjectType.over15: case CredentialSubjectType.over21: @@ -633,11 +640,6 @@ extension CredentialSubjectTypeExtension on CredentialSubjectType { case CredentialSubjectType.over65: case CredentialSubjectType.gender: case CredentialSubjectType.ageRange: - case CredentialSubjectType.ethereumAssociatedWallet: - case CredentialSubjectType.fantomAssociatedWallet: - case CredentialSubjectType.polygonAssociatedWallet: - case CredentialSubjectType.binanceAssociatedWallet: - case CredentialSubjectType.tezosAssociatedWallet: case CredentialSubjectType.defiCompliance: case CredentialSubjectType.tezotopiaMembership: case CredentialSubjectType.chainbornMembership: diff --git a/lib/app/shared/enum/type/profile/profile_type.dart b/lib/app/shared/enum/type/profile/profile_type.dart index a1e72e90b..cff571896 100644 --- a/lib/app/shared/enum/type/profile/profile_type.dart +++ b/lib/app/shared/enum/type/profile/profile_type.dart @@ -42,17 +42,4 @@ extension ProfileTypeX on ProfileType { return true; } } - - bool get supportAssociatedCredential { - switch (this) { - case ProfileType.custom: - case ProfileType.owfBaselineProfile: - return false; - case ProfileType.defaultOne: - case ProfileType.dutch: - case ProfileType.ebsiV3: - case ProfileType.enterprise: - return true; - } - } } From 85a9b99460d528a224eb17df8104354935aaf0e5 Mon Sep 17 00:00:00 2001 From: Bibash Shrestha Date: Wed, 28 Feb 2024 16:02:25 +0545 Subject: [PATCH 15/45] bug fix for crypto card --- .../credential_subject_type_extension.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/app/shared/enum/type/credential_subject_type/credential_subject_type_extension.dart b/lib/app/shared/enum/type/credential_subject_type/credential_subject_type_extension.dart index 79b577a16..7f2631af7 100644 --- a/lib/app/shared/enum/type/credential_subject_type/credential_subject_type_extension.dart +++ b/lib/app/shared/enum/type/credential_subject_type/credential_subject_type_extension.dart @@ -583,13 +583,13 @@ extension CredentialSubjectTypeExtension on CredentialSubjectType { case CredentialSubjectType.tezVoucher: case CredentialSubjectType.diplomaCard: case CredentialSubjectType.twitterCard: - return true; - case CredentialSubjectType.walletCredential: case CredentialSubjectType.tezosAssociatedWallet: case CredentialSubjectType.ethereumAssociatedWallet: case CredentialSubjectType.fantomAssociatedWallet: case CredentialSubjectType.polygonAssociatedWallet: case CredentialSubjectType.binanceAssociatedWallet: + return true; + case CredentialSubjectType.walletCredential: case CredentialSubjectType.tezosPooAddress: case CredentialSubjectType.ethereumPooAddress: case CredentialSubjectType.fantomPooAddress: From 714c7a03005c2e5d7b981c1e8f06ad4cc4ce0886 Mon Sep 17 00:00:00 2001 From: Bibash Shrestha Date: Wed, 28 Feb 2024 17:52:21 +0545 Subject: [PATCH 16/45] show token endpoint in developer mode --- lib/dashboard/qr_code/qr_code_scan/cubit/qr_code_scan_cubit.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/dashboard/qr_code/qr_code_scan/cubit/qr_code_scan_cubit.dart b/lib/dashboard/qr_code/qr_code_scan/cubit/qr_code_scan_cubit.dart index c44679af8..5720d899f 100644 --- a/lib/dashboard/qr_code/qr_code_scan/cubit/qr_code_scan_cubit.dart +++ b/lib/dashboard/qr_code/qr_code_scan/cubit/qr_code_scan_cubit.dart @@ -1275,7 +1275,6 @@ class QRCodeScanCubit extends Cubit { return; } } - await addCredentialData( scannedResponse: state.uri.toString(), credentialsCubit: credentialsCubit, From df34ef1ed449850ecab0958cbf4fdd677a8154d5 Mon Sep 17 00:00:00 2001 From: Bibash Shrestha Date: Wed, 28 Feb 2024 20:22:19 +0545 Subject: [PATCH 17/45] credential endpoint response added --- lib/dashboard/qr_code/qr_code_scan/cubit/qr_code_scan_cubit.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/dashboard/qr_code/qr_code_scan/cubit/qr_code_scan_cubit.dart b/lib/dashboard/qr_code/qr_code_scan/cubit/qr_code_scan_cubit.dart index 5720d899f..c44679af8 100644 --- a/lib/dashboard/qr_code/qr_code_scan/cubit/qr_code_scan_cubit.dart +++ b/lib/dashboard/qr_code/qr_code_scan/cubit/qr_code_scan_cubit.dart @@ -1275,6 +1275,7 @@ class QRCodeScanCubit extends Cubit { return; } } + await addCredentialData( scannedResponse: state.uri.toString(), credentialsCubit: credentialsCubit, From 3474ad02f663d0af8d77a19c4fc1693c207ae5b3 Mon Sep 17 00:00:00 2001 From: Bibash Shrestha Date: Fri, 1 Mar 2024 11:56:44 +0545 Subject: [PATCH 18/45] Remove category My advantage cards from My Wallet at setup #2452 --- lib/app/shared/enum/credential_category.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/app/shared/enum/credential_category.dart b/lib/app/shared/enum/credential_category.dart index 05b2e467c..af7c4faed 100644 --- a/lib/app/shared/enum/credential_category.dart +++ b/lib/app/shared/enum/credential_category.dart @@ -62,10 +62,10 @@ extension CredentialCategoryX on CredentialCategory { bool get showInHomeIfListEmpty { switch (this) { - case CredentialCategory.advantagesCards: case CredentialCategory.identityCards: return true; case CredentialCategory.professionalCards: + case CredentialCategory.advantagesCards: case CredentialCategory.contactInfoCredentials: case CredentialCategory.blockchainAccountsCards: case CredentialCategory.educationCards: From 8de83461b2a077a19433d98a472c88e68fad6b7c Mon Sep 17 00:00:00 2001 From: Bibash Shrestha Date: Fri, 1 Mar 2024 15:46:37 +0545 Subject: [PATCH 19/45] Add new switch in OIDC4VC settings OIDC4VCI Proof Type #2383 --- .../view/oidc4vc_settings_menu.dart | 1 + .../widget/proof_type_widget.dart | 73 ++++++++++++++++++ .../ssi/oidc4vc_settngs/widget/widget.dart | 1 + .../profile/cubit/profile_cubit.dart | 2 + .../profile/models/profile_setting.dart | 5 ++ lib/l10n/arb/app_en.arb | 4 +- lib/l10n/untranslated.json | 8 +- lib/oidc4vc/get_credential.dart | 3 + packages/oidc4vc/lib/oidc4vc.dart | 1 + packages/oidc4vc/lib/src/oidc4vc.dart | 75 ++++++++++++++++--- packages/oidc4vc/lib/src/proof_type.dart | 27 +++++++ packages/oidc4vc/pubspec.yaml | 2 + 12 files changed, 189 insertions(+), 13 deletions(-) create mode 100644 lib/dashboard/drawer/ssi/oidc4vc_settngs/widget/proof_type_widget.dart create mode 100644 packages/oidc4vc/lib/src/proof_type.dart diff --git a/lib/dashboard/drawer/ssi/oidc4vc_settngs/view/oidc4vc_settings_menu.dart b/lib/dashboard/drawer/ssi/oidc4vc_settngs/view/oidc4vc_settings_menu.dart index 87b667cfb..1eaf0d792 100644 --- a/lib/dashboard/drawer/ssi/oidc4vc_settngs/view/oidc4vc_settings_menu.dart +++ b/lib/dashboard/drawer/ssi/oidc4vc_settngs/view/oidc4vc_settings_menu.dart @@ -49,6 +49,7 @@ class Oidc4vcSettingMenuView extends StatelessWidget { const ClientTypeWidget(), const ClientCredentialsWidget(), const VCFormatWidget(), + const ProofTypeWidget(), const ProofHeaderWidget(), DrawerItem( title: l10n.clientMetadata, diff --git a/lib/dashboard/drawer/ssi/oidc4vc_settngs/widget/proof_type_widget.dart b/lib/dashboard/drawer/ssi/oidc4vc_settngs/widget/proof_type_widget.dart new file mode 100644 index 000000000..fc509e13d --- /dev/null +++ b/lib/dashboard/drawer/ssi/oidc4vc_settngs/widget/proof_type_widget.dart @@ -0,0 +1,73 @@ +import 'package:altme/app/app.dart'; +import 'package:altme/dashboard/dashboard.dart'; +import 'package:altme/l10n/l10n.dart'; +import 'package:altme/theme/theme.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:oidc4vc/oidc4vc.dart'; + +class ProofTypeWidget extends StatelessWidget { + const ProofTypeWidget({super.key}); + + @override + Widget build(BuildContext context) { + final l10n = context.l10n; + return BlocBuilder( + builder: (context, state) { + return OptionContainer( + title: l10n.proofType, + subtitle: l10n.proofTypeSubtitle, + body: ListView.builder( + itemCount: ProofType.values.length, + shrinkWrap: true, + physics: const ScrollPhysics(), + padding: EdgeInsets.zero, + itemBuilder: (context, index) { + final proofType = ProofType.values[index]; + return Column( + children: [ + if (index != 0) + Padding( + padding: const EdgeInsets.symmetric(horizontal: 8), + child: Divider( + height: 0, + color: Theme.of(context).colorScheme.borderColor, + ), + ), + ListTile( + onTap: () { + context.read().updateProfileSetting( + proofType: proofType, + ); + }, + shape: const RoundedRectangleBorder( + side: BorderSide( + color: Color(0xFFDDDDEE), + width: 0.5, + ), + ), + title: Text( + proofType.formattedString, + style: Theme.of(context).textTheme.bodyLarge?.copyWith( + color: Theme.of(context).colorScheme.onPrimary, + ), + ), + trailing: Icon( + state.model.profileSetting.selfSovereignIdentityOptions + .customOidc4vcProfile.proofType == + proofType + ? Icons.radio_button_checked + : Icons.radio_button_unchecked, + size: Sizes.icon2x, + color: Theme.of(context).colorScheme.onPrimary, + ), + ), + ], + ); + }, + ), + ); + }, + ); + } +} diff --git a/lib/dashboard/drawer/ssi/oidc4vc_settngs/widget/widget.dart b/lib/dashboard/drawer/ssi/oidc4vc_settngs/widget/widget.dart index 22a8f1a9d..6775d10b5 100644 --- a/lib/dashboard/drawer/ssi/oidc4vc_settngs/widget/widget.dart +++ b/lib/dashboard/drawer/ssi/oidc4vc_settngs/widget/widget.dart @@ -7,6 +7,7 @@ export 'did_key_type_widget.dart'; export 'draft_type_widget.dart'; export 'option_container.dart'; export 'proof_header_widget.dart'; +export 'proof_type_widget.dart'; export 'scope_parameter.dart'; export 'security_level_widget.dart'; export 'vc_format_widget.dart'; diff --git a/lib/dashboard/profile/cubit/profile_cubit.dart b/lib/dashboard/profile/cubit/profile_cubit.dart index b771a4d84..cd042fde0 100644 --- a/lib/dashboard/profile/cubit/profile_cubit.dart +++ b/lib/dashboard/profile/cubit/profile_cubit.dart @@ -397,6 +397,7 @@ class ProfileCubit extends Cubit { ClientType? clientType, VCFormatType? vcFormatType, ProofHeaderType? proofHeaderType, + ProofType? proofType, }) async { final profileModel = state.model.copyWith( profileSetting: state.model.profileSetting.copyWith( @@ -425,6 +426,7 @@ class ProfileCubit extends Cubit { oidc4vciDraft: oidc4vciDraftType, clientType: clientType, vcFormatType: vcFormatType, + proofType: proofType, ), ), ), diff --git a/lib/dashboard/profile/models/profile_setting.dart b/lib/dashboard/profile/models/profile_setting.dart index c0e6b4b5f..401aeef02 100644 --- a/lib/dashboard/profile/models/profile_setting.dart +++ b/lib/dashboard/profile/models/profile_setting.dart @@ -537,6 +537,7 @@ class CustomOidc4VcProfile extends Equatable { this.clientSecret = 'FGbzMrvUpeFr', this.vcFormatType = VCFormatType.jwtVcJson, this.proofHeader = ProofHeaderType.kid, + this.proofType = ProofType.jwt, }); factory CustomOidc4VcProfile.initial() => CustomOidc4VcProfile( @@ -575,6 +576,7 @@ class CustomOidc4VcProfile extends Equatable { final ClientType clientType; @JsonKey(name: 'vcFormat') final VCFormatType vcFormatType; + final ProofType proofType; Map toJson() => _$CustomOidc4VcProfileToJson(this); @@ -593,6 +595,7 @@ class CustomOidc4VcProfile extends Equatable { SIOPV2DraftType? siopv2Draft, ClientType? clientType, VCFormatType? vcFormatType, + ProofType? proofType, }) => CustomOidc4VcProfile( clientAuthentication: clientAuthentication ?? this.clientAuthentication, @@ -610,6 +613,7 @@ class CustomOidc4VcProfile extends Equatable { clientId: clientId ?? this.clientId, clientSecret: clientSecret ?? this.clientSecret, vcFormatType: vcFormatType ?? this.vcFormatType, + proofType: proofType ?? this.proofType, ); @override @@ -628,6 +632,7 @@ class CustomOidc4VcProfile extends Equatable { siopv2Draft, clientType, vcFormatType, + proofType, ]; } diff --git a/lib/l10n/arb/app_en.arb b/lib/l10n/arb/app_en.arb index fe8614abd..10969d667 100644 --- a/lib/l10n/arb/app_en.arb +++ b/lib/l10n/arb/app_en.arb @@ -1039,5 +1039,7 @@ "blockchainCardsDiscoverTitle": "Get a proof of crypto account ownership", "blockchainCardsDiscoverSubtitle": "Get a proof of crypto account ownership.", "successfullyAddedEnterpriseAccount": "Successfully added enterprise account!", - "successfullyUpdatedEnterpriseAccount": "Successfully updated enterprise account!" + "successfullyUpdatedEnterpriseAccount": "Successfully updated enterprise account!", + "proofType": "OIDC4VCI Proof Type", + "proofTypeSubtitle": "Default: jwt\nSelect one of the proof type." } diff --git a/lib/l10n/untranslated.json b/lib/l10n/untranslated.json index cdf1bef29..b7394d36b 100644 --- a/lib/l10n/untranslated.json +++ b/lib/l10n/untranslated.json @@ -13,7 +13,9 @@ "oWFBaselineProfile", "defaultProfile", "successfullyAddedEnterpriseAccount", - "successfullyUpdatedEnterpriseAccount" + "successfullyUpdatedEnterpriseAccount", + "proofType", + "proofTypeSubtitle" ], "es": [ @@ -30,6 +32,8 @@ "oWFBaselineProfile", "defaultProfile", "successfullyAddedEnterpriseAccount", - "successfullyUpdatedEnterpriseAccount" + "successfullyUpdatedEnterpriseAccount", + "proofType", + "proofTypeSubtitle" ] } diff --git a/lib/oidc4vc/get_credential.dart b/lib/oidc4vc/get_credential.dart index 0bd582f48..e4f9e8886 100644 --- a/lib/oidc4vc/get_credential.dart +++ b/lib/oidc4vc/get_credential.dart @@ -1,3 +1,5 @@ +import 'dart:convert'; + import 'package:altme/app/app.dart'; import 'package:altme/dashboard/dashboard.dart'; @@ -79,6 +81,7 @@ Future< proofHeaderType: customOidc4vcProfile.proofHeader, clientAuthentication: customOidc4vcProfile.clientAuthentication, redirectUri: Parameters.oidc4vcUniversalLink, + proofType: customOidc4vcProfile.proofType, ); return ( diff --git a/packages/oidc4vc/lib/oidc4vc.dart b/packages/oidc4vc/lib/oidc4vc.dart index 1540301b2..c48068b0d 100644 --- a/packages/oidc4vc/lib/oidc4vc.dart +++ b/packages/oidc4vc/lib/oidc4vc.dart @@ -18,6 +18,7 @@ export 'src/oidc4vci_draft_type.dart'; export 'src/oidc4vp_draft_type.dart'; export 'src/pkce_dart.dart'; export 'src/proof_header_type.dart'; +export 'src/proof_type.dart'; export 'src/soipv2_draft_type.dart'; export 'src/token_parameters.dart'; export 'src/vc_format_type.dart'; diff --git a/packages/oidc4vc/lib/src/oidc4vc.dart b/packages/oidc4vc/lib/src/oidc4vc.dart index 880b6d3b1..d776ca40d 100644 --- a/packages/oidc4vc/lib/src/oidc4vc.dart +++ b/packages/oidc4vc/lib/src/oidc4vc.dart @@ -5,6 +5,7 @@ import 'dart:convert'; import 'package:bip32/bip32.dart' as bip32; import 'package:bip39/bip39.dart' as bip393; import 'package:cryptography/cryptography.dart' as cryptography; +import 'package:did_kit/did_kit.dart'; import 'package:dio/dio.dart'; import 'package:elliptic/elliptic.dart' as elliptic; import 'package:flutter/foundation.dart'; @@ -410,6 +411,7 @@ class OIDC4VC { required OIDC4VCIDraftType oidc4vciDraftType, required ClientAuthentication clientAuthentication, required String redirectUri, + required ProofType proofType, String? preAuthorizedCode, String? userPin, String? code, @@ -516,6 +518,11 @@ class OIDC4VC { credentialDefinition: credentialDefinition, clientAuthentication: clientAuthentication, vct: vct, + proofType: proofType, + did: did, + issuer: issuer, + kid: kid, + privateKey: privateKey, ); credentialResponseData.add(credentialResponseDataValue); @@ -534,6 +541,11 @@ class OIDC4VC { clientAuthentication: clientAuthentication, vct: vct, credentialIdentifier: null, + proofType: proofType, + did: did, + issuer: issuer, + kid: kid, + privateKey: privateKey, ); credentialResponseData.add(credentialResponseDataValue); @@ -560,6 +572,11 @@ class OIDC4VC { required String? credentialIdentifier, required Map? credentialDefinition, required String? vct, + required ProofType proofType, + required String did, + required String issuer, + required String kid, + required String privateKey, }) async { final credentialData = await buildCredentialData( cnonce: cnonce, @@ -574,6 +591,11 @@ class OIDC4VC { credentialDefinition: credentialDefinition, clientAuthentication: clientAuthentication, vct: vct, + proofType: proofType, + did: did, + issuer: issuer, + kid: kid, + privateKey: privateKey, ); /// sign proof @@ -834,20 +856,53 @@ class OIDC4VC { required String? cnonce, required String? vct, required Map? credentialDefinition, + required ProofType proofType, + required String did, + required String issuer, + required String kid, + required String privateKey, }) async { final credentialData = {}; if (cryptoHolderBinding) { - final vcJwt = await getIssuerJwt( - tokenParameters: issuerTokenParameters, - clientAuthentication: clientAuthentication, - oidc4vciDraftType: oidc4vciDraftType, - cnonce: cnonce, - ); - credentialData['proof'] = { - 'proof_type': 'jwt', - 'jwt': vcJwt, - }; + switch (proofType) { + case ProofType.ldpVp: + final options = { + 'verificationMethod': kid, + 'proofPurpose': 'authentication', + 'domain': issuer, + }; + + if (cnonce != null) { + options['challenge'] = cnonce; + } + + final didKitProvider = DIDKitProvider(); + + final didAuth = await didKitProvider.didAuth( + did, + jsonEncode(options), + privateKey, + ); + + credentialData['proof'] = { + 'proof_type': 'ldp_vp', + 'ldp_vp': jsonDecode(didAuth), + }; + + case ProofType.jwt: + final vcJwt = await getIssuerJwt( + tokenParameters: issuerTokenParameters, + clientAuthentication: clientAuthentication, + oidc4vciDraftType: oidc4vciDraftType, + cnonce: cnonce, + ); + + credentialData['proof'] = { + 'proof_type': 'jwt', + 'jwt': vcJwt, + }; + } } switch (oidc4vciDraftType) { diff --git a/packages/oidc4vc/lib/src/proof_type.dart b/packages/oidc4vc/lib/src/proof_type.dart new file mode 100644 index 000000000..ec7835325 --- /dev/null +++ b/packages/oidc4vc/lib/src/proof_type.dart @@ -0,0 +1,27 @@ +import 'package:json_annotation/json_annotation.dart'; + +enum ProofType { + @JsonValue('ldp_vp') + ldpVp, + jwt, +} + +extension ProofTypeeX on ProofType { + String get formattedString { + switch (this) { + case ProofType.ldpVp: + return 'ldp_vc'; + case ProofType.jwt: + return 'jwt'; + } + } + + String get value { + switch (this) { + case ProofType.ldpVp: + return 'ldp_vc'; + case ProofType.jwt: + return 'jwt'; + } + } +} diff --git a/packages/oidc4vc/pubspec.yaml b/packages/oidc4vc/pubspec.yaml index 882e02704..cfdafa866 100644 --- a/packages/oidc4vc/pubspec.yaml +++ b/packages/oidc4vc/pubspec.yaml @@ -11,6 +11,8 @@ dependencies: bip39: ^1.0.6 credential_manifest: path: ../credential_manifest + did_kit: + path: ../did_kit crypto: ^3.0.3 cryptography: ^2.5.0 dart_bip32_bip44: ^0.2.0 From e07485048c5db511388af6bb55d20f42e2928830 Mon Sep 17 00:00:00 2001 From: Bibash Shrestha Date: Fri, 1 Mar 2024 15:56:48 +0545 Subject: [PATCH 20/45] Update DEFAULT profile settings #2450 --- lib/dashboard/profile/models/profile.dart | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/dashboard/profile/models/profile.dart b/lib/dashboard/profile/models/profile.dart index 44f292681..448f62c3b 100644 --- a/lib/dashboard/profile/models/profile.dart +++ b/lib/dashboard/profile/models/profile.dart @@ -68,6 +68,7 @@ class ProfileModel extends Equatable { clientId: clientId, clientSecret: clientSecret, vcFormatType: VCFormatType.jwtVc, + proofType: ProofType.jwt, ), ), settingsMenu: SettingsMenu.initial(), @@ -114,6 +115,7 @@ class ProfileModel extends Equatable { clientId: clientId, clientSecret: clientSecret, vcFormatType: VCFormatType.ldpVc, + proofType: ProofType.ldpVp, ), ), settingsMenu: SettingsMenu.initial(), @@ -182,6 +184,7 @@ class ProfileModel extends Equatable { clientId: clientId, clientSecret: clientSecret, vcFormatType: VCFormatType.jwtVcJson, + proofType: ProofType.jwt, ), ), settingsMenu: SettingsMenu.initial(), @@ -250,6 +253,7 @@ class ProfileModel extends Equatable { clientId: clientId, clientSecret: clientSecret, vcFormatType: VCFormatType.vcSdJWT, + proofType: ProofType.jwt, ), ), settingsMenu: SettingsMenu.initial(), From 9921ed490d3e9c4cf07db3aac87e1d66a9ea52eb Mon Sep 17 00:00:00 2001 From: Bibash Shrestha Date: Fri, 1 Mar 2024 17:45:20 +0545 Subject: [PATCH 21/45] Error message when scan or deeplik for configuration #2454 --- .../message/response_string/response_string.dart | 2 +- .../response_string_extension.dart | 3 +++ .../shared/message_handler/global_message.dart | 2 ++ .../shared/message_handler/response_message.dart | 6 ++++++ lib/enterprise/cubit/enterprise_cubit.dart | 15 +++++++++++---- lib/l10n/arb/app_en.arb | 3 ++- lib/l10n/untranslated.json | 12 ++++++++++-- 7 files changed, 35 insertions(+), 8 deletions(-) diff --git a/lib/app/shared/enum/message/response_string/response_string.dart b/lib/app/shared/enum/message/response_string/response_string.dart index f150ac1d9..f95b6d29b 100644 --- a/lib/app/shared/enum/message/response_string/response_string.dart +++ b/lib/app/shared/enum/message/response_string/response_string.dart @@ -156,6 +156,6 @@ enum ResponseString { RESPONSE_STRING_theServiceIsNotAvailable, RESPONSE_STRING_theIssuanceOfThisCredentialIsPending, RESPONSE_STRING_successfullyAddedEnterpriseAccount, - RESPONSE_STRING_successfullyUpdatedEnterpriseAccount, + RESPONSE_STRING_thisWalleIsAlreadyConfigured, } diff --git a/lib/app/shared/enum/message/response_string/response_string_extension.dart b/lib/app/shared/enum/message/response_string/response_string_extension.dart index 90b6d7e26..27d360deb 100644 --- a/lib/app/shared/enum/message/response_string/response_string_extension.dart +++ b/lib/app/shared/enum/message/response_string/response_string_extension.dart @@ -497,6 +497,9 @@ extension ResponseStringX on ResponseString { case ResponseString.RESPONSE_STRING_successfullyUpdatedEnterpriseAccount: return globalMessage .RESPONSE_STRING_successfullyUpdatedEnterpriseAccount; + + case ResponseString.RESPONSE_STRING_thisWalleIsAlreadyConfigured: + return globalMessage.RESPONSE_STRING_thisWalleIsAlreadyConfigured; } } } diff --git a/lib/app/shared/message_handler/global_message.dart b/lib/app/shared/message_handler/global_message.dart index b6bc96a76..76e90d6ec 100644 --- a/lib/app/shared/message_handler/global_message.dart +++ b/lib/app/shared/message_handler/global_message.dart @@ -388,4 +388,6 @@ class GlobalMessage { l10n.successfullyAddedEnterpriseAccount; String get RESPONSE_STRING_successfullyUpdatedEnterpriseAccount => l10n.successfullyUpdatedEnterpriseAccount; + String get RESPONSE_STRING_thisWalleIsAlreadyConfigured => + l10n.thisWalleIsAlreadyConfigured; } diff --git a/lib/app/shared/message_handler/response_message.dart b/lib/app/shared/message_handler/response_message.dart index cae348f84..14a615719 100644 --- a/lib/app/shared/message_handler/response_message.dart +++ b/lib/app/shared/message_handler/response_message.dart @@ -765,6 +765,12 @@ class ResponseMessage with MessageHandler { .RESPONSE_STRING_successfullyUpdatedEnterpriseAccount.localise( context, ); + + case ResponseString.RESPONSE_STRING_thisWalleIsAlreadyConfigured: + return ResponseString.RESPONSE_STRING_thisWalleIsAlreadyConfigured + .localise( + context, + ); } } return ''; diff --git a/lib/enterprise/cubit/enterprise_cubit.dart b/lib/enterprise/cubit/enterprise_cubit.dart index 8b9a8a4d6..197060256 100644 --- a/lib/enterprise/cubit/enterprise_cubit.dart +++ b/lib/enterprise/cubit/enterprise_cubit.dart @@ -50,10 +50,17 @@ class EnterpriseCubit extends Cubit { SecureStorageKeys.enterpriseEmail, ); - if (savedEmail != null && email == savedEmail) { - /// if email is matched then update the configuration - await updateTheConfiguration(); - return; + if (savedEmail != null) { + if (email == savedEmail) { + /// if email is matched then update the configuration + await updateTheConfiguration(); + return; + } else { + throw ResponseMessage( + message: + ResponseString.RESPONSE_STRING_thisWalleIsAlreadyConfigured, + ); + } } /// get vc and store it in the wallet diff --git a/lib/l10n/arb/app_en.arb b/lib/l10n/arb/app_en.arb index 10969d667..c8225e096 100644 --- a/lib/l10n/arb/app_en.arb +++ b/lib/l10n/arb/app_en.arb @@ -1041,5 +1041,6 @@ "successfullyAddedEnterpriseAccount": "Successfully added enterprise account!", "successfullyUpdatedEnterpriseAccount": "Successfully updated enterprise account!", "proofType": "OIDC4VCI Proof Type", - "proofTypeSubtitle": "Default: jwt\nSelect one of the proof type." + "proofTypeSubtitle": "Default: jwt\nSelect one of the proof type.", + "thisWalleIsAlreadyConfigured": "This wallet is already configured" } diff --git a/lib/l10n/untranslated.json b/lib/l10n/untranslated.json index b7394d36b..dc66734d6 100644 --- a/lib/l10n/untranslated.json +++ b/lib/l10n/untranslated.json @@ -15,7 +15,8 @@ "successfullyAddedEnterpriseAccount", "successfullyUpdatedEnterpriseAccount", "proofType", - "proofTypeSubtitle" + "proofTypeSubtitle", + "thisWalleIsAlreadyConfigured" ], "es": [ @@ -34,6 +35,13 @@ "successfullyAddedEnterpriseAccount", "successfullyUpdatedEnterpriseAccount", "proofType", - "proofTypeSubtitle" + "proofTypeSubtitle", + "thisWalleIsAlreadyConfigured" + ], + + "fr": [ + "proofType", + "proofTypeSubtitle", + "thisWalleIsAlreadyConfigured" ] } From 9512ae469caf6ade927e0870cdbc2667acd1557f Mon Sep 17 00:00:00 2001 From: hawkbee1 Date: Sat, 2 Mar 2024 08:23:24 +0000 Subject: [PATCH 22/45] Settings icon instead of drawer --- lib/dashboard/src/widgets/home_title_leading.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/dashboard/src/widgets/home_title_leading.dart b/lib/dashboard/src/widgets/home_title_leading.dart index bf441a218..d0a81c7b8 100644 --- a/lib/dashboard/src/widgets/home_title_leading.dart +++ b/lib/dashboard/src/widgets/home_title_leading.dart @@ -14,7 +14,7 @@ class HomeTitleLeading extends StatelessWidget { Widget build(BuildContext context) { return IconButton( icon: ImageIcon( - const AssetImage(IconStrings.icMenu), + const AssetImage(IconStrings.settings), color: Theme.of(context).colorScheme.leadingButton, ), onPressed: onPressed, From 833e47e13cf18aaa2b2367b4e45e97657a76404d Mon Sep 17 00:00:00 2001 From: hawkbee1 Date: Sat, 2 Mar 2024 17:29:35 +0000 Subject: [PATCH 23/45] Add language menu --- .../shared/constants/secure_storage_keys.dart | 1 + lib/app/shared/enum/type/language_type.dart | 29 +++++ lib/app/view/app.dart | 16 +-- .../drawer/src/view/drawer_page.dart | 10 ++ .../view/wallet_settings_menu.dart | 38 +++++++ .../widget/language_selector_widget.dart | 100 ++++++++++++++++++ .../detail/widgets/claims_data.dart | 2 +- .../widgets/credential_subject_data.dart | 2 +- lib/l10n/arb/app_ca.arb | 18 +++- lib/l10n/arb/app_en.arb | 13 ++- lib/l10n/arb/app_es.arb | 18 +++- lib/l10n/arb/app_fr.arb | 14 ++- lib/l10n/untranslated.json | 52 +++------ lib/lang/cubit/lang_cubit.dart | 74 +++++++++++-- lib/lang/cubit/lang_state.dart | 21 ++++ pubspec.lock | 96 ++++++++++------- 16 files changed, 406 insertions(+), 98 deletions(-) create mode 100644 lib/app/shared/enum/type/language_type.dart create mode 100644 lib/dashboard/drawer/wallet_settings/view/wallet_settings_menu.dart create mode 100644 lib/dashboard/drawer/wallet_settings/widget/language_selector_widget.dart create mode 100644 lib/lang/cubit/lang_state.dart diff --git a/lib/app/shared/constants/secure_storage_keys.dart b/lib/app/shared/constants/secure_storage_keys.dart index a5065719a..dfcc2d1a8 100644 --- a/lib/app/shared/constants/secure_storage_keys.dart +++ b/lib/app/shared/constants/secure_storage_keys.dart @@ -71,4 +71,5 @@ class SecureStorageKeys { static const String enterpriseEmail = 'enterpriseEmail'; static const String enterprisePassword = 'enterprisePassword'; static const String enterpriseWalletProvider = 'enterpriseWalletProvider'; + static const String language = 'language'; } diff --git a/lib/app/shared/enum/type/language_type.dart b/lib/app/shared/enum/type/language_type.dart new file mode 100644 index 000000000..8174e3ce7 --- /dev/null +++ b/lib/app/shared/enum/type/language_type.dart @@ -0,0 +1,29 @@ +import 'package:altme/l10n/l10n.dart'; + +enum LanguageType { + phone, + ca, + en, + es, + fr, +} + +extension LanguageTypeX on LanguageType { + String getTitle({ + required AppLocalizations l10n, + required String name, + }) { + switch (this) { + case LanguageType.phone: + return l10n.phoneLanguage; + case LanguageType.ca: + return l10n.catalan; + case LanguageType.en: + return l10n.english; + case LanguageType.es: + return l10n.spanish; + case LanguageType.fr: + return l10n.french; + } + } +} diff --git a/lib/app/view/app.dart b/lib/app/view/app.dart index 2d741f9c2..3bcc22f42 100644 --- a/lib/app/view/app.dart +++ b/lib/app/view/app.dart @@ -16,6 +16,7 @@ import 'package:altme/flavor/cubit/flavor_cubit.dart'; import 'package:altme/kyc_verification/cubit/kyc_verification_cubit.dart'; import 'package:altme/l10n/l10n.dart'; import 'package:altme/lang/cubit/lang_cubit.dart'; +import 'package:altme/lang/cubit/lang_state.dart'; import 'package:altme/onboarding/cubit/onboarding_cubit.dart'; import 'package:altme/polygon_id/cubit/polygon_id_cubit.dart'; import 'package:altme/query_by_example/query_by_example.dart'; @@ -252,21 +253,24 @@ class MaterialAppDefinition extends StatelessWidget { final bool isStaging = context.read().flavorMode == FlavorMode.staging; return BlocProvider( - create: (context) => LangCubit(), - child: BlocBuilder( - builder: (context, lang) { + create: (context) => LangCubit( + secureStorageProvider: getSecureStorage, + ), + child: BlocBuilder( + builder: (context, state) { if (isStaging) { final locale = DevicePreview.locale(context); if (locale != null) { context.read().setLocale(locale); } - } else { - context.read().fetchLocale(); + } + if (state == const Locale('en')) { + context.read().checkLocale(); } return MaterialApp( builder: isStaging ? DevicePreview.appBuilder : null, - locale: lang, + locale: state.locale, title: 'AltMe', darkTheme: AppTheme.darkThemeData, navigatorObservers: [MyRouteObserver(context)], diff --git a/lib/dashboard/drawer/src/view/drawer_page.dart b/lib/dashboard/drawer/src/view/drawer_page.dart index cf3489ed9..eab2a5854 100644 --- a/lib/dashboard/drawer/src/view/drawer_page.dart +++ b/lib/dashboard/drawer/src/view/drawer_page.dart @@ -1,6 +1,7 @@ import 'package:altme/app/app.dart'; import 'package:altme/dashboard/dashboard.dart'; import 'package:altme/dashboard/drawer/profile/view/pick_profile_menu.dart'; +import 'package:altme/dashboard/drawer/wallet_settings/view/wallet_settings_menu.dart'; import 'package:altme/enterprise/cubit/enterprise_cubit.dart'; import 'package:altme/l10n/l10n.dart'; import 'package:altme/theme/theme.dart'; @@ -87,6 +88,15 @@ class DrawerView extends StatelessWidget { .push(WalletSecurityMenu.route()); }, ), + const SizedBox(height: Sizes.spaceSmall), + DrawerCategoryItem( + title: l10n.walletSettings, + subTitle: l10n.walletSettingsDescription, + onClick: () { + Navigator.of(context) + .push(WalletSettingsMenu.route()); + }, + ), if (Parameters.walletHandlesCrypto) Column( children: [ diff --git a/lib/dashboard/drawer/wallet_settings/view/wallet_settings_menu.dart b/lib/dashboard/drawer/wallet_settings/view/wallet_settings_menu.dart new file mode 100644 index 000000000..97d2ae4e7 --- /dev/null +++ b/lib/dashboard/drawer/wallet_settings/view/wallet_settings_menu.dart @@ -0,0 +1,38 @@ +import 'package:altme/app/app.dart'; +import 'package:altme/dashboard/drawer/wallet_settings/widget/language_selector_widget.dart'; +import 'package:altme/l10n/l10n.dart'; +import 'package:flutter/material.dart'; + +class WalletSettingsMenu extends StatelessWidget { + const WalletSettingsMenu({super.key}); + + static Route route() { + return MaterialPageRoute( + settings: const RouteSettings(name: '/WalletSettingsMenu'), + builder: (_) => const WalletSettingsMenu(), + ); + } + + @override + Widget build(BuildContext context) { + return const WalletSettingsMenuView(); + } +} + +class WalletSettingsMenuView extends StatelessWidget { + const WalletSettingsMenuView({super.key}); + + @override + Widget build(BuildContext context) { + final l10n = context.l10n; + return BasePage( + title: l10n.languageSelectorTitle, + useSafeArea: true, + scrollView: true, + titleAlignment: Alignment.topCenter, + padding: const EdgeInsets.symmetric(horizontal: Sizes.spaceSmall), + titleLeading: const BackLeadingButton(), + body: const LanguageSelectorWidget(), + ); + } +} diff --git a/lib/dashboard/drawer/wallet_settings/widget/language_selector_widget.dart b/lib/dashboard/drawer/wallet_settings/widget/language_selector_widget.dart new file mode 100644 index 000000000..e8a11a340 --- /dev/null +++ b/lib/dashboard/drawer/wallet_settings/widget/language_selector_widget.dart @@ -0,0 +1,100 @@ +import 'package:altme/app/app.dart'; +import 'package:altme/app/shared/enum/type/language_type.dart'; +import 'package:altme/l10n/l10n.dart'; +import 'package:altme/lang/cubit/lang_cubit.dart'; +import 'package:altme/lang/cubit/lang_state.dart'; +import 'package:altme/theme/theme.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +class LanguageSelectorWidget extends StatelessWidget { + const LanguageSelectorWidget({super.key}); + + @override + Widget build(BuildContext context) { + final l10n = context.l10n; + return BlocBuilder( + builder: (context, state) { + return Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + mainAxisSize: MainAxisSize.max, + children: [ + Container( + padding: const EdgeInsets.all(Sizes.spaceSmall), + margin: const EdgeInsets.all(Sizes.spaceXSmall), + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.drawerSurface, + borderRadius: const BorderRadius.all( + Radius.circular(Sizes.largeRadius), + ), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 10), + ListView.builder( + itemCount: LanguageType.values.length, + shrinkWrap: true, + physics: const ScrollPhysics(), + padding: EdgeInsets.zero, + itemBuilder: (context, index) { + final languageType = LanguageType.values[index]; + + return Column( + children: [ + if (index != 0) + Padding( + padding: + const EdgeInsets.symmetric(horizontal: 8), + child: Divider( + height: 0, + color: + Theme.of(context).colorScheme.borderColor, + ), + ), + ListTile( + onTap: () async { + await context + .read() + .setLocale(Locale(languageType.name)); + }, + shape: const RoundedRectangleBorder( + side: BorderSide( + color: Color(0xFFDDDDEE), + width: 0.5, + ), + ), + title: Text( + languageType.getTitle( + l10n: l10n, + name: languageType.name, + ), + style: Theme.of(context) + .textTheme + .bodyLarge + ?.copyWith( + color: + Theme.of(context).colorScheme.onPrimary, + ), + ), + trailing: Icon( + state.languageType == languageType + ? Icons.radio_button_checked + : Icons.radio_button_unchecked, + size: Sizes.icon2x, + color: Theme.of(context).colorScheme.onPrimary, + ), + ), + ], + ); + }, + ), + ], + ), + ), + ], + ); + }, + ); + } +} diff --git a/lib/dashboard/home/tab_bar/credentials/detail/widgets/claims_data.dart b/lib/dashboard/home/tab_bar/credentials/detail/widgets/claims_data.dart index 7c613ed43..7e207a8a4 100644 --- a/lib/dashboard/home/tab_bar/credentials/detail/widgets/claims_data.dart +++ b/lib/dashboard/home/tab_bar/credentials/detail/widgets/claims_data.dart @@ -56,7 +56,7 @@ class ClaimsData extends StatelessWidget { } } - final languageCode = context.read().state.languageCode; + final languageCode = context.read().state.locale.languageCode; return Column( crossAxisAlignment: CrossAxisAlignment.start, diff --git a/lib/dashboard/home/tab_bar/credentials/detail/widgets/credential_subject_data.dart b/lib/dashboard/home/tab_bar/credentials/detail/widgets/credential_subject_data.dart index 5a68eb652..815968202 100644 --- a/lib/dashboard/home/tab_bar/credentials/detail/widgets/credential_subject_data.dart +++ b/lib/dashboard/home/tab_bar/credentials/detail/widgets/credential_subject_data.dart @@ -31,7 +31,7 @@ class CredentialSubjectData extends StatelessWidget { if (credentialSubjectData == null) return Container(); if (credentialSubjectData is! Map) return Container(); - final languageCode = context.read().state.languageCode; + final languageCode = context.read().state.locale.languageCode; return Column( crossAxisAlignment: CrossAxisAlignment.start, diff --git a/lib/l10n/arb/app_ca.arb b/lib/l10n/arb/app_ca.arb index a08e3b4dd..005754142 100644 --- a/lib/l10n/arb/app_ca.arb +++ b/lib/l10n/arb/app_ca.arb @@ -1027,5 +1027,21 @@ "congrats": "Felicitats!", "yourWalletConfigurationHasBeenSuccessfullyUpdated": "La configuració de la cartera s’ha actualitzat correctament", "continueString": "Continuar", - "walletProvider": "Proveïdor de cartera" + "walletProvider": "Proveïdor de cartera", + "clientTypeTitle" : "Tipus de Client OIDC4VCI", +"clientTypeSubtitle" : "Predeterminat: DID\nDesplaci per canviar el tipus de client", +"proofHeader" : "Capçalera de prova de possessió", +"proofHeaderSubtitle" : "Predeterminat: kid\nCanviar si es necessita JWK a la capçalera", +"theLdpFormatIsNotSupportedByThisDIDMethod": "El format LDP no és compatible amb aquest mètode DID", +"switchOffCryptoHolderBindingForThatDIDMethod": "Desactivar la vinculació del titular (o posseïdor) de criptoactius per a aquest mètode DID", +"thisTypeProofCannotBeUsedWithThisVCFormat": "Aquest tipus de prova no es pot fer servir amb aquest format de CV", +"enterprise" : "Organització/Empresa", +"oWFBaselineProfile": "Perfil de Línia Base d'OWF", +"defaultProfile" : "Predeterminat", +"blockchainCardsDiscoverTitle": "Obtenir prova de propietat de compte cripto", +"blockchainCardsDiscoverSubtitle" : "Obtenir prova de propietat de compte de criptoactius", +"successfullyAddedEnterpriseAccount": "Compte d'Organització/Empresa afegida amb èxit!", +"successfullyUpdatedEnterpriseAccount" : "Compte d'Organització/Empresa actualitzada amb èxit!", +"languageSelectorTitle": "catalan" + } \ No newline at end of file diff --git a/lib/l10n/arb/app_en.arb b/lib/l10n/arb/app_en.arb index c8225e096..debd5aaac 100644 --- a/lib/l10n/arb/app_en.arb +++ b/lib/l10n/arb/app_en.arb @@ -840,8 +840,6 @@ "financeCredentialsHomeTitle": "My financial credentials", "financeCredentialsDiscoverTitle": "Get verified financial credentials", "financeCredentialsDiscoverSubtitle": "Access new investment opportunities in web3.", - "blockchainCardsDiscoverTitle": "Get a proof of crypto account ownership", - "blockchainCardsDiscoverSubtitle": "Get a proof of crypto account ownership.", "financeCredentialsHomeSubtitle": "Access new investment opportunities in web3", "hummanityProofCredentialsHomeTitle": "My proof of humanity", "hummanityProofCredentialsHomeSubtitle": "Easily prove you are a human and not a bot.", @@ -1042,5 +1040,14 @@ "successfullyUpdatedEnterpriseAccount": "Successfully updated enterprise account!", "proofType": "OIDC4VCI Proof Type", "proofTypeSubtitle": "Default: jwt\nSelect one of the proof type.", - "thisWalleIsAlreadyConfigured": "This wallet is already configured" + "thisWalleIsAlreadyConfigured": "This wallet is already configured", + "walletSettings": "Wallet Settings", + "walletSettingsDescription": "Choose your language", + "languageSelectorTitle": "Language", + "french": "Français", + "spanish": "Español", + "catalan": "Català", + "english": "English", + "phoneLanguage": "Phone language" + } diff --git a/lib/l10n/arb/app_es.arb b/lib/l10n/arb/app_es.arb index 1e874f867..6d53556be 100644 --- a/lib/l10n/arb/app_es.arb +++ b/lib/l10n/arb/app_es.arb @@ -1027,5 +1027,21 @@ "congrats": "¡Enhorabuena!", "yourWalletConfigurationHasBeenSuccessfullyUpdated": "Configuración de cartera actualizada", "continueString": "Continuar", - "walletProvider": "Proveedor de cartera" + "walletProvider": "Proveedor de cartera", + "clientTypeTitle": "Tipo de Cliente OIDC4VCI", + "clientTypeSubtitle" : "Predeterminado: DID\nDesplace para cambiar el tipo de cliente", + "proofHeader" : "Encabezado de Prueba de Posesión", + "proofHeaderSubtitle" : "Predeterminado: kid\nCambiar si necesita JWK en el encabezado.", + "theLdpFormatIsNotSupportedByThisDIDMethod": "El formato LDP no es compatible con este método DID.", + "switchOffCryptoHolderBindingForThatDIDMethod": "Desactivar la vinculación del titular (o poseedor) de criptoactivos para ese método DID", + "thisTypeProofCannotBeUsedWithThisVCFormat": "Este tipo de prueba no se puede utilizar con este formato de CV.", + "enterprise" : "Organización/Empresa", + "oWFBaselineProfile": "Perfil de Línea Base de OWF", + "defaultProfile" : "Predeterminado", + "blockchainCardsDiscoverTitle": "Obtener prueba de propiedad de cuenta cripto", + "blockchainCardsDiscoverSubtitle" : "Obtener prueba de propiedad de cuenta de criptoactivos", + "successfullyAddedEnterpriseAccount":"¡Cuenta de Organización/Empresa añadida con éxito!", + "successfullyUpdatedEnterpriseAccount": "¡Cuenta de Organiza ción/Empresa actualizada con éxito!", + "languageSelectorTitle": "espagnol" + } \ No newline at end of file diff --git a/lib/l10n/arb/app_fr.arb b/lib/l10n/arb/app_fr.arb index af9274421..d3891aaad 100644 --- a/lib/l10n/arb/app_fr.arb +++ b/lib/l10n/arb/app_fr.arb @@ -1039,6 +1039,16 @@ "blockchainCardsDiscoverTitle": "Prouvez que vous possédez un compte crypto.", "blockchainCardsDiscoverSubtitle": "Prouvez que vous possédez un compte crypto.", "successfullyAddedEnterpriseAccount": "Compte entreprise ajouté avec succès !", - "successfullyUpdatedEnterpriseAccount": "Compte entreprise mis à jour avec succès !" - + "successfullyUpdatedEnterpriseAccount": "Compte entreprise mis à jour avec succès !", + "proofType": "Type de preuve OIDC4VCI", + "proofTypeSubtitle": "Par défault: jwt\nSéléctionnez un type de preuve.", + "thisWalleIsAlreadyConfigured": "Ce wallet est déjà configuré", + "walletSettings": "Paramètres du wallet", + "walletSettingsDescription": "Choisissez votre langue", + "languageSelectorTitle": "Langue", + "french": "Français", + "spanish": "Español", + "catalan": "Català", + "english": "English", + "phoneLanguage": "Langue du téléphone" } diff --git a/lib/l10n/untranslated.json b/lib/l10n/untranslated.json index dc66734d6..cc5db51dc 100644 --- a/lib/l10n/untranslated.json +++ b/lib/l10n/untranslated.json @@ -1,47 +1,27 @@ { "ca": [ - "blockchainCardsDiscoverTitle", - "blockchainCardsDiscoverSubtitle", - "clientTypeTitle", - "clientTypeSubtitle", - "proofHeader", - "proofHeaderSubtitle", - "theLdpFormatIsNotSupportedByThisDIDMethod", - "switchOffCryptoHolderBindingForThatDIDMethod", - "thisTypeProofCannotBeUsedWithThisVCFormat", - "enterprise", - "oWFBaselineProfile", - "defaultProfile", - "successfullyAddedEnterpriseAccount", - "successfullyUpdatedEnterpriseAccount", "proofType", "proofTypeSubtitle", - "thisWalleIsAlreadyConfigured" + "thisWalleIsAlreadyConfigured", + "walletSettings", + "walletSettingsDescription", + "french", + "spanish", + "catalan", + "english", + "phoneLanguage" ], "es": [ - "blockchainCardsDiscoverTitle", - "blockchainCardsDiscoverSubtitle", - "clientTypeTitle", - "clientTypeSubtitle", - "proofHeader", - "proofHeaderSubtitle", - "theLdpFormatIsNotSupportedByThisDIDMethod", - "switchOffCryptoHolderBindingForThatDIDMethod", - "thisTypeProofCannotBeUsedWithThisVCFormat", - "enterprise", - "oWFBaselineProfile", - "defaultProfile", - "successfullyAddedEnterpriseAccount", - "successfullyUpdatedEnterpriseAccount", "proofType", "proofTypeSubtitle", - "thisWalleIsAlreadyConfigured" - ], - - "fr": [ - "proofType", - "proofTypeSubtitle", - "thisWalleIsAlreadyConfigured" + "thisWalleIsAlreadyConfigured", + "walletSettings", + "walletSettingsDescription", + "french", + "spanish", + "catalan", + "english", + "phoneLanguage" ] } diff --git a/lib/lang/cubit/lang_cubit.dart b/lib/lang/cubit/lang_cubit.dart index 2b509497b..708fa342f 100644 --- a/lib/lang/cubit/lang_cubit.dart +++ b/lib/lang/cubit/lang_cubit.dart @@ -1,26 +1,78 @@ import 'dart:async'; +import 'package:altme/app/shared/enum/type/language_type.dart'; +import 'package:altme/app/shared/shared.dart'; import 'package:altme/l10n/l10n.dart'; +import 'package:altme/lang/cubit/lang_state.dart'; import 'package:bloc/bloc.dart'; import 'package:devicelocale/devicelocale.dart'; import 'package:flutter/material.dart'; +import 'package:secure_storage/secure_storage.dart'; -class LangCubit extends Cubit { - LangCubit() : super(const Locale('en', 'US')); +class LangCubit extends Cubit { + LangCubit({required this.secureStorageProvider}) + : super( + const LangState( + locale: Locale('en'), + languageType: LanguageType.phone, + ), + ); + final SecureStorageProvider secureStorageProvider; - Future fetchLocale() async { - final Locale? locale = await Devicelocale.currentAsLocale; - - final langauageCode = locale!.languageCode; + /// emit new state if language recorded is dufferent than english + Future checkLocale() async { + final languageType = await getRecordedLanguage(); + emit(state.copyWith(languageType: languageType)); + } - if (AppLocalizations.supportedLocales.contains(Locale(langauageCode))) { - setLocale(locale); + Future getRecordedLanguage() async { + LanguageType languageType = LanguageType.phone; + final languageTypeString = + await secureStorageProvider.get(SecureStorageKeys.language); + if (languageTypeString != null) { + languageType = getLanguageType(languageTypeString, languageType); } else { - setLocale(const Locale('en', 'US')); + await recordLanguage(LanguageType.phone.name); + languageType = LanguageType.phone; + } + return languageType; + } + + LanguageType getLanguageType( + String languageTypeString, + LanguageType languageType, + ) { + final enumVal = LanguageType.values.firstWhereOrNull( + (ele) => ele.name == languageTypeString, + ); + if (enumVal != null) { + return enumVal; } + return languageType; } - void setLocale(Locale locale) { - emit(locale); + Future recordLanguage(String language) async { + await secureStorageProvider.set( + SecureStorageKeys.language, + language, + ); + } + + Future setLocale(Locale locale) async { + Locale newLocale = const Locale('en'); + LanguageType newlanguageType = LanguageType.phone; + if (locale == Locale(LanguageType.phone.name)) { + await recordLanguage(LanguageType.phone.name); + + newLocale = await Devicelocale.currentAsLocale ?? const Locale('en'); + } else { + await recordLanguage(locale.languageCode); + newLocale = locale; + newlanguageType = getLanguageType(locale.languageCode, newlanguageType) + } + if (AppLocalizations.supportedLocales + .contains(Locale(newLocale.languageCode))) { + emit(LangState(languageType: newlanguageType, locale: newLocale)); + } } } diff --git a/lib/lang/cubit/lang_state.dart b/lib/lang/cubit/lang_state.dart new file mode 100644 index 000000000..c81eaccbe --- /dev/null +++ b/lib/lang/cubit/lang_state.dart @@ -0,0 +1,21 @@ +import 'dart:ui'; + +import 'package:altme/app/shared/enum/type/language_type.dart'; +import 'package:equatable/equatable.dart'; + +class LangState extends Equatable { + const LangState({required this.locale, required this.languageType}); + + final Locale locale; + final LanguageType languageType; + + @override + // TODO: implement props + List get props => throw UnimplementedError(); + + LangState copyWith({Locale? locale, LanguageType? languageType}) { + return LangState( + languageType: languageType ?? this.languageType, + locale: locale ?? this.locale); + } +} diff --git a/pubspec.lock b/pubspec.lock index 8159322d1..4508659c0 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,10 +5,10 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: eb376e9acf6938204f90eb3b1f00b578640d3188b4c8a8ec054f9f479af8d051 + sha256: "0b2f2bd91ba804e53a61d757b986f89f1f9eaed5b11e4b2f5a2468d86d6c9fc7" url: "https://pub.dev" source: hosted - version: "64.0.0" + version: "67.0.0" adaptive_number: dependency: transitive description: @@ -21,10 +21,10 @@ packages: dependency: transitive description: name: analyzer - sha256: "69f54f967773f6c26c7dcb13e93d7ccee8b17a641689da39e878d5cf13b06893" + sha256: "37577842a27e4338429a1cbc32679d508836510b056f1eedf0c8d20e39c1383d" url: "https://pub.dev" source: hosted - version: "6.2.0" + version: "6.4.1" android_intent_plus: dependency: transitive description: @@ -437,10 +437,10 @@ packages: dependency: transitive description: name: cross_file - sha256: fedaadfa3a6996f75211d835aaeb8fede285dae94262485698afd832371b9a5e + sha256: "55d7b444feb71301ef6b8838dbc1ae02e63dd48c8773f3810ff53bb1e2945b32" url: "https://pub.dev" source: hosted - version: "0.3.3+8" + version: "0.3.4+1" crypto: dependency: "direct main" description: @@ -500,10 +500,10 @@ packages: dependency: transitive description: name: dart_style - sha256: "25b4624c231844a7a70a3817a729a6190a751ef1c07ded256e126a3b72261444" + sha256: "99e066ce75c89d6b29903d788a7bb9369cf754f7b24bf70bf4b6d6d6b26853b9" url: "https://pub.dev" source: hosted - version: "2.3.5" + version: "2.3.6" dart_web3: dependency: transitive description: @@ -973,10 +973,10 @@ packages: dependency: "direct main" description: name: flutter_markdown - sha256: "5b24061317f850af858ef7151dadbb6eb77c1c449c954c7bb064e8a5e0e7d81f" + sha256: a64c5323ac83ed2b7940d2b6288d160aa1753ff271ba9d9b2a86770414aa3eab url: "https://pub.dev" source: hosted - version: "0.6.20" + version: "0.6.20+1" flutter_native_timezone: dependency: "direct main" description: @@ -1127,10 +1127,10 @@ packages: dependency: "direct main" description: name: google_fonts - sha256: f0b8d115a13ecf827013ec9fc883390ccc0e87a96ed5347a3114cac177ef18e8 + sha256: "5b1726fee554d1cc9db1baef8061b126567ff0a1140a03ed7de936e62f2ab98b" url: "https://pub.dev" source: hosted - version: "6.1.0" + version: "6.2.0" google_mlkit_barcode_scanning: dependency: "direct main" description: @@ -1199,10 +1199,10 @@ packages: dependency: "direct overridden" description: name: http - sha256: a2bbf9d017fcced29139daa8ed2bba4ece450ab222871df93ca9eec6f80c34ba + sha256: "761a297c042deedc1ffbb156d6e2af13886bb305c2a343a4d972504cd67dd938" url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.2.1" http_mock_adapter: dependency: "direct dev" description: @@ -1287,10 +1287,10 @@ packages: dependency: transitive description: name: image_picker_platform_interface - sha256: fa4e815e6fcada50e35718727d83ba1c92f1edf95c0b4436554cec301b56233b + sha256: "3d2c323daea9d60608f1caf30be32a938916f4975434b8352e6f73dae496da38" url: "https://pub.dev" source: hosted - version: "2.9.3" + version: "2.9.4" image_picker_windows: dependency: transitive description: @@ -1385,6 +1385,30 @@ packages: relative: true source: path version: "1.0.0+1" + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" + url: "https://pub.dev" + source: hosted + version: "10.0.0" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 + url: "https://pub.dev" + source: hosted + version: "2.0.1" + leak_tracker_testing: + dependency: transitive + description: + name: leak_tracker_testing + sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 + url: "https://pub.dev" + source: hosted + version: "2.0.1" linkify: dependency: transitive description: @@ -1469,26 +1493,26 @@ packages: dependency: transitive description: name: matcher - sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb url: "https://pub.dev" source: hosted - version: "0.12.16" + version: "0.12.16+1" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" + sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" url: "https://pub.dev" source: hosted - version: "0.5.0" + version: "0.8.0" matrix: dependency: "direct main" description: name: matrix - sha256: "64b71793b689f57521f24d5412dadd090a61762084971ff13c7b8870b3cebeb7" + sha256: baefc62fd4ea6e857fd8cfe6f8b0421a08cd58223dbf94c9b3cc3bc29497a8ff url: "https://pub.dev" source: hosted - version: "0.25.11" + version: "0.25.12" matrix_api_lite: dependency: transitive description: @@ -1509,10 +1533,10 @@ packages: dependency: transitive description: name: meta - sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e + sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.11.0" mime: dependency: "direct main" description: @@ -1660,10 +1684,10 @@ packages: dependency: "direct main" description: name: path - sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.dev" source: hosted - version: "1.8.3" + version: "1.9.0" path_drawing: dependency: transitive description: @@ -2115,10 +2139,10 @@ packages: dependency: transitive description: name: shared_preferences_web - sha256: "7b15ffb9387ea3e237bb7a66b8a23d2147663d391cafc5c8f37b2e7b4bde5d21" + sha256: "9aee1089b36bd2aafe06582b7d7817fd317ef05fc30e6ba14bff247d0933042a" url: "https://pub.dev" source: hosted - version: "2.2.2" + version: "2.3.0" shared_preferences_windows: dependency: transitive description: @@ -2449,10 +2473,10 @@ packages: dependency: transitive description: name: url_launcher_web - sha256: fff0932192afeedf63cdd50ecbb1bc825d31aed259f02bb8dba0f3b729a5e88b + sha256: "3692a459204a33e04bc94f5fb91158faf4f2c8903281ddd82915adecdb1a901d" url: "https://pub.dev" source: hosted - version: "2.2.3" + version: "2.3.0" url_launcher_windows: dependency: transitive description: @@ -2553,10 +2577,10 @@ packages: dependency: transitive description: name: web - sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 + sha256: "1d9158c616048c38f712a6646e317a3426da10e884447626167240d45209cbad" url: "https://pub.dev" source: hosted - version: "0.3.0" + version: "0.5.0" web3dart: dependency: transitive description: @@ -2569,10 +2593,10 @@ packages: dependency: transitive description: name: web_socket_channel - sha256: d88238e5eac9a42bb43ca4e721edba3c08c6354d4a53063afaa568516217621b + sha256: "1d8e795e2a8b3730c41b8a98a2dff2e0fb57ae6f0764a1c46ec5915387d257b2" url: "https://pub.dev" source: hosted - version: "2.4.0" + version: "2.4.4" webkit_inspection_protocol: dependency: transitive description: @@ -2686,5 +2710,5 @@ packages: source: hosted version: "2.2.0" sdks: - dart: ">=3.2.3 <4.0.0" - flutter: ">=3.16.6" + dart: ">=3.3.0 <4.0.0" + flutter: ">=3.19.0" From 7bfb7adfc96fdba34072be659573629b62d8db32 Mon Sep 17 00:00:00 2001 From: hawkbee1 Date: Sat, 2 Mar 2024 17:32:09 +0000 Subject: [PATCH 24/45] bug correction: forgotten ; --- lib/lang/cubit/lang_cubit.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/lang/cubit/lang_cubit.dart b/lib/lang/cubit/lang_cubit.dart index 708fa342f..0abd28e65 100644 --- a/lib/lang/cubit/lang_cubit.dart +++ b/lib/lang/cubit/lang_cubit.dart @@ -68,11 +68,11 @@ class LangCubit extends Cubit { } else { await recordLanguage(locale.languageCode); newLocale = locale; - newlanguageType = getLanguageType(locale.languageCode, newlanguageType) + newlanguageType = getLanguageType(locale.languageCode, newlanguageType); } if (AppLocalizations.supportedLocales .contains(Locale(newLocale.languageCode))) { emit(LangState(languageType: newlanguageType, locale: newLocale)); - } + } } } From 8f2d734a749935b3a163caf2b324371f7a0d964e Mon Sep 17 00:00:00 2001 From: hawkbee1 Date: Sat, 2 Mar 2024 17:39:49 +0000 Subject: [PATCH 25/45] Add props to LangState --- lib/lang/cubit/lang_state.dart | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/lang/cubit/lang_state.dart b/lib/lang/cubit/lang_state.dart index c81eaccbe..cd6404adc 100644 --- a/lib/lang/cubit/lang_state.dart +++ b/lib/lang/cubit/lang_state.dart @@ -10,8 +10,10 @@ class LangState extends Equatable { final LanguageType languageType; @override - // TODO: implement props - List get props => throw UnimplementedError(); + List get props => [ + locale, + languageType, + ]; LangState copyWith({Locale? locale, LanguageType? languageType}) { return LangState( From dcb6c02be630765c7ac262e58767b12ba1845581 Mon Sep 17 00:00:00 2001 From: hawkbee1 Date: Sun, 3 Mar 2024 09:19:46 +0000 Subject: [PATCH 26/45] version: 2.3.13+403 --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index bb612d5c2..796c30de1 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: altme description: AltMe Flutter App -version: 2.3.12+402 +version: 2.3.13+403 environment: sdk: ">=3.1.0 <4.0.0" From 51e6bfb51bed168cd26541106eb4a52c83e55187 Mon Sep 17 00:00:00 2001 From: hawkbee1 Date: Mon, 4 Mar 2024 10:18:44 +0100 Subject: [PATCH 27/45] fix google_font version due to error on ios for last version: https://stackoverflow.com/questions/78090711/error-type-fontfeature-not-found-flutter-google-fonts-package-error --- pubspec.lock | 88 +++++++++++++++++++--------------------------------- pubspec.yaml | 2 +- 2 files changed, 33 insertions(+), 57 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index 4508659c0..95df06ab3 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,10 +5,10 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: "0b2f2bd91ba804e53a61d757b986f89f1f9eaed5b11e4b2f5a2468d86d6c9fc7" + sha256: eb376e9acf6938204f90eb3b1f00b578640d3188b4c8a8ec054f9f479af8d051 url: "https://pub.dev" source: hosted - version: "67.0.0" + version: "64.0.0" adaptive_number: dependency: transitive description: @@ -21,10 +21,10 @@ packages: dependency: transitive description: name: analyzer - sha256: "37577842a27e4338429a1cbc32679d508836510b056f1eedf0c8d20e39c1383d" + sha256: "69f54f967773f6c26c7dcb13e93d7ccee8b17a641689da39e878d5cf13b06893" url: "https://pub.dev" source: hosted - version: "6.4.1" + version: "6.2.0" android_intent_plus: dependency: transitive description: @@ -437,10 +437,10 @@ packages: dependency: transitive description: name: cross_file - sha256: "55d7b444feb71301ef6b8838dbc1ae02e63dd48c8773f3810ff53bb1e2945b32" + sha256: fedaadfa3a6996f75211d835aaeb8fede285dae94262485698afd832371b9a5e url: "https://pub.dev" source: hosted - version: "0.3.4+1" + version: "0.3.3+8" crypto: dependency: "direct main" description: @@ -973,10 +973,10 @@ packages: dependency: "direct main" description: name: flutter_markdown - sha256: a64c5323ac83ed2b7940d2b6288d160aa1753ff271ba9d9b2a86770414aa3eab + sha256: "5b24061317f850af858ef7151dadbb6eb77c1c449c954c7bb064e8a5e0e7d81f" url: "https://pub.dev" source: hosted - version: "0.6.20+1" + version: "0.6.20" flutter_native_timezone: dependency: "direct main" description: @@ -1127,10 +1127,10 @@ packages: dependency: "direct main" description: name: google_fonts - sha256: "5b1726fee554d1cc9db1baef8061b126567ff0a1140a03ed7de936e62f2ab98b" + sha256: f0b8d115a13ecf827013ec9fc883390ccc0e87a96ed5347a3114cac177ef18e8 url: "https://pub.dev" source: hosted - version: "6.2.0" + version: "6.1.0" google_mlkit_barcode_scanning: dependency: "direct main" description: @@ -1199,10 +1199,10 @@ packages: dependency: "direct overridden" description: name: http - sha256: "761a297c042deedc1ffbb156d6e2af13886bb305c2a343a4d972504cd67dd938" + sha256: a2bbf9d017fcced29139daa8ed2bba4ece450ab222871df93ca9eec6f80c34ba url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.2.0" http_mock_adapter: dependency: "direct dev" description: @@ -1287,10 +1287,10 @@ packages: dependency: transitive description: name: image_picker_platform_interface - sha256: "3d2c323daea9d60608f1caf30be32a938916f4975434b8352e6f73dae496da38" + sha256: fa4e815e6fcada50e35718727d83ba1c92f1edf95c0b4436554cec301b56233b url: "https://pub.dev" source: hosted - version: "2.9.4" + version: "2.9.3" image_picker_windows: dependency: transitive description: @@ -1385,30 +1385,6 @@ packages: relative: true source: path version: "1.0.0+1" - leak_tracker: - dependency: transitive - description: - name: leak_tracker - sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" - url: "https://pub.dev" - source: hosted - version: "10.0.0" - leak_tracker_flutter_testing: - dependency: transitive - description: - name: leak_tracker_flutter_testing - sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 - url: "https://pub.dev" - source: hosted - version: "2.0.1" - leak_tracker_testing: - dependency: transitive - description: - name: leak_tracker_testing - sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 - url: "https://pub.dev" - source: hosted - version: "2.0.1" linkify: dependency: transitive description: @@ -1493,18 +1469,18 @@ packages: dependency: transitive description: name: matcher - sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb + sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" url: "https://pub.dev" source: hosted - version: "0.12.16+1" + version: "0.12.16" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" + sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" url: "https://pub.dev" source: hosted - version: "0.8.0" + version: "0.5.0" matrix: dependency: "direct main" description: @@ -1533,10 +1509,10 @@ packages: dependency: transitive description: name: meta - sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 + sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e url: "https://pub.dev" source: hosted - version: "1.11.0" + version: "1.10.0" mime: dependency: "direct main" description: @@ -1684,10 +1660,10 @@ packages: dependency: "direct main" description: name: path - sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" + sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" url: "https://pub.dev" source: hosted - version: "1.9.0" + version: "1.8.3" path_drawing: dependency: transitive description: @@ -2139,10 +2115,10 @@ packages: dependency: transitive description: name: shared_preferences_web - sha256: "9aee1089b36bd2aafe06582b7d7817fd317ef05fc30e6ba14bff247d0933042a" + sha256: "7b15ffb9387ea3e237bb7a66b8a23d2147663d391cafc5c8f37b2e7b4bde5d21" url: "https://pub.dev" source: hosted - version: "2.3.0" + version: "2.2.2" shared_preferences_windows: dependency: transitive description: @@ -2473,10 +2449,10 @@ packages: dependency: transitive description: name: url_launcher_web - sha256: "3692a459204a33e04bc94f5fb91158faf4f2c8903281ddd82915adecdb1a901d" + sha256: fff0932192afeedf63cdd50ecbb1bc825d31aed259f02bb8dba0f3b729a5e88b url: "https://pub.dev" source: hosted - version: "2.3.0" + version: "2.2.3" url_launcher_windows: dependency: transitive description: @@ -2577,10 +2553,10 @@ packages: dependency: transitive description: name: web - sha256: "1d9158c616048c38f712a6646e317a3426da10e884447626167240d45209cbad" + sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 url: "https://pub.dev" source: hosted - version: "0.5.0" + version: "0.3.0" web3dart: dependency: transitive description: @@ -2593,10 +2569,10 @@ packages: dependency: transitive description: name: web_socket_channel - sha256: "1d8e795e2a8b3730c41b8a98a2dff2e0fb57ae6f0764a1c46ec5915387d257b2" + sha256: d88238e5eac9a42bb43ca4e721edba3c08c6354d4a53063afaa568516217621b url: "https://pub.dev" source: hosted - version: "2.4.4" + version: "2.4.0" webkit_inspection_protocol: dependency: transitive description: @@ -2710,5 +2686,5 @@ packages: source: hosted version: "2.2.0" sdks: - dart: ">=3.3.0 <4.0.0" - flutter: ">=3.19.0" + dart: ">=3.2.3 <4.0.0" + flutter: ">=3.16.6" diff --git a/pubspec.yaml b/pubspec.yaml index 796c30de1..caac4ccb3 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -61,7 +61,7 @@ dependencies: flutter_olm: ^1.4.1 flutter_openssl_crypto: ^0.3.0 flutter_svg: ^2.0.6 - google_fonts: ^6.1.0 + google_fonts: 6.1.0 #google_mlkit_face_detection: ^0.5.0 google_mlkit_barcode_scanning: ^0.10.0 image: ^4.0.17 From 81c7eec819e8354897fcd76dc8005b34edc4b7c2 Mon Sep 17 00:00:00 2001 From: hawkbee1 Date: Mon, 4 Mar 2024 10:19:36 +0100 Subject: [PATCH 28/45] fix dependency conflict in oidc4vc package --- packages/oidc4vc/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/oidc4vc/pubspec.yaml b/packages/oidc4vc/pubspec.yaml index cfdafa866..e0ec417ae 100644 --- a/packages/oidc4vc/pubspec.yaml +++ b/packages/oidc4vc/pubspec.yaml @@ -43,5 +43,5 @@ dev_dependencies: flutter_test: sdk: flutter json_serializable: ^6.7.0 - mocktail: ^0.3.0 + mocktail: ^1.0.3 very_good_analysis: ^5.0.0+1 From 2227e2d29c86ad361fa51909d32db46da335afcf Mon Sep 17 00:00:00 2001 From: Bibash Shrestha Date: Mon, 4 Mar 2024 11:29:56 +0545 Subject: [PATCH 29/45] feat: Set crypto holder binding to false #2465 --- lib/dashboard/profile/models/profile.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/dashboard/profile/models/profile.dart b/lib/dashboard/profile/models/profile.dart index 448f62c3b..53eef475f 100644 --- a/lib/dashboard/profile/models/profile.dart +++ b/lib/dashboard/profile/models/profile.dart @@ -103,7 +103,7 @@ class ProfileModel extends Equatable { customOidc4vcProfile: CustomOidc4VcProfile( clientAuthentication: ClientAuthentication.clientId, credentialManifestSupport: false, - cryptoHolderBinding: false, + cryptoHolderBinding: true, defaultDid: Parameters.didKeyTypeForDefault, oidc4vciDraft: OIDC4VCIDraftType.draft11, oidc4vpDraft: OIDC4VPDraftType.draft18, From 1b3cea592a5faccb407842eae63cd0d277833517 Mon Sep 17 00:00:00 2001 From: Bibash Shrestha Date: Mon, 4 Mar 2024 11:31:17 +0545 Subject: [PATCH 30/45] Wording : replace ldp_vc by ldp_vp #2466 --- packages/oidc4vc/lib/src/proof_type.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/oidc4vc/lib/src/proof_type.dart b/packages/oidc4vc/lib/src/proof_type.dart index ec7835325..19077d8cf 100644 --- a/packages/oidc4vc/lib/src/proof_type.dart +++ b/packages/oidc4vc/lib/src/proof_type.dart @@ -10,7 +10,7 @@ extension ProofTypeeX on ProofType { String get formattedString { switch (this) { case ProofType.ldpVp: - return 'ldp_vc'; + return 'ldp_vp'; case ProofType.jwt: return 'jwt'; } @@ -19,7 +19,7 @@ extension ProofTypeeX on ProofType { String get value { switch (this) { case ProofType.ldpVp: - return 'ldp_vc'; + return 'ldp_vp'; case ProofType.jwt: return 'jwt'; } From 1d48dff7cfd5e8782323e5cd1edb8b21544ca5f6 Mon Sep 17 00:00:00 2001 From: Bibash Shrestha Date: Mon, 4 Mar 2024 12:38:38 +0545 Subject: [PATCH 31/45] feat: Remove did switch dependencies #2467 --- .../widget/did_key_type_widget.dart | 16 ---------------- lib/l10n/arb/app_en.arb | 3 +-- lib/l10n/arb/app_fr.arb | 1 - 3 files changed, 1 insertion(+), 19 deletions(-) diff --git a/lib/dashboard/drawer/ssi/oidc4vc_settngs/widget/did_key_type_widget.dart b/lib/dashboard/drawer/ssi/oidc4vc_settngs/widget/did_key_type_widget.dart index 07ad625e8..d8f0f5262 100644 --- a/lib/dashboard/drawer/ssi/oidc4vc_settngs/widget/did_key_type_widget.dart +++ b/lib/dashboard/drawer/ssi/oidc4vc_settngs/widget/did_key_type_widget.dart @@ -60,22 +60,6 @@ class DidKeyTypeWidget extends StatelessWidget { return; } - ///if DID method is did eddsa then Cryrto Holder Binding - ///must be Off -> display message "Switch off Crypto - ///Holder Binding for that DID Method" - if (didKeyType == DidKeyType.edDSA && - customOidc4vcProfile.cryptoHolderBinding) { - showDialog( - context: context, - builder: (context) => ErrorDetailsDialog( - erroDescription: l10n - .switchOffCryptoHolderBindingForThatDIDMethod, - ), - ); - - return; - } - context.read().updateProfileSetting( didKeyType: didKeyType, ); diff --git a/lib/l10n/arb/app_en.arb b/lib/l10n/arb/app_en.arb index debd5aaac..b2062168b 100644 --- a/lib/l10n/arb/app_en.arb +++ b/lib/l10n/arb/app_en.arb @@ -1028,8 +1028,7 @@ "clientTypeSubtitle": "Default: DID\nSwitch to change the client type", "proofHeader": "Proof of Possession Header", "proofHeaderSubtitle": "Default: kid\nSwitch if jwk is needed in header.", - "theLdpFormatIsNotSupportedByThisDIDMethod": "The ldp_format is not supported by this DID method.", - "switchOffCryptoHolderBindingForThatDIDMethod": "Switch off Crypto Holder Binding for that DID Method.", + "theLdpFormatIsNotSupportedByThisDIDMethod": "The ldp_format is not supported by this DID method.", "thisTypeProofCannotBeUsedWithThisVCFormat": "This type proof cannot be used with this VC Format.", "enterprise": "Enterprise", "oWFBaselineProfile": "OWF Baseline Profile", diff --git a/lib/l10n/arb/app_fr.arb b/lib/l10n/arb/app_fr.arb index d3891aaad..ced6e07a9 100644 --- a/lib/l10n/arb/app_fr.arb +++ b/lib/l10n/arb/app_fr.arb @@ -1031,7 +1031,6 @@ "continueString": "Continuer", "walletProvider": "Fournisseur de Portefeuille", "theLdpFormatIsNotSupportedByThisDIDMethod": "Le format LDP n'est pas pris en charge par cette méthode DID.", - "switchOffCryptoHolderBindingForThatDIDMethod": "Désactivez la fonctionnalité \"Crypto Holder Binding\" pour cette méthode DID.", "thisTypeProofCannotBeUsedWithThisVCFormat": "Ce type de preuve ne peut pas être utilisé avec ce format de VC.", "enterprise": "Entreprise", "oWFBaselineProfile": "Profil de base OWF", From c190515b857fd87e244f6d78fb87505b0c017d91 Mon Sep 17 00:00:00 2001 From: Bibash Shrestha Date: Mon, 4 Mar 2024 13:35:23 +0545 Subject: [PATCH 32/45] feat: Update value of iss #2463 --- lib/oidc4vc/get_credential.dart | 21 +++++++++++++++++++++ lib/splash/view/splash_page.dart | 5 ----- packages/oidc4vc/lib/src/oidc4vc.dart | 18 ++++++++---------- 3 files changed, 29 insertions(+), 15 deletions(-) diff --git a/lib/oidc4vc/get_credential.dart b/lib/oidc4vc/get_credential.dart index e4f9e8886..a2fd08026 100644 --- a/lib/oidc4vc/get_credential.dart +++ b/lib/oidc4vc/get_credential.dart @@ -55,6 +55,26 @@ Future< final index = getIndexValue(isEBSIV3: isEBSIV3, didKeyType: didKeyType); + var iss = ''; + + switch (customOidc4vcProfile.clientType) { + case ClientType.jwkThumbprint: + final tokenParameters = TokenParameters( + privateKey: jsonDecode(privateKey) as Map, + did: '', // just added as it is required field + mediaType: MediaType.basic, // just added as it is required field + clientType: + ClientType.jwkThumbprint, // just added as it is required field + proofHeaderType: customOidc4vcProfile.proofHeader, + clientId: '', + ); + iss = tokenParameters.thumbprint; + case ClientType.did: + iss = did; + case ClientType.confidential: + iss = customOidc4vcProfile.clientId ?? ''; + } + final ( List encodedCredentialOrFutureTokens, String? deferredCredentialEndpoint, @@ -82,6 +102,7 @@ Future< clientAuthentication: customOidc4vcProfile.clientAuthentication, redirectUri: Parameters.oidc4vcUniversalLink, proofType: customOidc4vcProfile.proofType, + iss: iss, ); return ( diff --git a/lib/splash/view/splash_page.dart b/lib/splash/view/splash_page.dart index 2d6b5d862..b6d8f12c7 100644 --- a/lib/splash/view/splash_page.dart +++ b/lib/splash/view/splash_page.dart @@ -102,11 +102,6 @@ class _SplashViewState extends State { return; } - if (uri.toString().startsWith('configuration://?')) { - await context.read().requestTheConfiguration(uri!); - return; - } - if (uri.toString().startsWith(Parameters.authorizeEndPoint)) { context.read().addDeepLink(uri!.toString()); await context.read().deepLink(); diff --git a/packages/oidc4vc/lib/src/oidc4vc.dart b/packages/oidc4vc/lib/src/oidc4vc.dart index d776ca40d..046586d68 100644 --- a/packages/oidc4vc/lib/src/oidc4vc.dart +++ b/packages/oidc4vc/lib/src/oidc4vc.dart @@ -412,6 +412,7 @@ class OIDC4VC { required ClientAuthentication clientAuthentication, required String redirectUri, required ProofType proofType, + required String iss, String? preAuthorizedCode, String? userPin, String? code, @@ -523,6 +524,7 @@ class OIDC4VC { issuer: issuer, kid: kid, privateKey: privateKey, + iss: iss, ); credentialResponseData.add(credentialResponseDataValue); @@ -546,6 +548,7 @@ class OIDC4VC { issuer: issuer, kid: kid, privateKey: privateKey, + iss: iss, ); credentialResponseData.add(credentialResponseDataValue); @@ -577,6 +580,7 @@ class OIDC4VC { required String issuer, required String kid, required String privateKey, + required String iss, }) async { final credentialData = await buildCredentialData( cnonce: cnonce, @@ -596,6 +600,7 @@ class OIDC4VC { issuer: issuer, kid: kid, privateKey: privateKey, + iss: iss, ); /// sign proof @@ -858,6 +863,7 @@ class OIDC4VC { required Map? credentialDefinition, required ProofType proofType, required String did, + required String iss, required String issuer, required String kid, required String privateKey, @@ -896,6 +902,7 @@ class OIDC4VC { clientAuthentication: clientAuthentication, oidc4vciDraftType: oidc4vciDraftType, cnonce: cnonce, + iss: iss, ); credentialData['proof'] = { @@ -1148,20 +1155,11 @@ class OIDC4VC { required IssuerTokenParameters tokenParameters, required ClientAuthentication clientAuthentication, required OIDC4VCIDraftType oidc4vciDraftType, + required String iss, String? cnonce, }) async { final iat = (DateTime.now().millisecondsSinceEpoch / 1000).round() - 30; - var iss = tokenParameters.did; - - if (clientAuthentication == ClientAuthentication.clientSecretPost || - clientAuthentication == ClientAuthentication.clientSecretBasic) { - if (oidc4vciDraftType == OIDC4VCIDraftType.draft11 || - oidc4vciDraftType == OIDC4VCIDraftType.draft13) { - iss = tokenParameters.clientId; - } - } - final payload = { 'iss': iss, 'iat': iat, From aeb1ecb3315ed9525ad93d6656d4a8e8d12f0306 Mon Sep 17 00:00:00 2001 From: Bibash Shrestha Date: Mon, 4 Mar 2024 16:12:50 +0545 Subject: [PATCH 33/45] feat: Handle multiple deeplink call --- lib/splash/view/splash_page.dart | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/lib/splash/view/splash_page.dart b/lib/splash/view/splash_page.dart index b6d8f12c7..74e646c1b 100644 --- a/lib/splash/view/splash_page.dart +++ b/lib/splash/view/splash_page.dart @@ -78,11 +78,24 @@ class _SplashViewState extends State { bool isPolygonFunctionCalled = false; + String? _deeplink; + Future processIncomingUri(Uri? uri, BuildContext context) async { final l10n = context.l10n; String beaconData = ''; bool isBeaconRequest = false; + Timer.periodic(const Duration(seconds: 3), (timer) { + timer.cancel(); + _deeplink = null; + }); + + if (_deeplink != null && _deeplink == uri.toString()) { + return; + } + + _deeplink = uri.toString(); + if (uri.toString().startsWith('${Urls.appDeepLink}/dashboard')) { await Navigator.pushAndRemoveUntil( context, From 44dde0dd16984b6c7d8c0b60a86abaaf3c1df36e Mon Sep 17 00:00:00 2001 From: Bibash Shrestha Date: Mon, 4 Mar 2024 16:33:06 +0545 Subject: [PATCH 34/45] feat: Update enterprise flow update #2454 #2468 --- lib/enterprise/cubit/enterprise_cubit.dart | 54 +++++++++++++++------- 1 file changed, 37 insertions(+), 17 deletions(-) diff --git a/lib/enterprise/cubit/enterprise_cubit.dart b/lib/enterprise/cubit/enterprise_cubit.dart index 197060256..1ee9e24db 100644 --- a/lib/enterprise/cubit/enterprise_cubit.dart +++ b/lib/enterprise/cubit/enterprise_cubit.dart @@ -50,17 +50,23 @@ class EnterpriseCubit extends Cubit { SecureStorageKeys.enterpriseEmail, ); + // if (savedEmail != null) { + // if (email == savedEmail) { + // /// if email is matched then update the configuration + // await updateTheConfiguration(); + // return; + // } else { + // throw ResponseMessage( + // message: + // ResponseString.RESPONSE_STRING_thisWalleIsAlreadyConfigured, + // ); + // } + // } + if (savedEmail != null) { - if (email == savedEmail) { - /// if email is matched then update the configuration - await updateTheConfiguration(); - return; - } else { - throw ResponseMessage( - message: - ResponseString.RESPONSE_STRING_thisWalleIsAlreadyConfigured, - ); - } + throw ResponseMessage( + message: ResponseString.RESPONSE_STRING_thisWalleIsAlreadyConfigured, + ); } /// get vc and store it in the wallet @@ -273,7 +279,7 @@ class EnterpriseCubit extends Cubit { data: data, ); - String jwtVc = response.toString(); + final jwtVc = response.toString(); /// parse final header = jwtDecode.parseJwtHeader(jwtVc!); @@ -299,26 +305,40 @@ class EnterpriseCubit extends Cubit { try { emit(state.loading()); + final savedEmail = await profileCubit.secureStorageProvider.get( + SecureStorageKeys.enterpriseEmail, + ); + final savedPassword = await profileCubit.secureStorageProvider.get( + SecureStorageKeys.enterprisePassword, + ); + final provider = await profileCubit.secureStorageProvider.get( SecureStorageKeys.enterpriseWalletProvider, ); - if (provider == null) { + final walletAttestationData = + await profileCubit.secureStorageProvider.get( + SecureStorageKeys.walletAttestationData, + ); + + if (savedEmail == null || + savedPassword == null || + provider == null || + walletAttestationData == null) { throw ResponseMessage( data: { 'error': 'invalid_request', - 'error_description': 'The wallet provider does not match.', + 'error_description': 'The wallet is not configured yet.', }, ); } - final walletAttestationData = - await profileCubit.secureStorageProvider.get( - SecureStorageKeys.walletAttestationData, - ); + final encodedData = utf8.encode('$savedEmail:$savedPassword'); + final base64Encoded = base64UrlEncode(encodedData).replaceAll('=', ''); final headers = { 'Content-Type': 'application/x-www-form-urlencoded', + 'Authorization': 'Basic $base64Encoded', }; final data = { From 4f2b670fc60fdf89b2904c1b744e6d4260903630 Mon Sep 17 00:00:00 2001 From: Bibash Shrestha Date: Mon, 4 Mar 2024 16:59:18 +0545 Subject: [PATCH 35/45] feat: Display issuer of verifiable id sd-jwt #2469 --- .../credential_subject_type_extension.dart | 32 +++++--- lib/credentials/cubit/credentials_cubit.dart | 10 ++- .../profile/models/profile_setting.dart | 3 + .../profile/models/profile_setting.json | 80 ------------------- pubspec.lock | 4 +- 5 files changed, 35 insertions(+), 94 deletions(-) delete mode 100644 lib/dashboard/profile/models/profile_setting.json diff --git a/lib/app/shared/enum/type/credential_subject_type/credential_subject_type_extension.dart b/lib/app/shared/enum/type/credential_subject_type/credential_subject_type_extension.dart index 7f2631af7..7fbd628e6 100644 --- a/lib/app/shared/enum/type/credential_subject_type/credential_subject_type_extension.dart +++ b/lib/app/shared/enum/type/credential_subject_type/credential_subject_type_extension.dart @@ -767,7 +767,8 @@ extension CredentialSubjectTypeExtension on CredentialSubjectType { image = ImageStrings.dummyOver13Card; link = '${Urls.id360Url}' - '?format=${vcFormatType.urlValue}' + '?draft=${oidc4vcDraftType.numbering}' + '&format=${vcFormatType.urlValue}' '&type=over13'; whyGetThisCard = ResponseString.RESPONSE_STRING_over13WhyGetThisCard; @@ -779,7 +780,8 @@ extension CredentialSubjectTypeExtension on CredentialSubjectType { image = ImageStrings.dummyOver15Card; link = '${Urls.id360Url}' - '?format=${vcFormatType.urlValue}' + '?draft=${oidc4vcDraftType.numbering}' + '&format=${vcFormatType.urlValue}' '&type=over15'; whyGetThisCard = ResponseString.RESPONSE_STRING_over15WhyGetThisCard; @@ -791,7 +793,8 @@ extension CredentialSubjectTypeExtension on CredentialSubjectType { image = ImageStrings.dummyOver18Card; link = '${Urls.id360Url}' - '?format=${vcFormatType.urlValue}' + '?draft=${oidc4vcDraftType.numbering}' + '&format=${vcFormatType.urlValue}' '&type=over18'; whyGetThisCard = ResponseString.RESPONSE_STRING_over18WhyGetThisCard; @@ -803,7 +806,8 @@ extension CredentialSubjectTypeExtension on CredentialSubjectType { image = ImageStrings.dummyOver21Card; link = '${Urls.id360Url}' - '?format=${vcFormatType.urlValue}' + '?draft=${oidc4vcDraftType.numbering}' + '&format=${vcFormatType.urlValue}' '&type=over21'; whyGetThisCard = ResponseString.RESPONSE_STRING_over18WhyGetThisCard; @@ -815,7 +819,8 @@ extension CredentialSubjectTypeExtension on CredentialSubjectType { image = ImageStrings.dummyOver50Card; link = '${Urls.id360Url}' - '?format=${vcFormatType.urlValue}' + '?draft=${oidc4vcDraftType.numbering}' + '&format=${vcFormatType.urlValue}' '&type=over50'; whyGetThisCard = ResponseString.RESPONSE_STRING_over18WhyGetThisCard; @@ -827,7 +832,8 @@ extension CredentialSubjectTypeExtension on CredentialSubjectType { image = ImageStrings.dummyOver65Card; link = '${Urls.id360Url}' - '?format=${vcFormatType.urlValue}' + '?draft=${oidc4vcDraftType.numbering}' + '&format=${vcFormatType.urlValue}' '&type=over65'; whyGetThisCard = ResponseString.RESPONSE_STRING_over18WhyGetThisCard; @@ -857,9 +863,16 @@ extension CredentialSubjectTypeExtension on CredentialSubjectType { case CredentialSubjectType.verifiableIdCard: image = ImageStrings.dummyVerifiableIdCard; + var type = 'verifiableid'; + + if (vcFormatType == VCFormatType.vcSdJWT) { + type = 'identitycredential'; + } + link = '${Urls.id360Url}' - '?format=${vcFormatType.urlValue}' - '&type=verifiableid'; + '?draft=${oidc4vcDraftType.numbering}' + '&format=${vcFormatType.urlValue}' + '&type=$type'; whyGetThisCard = ResponseString.RESPONSE_STRING_verifiableIdCardWhyGetThisCard; @@ -926,7 +939,8 @@ extension CredentialSubjectTypeExtension on CredentialSubjectType { image = ImageStrings.livenessDummy; link = '${Urls.id360Url}' - '?format=${vcFormatType.urlValue}' + '?draft=${oidc4vcDraftType.numbering}' + '&format=${vcFormatType.urlValue}' '&type=liveness'; whyGetThisCard = diff --git a/lib/credentials/cubit/credentials_cubit.dart b/lib/credentials/cubit/credentials_cubit.dart index f2763b090..af8e799c6 100644 --- a/lib/credentials/cubit/credentials_cubit.dart +++ b/lib/credentials/cubit/credentials_cubit.dart @@ -706,11 +706,15 @@ class CredentialsCubit extends Cubit { final displayVerifiableId = vcFormatType == VCFormatType.ldpVc && discoverCardsOptions.displayVerifiableId; final displayVerifiableIdJwt = - (vcFormatType == VCFormatType.jwtVcJson || - vcFormatType == VCFormatType.vcSdJWT) && + vcFormatType == VCFormatType.jwtVcJson && discoverCardsOptions.displayVerifiableIdJwt; + final displayVerifiableIdSdJwt = + vcFormatType == VCFormatType.vcSdJWT && + discoverCardsOptions.displayVerifiableIdSdJwt; - if (displayVerifiableId || displayVerifiableIdJwt) { + if (displayVerifiableId || + displayVerifiableIdJwt || + displayVerifiableIdSdJwt) { allSubjectTypeForCategory .add(CredentialSubjectType.verifiableIdCard); } diff --git a/lib/dashboard/profile/models/profile_setting.dart b/lib/dashboard/profile/models/profile_setting.dart index 401aeef02..15b89cf8b 100644 --- a/lib/dashboard/profile/models/profile_setting.dart +++ b/lib/dashboard/profile/models/profile_setting.dart @@ -181,6 +181,7 @@ class DiscoverCardsOptions extends Equatable { required this.displayExternalIssuer, this.displayOver18Jwt = false, this.displayVerifiableIdJwt = true, + this.displayVerifiableIdSdJwt = true, this.displayEmailPass = true, this.displayEmailPassJwt = true, this.displayPhonePass = true, @@ -202,6 +203,7 @@ class DiscoverCardsOptions extends Equatable { displayOver21: false, displayOver50: false, displayVerifiableId: true, + displayVerifiableIdSdJwt: true, displayOver65: false, displayAgeRange: false, displayGender: false, @@ -249,6 +251,7 @@ class DiscoverCardsOptions extends Equatable { final bool displayAgeRange; final bool displayVerifiableId; final bool displayVerifiableIdJwt; + final bool displayVerifiableIdSdJwt; final bool displayGender; final List displayExternalIssuer; final bool displayChainborn; diff --git a/lib/dashboard/profile/models/profile_setting.json b/lib/dashboard/profile/models/profile_setting.json deleted file mode 100644 index e114ffe7c..000000000 --- a/lib/dashboard/profile/models/profile_setting.json +++ /dev/null @@ -1,80 +0,0 @@ -{ - "blockchainOptions": { - "bnbSupport": false, - "ethereumSupport": false, - "fantomSupport": false, - "hederaSupport": false, - "infuraApiKey": "", - "infuraRpcNode": false, - "polygonSupport": false, - "tezosSupport": false, - "tzproApiKey": "", - "tzproRpcNode": false - }, - "discoverCardsOptions": { - "displayDefi": true, - "displayHumanity": false, - "displayOver13": false, - "displayOver15": true, - "displayOver18": true, - "displayOver21": false, - "displayOver50": false, - "displayOver65": false, - "displayRewardsCategory": true, - "displayVerifiableId": true - }, - "exp": 1710845400, - "generalOptions": { - "companyLogo": "https://wallet-provider.talao.co/logos/Test_Bibash.png", - "companyName": "Ncell", - "companyWebsite": "www.ncell.com", - "customerPlan": "paid", - "profileId": "MjUxZTljZW", - "profileName": "Bibash Wallet", - "profileVersion": "1.0", - "published": "2023-12-20", - "tagLine": "ncell", - "walletType": "altme" - }, - "helpCenterOptions": { - "customChatSupport": false, - "customChatSupportName": null, - "customEmail": null, - "customEmailSupport": false, - "displayChatSupport": false, - "displayEmailSupport": false - }, - "iat": 1703069400, - "iss": "did:web:talao.co", - "jti": "a2d0c081-9f25-11ee-9b58-0a1628958560", - "selfSovereignIdentityOptions": { - "customOidc4vcProfile": { - "clientAuthentication": "none", - "client_id": null, - "client_secret": null, - "credentialManifestSupport": true, - "cryptoHolderBinding": false, - "defaultDid": "did:key:p-256", - "oidc4vciDraft": "11", - "oidc4vpDraft": "18", - "scope": false, - "securityLevel": false, - "siopv2Draft": "12", - "subjectSyntaxeType": "did", - "userPinDigits": "6" - }, - "displayManageDecentralizedId": true - }, - "settingsMenu": { - "displayDeveloperMode": true, - "displayHelpCenter": true, - "displayProfile": true - }, - "version": "1.10", - "walletSecurityOptions": { - "confirmSecurityVerifierAccess": true, - "displaySecurityAdvancedSettings": false, - "secureSecurityAuthenticationWithPinCode": true, - "verifySecurityIssuerWebsiteIdentity": true - } -} \ No newline at end of file diff --git a/pubspec.lock b/pubspec.lock index 95df06ab3..dceed54c1 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1445,10 +1445,10 @@ packages: dependency: transitive description: name: logger - sha256: "6bbb9d6f7056729537a4309bda2e74e18e5d9f14302489cc1e93f33b3fe32cac" + sha256: b3ff55aeb08d9d8901b767650285872cb1bb8f508373b3e348d60268b0c7f770 url: "https://pub.dev" source: hosted - version: "2.0.2+1" + version: "2.1.0" logging: dependency: transitive description: From 870f2cad7f2a128b411d265fda231fbb5b2817f0 Mon Sep 17 00:00:00 2001 From: Bibash Shrestha Date: Mon, 4 Mar 2024 17:01:31 +0545 Subject: [PATCH 36/45] version update to 2.3.14+404 --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index caac4ccb3..cd42c0bbc 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: altme description: AltMe Flutter App -version: 2.3.13+403 +version: 2.3.14+404 environment: sdk: ">=3.1.0 <4.0.0" From dcd06017d43d120ff7ed7aab74bafbac0864ca84 Mon Sep 17 00:00:00 2001 From: Bibash Shrestha Date: Tue, 5 Mar 2024 11:07:40 +0545 Subject: [PATCH 37/45] refactor: Bug fix over18 default not working #2470 --- .../credentials/helper_functions/discover_credential.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/dashboard/home/tab_bar/credentials/helper_functions/discover_credential.dart b/lib/dashboard/home/tab_bar/credentials/helper_functions/discover_credential.dart index bedb7cb03..edfbb3af3 100644 --- a/lib/dashboard/home/tab_bar/credentials/helper_functions/discover_credential.dart +++ b/lib/dashboard/home/tab_bar/credentials/helper_functions/discover_credential.dart @@ -97,6 +97,7 @@ Future discoverCredential({ } } + LoadingView().hide(); await Navigator.push( context, ChooseVerificationMethodPage.route( From 8d109f68240ecc086f92bc742d5a487b09e9f0da Mon Sep 17 00:00:00 2001 From: Bibash Shrestha Date: Tue, 5 Mar 2024 11:12:29 +0545 Subject: [PATCH 38/45] version update to 2.3.15+405 --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index cd42c0bbc..adbb56ebf 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: altme description: AltMe Flutter App -version: 2.3.14+404 +version: 2.3.15+405 environment: sdk: ">=3.1.0 <4.0.0" From 23ef3238a61992a075b9fdbfde20a14007019977 Mon Sep 17 00:00:00 2001 From: Bibash Shrestha Date: Tue, 5 Mar 2024 13:05:34 +0545 Subject: [PATCH 39/45] Enterprise profile must be last in the list #2396 --- lib/app/shared/enum/type/profile/profile_type.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/app/shared/enum/type/profile/profile_type.dart b/lib/app/shared/enum/type/profile/profile_type.dart index cff571896..6b2f2f300 100644 --- a/lib/app/shared/enum/type/profile/profile_type.dart +++ b/lib/app/shared/enum/type/profile/profile_type.dart @@ -4,9 +4,9 @@ enum ProfileType { defaultOne, ebsiV3, dutch, - enterprise, owfBaselineProfile, custom, + enterprise, } extension ProfileTypeX on ProfileType { From b705e906d818a5043a892b30867ecacf43e62249 Mon Sep 17 00:00:00 2001 From: Bibash Shrestha Date: Tue, 5 Mar 2024 15:36:29 +0545 Subject: [PATCH 40/45] feat: Add logo in second level setting of drawer #2249 --- .../about_altme/view/about_altme_menu.dart | 163 ++++++++---------- .../view/blockchain_settings_menu.dart | 87 ++++------ lib/dashboard/drawer/drawer.dart | 2 + .../help_center/view/help_center_menu.dart | 106 ++++++------ .../profile/view/pick_profile_menu.dart | 20 ++- .../drawer/src/view/drawer_page.dart | 9 +- .../drawer/ssi/src/view/ssi_menu.dart | 118 ++++++------- .../src/view/wallet_security_menu.dart | 133 +++++++------- .../view/wallet_settings_menu.dart | 20 ++- .../wallet_settings/wallet_settings.dart | 2 + .../widget/language_selector_widget.dart | 13 ++ lib/dashboard/drawer/widget/drawer_logo.dart | 25 +++ lib/dashboard/drawer/widget/widget.dart | 1 + 13 files changed, 348 insertions(+), 351 deletions(-) create mode 100644 lib/dashboard/drawer/wallet_settings/wallet_settings.dart create mode 100644 lib/dashboard/drawer/widget/drawer_logo.dart create mode 100644 lib/dashboard/drawer/widget/widget.dart diff --git a/lib/dashboard/drawer/about_altme/about_altme/view/about_altme_menu.dart b/lib/dashboard/drawer/about_altme/about_altme/view/about_altme_menu.dart index 94b6924ab..bceccf02d 100644 --- a/lib/dashboard/drawer/about_altme/about_altme/view/about_altme_menu.dart +++ b/lib/dashboard/drawer/about_altme/about_altme/view/about_altme_menu.dart @@ -34,100 +34,85 @@ class AboutAltmeView extends StatelessWidget { final profileModel = context.read().state.model; final profileSetting = profileModel.profileSetting; - return Drawer( + return BasePage( backgroundColor: Theme.of(context).colorScheme.drawerBackground, - child: SafeArea( - child: SingleChildScrollView( - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 15), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - BackLeadingButton( - padding: EdgeInsets.zero, - color: Theme.of(context).colorScheme.onPrimary, - ), - WalletLogo( - profileModel: profileModel, - height: 90, - width: MediaQuery.of(context).size.shortestSide * 0.5, - showPoweredBy: true, - ), - const SizedBox(height: Sizes.spaceSmall), - const AppVersionDrawer(), - if (profileModel.profileType == ProfileType.enterprise) ...[ - const SizedBox(height: Sizes.spaceLarge), - Padding( - padding: const EdgeInsets.symmetric( - horizontal: Sizes.spaceXSmall, - ), - child: Text( - profileSetting.generalOptions.companyName, - style: Theme.of(context) - .textTheme - .drawerItemTitle - .copyWith( - fontSize: 18, - ), - ), - ), - const SizedBox(height: Sizes.spaceXSmall), - EnterpriseData( - title: l10n.profileName, - value: profileSetting.generalOptions.profileName, - ), - // EnterpriseData( - // title: l10n.companyName, - // value: profileSetting.generalOptions.companyName, - // ), - EnterpriseData( - title: l10n.configFileIdentifier, - value: profileSetting.generalOptions.profileId, - ), - const SizedBox(height: Sizes.spaceSmall), - Padding( - padding: const EdgeInsets.symmetric( - horizontal: Sizes.spaceXSmall, + useSafeArea: true, + scrollView: true, + titleAlignment: Alignment.topCenter, + padding: const EdgeInsets.symmetric(horizontal: Sizes.spaceSmall), + body: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + BackLeadingButton( + padding: EdgeInsets.zero, + color: Theme.of(context).colorScheme.onPrimary, + ), + const DrawerLogo(), + const AppVersionDrawer(), + if (profileModel.profileType == ProfileType.enterprise) ...[ + const SizedBox(height: Sizes.spaceLarge), + Padding( + padding: const EdgeInsets.symmetric( + horizontal: Sizes.spaceXSmall, + ), + child: Text( + profileSetting.generalOptions.companyName, + style: Theme.of(context).textTheme.drawerItemTitle.copyWith( + fontSize: 18, ), - child: Text( - l10n.about, - style: Theme.of(context) - .textTheme - .drawerItemTitle - .copyWith( - fontSize: 18, - ), + ), + ), + const SizedBox(height: Sizes.spaceXSmall), + EnterpriseData( + title: l10n.profileName, + value: profileSetting.generalOptions.profileName, + ), + // EnterpriseData( + // title: l10n.companyName, + // value: profileSetting.generalOptions.companyName, + // ), + EnterpriseData( + title: l10n.configFileIdentifier, + value: profileSetting.generalOptions.profileId, + ), + const SizedBox(height: Sizes.spaceSmall), + Padding( + padding: const EdgeInsets.symmetric( + horizontal: Sizes.spaceXSmall, + ), + child: Text( + l10n.about, + style: Theme.of(context).textTheme.drawerItemTitle.copyWith( + fontSize: 18, ), - ), - ], - const SizedBox(height: Sizes.spaceXSmall), - FutureBuilder( - future: PackageInfo.fromPlatform(), - builder: (_, snapShot) { - var appVersion = '...'; - if (snapShot.connectionState == ConnectionState.done) { - appVersion = snapShot.data?.version ?? '0.1.0'; - } - return DrawerItem( - title: '${l10n.yourAppVersion} : $appVersion', - trailing: const Center(), - ); - }, - ), - DrawerItem( - title: l10n.termsOfUse, - onTap: () => - Navigator.of(context).push(TermsPage.route()), - ), - DrawerItem( - title: l10n.softwareLicenses, - onTap: () => Navigator.of(context) - .push(SoftwareLicensePage.route()), - ), - ], + ), ), + ], + const SizedBox(height: Sizes.spaceXSmall), + FutureBuilder( + future: PackageInfo.fromPlatform(), + builder: (_, snapShot) { + var appVersion = '...'; + if (snapShot.connectionState == ConnectionState.done) { + appVersion = snapShot.data?.version ?? '0.1.0'; + } + return DrawerItem( + title: '${l10n.yourAppVersion} : $appVersion', + trailing: const Center(), + ); + }, + ), + DrawerItem( + title: l10n.termsOfUse, + onTap: () => + Navigator.of(context).push(TermsPage.route()), + ), + DrawerItem( + title: l10n.softwareLicenses, + onTap: () => Navigator.of(context) + .push(SoftwareLicensePage.route()), ), - ), + ], ), ); }, diff --git a/lib/dashboard/drawer/blockchain_settings/blockchain_settings/view/blockchain_settings_menu.dart b/lib/dashboard/drawer/blockchain_settings/blockchain_settings/view/blockchain_settings_menu.dart index bfb6e586a..64f80d6ec 100644 --- a/lib/dashboard/drawer/blockchain_settings/blockchain_settings/view/blockchain_settings_menu.dart +++ b/lib/dashboard/drawer/blockchain_settings/blockchain_settings/view/blockchain_settings_menu.dart @@ -28,58 +28,47 @@ class BlockchainSettingsView extends StatelessWidget { @override Widget build(BuildContext context) { final l10n = context.l10n; - return Drawer( + return BasePage( backgroundColor: Theme.of(context).colorScheme.drawerBackground, - child: SafeArea( - child: SingleChildScrollView( - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 15), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - BackLeadingButton( - padding: EdgeInsets.zero, - color: Theme.of(context).colorScheme.onPrimary, - ), - WalletLogo( - profileModel: context.read().state.model, - height: 90, - width: MediaQuery.of(context).size.shortestSide * 0.5, - showPoweredBy: true, - ), - const SizedBox(height: Sizes.spaceSmall), - DrawerItem( - title: l10n.manageAccounts, - onTap: () { - Navigator.of(context) - .push(ManageAccountsPage.route()); - }, - ), - DrawerItem( - title: l10n.manageConnectedApps, - onTap: () { - Navigator.of(context).push( - ConnectedDappsPage.route( - walletAddress: context - .read() - .state - .currentAccount! - .walletAddress, - ), - ); - }, - ), - DrawerItem( - title: l10n.blockchainNetwork, - onTap: () async { - await Navigator.of(context) - .push(ManageNetworkPage.route()); - }, + useSafeArea: true, + scrollView: true, + titleAlignment: Alignment.topCenter, + padding: const EdgeInsets.symmetric(horizontal: Sizes.spaceSmall), + body: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + BackLeadingButton( + padding: EdgeInsets.zero, + color: Theme.of(context).colorScheme.onPrimary, + ), + const DrawerLogo(), + DrawerItem( + title: l10n.manageAccounts, + onTap: () { + Navigator.of(context).push(ManageAccountsPage.route()); + }, + ), + DrawerItem( + title: l10n.manageConnectedApps, + onTap: () { + Navigator.of(context).push( + ConnectedDappsPage.route( + walletAddress: context + .read() + .state + .currentAccount! + .walletAddress, ), - ], - ), + ); + }, + ), + DrawerItem( + title: l10n.blockchainNetwork, + onTap: () async { + await Navigator.of(context).push(ManageNetworkPage.route()); + }, ), - ), + ], ), ); } diff --git a/lib/dashboard/drawer/drawer.dart b/lib/dashboard/drawer/drawer.dart index 1dc080902..13d3ae83b 100644 --- a/lib/dashboard/drawer/drawer.dart +++ b/lib/dashboard/drawer/drawer.dart @@ -7,3 +7,5 @@ export 'reset_wallet/reset_wallet.dart'; export 'src/src.dart'; export 'ssi/ssi.dart'; export 'wallet_security/wallet_security.dart'; +export 'wallet_settings/wallet_settings.dart'; +export 'widget/widget.dart'; diff --git a/lib/dashboard/drawer/help_center/help_center/view/help_center_menu.dart b/lib/dashboard/drawer/help_center/help_center/view/help_center_menu.dart index ad466f618..17e681773 100644 --- a/lib/dashboard/drawer/help_center/help_center/view/help_center_menu.dart +++ b/lib/dashboard/drawer/help_center/help_center/view/help_center_menu.dart @@ -51,69 +51,59 @@ class HelpCenterView extends StatelessWidget { customChatSupportName = helpCenterOptions.customChatSupportName!; } - return Drawer( + return BasePage( backgroundColor: Theme.of(context).colorScheme.drawerBackground, - child: SafeArea( - child: SingleChildScrollView( - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 15), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - BackLeadingButton( - padding: EdgeInsets.zero, - color: Theme.of(context).colorScheme.onPrimary, - ), - WalletLogo( - profileModel: context.read().state.model, - height: 90, - width: MediaQuery.of(context).size.shortestSide * 0.5, - showPoweredBy: true, - ), - if (helpCenterOptions.displayChatSupport) ...[ - const SizedBox(height: Sizes.spaceSmall), - DrawerItem( - title: '${l10n.chatWith} $customChatSupportName', - onTap: () { - Navigator.of(context).push( - AltmeSupportChatPage.route( - appBarTitle: - '${l10n.chatWith} $customChatSupportName', - ), - ); - }, + useSafeArea: true, + scrollView: true, + titleAlignment: Alignment.topCenter, + padding: const EdgeInsets.symmetric(horizontal: Sizes.spaceSmall), + body: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + BackLeadingButton( + padding: EdgeInsets.zero, + color: Theme.of(context).colorScheme.onPrimary, + ), + const DrawerLogo(), + if (helpCenterOptions.displayChatSupport) ...[ + DrawerItem( + title: '${l10n.chatWith} $customChatSupportName', + onTap: () { + Navigator.of(context).push( + AltmeSupportChatPage.route( + appBarTitle: '${l10n.chatWith} $customChatSupportName', ), - ], - if (helpCenterOptions.displayEmailSupport) ...[ - DrawerItem( - title: l10n.sendAnEmail, - onTap: () { - Navigator.of(context).push( - ContactUsPage.route( - email: email, - ), - ); - }, + ); + }, + ), + ], + if (helpCenterOptions.displayEmailSupport) ...[ + DrawerItem( + title: l10n.sendAnEmail, + onTap: () { + Navigator.of(context).push( + ContactUsPage.route( + email: email, ), - ], - DrawerItem( - title: l10n.faqs, - onTap: () { - Navigator.of(context).push(FAQsPage.route()); - }, - ), - DrawerItem( - onTap: () { - LaunchUrl.launch( - 'https://${AltMeStrings.appContactWebsiteName}', - ); - }, - title: l10n.officialWebsite, - ), - ], + ); + }, ), + ], + DrawerItem( + title: l10n.faqs, + onTap: () { + Navigator.of(context).push(FAQsPage.route()); + }, + ), + DrawerItem( + onTap: () { + LaunchUrl.launch( + 'https://${AltMeStrings.appContactWebsiteName}', + ); + }, + title: l10n.officialWebsite, ), - ), + ], ), ); } diff --git a/lib/dashboard/drawer/profile/view/pick_profile_menu.dart b/lib/dashboard/drawer/profile/view/pick_profile_menu.dart index 31b21f654..4488347c9 100644 --- a/lib/dashboard/drawer/profile/view/pick_profile_menu.dart +++ b/lib/dashboard/drawer/profile/view/pick_profile_menu.dart @@ -1,6 +1,8 @@ import 'package:altme/app/app.dart'; +import 'package:altme/dashboard/dashboard.dart'; import 'package:altme/dashboard/drawer/profile/widget/profile_selector_widget.dart'; -import 'package:altme/l10n/l10n.dart'; + +import 'package:altme/theme/theme.dart'; import 'package:flutter/material.dart'; class PickProfileMenu extends StatelessWidget { @@ -24,15 +26,23 @@ class PickProfileMenuView extends StatelessWidget { @override Widget build(BuildContext context) { - final l10n = context.l10n; return BasePage( - title: l10n.walletProfiles, + backgroundColor: Theme.of(context).colorScheme.drawerBackground, useSafeArea: true, scrollView: true, titleAlignment: Alignment.topCenter, padding: const EdgeInsets.symmetric(horizontal: Sizes.spaceSmall), - titleLeading: const BackLeadingButton(), - body: const ProfileSelectorWidget(), + body: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + BackLeadingButton( + padding: EdgeInsets.zero, + color: Theme.of(context).colorScheme.onPrimary, + ), + const DrawerLogo(), + const ProfileSelectorWidget(), + ], + ), ); } } diff --git a/lib/dashboard/drawer/src/view/drawer_page.dart b/lib/dashboard/drawer/src/view/drawer_page.dart index eab2a5854..b2f1b8db2 100644 --- a/lib/dashboard/drawer/src/view/drawer_page.dart +++ b/lib/dashboard/drawer/src/view/drawer_page.dart @@ -44,14 +44,7 @@ class DrawerView extends StatelessWidget { ), ), - WalletLogo( - profileModel: profileModel, - height: 90, - width: MediaQuery.of(context).size.shortestSide * 0.5, - showPoweredBy: true, - ), - - const SizedBox(height: Sizes.spaceSmall), + const DrawerLogo(), const AppVersionDrawer(), const SizedBox(height: Sizes.spaceLarge), if (profileModel.profileType == ProfileType.enterprise) ...[ diff --git a/lib/dashboard/drawer/ssi/src/view/ssi_menu.dart b/lib/dashboard/drawer/ssi/src/view/ssi_menu.dart index dcacde0fd..7766cc1f1 100644 --- a/lib/dashboard/drawer/ssi/src/view/ssi_menu.dart +++ b/lib/dashboard/drawer/ssi/src/view/ssi_menu.dart @@ -36,74 +36,62 @@ class SSIView extends StatelessWidget { .profileSetting .selfSovereignIdentityOptions .displayManageDecentralizedId; - return Drawer( + return BasePage( backgroundColor: Theme.of(context).colorScheme.drawerBackground, - child: SafeArea( - child: SingleChildScrollView( - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 15), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - BackLeadingButton( - padding: EdgeInsets.zero, - color: Theme.of(context).colorScheme.onPrimary, - ), - WalletLogo( - profileModel: context.read().state.model, - height: 90, - width: MediaQuery.of(context).size.shortestSide * 0.5, - showPoweredBy: true, - ), - const SizedBox( - height: Sizes.spaceSmall, - ), - if (displayManageDecentralizedId) - DrawerItem( - title: l10n.manageDecentralizedID, - onTap: () { - Navigator.of(context).push(DidMenu.route()); - }, - ), - DrawerItem( - title: l10n.backup, - onTap: () async { - await Navigator.of(context).push(BackupMenu.route()); - }, - ), - DrawerItem( - title: l10n.restore, - onTap: () async { - await Navigator.of(context).push(RestoreMenu.route()); - }, - ), - DrawerItem( - title: l10n.searchCredentials, - onTap: () { - Navigator.of(context).push(SearchPage.route()); - }, - ), - if (context.read().state.model.profileType == - ProfileType.custom) ...[ - DrawerItem( - title: l10n.oidc4vc_settings, - onTap: () { - Navigator.of(context) - .push(Oidc4vcSettingMenu.route()); - }, - ), - DrawerItem( - title: l10n.trustFramework, - onTap: () async { - await Navigator.of(context) - .push(TrustFrameworkPage.route()); - }, - ), - ], - ], + useSafeArea: true, + scrollView: true, + titleAlignment: Alignment.topCenter, + padding: const EdgeInsets.symmetric(horizontal: Sizes.spaceSmall), + body: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + BackLeadingButton( + padding: EdgeInsets.zero, + color: Theme.of(context).colorScheme.onPrimary, + ), + const DrawerLogo(), + if (displayManageDecentralizedId) + DrawerItem( + title: l10n.manageDecentralizedID, + onTap: () { + Navigator.of(context).push(DidMenu.route()); + }, ), + DrawerItem( + title: l10n.backup, + onTap: () async { + await Navigator.of(context).push(BackupMenu.route()); + }, + ), + DrawerItem( + title: l10n.restore, + onTap: () async { + await Navigator.of(context).push(RestoreMenu.route()); + }, + ), + DrawerItem( + title: l10n.searchCredentials, + onTap: () { + Navigator.of(context).push(SearchPage.route()); + }, ), - ), + if (context.read().state.model.profileType == + ProfileType.custom) ...[ + DrawerItem( + title: l10n.oidc4vc_settings, + onTap: () { + Navigator.of(context).push(Oidc4vcSettingMenu.route()); + }, + ), + DrawerItem( + title: l10n.trustFramework, + onTap: () async { + await Navigator.of(context) + .push(TrustFrameworkPage.route()); + }, + ), + ], + ], ), ); } diff --git a/lib/dashboard/drawer/wallet_security/src/view/wallet_security_menu.dart b/lib/dashboard/drawer/wallet_security/src/view/wallet_security_menu.dart index fc35a6fb7..da236fc3e 100644 --- a/lib/dashboard/drawer/wallet_security/src/view/wallet_security_menu.dart +++ b/lib/dashboard/drawer/wallet_security/src/view/wallet_security_menu.dart @@ -31,81 +31,72 @@ class WalletSecurityView extends StatelessWidget { final l10n = context.l10n; return BlocBuilder( builder: (context, state) { - return Drawer( + return BasePage( backgroundColor: Theme.of(context).colorScheme.drawerBackground, - child: SafeArea( - child: SingleChildScrollView( - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 15), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - BackLeadingButton( - padding: EdgeInsets.zero, - color: Theme.of(context).colorScheme.onPrimary, - ), - WalletLogo( - profileModel: context.read().state.model, - height: 90, - width: MediaQuery.of(context).size.shortestSide * 0.5, - showPoweredBy: true, - ), - const SizedBox(height: Sizes.spaceSmall), - DrawerItem( - title: l10n.protectYourWallet, - subtitle: l10n.secureYourWalletWithPINCodeAndBiometrics, - onTap: () async { - await securityCheck( - context: context, - localAuthApi: LocalAuthApi(), - onSuccess: () { - Navigator.of(context) - .push(ProtectWalletPage.route()); - }, - ); - }, - ), - DrawerItem( - title: l10n.showWalletRecoveryPhrase, - subtitle: l10n.showWalletRecoveryPhraseSubtitle, - onTap: () async { - final confirm = await showDialog( - context: context, - builder: (context) => ConfirmDialog( - title: l10n.warningDialogTitle, - subtitle: l10n.warningDialogSubtitle, - yes: l10n.showDialogYes, - no: l10n.showDialogNo, - ), - ) ?? - false; + useSafeArea: true, + scrollView: true, + titleAlignment: Alignment.topCenter, + padding: const EdgeInsets.symmetric(horizontal: Sizes.spaceSmall), + body: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + BackLeadingButton( + padding: EdgeInsets.zero, + color: Theme.of(context).colorScheme.onPrimary, + ), + const DrawerLogo(), + DrawerItem( + title: l10n.protectYourWallet, + subtitle: l10n.secureYourWalletWithPINCodeAndBiometrics, + onTap: () async { + await securityCheck( + context: context, + localAuthApi: LocalAuthApi(), + onSuccess: () { + Navigator.of(context) + .push(ProtectWalletPage.route()); + }, + ); + }, + ), + DrawerItem( + title: l10n.showWalletRecoveryPhrase, + subtitle: l10n.showWalletRecoveryPhraseSubtitle, + onTap: () async { + final confirm = await showDialog( + context: context, + builder: (context) => ConfirmDialog( + title: l10n.warningDialogTitle, + subtitle: l10n.warningDialogSubtitle, + yes: l10n.showDialogYes, + no: l10n.showDialogNo, + ), + ) ?? + false; - if (confirm) { - await securityCheck( - context: context, - localAuthApi: LocalAuthApi(), - onSuccess: () { - Navigator.of(context) - .push(RecoveryKeyPage.route()); - }, - ); - } + if (confirm) { + await securityCheck( + context: context, + localAuthApi: LocalAuthApi(), + onSuccess: () { + Navigator.of(context) + .push(RecoveryKeyPage.route()); }, - ), - if (context.read().state.model.profileType == - ProfileType.custom) - DrawerItem( - title: l10n.advancedSecuritySettings, - onTap: () { - Navigator.of(context).push( - AdvancedSecuritySettingsMenu.route(), - ); - }, - ), - ], - ), + ); + } + }, ), - ), + if (context.read().state.model.profileType == + ProfileType.custom) + DrawerItem( + title: l10n.advancedSecuritySettings, + onTap: () { + Navigator.of(context).push( + AdvancedSecuritySettingsMenu.route(), + ); + }, + ), + ], ), ); }, diff --git a/lib/dashboard/drawer/wallet_settings/view/wallet_settings_menu.dart b/lib/dashboard/drawer/wallet_settings/view/wallet_settings_menu.dart index 97d2ae4e7..5bcd9834a 100644 --- a/lib/dashboard/drawer/wallet_settings/view/wallet_settings_menu.dart +++ b/lib/dashboard/drawer/wallet_settings/view/wallet_settings_menu.dart @@ -1,6 +1,6 @@ import 'package:altme/app/app.dart'; -import 'package:altme/dashboard/drawer/wallet_settings/widget/language_selector_widget.dart'; -import 'package:altme/l10n/l10n.dart'; +import 'package:altme/dashboard/dashboard.dart'; +import 'package:altme/theme/theme.dart'; import 'package:flutter/material.dart'; class WalletSettingsMenu extends StatelessWidget { @@ -24,15 +24,23 @@ class WalletSettingsMenuView extends StatelessWidget { @override Widget build(BuildContext context) { - final l10n = context.l10n; return BasePage( - title: l10n.languageSelectorTitle, + backgroundColor: Theme.of(context).colorScheme.drawerBackground, useSafeArea: true, scrollView: true, titleAlignment: Alignment.topCenter, padding: const EdgeInsets.symmetric(horizontal: Sizes.spaceSmall), - titleLeading: const BackLeadingButton(), - body: const LanguageSelectorWidget(), + body: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + BackLeadingButton( + padding: EdgeInsets.zero, + color: Theme.of(context).colorScheme.onPrimary, + ), + const DrawerLogo(), + const LanguageSelectorWidget(), + ], + ), ); } } diff --git a/lib/dashboard/drawer/wallet_settings/wallet_settings.dart b/lib/dashboard/drawer/wallet_settings/wallet_settings.dart new file mode 100644 index 000000000..3cdec482d --- /dev/null +++ b/lib/dashboard/drawer/wallet_settings/wallet_settings.dart @@ -0,0 +1,2 @@ +export 'view/wallet_settings_menu.dart'; +export 'widget/language_selector_widget.dart'; diff --git a/lib/dashboard/drawer/wallet_settings/widget/language_selector_widget.dart b/lib/dashboard/drawer/wallet_settings/widget/language_selector_widget.dart index e8a11a340..f4048b3a2 100644 --- a/lib/dashboard/drawer/wallet_settings/widget/language_selector_widget.dart +++ b/lib/dashboard/drawer/wallet_settings/widget/language_selector_widget.dart @@ -31,6 +31,19 @@ class LanguageSelectorWidget extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ + const SizedBox(height: 10), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 10), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + l10n.walletSettingsDescription, + style: Theme.of(context).textTheme.drawerItemSubtitle, + ), + ], + ), + ), const SizedBox(height: 10), ListView.builder( itemCount: LanguageType.values.length, diff --git a/lib/dashboard/drawer/widget/drawer_logo.dart b/lib/dashboard/drawer/widget/drawer_logo.dart new file mode 100644 index 000000000..b6acab6a9 --- /dev/null +++ b/lib/dashboard/drawer/widget/drawer_logo.dart @@ -0,0 +1,25 @@ +import 'package:altme/app/app.dart'; +import 'package:altme/dashboard/dashboard.dart'; + +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +class DrawerLogo extends StatelessWidget { + const DrawerLogo({super.key}); + + @override + Widget build(BuildContext context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + WalletLogo( + profileModel: context.read().state.model, + height: 90, + width: MediaQuery.of(context).size.shortestSide * 0.5, + showPoweredBy: true, + ), + const SizedBox(height: Sizes.spaceSmall), + ], + ); + } +} diff --git a/lib/dashboard/drawer/widget/widget.dart b/lib/dashboard/drawer/widget/widget.dart new file mode 100644 index 000000000..ad2271eae --- /dev/null +++ b/lib/dashboard/drawer/widget/widget.dart @@ -0,0 +1 @@ +export 'drawer_logo.dart'; From 212df93805bd09e8fca5caed80edccb4cba37a8c Mon Sep 17 00:00:00 2001 From: Bibash Shrestha Date: Tue, 5 Mar 2024 15:48:29 +0545 Subject: [PATCH 41/45] feat: Remove unncecesary developer data in authorization code flow #2462 --- .../helper_functions/helper_functions.dart | 14 ------ lib/splash/bloclisteners/blocklisteners.dart | 46 ------------------- 2 files changed, 60 deletions(-) diff --git a/lib/app/shared/helper_functions/helper_functions.dart b/lib/app/shared/helper_functions/helper_functions.dart index 852530946..4fee4c19b 100644 --- a/lib/app/shared/helper_functions/helper_functions.dart +++ b/lib/app/shared/helper_functions/helper_functions.dart @@ -1161,20 +1161,6 @@ ${openIdConfiguration != null ? const JsonEncoder.withIndent(' ').convert(openI '''; } -String getFormattedStringOIDC4VCIAuthorizedCodeFlow({ - required String url, - Map? statePayload, - dynamic codeForAuthorisedFlow, -}) { - return ''' -SCHEME : ${getSchemeFromUrl(url)}\n -STATE : -${statePayload != null ? const JsonEncoder.withIndent(' ').convert(statePayload) : 'None'}\n -CODE : -$codeForAuthorisedFlow -'''; -} - String getFormattedStringResponse({ required Map? tokenData, required List? credentialData, diff --git a/lib/splash/bloclisteners/blocklisteners.dart b/lib/splash/bloclisteners/blocklisteners.dart index 02a8c9753..7236ad022 100644 --- a/lib/splash/bloclisteners/blocklisteners.dart +++ b/lib/splash/bloclisteners/blocklisteners.dart @@ -490,52 +490,6 @@ final qrCodeBlocListener = BlocListener( final statePayload = jwt.payload as Map; - /// if dev mode is ON show some dialog to show data - if (profileCubit.state.model.isDeveloperMode) { - final String formattedData = - getFormattedStringOIDC4VCIAuthorizedCodeFlow( - url: state.uri.toString(), - codeForAuthorisedFlow: codeForAuthorisedFlow, - statePayload: statePayload, - ); - - LoadingView().hide(); - final bool moveAhead = await showDialog( - context: context, - builder: (_) { - return DeveloperModeDialog( - onDisplay: () async { - Navigator.of(context).pop(false); - await Navigator.of(context).push( - JsonViewerPage.route( - title: l10n.display, - data: formattedData, - ), - ); - return; - }, - onDownload: () { - Navigator.of(context).pop(false); - - final box = context.findRenderObject() as RenderBox?; - final subject = l10n.shareWith; - - Share.share( - formattedData, - subject: subject, - sharePositionOrigin: - box!.localToGlobal(Offset.zero) & box.size, - ); - }, - onSkip: () { - Navigator.of(context).pop(true); - }, - ); - }, - ) ?? - true; - if (!moveAhead) return; - } await context.read().authorizedFlowCompletion( statePayload: statePayload, codeForAuthorisedFlow: codeForAuthorisedFlow, From d412f62f100250d24dfb595e3870ed4ab679f842 Mon Sep 17 00:00:00 2001 From: Bibash Shrestha Date: Tue, 5 Mar 2024 17:59:24 +0545 Subject: [PATCH 42/45] feat: Handle token and credential independently to show data in developer mode #2473 --- .../helper_functions/helper_functions.dart | 10 +- .../cubit/qr_code_scan_cubit.dart | 95 +++++++++-- lib/oidc4vc/add_credential_data.dart | 1 - lib/oidc4vc/get_credential.dart | 30 +--- packages/oidc4vc/lib/src/oidc4vc.dart | 156 +++++++++--------- 5 files changed, 176 insertions(+), 116 deletions(-) diff --git a/lib/app/shared/helper_functions/helper_functions.dart b/lib/app/shared/helper_functions/helper_functions.dart index 4fee4c19b..f04957af4 100644 --- a/lib/app/shared/helper_functions/helper_functions.dart +++ b/lib/app/shared/helper_functions/helper_functions.dart @@ -1161,13 +1161,19 @@ ${openIdConfiguration != null ? const JsonEncoder.withIndent(' ').convert(openI '''; } -String getFormattedStringResponse({ +String getFormattedTokenResponse({ required Map? tokenData, - required List? credentialData, }) { return ''' TOKEN RESPONSE : ${tokenData != null ? const JsonEncoder.withIndent(' ').convert(tokenData) : 'None'}\n +'''; +} + +String getFormattedCredentialResponse({ + required List? credentialData, +}) { + return ''' CREDENTIAL RESPONSE : ${credentialData != null ? const JsonEncoder.withIndent(' ').convert(credentialData) : 'None'}\n '''; diff --git a/lib/dashboard/qr_code/qr_code_scan/cubit/qr_code_scan_cubit.dart b/lib/dashboard/qr_code/qr_code_scan/cubit/qr_code_scan_cubit.dart index c44679af8..da1862a45 100644 --- a/lib/dashboard/qr_code/qr_code_scan/cubit/qr_code_scan_cubit.dart +++ b/lib/dashboard/qr_code/qr_code_scan/cubit/qr_code_scan_cubit.dart @@ -1194,6 +1194,9 @@ class QRCodeScanCubit extends Cubit { } } + String? savedNonce; + String? savedAccessToken; + List? savedAuthorizationDetails; Completer? completer; Future addCredentialsInLoop({ @@ -1224,37 +1227,93 @@ class QRCodeScanCubit extends Cubit { /// preAuthorizedCode != null /// this is full phase flow for preAuthorizedCode + /// get openid configuration + final openIdConfiguration = await oidc4vc.getOpenIdConfig( + baseUrl: issuer, + isAuthorizationServer: false, + oidc4vciDraftType: customOidc4vcProfile.oidc4vciDraft, + ); + + if (savedAccessToken == null) { + /// get token response + final ( + Map? tokenResponse, + String? accessToken, + String? cnonce, + List? authorizationDetails, + ) = await oidc4vc.getTokenResponse( + preAuthorizedCode: preAuthorizedCode, + issuer: issuer, + clientId: clientId, + clientSecret: clientSecret, + userPin: userPin, + code: codeForAuthorisedFlow, + codeVerifier: codeVerifier, + authorization: authorization, + oidc4vciDraftType: customOidc4vcProfile.oidc4vciDraft, + redirectUri: Parameters.oidc4vcUniversalLink, + openIdConfiguration: openIdConfiguration, + ); + + savedAccessToken = accessToken; + savedNonce = cnonce; + savedAuthorizationDetails = authorizationDetails; + + if (profileCubit.state.model.isDeveloperMode) { + completer = Completer(); + + final formattedData = + getFormattedTokenResponse(tokenData: tokenResponse); + emit( + state.copyWith( + qrScanStatus: QrScanStatus.pauseForDialog, + dialogData: formattedData, + ), + ); + + final value = await completer!.future; + + if (value) { + completer = null; + } else { + completer = null; + resetNonceAndAccessTokenAndAuthorizationDetails(); + goBack(); + return; + } + } + } + + if (savedAccessToken == null || savedNonce == null) { + throw Exception(); + } + /// get credentials final ( List encodedCredentialOrFutureTokens, String? deferredCredentialEndpoint, String format, - OpenIdConfiguration? openIdConfiguration, - Map? tokenResponse, ) = await getCredential( oidc4vc: oidc4vc, isEBSIV3: isEBSIV3, didKitProvider: didKitProvider, credential: selectedCredentials[i], - userPin: userPin, issuer: issuer, - preAuthorizedCode: preAuthorizedCode, - codeForAuthorisedFlow: codeForAuthorisedFlow, - codeVerifier: codeVerifier, cryptoHolderBinding: customOidc4vcProfile.cryptoHolderBinding, - authorization: authorization, oidc4vciDraftType: customOidc4vcProfile.oidc4vciDraft, didKeyType: customOidc4vcProfile.defaultDid, clientId: clientId, - clientSecret: clientSecret, profileCubit: profileCubit, + accessToken: savedAccessToken!, + nonce: savedNonce!, + authorizationDetails: savedAuthorizationDetails, + openIdConfiguration: openIdConfiguration, ); if (profileCubit.state.model.isDeveloperMode) { completer = Completer(); - final formattedData = getFormattedStringResponse( - tokenData: tokenResponse, + final formattedData = getFormattedCredentialResponse( credentialData: encodedCredentialOrFutureTokens, ); emit( @@ -1270,12 +1329,13 @@ class QRCodeScanCubit extends Cubit { completer = null; } else { completer = null; - oidc4vc.resetNonceAndAccessTokenAndAuthorizationDetails(); + resetNonceAndAccessTokenAndAuthorizationDetails(); goBack(); return; } } + /// add credentials await addCredentialData( scannedResponse: state.uri.toString(), credentialsCubit: credentialsCubit, @@ -1290,23 +1350,26 @@ class QRCodeScanCubit extends Cubit { encodedCredentialOrFutureTokens: encodedCredentialOrFutureTokens, format: format, openIdConfiguration: openIdConfiguration, - tokenResponse: tokenResponse, ); - - /// add credentials } else { throw Exception(); } } - oidc4vc.resetNonceAndAccessTokenAndAuthorizationDetails(); + resetNonceAndAccessTokenAndAuthorizationDetails(); goBack(); } catch (e) { - oidc4vc.resetNonceAndAccessTokenAndAuthorizationDetails(); + resetNonceAndAccessTokenAndAuthorizationDetails(); emitError(e); } } + void resetNonceAndAccessTokenAndAuthorizationDetails() { + savedAccessToken = null; + savedNonce = null; + savedAuthorizationDetails = null; + } + void goBack() { emit(state.copyWith(qrScanStatus: QrScanStatus.goBack)); } diff --git a/lib/oidc4vc/add_credential_data.dart b/lib/oidc4vc/add_credential_data.dart index 8970bca09..3b6dffa61 100644 --- a/lib/oidc4vc/add_credential_data.dart +++ b/lib/oidc4vc/add_credential_data.dart @@ -13,7 +13,6 @@ Future addCredentialData({ required String? deferredCredentialEndpoint, required String format, required OpenIdConfiguration? openIdConfiguration, - required Map? tokenResponse, required SecureStorageProvider secureStorageProvider, required ProfileCubit profileCubit, required CredentialsCubit credentialsCubit, diff --git a/lib/oidc4vc/get_credential.dart b/lib/oidc4vc/get_credential.dart index a2fd08026..339455256 100644 --- a/lib/oidc4vc/get_credential.dart +++ b/lib/oidc4vc/get_credential.dart @@ -15,25 +15,21 @@ Future< List, String?, String, - OpenIdConfiguration?, - Map? )> getCredential({ required OIDC4VC oidc4vc, required bool isEBSIV3, required DIDKitProvider didKitProvider, required dynamic credential, required ProfileCubit profileCubit, - required String? userPin, - required String? preAuthorizedCode, required String issuer, - required String? codeForAuthorisedFlow, - required String? codeVerifier, required bool cryptoHolderBinding, - required String? authorization, required OIDC4VCIDraftType oidc4vciDraftType, required DidKeyType didKeyType, required String? clientId, - required String? clientSecret, + required String accessToken, + required String nonce, + required OpenIdConfiguration openIdConfiguration, + required List? authorizationDetails, }) async { final privateKey = await fetchPrivateKey( isEBSIV3: isEBSIV3, @@ -53,8 +49,6 @@ Future< final customOidc4vcProfile = profileCubit.state.model.profileSetting .selfSovereignIdentityOptions.customOidc4vcProfile; - final index = getIndexValue(isEBSIV3: isEBSIV3, didKeyType: didKeyType); - var iss = ''; switch (customOidc4vcProfile.clientType) { @@ -79,37 +73,29 @@ Future< List encodedCredentialOrFutureTokens, String? deferredCredentialEndpoint, String format, - OpenIdConfiguration? openIdConfiguration, - Map? tokenResponse, ) = await oidc4vc.getCredential( - preAuthorizedCode: preAuthorizedCode, issuer: issuer, credential: credential, did: did, kid: kid, clientId: clientId, - clientSecret: clientSecret, privateKey: privateKey, - indexValue: index, - userPin: userPin, - code: codeForAuthorisedFlow, - codeVerifier: codeVerifier, cryptoHolderBinding: cryptoHolderBinding, - authorization: authorization, oidc4vciDraftType: oidc4vciDraftType, clientType: customOidc4vcProfile.clientType, proofHeaderType: customOidc4vcProfile.proofHeader, clientAuthentication: customOidc4vcProfile.clientAuthentication, - redirectUri: Parameters.oidc4vcUniversalLink, proofType: customOidc4vcProfile.proofType, iss: iss, + accessToken: accessToken, + cnonce: nonce, + authorizationDetails: authorizationDetails, + openIdConfiguration: openIdConfiguration, ); return ( encodedCredentialOrFutureTokens, deferredCredentialEndpoint, format, - openIdConfiguration, - tokenResponse, ); } diff --git a/packages/oidc4vc/lib/src/oidc4vc.dart b/packages/oidc4vc/lib/src/oidc4vc.dart index 046586d68..8bb14d861 100644 --- a/packages/oidc4vc/lib/src/oidc4vc.dart +++ b/packages/oidc4vc/lib/src/oidc4vc.dart @@ -382,84 +382,32 @@ class OIDC4VC { }); } - String? cnonce; - String? accessToken; - List? authorizationDetails; - /// Retreive credential_type from url /// credentialResponseData, deferredCredentialEndpoint, format, - /// openIdConfiguration, tokenResponse Future< ( List, String?, String, - OpenIdConfiguration?, - Map? )> getCredential({ required String issuer, required dynamic credential, required String did, required String? clientId, - required String? clientSecret, required String kid, - required int indexValue, required String privateKey, required bool cryptoHolderBinding, required ClientType clientType, required ProofHeaderType proofHeaderType, required OIDC4VCIDraftType oidc4vciDraftType, required ClientAuthentication clientAuthentication, - required String redirectUri, required ProofType proofType, required String iss, - String? preAuthorizedCode, - String? userPin, - String? code, - String? codeVerifier, - String? authorization, + required OpenIdConfiguration openIdConfiguration, + required String accessToken, + required String cnonce, + List? authorizationDetails, }) async { - final openIdConfiguration = await getOpenIdConfig( - baseUrl: issuer, - isAuthorizationServer: false, - oidc4vciDraftType: oidc4vciDraftType, - ); - - final tokenEndPoint = await readTokenEndPoint( - openIdConfiguration: openIdConfiguration, - issuer: issuer, - oidc4vciDraftType: oidc4vciDraftType, - ); - - Map? tokenResponse; - - if (accessToken == null) { - final tokenData = buildTokenData( - preAuthorizedCode: preAuthorizedCode, - userPin: userPin, - code: code, - codeVerifier: codeVerifier, - clientId: clientId, - clientSecret: clientSecret, - authorization: authorization, - redirectUri: redirectUri, - ); - - tokenResponse = await getToken( - tokenEndPoint: tokenEndPoint, - tokenData: tokenData, - authorization: authorization, - ); - - if (tokenResponse.containsKey('c_nonce')) { - cnonce = tokenResponse['c_nonce'] as String; - } - - accessToken = tokenResponse['access_token'] as String; - authorizationDetails = - tokenResponse['authorization_details'] as List?; - } - final issuerTokenParameters = IssuerTokenParameters( privateKey: jsonDecode(privateKey) as Map, did: did, @@ -506,8 +454,11 @@ class OIDC4VC { .map((dynamic element) => element.toString()) .toList(); + var nonce = cnonce; + for (final credentialIdentifier in credentialIdentifiers) { - final credentialResponseDataValue = await getSingleCredential( + final (credentialResponseDataValue, updateNonce) = + await getSingleCredential( issuerTokenParameters: issuerTokenParameters, openIdConfiguration: openIdConfiguration, credentialType: credentialType, @@ -525,13 +476,18 @@ class OIDC4VC { kid: kid, privateKey: privateKey, iss: iss, + accessToken: accessToken, + nonce: nonce, ); + /// update nonce value + nonce = updateNonce; + credentialResponseData.add(credentialResponseDataValue); } // } else { - final credentialResponseDataValue = await getSingleCredential( + final (credentialResponseDataValue, _) = await getSingleCredential( issuerTokenParameters: issuerTokenParameters, openIdConfiguration: openIdConfiguration, credentialType: credentialType, @@ -549,6 +505,8 @@ class OIDC4VC { kid: kid, privateKey: privateKey, iss: iss, + accessToken: accessToken, + nonce: cnonce, ); credentialResponseData.add(credentialResponseDataValue); @@ -558,12 +516,64 @@ class OIDC4VC { credentialResponseData, deferredCredentialEndpoint, format, - openIdConfiguration, - tokenResponse, ); } - Future getSingleCredential({ + /// tokenResponse, accessToken, cnonce, authorizationDetails + Future<(Map?, String?, String?, List?)> + getTokenResponse({ + required String issuer, + required String? clientId, + required String? clientSecret, + required OIDC4VCIDraftType oidc4vciDraftType, + required String redirectUri, + required OpenIdConfiguration openIdConfiguration, + String? preAuthorizedCode, + String? userPin, + String? code, + String? codeVerifier, + String? authorization, + }) async { + final tokenEndPoint = await readTokenEndPoint( + openIdConfiguration: openIdConfiguration, + issuer: issuer, + oidc4vciDraftType: oidc4vciDraftType, + ); + + Map? tokenResponse; + String? accessToken; + String? cnonce; + List? authorizationDetails; + + final tokenData = buildTokenData( + preAuthorizedCode: preAuthorizedCode, + userPin: userPin, + code: code, + codeVerifier: codeVerifier, + clientId: clientId, + clientSecret: clientSecret, + authorization: authorization, + redirectUri: redirectUri, + ); + + tokenResponse = await getToken( + tokenEndPoint: tokenEndPoint, + tokenData: tokenData, + authorization: authorization, + ); + + if (tokenResponse.containsKey('c_nonce')) { + cnonce = tokenResponse['c_nonce'] as String; + } + + accessToken = tokenResponse['access_token'] as String; + authorizationDetails = + tokenResponse['authorization_details'] as List?; + + return (tokenResponse, accessToken, cnonce, authorizationDetails); + } + + Future<(dynamic, String)> getSingleCredential({ required IssuerTokenParameters issuerTokenParameters, required OpenIdConfiguration openIdConfiguration, required String credentialType, @@ -581,9 +591,11 @@ class OIDC4VC { required String kid, required String privateKey, required String iss, + required String accessToken, + required String nonce, }) async { final credentialData = await buildCredentialData( - cnonce: cnonce, + nonce: nonce, issuerTokenParameters: issuerTokenParameters, openIdConfiguration: openIdConfiguration, credentialType: credentialType, @@ -607,8 +619,6 @@ class OIDC4VC { final credentialEndpoint = readCredentialEndpoint(openIdConfiguration); - if (accessToken == null) throw Exception(); - final credentialHeaders = { 'Content-Type': 'application/json', 'Authorization': 'Bearer $accessToken', @@ -622,12 +632,14 @@ class OIDC4VC { final credentialResponseData = credentialResponse.data; + var cnonce = nonce; + if (credentialResponseData is Map && credentialResponseData.containsKey('c_nonce')) { cnonce = credentialResponseData['c_nonce'].toString(); } - return credentialResponseData; + return (credentialResponseData, cnonce); } /// get Deferred credential from url @@ -648,12 +660,6 @@ class OIDC4VC { return credentialResponse.data; } - void resetNonceAndAccessTokenAndAuthorizationDetails() { - cnonce = null; - accessToken = null; - authorizationDetails = null; - } - Map buildTokenData({ required String redirectUri, String? preAuthorizedCode, @@ -858,7 +864,7 @@ class OIDC4VC { required OIDC4VCIDraftType oidc4vciDraftType, required ClientAuthentication clientAuthentication, required String? credentialIdentifier, - required String? cnonce, + required String? nonce, required String? vct, required Map? credentialDefinition, required ProofType proofType, @@ -879,8 +885,8 @@ class OIDC4VC { 'domain': issuer, }; - if (cnonce != null) { - options['challenge'] = cnonce; + if (nonce != null) { + options['challenge'] = nonce; } final didKitProvider = DIDKitProvider(); @@ -901,7 +907,7 @@ class OIDC4VC { tokenParameters: issuerTokenParameters, clientAuthentication: clientAuthentication, oidc4vciDraftType: oidc4vciDraftType, - cnonce: cnonce, + cnonce: nonce, iss: iss, ); From 4f5111d204c4fc23e43cab9d8fd9dc432f48af13 Mon Sep 17 00:00:00 2001 From: Bibash Shrestha Date: Tue, 5 Mar 2024 18:19:54 +0545 Subject: [PATCH 43/45] remove unnecessary code --- lib/enterprise/cubit/enterprise_cubit.dart | 5 ----- 1 file changed, 5 deletions(-) diff --git a/lib/enterprise/cubit/enterprise_cubit.dart b/lib/enterprise/cubit/enterprise_cubit.dart index 1ee9e24db..6c90b49fa 100644 --- a/lib/enterprise/cubit/enterprise_cubit.dart +++ b/lib/enterprise/cubit/enterprise_cubit.dart @@ -95,11 +95,6 @@ class EnterpriseCubit extends Cubit { walletType: WalletType.enterprise, ); - /// load credentials - await walletCubit.credentialsCubit.loadAllCredentials( - blockchainType: walletCubit.state.currentAccount!.blockchainType, - ); - // if enterprise and walletAttestation data is available and added await walletCubit.credentialsCubit.addWalletCredential( blockchainType: walletCubit.state.currentAccount?.blockchainType, From 644af72874bac9853057f1b0c02a6920afeff35a Mon Sep 17 00:00:00 2001 From: Bibash Shrestha Date: Tue, 5 Mar 2024 18:21:12 +0545 Subject: [PATCH 44/45] small fix --- lib/app/view/app.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/app/view/app.dart b/lib/app/view/app.dart index 3bcc22f42..dba31a254 100644 --- a/lib/app/view/app.dart +++ b/lib/app/view/app.dart @@ -264,7 +264,7 @@ class MaterialAppDefinition extends StatelessWidget { context.read().setLocale(locale); } } - if (state == const Locale('en')) { + if (state.locale == const Locale('en')) { context.read().checkLocale(); } From 5ec65a00e5e607e7a177d02d583682f0a354ffac Mon Sep 17 00:00:00 2001 From: Bibash Shrestha Date: Tue, 5 Mar 2024 18:37:03 +0545 Subject: [PATCH 45/45] version update --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index adbb56ebf..9e41ba9c9 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: altme description: AltMe Flutter App -version: 2.3.15+405 +version: 2.3.16+406 environment: sdk: ">=3.1.0 <4.0.0"