Cw 428 send to nostr addresses (#1271)
* add nostr address resolver * Add Nostr localization --------- Co-authored-by: OmarHatem <omarh.ismail1@gmail.com>
Serhii committed
Jan 27, 2024 at 04:34 UTC
fc352a6da3c09d179de41cf967de5258b84a857e
34 files changed
+370
-33
lib/entities/parse_address_from_domain.dart
+27
-1
@@ -6,12 +6,14 @@ import 'package:cake_wallet/entities/parsed_address.dart';
6
import 'package:cake_wallet/entities/unstoppable_domain_address.dart';
7
import 'package:cake_wallet/entities/emoji_string_extension.dart';
8
import 'package:cake_wallet/mastodon/mastodon_api.dart';
9
+import 'package:cake_wallet/nostr/nostr_api.dart';
10
import 'package:cake_wallet/store/settings_store.dart';
11
import 'package:cake_wallet/twitter/twitter_api.dart';
12
import 'package:cw_core/crypto_currency.dart';
13
import 'package:cw_core/wallet_base.dart';
14
import 'package:cw_core/wallet_type.dart';
15
import 'package:cake_wallet/entities/fio_address_provider.dart';
16
+import 'package:flutter/cupertino.dart';
17
18
class AddressResolver {
19
AddressResolver({required this.yatService, required this.wallet, required this.settingsStore})
@@ -58,7 +60,16 @@ class AddressResolver {
60
});
61
}
62
61
- Future<ParsedAddress> resolve(String text, String ticker) async {
63
+ bool isEmailFormat(String address) {
64
+ final RegExp emailRegex = RegExp(
65
+ r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$',
66
+ caseSensitive: false,
67
+ );
68
+ return emailRegex.hasMatch(address);
69
+ }
70
+
71
+
72
+ Future<ParsedAddress> resolve(BuildContext context, String text, String ticker) async {
73
try {
74
if (text.startsWith('@') && !text.substring(1).contains('@')) {
75
if(settingsStore.lookupsTwitter) {
@@ -165,6 +176,21 @@ class AddressResolver {
176
}
177
}
178
}
179
+ if (isEmailFormat(text)) {
180
+ final nostrProfile = await NostrProfileHandler.queryProfile(context, text);
181
+ if (nostrProfile?.relays != null) {
182
+ final nostrUserData =
183
+ await NostrProfileHandler.processRelays(context, nostrProfile!, text);
184
+
185
+ if (nostrUserData != null) {
186
+ String? addressFromBio = extractAddressByType(
187
+ raw: nostrUserData.about, type: CryptoCurrency.fromString(ticker));
188
+ if (addressFromBio != null) {
189
+ return ParsedAddress.nostrAddress(address: addressFromBio, name: text);
190
+ }
191
+ }
192
+ }
193
+ }
194
} catch (e) {
195
print(e.toString());
196
}
lib/entities/parsed_address.dart
+23
-4
@@ -2,7 +2,18 @@ import 'package:cake_wallet/entities/openalias_record.dart';
2
import 'package:cake_wallet/entities/yat_record.dart';
3
4
5
-enum ParseFrom { unstoppableDomains, openAlias, yatRecord, fio, notParsed, twitter, ens, contact, mastodon }
5
+enum ParseFrom {
6
+ unstoppableDomains,
7
+ openAlias,
8
+ yatRecord,
9
+ fio,
10
+ notParsed,
11
+ twitter,
12
+ ens,
13
+ contact,
14
+ mastodon,
15
+ nostr
16
+}
17
18
class ParsedAddress {
19
ParsedAddress({
@@ -11,9 +22,9 @@ class ParsedAddress {
22
this.description = '',
23
this.parseFrom = ParseFrom.notParsed,
24
});
14
-
25
+
26
factory ParsedAddress.fetchEmojiAddress({
16
- List<YatRecord>? addresses,
27
+ List<YatRecord>? addresses,
28
required String name,
29
}){
30
if (addresses?.isEmpty ?? true) {
@@ -28,7 +39,7 @@ class ParsedAddress {
39
}
40
41
factory ParsedAddress.fetchUnstoppableDomainAddress({
31
- String? address,
42
+ String? address,
43
required String name,
44
}){
45
if (address?.isEmpty ?? true) {
@@ -94,6 +105,14 @@ class ParsedAddress {
105
);
106
}
107
108
+ factory ParsedAddress.nostrAddress({required String address, required String name}) {
109
+ return ParsedAddress(
110
+ addresses: [address],
111
+ name: name,
112
+ parseFrom: ParseFrom.nostr,
113
+ );
114
+ }
115
+
116
final List<String> addresses;
117
final String name;
118
final String description;
lib/nostr/nostr_api.dart
new
+142
@@ -0,0 +1,142 @@
1
+import 'dart:convert';
2
+
3
+import 'package:cake_wallet/generated/i18n.dart';
4
+import 'package:cake_wallet/nostr/nostr_user.dart';
5
+import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
6
+import 'package:cake_wallet/src/widgets/picker.dart';
7
+import 'package:cake_wallet/utils/show_pop_up.dart';
8
+import 'package:flutter/material.dart';
9
+import 'package:nostr_tools/nostr_tools.dart';
10
+
11
+class NostrProfileHandler {
12
+ static final relayToDomainMap = {
13
+ 'relay.snort.social': 'snort.social',
14
+ };
15
+
16
+ static Nip05 _nip05 = Nip05();
17
+
18
+ static Future<ProfilePointer?> queryProfile(BuildContext context, String nip05Address) async {
19
+ var profile = await _nip05.queryProfile(nip05Address);
20
+ if (profile?.pubkey != null) {
21
+ if (profile?.relays?.isNotEmpty == true) {
22
+ return profile;
23
+ } else {
24
+ await _showErrorDialog(context, S.of(context).no_relays, S.of(context).no_relays_message);
25
+ }
26
+ }
27
+ return null;
28
+ }
29
+
30
+ static Future<UserMetadata?> processRelays(
31
+ BuildContext context, ProfilePointer profile, String nip05Address) async {
32
+ String userDomain = _extractDomain(nip05Address);
33
+ const int metaData = 0;
34
+
35
+ for (String relayUrl in profile.relays ?? []) {
36
+ final relayDomain = _getDomainFromRelayUrl(relayUrl);
37
+ final formattedRelayDomain = relayToDomainMap[relayDomain] ?? relayDomain;
38
+ if (formattedRelayDomain == userDomain) {
39
+ final userDomainData = await _fetchInfoFromRelay(relayUrl, profile.pubkey, [metaData]);
40
+ if (userDomainData != null) {
41
+ return userDomainData;
42
+ }
43
+ }
44
+ }
45
+ await _showErrorDialog(context, S.of(context).no_relays, S.of(context).no_relay_on_domain);
46
+
47
+ String? chosenRelayUrl = await _showRelayChoiceDialog(context, profile.relays ?? []);
48
+ if (chosenRelayUrl != null) {
49
+ final userData = await _fetchInfoFromRelay(chosenRelayUrl, profile.pubkey, [metaData]);
50
+ if (userData != null) {
51
+ return userData;
52
+ }
53
+ }
54
+
55
+ return null;
56
+ }
57
+
58
+ static Future<UserMetadata?> _fetchInfoFromRelay(
59
+ String relayUrl, String userPubKey, List<int> kinds) async {
60
+ try {
61
+ final relay = RelayApi(relayUrl: relayUrl);
62
+ final stream = await relay.connect();
63
+
64
+ relay.sub([
65
+ Filter(
66
+ kinds: kinds,
67
+ authors: [userPubKey],
68
+ )
69
+ ]);
70
+
71
+ await for (var message in stream) {
72
+ if (message.type == 'EVENT') {
73
+ final event = message.message as Event;
74
+
75
+ final eventContent = json.decode(event.content) as Map<String, dynamic>;
76
+
77
+ final userMetadata = UserMetadata.fromJson(eventContent);
78
+ relay.close();
79
+ return userMetadata;
80
+ }
81
+ }
82
+
83
+ relay.close();
84
+ return null;
85
+ } catch (e) {
86
+ print('[!] Error with relay $relayUrl: $e');
87
+ return null;
88
+ }
89
+ }
90
+
91
+ static Future<void> _showErrorDialog(
92
+ BuildContext context, String title, String errorMessage) async {
93
+ if (context.mounted) {
94
+ await showPopUp<void>(
95
+ context: context,
96
+ builder: (BuildContext dialogContext) {
97
+ return AlertWithOneAction(
98
+ alertTitle: title,
99
+ alertContent: errorMessage,
100
+ buttonText: S.of(dialogContext).ok,
101
+ buttonAction: () => Navigator.of(dialogContext).pop(),
102
+ );
103
+ },
104
+ );
105
+ }
106
+ }
107
+
108
+ static String _extractDomain(String nip05Address) {
109
+ var parts = nip05Address.split('@');
110
+ return parts.length == 2 ? parts[1] : '';
111
+ }
112
+
113
+ static String _getDomainFromRelayUrl(String relayUrl) {
114
+ try {
115
+ var uri = Uri.parse(relayUrl);
116
+ return uri.host;
117
+ } catch (e) {
118
+ print('Error parsing URL: $e');
119
+ return '';
120
+ }
121
+ }
122
+
123
+ static Future<String?> _showRelayChoiceDialog(BuildContext context, List<String> relays) async {
124
+ String? selectedRelay;
125
+
126
+ if (context.mounted) {
127
+ await showPopUp<void>(
128
+ context: context,
129
+ builder: (BuildContext dialogContext) {
130
+ return Picker<String>(
131
+ selectedAtIndex: 0,
132
+ title: S.of(dialogContext).choose_relay,
133
+ items: relays,
134
+ onItemSelected: (String relay) => selectedRelay = relay,
135
+ );
136
+ },
137
+ );
138
+ }
139
+
140
+ return selectedRelay;
141
+ }
142
+}
lib/nostr/nostr_user.dart
new
+35
@@ -0,0 +1,35 @@
1
+
2
+class UserMetadata {
3
+ final String name;
4
+ final String lnurl;
5
+ final String email;
6
+ final String picture;
7
+ final String about;
8
+ final String nip05;
9
+ final String banner;
10
+ final String website;
11
+
12
+ UserMetadata({
13
+ required this.name,
14
+ required this.lnurl,
15
+ required this.email,
16
+ required this.picture,
17
+ required this.about,
18
+ required this.nip05,
19
+ required this.banner,
20
+ required this.website,
21
+ });
22
+
23
+ factory UserMetadata.fromJson(Map<String, dynamic> json) {
24
+ return UserMetadata(
25
+ name: json['name'] as String? ?? '',
26
+ lnurl: json['lud06'] as String? ?? '',
27
+ email: json['lud16'] as String? ?? '',
28
+ picture: json['picture'] as String? ?? '',
29
+ about: json['about'] as String? ?? '',
30
+ nip05: json['nip05'] as String? ?? '',
31
+ banner: json['banner'] as String? ?? '',
32
+ website: json['website'] as String? ?? '',
33
+ );
34
+ }
35
+}
\ No newline at end of file
lib/src/screens/exchange/exchange_page.dart
+1
-1
@@ -557,7 +557,7 @@ class ExchangePage extends BasePage {
557
}
558
559
Future<String> fetchParsedAddress(BuildContext context, String domain, String ticker) async {
560
- final parsedAddress = await getIt.get<AddressResolver>().resolve(domain, ticker);
560
+ final parsedAddress = await getIt.get<AddressResolver>().resolve(context, domain, ticker);
561
final address = await extractAddressFromParsed(context, parsedAddress);
562
return address;
563
}
lib/src/screens/send/widgets/extract_address_from_parsed.dart
+5
@@ -43,6 +43,11 @@ Future<String> extractAddressFromParsed(
43
content = S.of(context).extracted_address_content('${parsedAddress.name} (Mastodon)');
44
address = parsedAddress.addresses.first;
45
break;
46
+ case ParseFrom.nostr:
47
+ title = S.of(context).address_detected;
48
+ content = S.of(context).extracted_address_content('${parsedAddress.name} (Nostr NIP-05)');
49
+ address = parsedAddress.addresses.first;
50
+ break;
51
case ParseFrom.yatRecord:
52
if (parsedAddress.name.isEmpty) {
53
title = S.of(context).yat_error;
lib/view_model/send/output.dart
+1
-1
@@ -262,7 +262,7 @@ abstract class OutputBase with Store {
262
Future<void> fetchParsedAddress(BuildContext context) async {
263
final domain = address;
264
final ticker = cryptoCurrencyHandler().title.toLowerCase();
265
- parsedAddress = await getIt.get<AddressResolver>().resolve(domain, ticker);
265
+ parsedAddress = await getIt.get<AddressResolver>().resolve(context, domain, ticker);
266
extractedAddress = await extractAddressFromParsed(context, parsedAddress);
267
note = parsedAddress.description;
268
}
pubspec_base.yaml
+6
@@ -105,6 +105,7 @@ dependencies:
105
socks5_proxy: ^1.0.4
106
flutter_svg: ^2.0.9
107
polyseed: ^0.0.2
108
+ nostr_tools: ^1.0.9
109
110
dev_dependencies:
111
flutter_test:
@@ -123,6 +124,11 @@ dev_dependencies:
124
url: https://github.com/cake-tech/google-translator.git
125
version: 1.0.0
126
127
+dependency_overrides:
128
+ bech32:
129
+ git:
130
+ url: https://github.com/cake-tech/bech32.git
131
+
132
flutter_icons:
133
image_path: "assets/images/app_logo.png"
134
android: true
res/values/strings_ar.arb
+5
-1
@@ -764,5 +764,9 @@
764
"confirmed_tx": "مؤكد",
765
"transaction_details_source_address": "عنوان المصدر",
766
"pause_wallet_creation": ".ﺎﻴًﻟﺎﺣ ﺎﺘًﻗﺆﻣ ﺔﻔﻗﻮﺘﻣ Haven Wallet ءﺎﺸﻧﺇ ﻰﻠﻋ ﺓﺭﺪﻘﻟﺍ",
767
- "camera_consent": ".ﻞﻴﺻﺎﻔﺘﻟﺍ ﻰﻠﻋ ﻝﻮﺼﺤﻠﻟ ﻢﻬﺑ ﺔﺻﺎﺨﻟﺍ ﺔﻴﺻﻮﺼﺨﻟﺍ ﺔﺳﺎﻴﺳ ﻦﻣ ﻖﻘﺤﺘﻟﺍ ﻰﺟﺮﻳ .${provider} ﻝﻮﻠ"
767
+ "camera_consent": ".ﻞﻴﺻﺎﻔﺘﻟﺍ ﻰﻠﻋ ﻝﻮﺼﺤﻠﻟ ﻢﻬﺑ ﺔﺻﺎﺨﻟﺍ ﺔﻴﺻﻮﺼﺨﻟﺍ ﺔﺳﺎﻴﺳ ﻦﻣ ﻖﻘﺤﺘﻟﺍ ﻰﺟﺮﻳ .${provider} ﻝﻮﻠ",
768
+ "no_relays": " ﺕﻼﺣﺮﻤﻟﺍ ﻻ",
769
+ "choose_relay": " ﻡﺍﺪﺨﺘﺳﻼﻟ ﻊﺑﺎﺘﺘﻟﺍ ﺭﺎﻴﺘﺧﺍ ءﺎﺟﺮﻟﺍ",
770
+ "no_relays_message": ".ﻪﺑ ﺹﺎﺨﻟﺍ Nostr ﻞﺠﺳ ﻰﻟﺇ ﺕﻼﺣﺮﻤﻟﺍ ﺔﻓﺎﺿﻹ ﻢﻠﺘﺴﻤﻟﺍ ﺩﺎﺷﺭﺇ ﻰﺟﺮﻳ .ﺕﻼﺣﺮﻣ ﻱﺃ ﻰﻠﻋ ﻱﻮﺘﺤﻳ ﻻ",
771
+ "no_relay_on_domain": ".ﻡﺍﺪﺨﺘﺳﻼﻟ ﻊﺑﺎﺘﺘﻟﺍ ﺭﺎﻴﺘﺧﺍ ءﺎﺟﺮﻟﺍ .ﺡﺎﺘﻣ ﺮﻴﻏ ﻞﻴﺣﺮﺘﻟﺍ ﻥﺃ ﻭﺃ ﻡﺪﺨﺘﺴﻤﻟﺍ ﻝﺎﺠﻤﻟ ﻞﻴﺣﺮﺗ ﺪ"
772
}
res/values/strings_bg.arb
+5
-1
@@ -760,5 +760,9 @@
760
"confirmed_tx": "Потвърдено",
761
"transaction_details_source_address": "Адрес на източника",
762
"pause_wallet_creation": "Възможността за създаване на Haven Wallet в момента е на пауза.",
763
- "camera_consent": "Вашият фотоапарат ще бъде използван за заснемане на изображение с цел идентификация от ${provider}. Моля, проверете тяхната политика за поверителност за подробности."
763
+ "camera_consent": "Вашият фотоапарат ще бъде използван за заснемане на изображение с цел идентификация от ${provider}. Моля, проверете тяхната политика за поверителност за подробности.",
764
+ "no_relays": "Без релета",
765
+ "choose_relay": "Моля, изберете реле, което да използвате",
766
+ "no_relays_message": "Намерихме запис Nostr NIP-05 за този потребител, но той не съдържа релета. Моля, инструктирайте получателя да добави релета към своя Nostr запис.",
767
+ "no_relay_on_domain": "Няма реле за домейна на потребителя или релето не е налично. Моля, изберете реле, което да използвате."
768
}
res/values/strings_cs.arb
+5
-1
@@ -760,5 +760,9 @@
760
"confirmed_tx": "Potvrzeno",
761
"transaction_details_source_address": "Zdrojová adresa",
762
"pause_wallet_creation": "Možnost vytvářet Haven Wallet je momentálně pozastavena.",
763
- "camera_consent": "Váš fotoaparát použije k pořízení snímku pro účely identifikace ${provider}. Podrobnosti najdete v jejich Zásadách ochrany osobních údajů."
763
+ "camera_consent": "Váš fotoaparát použije k pořízení snímku pro účely identifikace ${provider}. Podrobnosti najdete v jejich Zásadách ochrany osobních údajů.",
764
+ "no_relays": "Žádná relé",
765
+ "choose_relay": "Vyberte relé, které chcete použít",
766
+ "no_relays_message": "Pro tohoto uživatele jsme našli záznam Nostr NIP-05, který však neobsahuje žádná relé. Požádejte příjemce, aby přidal přenosy do svého záznamu Nostr.",
767
+ "no_relay_on_domain": "Pro doménu uživatele neexistuje přenos nebo je přenos nedostupný. Vyberte relé, které chcete použít."
768
}
res/values/strings_de.arb
+5
-1
@@ -768,5 +768,9 @@
768
"confirmed_tx": "Bestätigt",
769
"transaction_details_source_address": "Quelladresse",
770
"pause_wallet_creation": "Die Möglichkeit, Haven Wallet zu erstellen, ist derzeit pausiert.",
771
- "camera_consent": "Mit Ihrer Kamera wird bis zum ${provider} ein Bild zur Identifizierung aufgenommen. Weitere Informationen finden Sie in deren Datenschutzbestimmungen."
771
+ "camera_consent": "Mit Ihrer Kamera wird bis zum ${provider} ein Bild zur Identifizierung aufgenommen. Weitere Informationen finden Sie in deren Datenschutzbestimmungen.",
772
+ "no_relays": "Keine Relais",
773
+ "choose_relay": "Bitte wählen Sie ein zu verwendendes Relais aus",
774
+ "no_relays_message": "Wir haben einen Nostr NIP-05-Eintrag für diesen Benutzer gefunden, der jedoch keine Relays enthält. Bitte weisen Sie den Empfänger an, Relays zu seinem Nostr-Datensatz hinzuzufügen.",
775
+ "no_relay_on_domain": "Es gibt kein Relay für die Domäne des Benutzers oder das Relay ist nicht verfügbar. Bitte wählen Sie ein zu verwendendes Relais aus."
776
}
res/values/strings_en.arb
+5
-1
@@ -769,5 +769,9 @@
769
"confirmed_tx": "Confirmed",
770
"transaction_details_source_address": "Source address",
771
"pause_wallet_creation": "Ability to create Haven Wallet is currently paused.",
772
- "camera_consent": "Your camera will be used to capture an image for identification purposes by ${provider}. Please check their Privacy Policy for details."
772
+ "camera_consent": "Your camera will be used to capture an image for identification purposes by ${provider}. Please check their Privacy Policy for details.",
773
+ "no_relays": "No relays",
774
+ "choose_relay": "Please choose a relay to use",
775
+ "no_relays_message": "We found a Nostr NIP-05 record for this user, but it does not contain any relays. Please instruct the recipient to add relays to their Nostr record.",
776
+ "no_relay_on_domain": "There isn't a relay for user's domain or the relay is unavailable. Please choose a relay to use."
777
}
res/values/strings_es.arb
+5
-1
@@ -768,5 +768,9 @@
768
"confirmed_tx": "Confirmado",
769
"transaction_details_source_address": "Dirección de la fuente",
770
"pause_wallet_creation": "La capacidad para crear Haven Wallet está actualmente pausada.",
771
- "camera_consent": "Su cámara será utilizada para capturar una imagen con fines de identificación por ${provider}. Consulte su Política de privacidad para obtener más detalles."
771
+ "camera_consent": "Su cámara será utilizada para capturar una imagen con fines de identificación por ${provider}. Consulte su Política de privacidad para obtener más detalles.",
772
+ "no_relays": "Sin relevos",
773
+ "choose_relay": "Por favor elija un relé para usar",
774
+ "no_relays_message": "Encontramos un registro Nostr NIP-05 para este usuario, pero no contiene ningún relé. Indique al destinatario que agregue retransmisiones a su registro Nostr.",
775
+ "no_relay_on_domain": "No hay una retransmisión para el dominio del usuario o la retransmisión no está disponible. Elija un relé para usar."
776
}
res/values/strings_fr.arb
+5
-1
@@ -768,5 +768,9 @@
768
"confirmed_tx": "Confirmé",
769
"transaction_details_source_address": "Adresse source",
770
"pause_wallet_creation": "La possibilité de créer Haven Wallet est actuellement suspendue.",
771
- "camera_consent": "Votre appareil photo sera utilisé pour capturer une image à des fins d'identification par ${provider}. Veuillez consulter leur politique de confidentialité pour plus de détails."
771
+ "camera_consent": "Votre appareil photo sera utilisé pour capturer une image à des fins d'identification par ${provider}. Veuillez consulter leur politique de confidentialité pour plus de détails.",
772
+ "no_relays": "Pas de relais",
773
+ "choose_relay": "Veuillez choisir un relais à utiliser",
774
+ "no_relays_message": "Nous avons trouvé un enregistrement Nostr NIP-05 pour cet utilisateur, mais il ne contient aucun relais. Veuillez demander au destinataire d'ajouter des relais à son enregistrement Nostr.",
775
+ "no_relay_on_domain": "Il n'existe pas de relais pour le domaine de l'utilisateur ou le relais n'est pas disponible. Veuillez choisir un relais à utiliser."
776
}
res/values/strings_ha.arb
+5
-1
@@ -750,5 +750,9 @@
750
"confirmed_tx": "Tabbatar",
751
"transaction_details_source_address": "Adireshin Incord",
752
"pause_wallet_creation": "A halin yanzu an dakatar da ikon ƙirƙirar Haven Wallet.",
753
- "camera_consent": "Za a yi amfani da kyamarar ku don ɗaukar hoto don dalilai na tantancewa ta ${provider}. Da fatan za a duba Manufar Sirri don cikakkun bayanai."
753
+ "camera_consent": "Za a yi amfani da kyamarar ku don ɗaukar hoto don dalilai na tantancewa ta ${provider}. Da fatan za a duba Manufar Sirri don cikakkun bayanai.",
754
+ "no_relays": "Babu relays",
755
+ "choose_relay": "Da fatan za a zaɓi gudun ba da sanda don amfani",
756
+ "no_relays_message": "Mun sami rikodin Nostr NIP-05 don wannan mai amfani, amma ba ya ƙunshe da kowane relays. Da fatan za a umurci mai karɓa ya ƙara relays zuwa rikodin su na Nostr.",
757
+ "no_relay_on_domain": "Babu gudun ba da sanda ga yankin mai amfani ko kuma ba a samu ba. Da fatan za a zaɓi gudun ba da sanda don amfani."
758
}
res/values/strings_hi.arb
+5
-1
@@ -768,5 +768,9 @@
768
"confirmed_tx": "की पुष्टि",
769
"transaction_details_source_address": "स्रोत पता",
770
"pause_wallet_creation": "हेवन वॉलेट बनाने की क्षमता फिलहाल रुकी हुई है।",
771
- "camera_consent": "आपके कैमरे का उपयोग ${provider} द्वारा पहचान उद्देश्यों के लिए एक छवि कैप्चर करने के लिए किया जाएगा। विवरण के लिए कृपया उनकी गोपनीयता नीति जांचें।"
771
+ "camera_consent": "आपके कैमरे का उपयोग ${provider} द्वारा पहचान उद्देश्यों के लिए एक छवि कैप्चर करने के लिए किया जाएगा। विवरण के लिए कृपया उनकी गोपनीयता नीति जांचें।",
772
+ "no_relays": "कोई रिले नहीं",
773
+ "choose_relay": "कृपया उपयोग करने के लिए एक रिले चुनें",
774
+ "no_relays_message": "हमें इस उपयोगकर्ता के लिए एक Nostr NIP-05 रिकॉर्ड मिला, लेकिन इसमें कोई रिले नहीं है। कृपया प्राप्तकर्ता को अपने नॉस्ट्र रिकॉर्ड में रिले जोड़ने का निर्देश दें।",
775
+ "no_relay_on_domain": "उपयोगकर्ता के डोमेन के लिए कोई रिले नहीं है या रिले अनुपलब्ध है। कृपया उपयोग करने के लिए एक रिले चुनें।"
776
}
res/values/strings_hr.arb
+5
-1
@@ -766,5 +766,9 @@
766
"confirmed_tx": "Potvrđen",
767
"transaction_details_source_address": "Adresa izvora",
768
"pause_wallet_creation": "Mogućnost stvaranja novčanika Haven trenutno je pauzirana.",
769
- "camera_consent": "Vaš će fotoaparat koristiti za snimanje slike u svrhu identifikacije od strane ${provider}. Pojedinosti potražite u njihovoj politici privatnosti."
769
+ "camera_consent": "Vaš će fotoaparat koristiti za snimanje slike u svrhu identifikacije od strane ${provider}. Pojedinosti potražite u njihovoj politici privatnosti.",
770
+ "no_relays": "Nema releja",
771
+ "choose_relay": "Odaberite relej za korištenje",
772
+ "no_relays_message": "Pronašli smo zapis Nostr NIP-05 za ovog korisnika, ali on ne sadrži nikakve releje. Uputite primatelja da doda releje u svoj Nostr zapis.",
773
+ "no_relay_on_domain": "Ne postoji relej za korisničku domenu ili je relej nedostupan. Odaberite relej za korištenje."
774
}
res/values/strings_id.arb
+5
-1
@@ -756,5 +756,9 @@
756
"confirmed_tx": "Dikonfirmasi",
757
"transaction_details_source_address": "Alamat sumber",
758
"pause_wallet_creation": "Kemampuan untuk membuat Haven Wallet saat ini dijeda.",
759
- "camera_consent": "Kamera Anda akan digunakan untuk mengambil gambar untuk tujuan identifikasi oleh ${provider}. Silakan periksa Kebijakan Privasi mereka untuk detailnya."
759
+ "camera_consent": "Kamera Anda akan digunakan untuk mengambil gambar untuk tujuan identifikasi oleh ${provider}. Silakan periksa Kebijakan Privasi mereka untuk detailnya.",
760
+ "no_relays": "Tidak ada relay",
761
+ "choose_relay": "Silakan pilih relai yang akan digunakan",
762
+ "no_relays_message": "Kami menemukan catatan Nostr NIP-05 untuk pengguna ini, tetapi tidak berisi relay apa pun. Harap instruksikan penerima untuk menambahkan relay ke catatan Nostr mereka.",
763
+ "no_relay_on_domain": "Tidak ada relai untuk domain pengguna atau relai tidak tersedia. Silakan pilih relai yang akan digunakan."
764
}
res/values/strings_it.arb
+5
-1
@@ -768,5 +768,9 @@
768
"confirmed_tx": "Confermato",
769
"transaction_details_source_address": "Indirizzo di partenza",
770
"pause_wallet_creation": "La possibilità di creare Haven Wallet è attualmente sospesa.",
771
- "camera_consent": "La tua fotocamera verrà utilizzata per acquisire un'immagine a scopo identificativo da ${provider}. Si prega di controllare la loro Informativa sulla privacy per i dettagli."
771
+ "camera_consent": "La tua fotocamera verrà utilizzata per acquisire un'immagine a scopo identificativo da ${provider}. Si prega di controllare la loro Informativa sulla privacy per i dettagli.",
772
+ "no_relays": "Nessun relè",
773
+ "choose_relay": "Scegli un relè da utilizzare",
774
+ "no_relays_message": "Abbiamo trovato un record Nostr NIP-05 per questo utente, ma non contiene alcun relè. Si prega di indicare al destinatario di aggiungere inoltri al proprio record Nostr.",
775
+ "no_relay_on_domain": "Non esiste un inoltro per il dominio dell'utente oppure l'inoltro non è disponibile. Scegli un relè da utilizzare."
776
}
res/values/strings_ja.arb
+5
-1
@@ -768,5 +768,9 @@
768
"confirmed_tx": "確認済み",
769
"transaction_details_source_address": "ソースアドレス",
770
"pause_wallet_creation": "Haven Wallet を作成する機能は現在一時停止されています。",
771
- "camera_consent": "あなたのカメラは、${provider}_ までに識別目的で画像を撮影するために使用されます。詳細については、プライバシー ポリシーをご確認ください。"
771
+ "camera_consent": "あなたのカメラは、${provider}_ までに識別目的で画像を撮影するために使用されます。詳細については、プライバシー ポリシーをご確認ください。",
772
+ "no_relays": "リレーなし",
773
+ "choose_relay": "使用するリレーを選択してください",
774
+ "no_relays_message": "このユーザーの Nostr NIP-05 レコードが見つかりましたが、リレーは含まれていません。受信者に Nostr レコードにリレーを追加するよう指示してください。",
775
+ "no_relay_on_domain": "ユーザーのドメインのリレーが存在しないか、リレーが使用できません。使用するリレーを選択してください。"
776
}
res/values/strings_ko.arb
+5
-1
@@ -766,5 +766,9 @@
766
"confirmed_tx": "확인",
767
"transaction_details_source_address": "소스 주소",
768
"pause_wallet_creation": "Haven Wallet 생성 기능이 현재 일시 중지되었습니다.",
769
- "camera_consent": "귀하의 카메라는 ${provider}의 식별 목적으로 이미지를 캡처하는 데 사용됩니다. 자세한 내용은 해당 개인정보 보호정책을 확인하세요."
769
+ "camera_consent": "귀하의 카메라는 ${provider}의 식별 목적으로 이미지를 캡처하는 데 사용됩니다. 자세한 내용은 해당 개인정보 보호정책을 확인하세요.",
770
+ "no_relays": "릴레이 없음",
771
+ "choose_relay": "사용할 릴레이를 선택해주세요",
772
+ "no_relays_message": "이 사용자에 대한 Nostr NIP-05 레코드를 찾았지만 릴레이가 포함되어 있지 않습니다. 수신자에게 Nostr 기록에 릴레이를 추가하도록 지시하십시오.",
773
+ "no_relay_on_domain": "사용자 도메인에 릴레이가 없거나 릴레이를 사용할 수 없습니다. 사용할 릴레이를 선택해주세요."
774
}
res/values/strings_my.arb
+5
-1
@@ -766,5 +766,9 @@
766
"confirmed_tx": "အတည်ပြုသည်",
767
"transaction_details_source_address": "အရင်းအမြစ်လိပ်စာ",
768
"pause_wallet_creation": "Haven Wallet ဖန်တီးနိုင်မှုကို လောလောဆယ် ခေတ္တရပ်ထားသည်။",
769
- "camera_consent": "မှတ်ပုံတင်ခြင်းရည်ရွယ်ချက်များအတွက် ${provider} တွင် သင့်ကင်မရာကို အသုံးပြုပါမည်။ အသေးစိတ်အတွက် ၎င်းတို့၏ ကိုယ်ရေးကိုယ်တာမူဝါဒကို စစ်ဆေးပါ။"
769
+ "camera_consent": "မှတ်ပုံတင်ခြင်းရည်ရွယ်ချက်များအတွက် ${provider} တွင် သင့်ကင်မရာကို အသုံးပြုပါမည်။ အသေးစိတ်အတွက် ၎င်းတို့၏ ကိုယ်ရေးကိုယ်တာမူဝါဒကို စစ်ဆေးပါ။",
770
+ "no_relays": "Relay မရှိပါ။",
771
+ "choose_relay": "အသုံးပြုရန် relay ကိုရွေးချယ်ပါ။",
772
+ "no_relays_message": "ဤအသုံးပြုသူအတွက် Nostr NIP-05 မှတ်တမ်းကို ကျွန်ုပ်တို့တွေ့ရှိသော်လည်း ၎င်းတွင် မည်သည့် relays မှ မပါဝင်ပါ။ ကျေးဇူးပြု၍ လက်ခံသူကို ၎င်းတို့၏ Nostr မှတ်တမ်းတွင် ထပ်လောင်းထည့်ရန် ညွှန်ကြားပါ။",
773
+ "no_relay_on_domain": "အသုံးပြုသူ၏ဒိုမိန်းအတွက် ထပ်ဆင့်လွှင့်ခြင်း မရှိပါ သို့မဟုတ် ထပ်ဆင့်လွှင့်ခြင်း မရနိုင်ပါ။ အသုံးပြုရန် relay ကိုရွေးချယ်ပါ။"
774
}
res/values/strings_nl.arb
+5
-1
@@ -768,5 +768,9 @@
768
"confirmed_tx": "Bevestigd",
769
"transaction_details_source_address": "Bron adres",
770
"pause_wallet_creation": "De mogelijkheid om Haven Wallet te maken is momenteel onderbroken.",
771
- "camera_consent": "Uw camera wordt gebruikt om vóór ${provider} een beeld vast te leggen voor identificatiedoeleinden. Raadpleeg hun privacybeleid voor meer informatie."
771
+ "camera_consent": "Uw camera wordt gebruikt om vóór ${provider} een beeld vast te leggen voor identificatiedoeleinden. Raadpleeg hun privacybeleid voor meer informatie.",
772
+ "no_relays": "Geen relais",
773
+ "choose_relay": "Kies een relais dat u wilt gebruiken",
774
+ "no_relays_message": "We hebben een Nostr NIP-05-record voor deze gebruiker gevonden, maar deze bevat geen relays. Instrueer de ontvanger om relays toe te voegen aan zijn Nostr-record.",
775
+ "no_relay_on_domain": "Er is geen relay voor het domein van de gebruiker of de relay is niet beschikbaar. Kies een relais dat u wilt gebruiken."
776
}
res/values/strings_pl.arb
+5
-1
@@ -768,5 +768,9 @@
768
"confirmed_tx": "Potwierdzony",
769
"transaction_details_source_address": "Adres źródłowy",
770
"pause_wallet_creation": "Możliwość utworzenia Portfela Haven jest obecnie wstrzymana.",
771
- "camera_consent": "Twój aparat zostanie użyty do przechwycenia obrazu w celach identyfikacyjnych przez ${provider}. Aby uzyskać szczegółowe informacje, sprawdź ich Politykę prywatności."
771
+ "camera_consent": "Twój aparat zostanie użyty do przechwycenia obrazu w celach identyfikacyjnych przez ${provider}. Aby uzyskać szczegółowe informacje, sprawdź ich Politykę prywatności.",
772
+ "no_relays": "Żadnych przekaźników",
773
+ "choose_relay": "Wybierz przekaźnik, którego chcesz użyć",
774
+ "no_relays_message": "Znaleźliśmy rekord Nostr NIP-05 dla tego użytkownika, ale nie zawiera on żadnych przekaźników. Poinstruuj odbiorcę, aby dodał przekaźniki do swojego rekordu Nostr.",
775
+ "no_relay_on_domain": "Brak przekaźnika dla domeny użytkownika lub przekaźnik jest niedostępny. Wybierz przekaźnik, którego chcesz użyć."
776
}
res/values/strings_pt.arb
+5
-1
@@ -767,5 +767,9 @@
767
"confirmed_tx": "Confirmado",
768
"transaction_details_source_address": "Endereço de Origem",
769
"pause_wallet_creation": "A capacidade de criar a Haven Wallet está atualmente pausada.",
770
- "camera_consent": "Sua câmera será usada para capturar uma imagem para fins de identificação por ${provider}. Por favor, verifique a Política de Privacidade para obter detalhes."
770
+ "camera_consent": "Sua câmera será usada para capturar uma imagem para fins de identificação por ${provider}. Por favor, verifique a Política de Privacidade para obter detalhes.",
771
+ "no_relays": "Sem relés",
772
+ "choose_relay": "Escolha um relé para usar",
773
+ "no_relays_message": "Encontramos um registro Nostr NIP-05 para este usuário, mas ele não contém nenhum relé. Instrua o destinatário a adicionar retransmissões ao seu registro Nostr.",
774
+ "no_relay_on_domain": "Não há uma retransmissão para o domínio do usuário ou a retransmissão está indisponível. Escolha um relé para usar."
775
}
res/values/strings_ru.arb
+5
-1
@@ -768,5 +768,9 @@
768
"confirmed_tx": "Подтвержденный",
769
"transaction_details_source_address": "Адрес источника",
770
"pause_wallet_creation": "Возможность создания Haven Wallet в настоящее время приостановлена.",
771
- "camera_consent": "Ваша камера будет использоваться для захвата изображения в целях идентификации ${provider}. Пожалуйста, ознакомьтесь с их Политикой конфиденциальности для получения подробной информации."
771
+ "camera_consent": "Ваша камера будет использоваться для захвата изображения в целях идентификации ${provider}. Пожалуйста, ознакомьтесь с их Политикой конфиденциальности для получения подробной информации.",
772
+ "no_relays": "Нет реле",
773
+ "choose_relay": "Пожалуйста, выберите реле для использования",
774
+ "no_relays_message": "Мы нашли запись Nostr NIP-05 для этого пользователя, но она не содержит никаких реле. Попросите получателя добавить реле в свою запись Nostr.",
775
+ "no_relay_on_domain": "Для домена пользователя реле не существует или реле недоступно. Пожалуйста, выберите реле для использования."
776
}
res/values/strings_th.arb
+5
-1
@@ -766,5 +766,9 @@
766
"confirmed_tx": "ซึ่งยืนยันแล้ว",
767
"transaction_details_source_address": "ที่อยู่แหล่งกำเนิด",
768
"pause_wallet_creation": "ขณะนี้ความสามารถในการสร้าง Haven Wallet ถูกหยุดชั่วคราว",
769
- "camera_consent": "กล้องของคุณจะถูกนำมาใช้เพื่อจับภาพเพื่อวัตถุประสงค์ในการระบุตัวตนภายใน ${provider} โปรดตรวจสอบนโยบายความเป็นส่วนตัวเพื่อดูรายละเอียด"
769
+ "camera_consent": "กล้องของคุณจะถูกนำมาใช้เพื่อจับภาพเพื่อวัตถุประสงค์ในการระบุตัวตนภายใน ${provider} โปรดตรวจสอบนโยบายความเป็นส่วนตัวเพื่อดูรายละเอียด",
770
+ "no_relays": "ไม่มีรีเลย์",
771
+ "choose_relay": "กรุณาเลือกรีเลย์ที่จะใช้",
772
+ "no_relays_message": "เราพบบันทึก Nostr NIP-05 สำหรับผู้ใช้รายนี้ แต่ไม่มีรีเลย์ใดๆ โปรดแนะนำให้ผู้รับเพิ่มรีเลย์ลงในบันทึก Nostr ของตน",
773
+ "no_relay_on_domain": "ไม่มีการส่งต่อสำหรับโดเมนของผู้ใช้ หรือการส่งต่อไม่พร้อมใช้งาน กรุณาเลือกรีเลย์ที่จะใช้"
774
}
res/values/strings_tl.arb
+5
-1
@@ -762,5 +762,9 @@
762
"confirmed_tx": "Nakumpirma",
763
"transaction_details_source_address": "SOURCE ADDRESS",
764
"pause_wallet_creation": "Kasalukuyang naka-pause ang kakayahang gumawa ng Haven Wallet.",
765
- "camera_consent": "Gagamitin ang iyong camera upang kumuha ng larawan para sa mga layunin ng pagkakakilanlan sa pamamagitan ng ${provider}. Pakisuri ang kanilang Patakaran sa Privacy para sa mga detalye."
765
+ "camera_consent": "Gagamitin ang iyong camera upang kumuha ng larawan para sa mga layunin ng pagkakakilanlan sa pamamagitan ng ${provider}. Pakisuri ang kanilang Patakaran sa Privacy para sa mga detalye.",
766
+ "no_relays": "Walang mga relay",
767
+ "choose_relay": "Mangyaring pumili ng relay na gagamitin",
768
+ "no_relays_message": "Nakakita kami ng Nostr NIP-05 record para sa user na ito, ngunit hindi ito naglalaman ng anumang mga relay. Mangyaring atasan ang tatanggap na magdagdag ng mga relay sa kanilang Nostr record.",
769
+ "no_relay_on_domain": "Walang relay para sa domain ng user o hindi available ang relay. Mangyaring pumili ng relay na gagamitin."
770
}
res/values/strings_tr.arb
+5
-1
@@ -766,5 +766,9 @@
766
"confirmed_tx": "Onaylanmış",
767
"transaction_details_source_address": "Kaynak adresi",
768
"pause_wallet_creation": "Haven Cüzdanı oluşturma yeteneği şu anda duraklatıldı.",
769
- "camera_consent": "Kameranız ${provider} tarihine kadar tanımlama amacıyla bir görüntü yakalamak için kullanılacaktır. Ayrıntılar için lütfen Gizlilik Politikalarını kontrol edin."
769
+ "camera_consent": "Kameranız ${provider} tarihine kadar tanımlama amacıyla bir görüntü yakalamak için kullanılacaktır. Ayrıntılar için lütfen Gizlilik Politikalarını kontrol edin.",
770
+ "no_relays": "Röle yok",
771
+ "choose_relay": "Lütfen kullanmak için bir röle seçin",
772
+ "no_relays_message": "Bu kullanıcı için bir Nostr NIP-05 kaydı bulduk ancak bu kayıt herhangi bir aktarma içermiyor. Lütfen alıcıya Nostr kayıtlarına aktarma eklemesi talimatını verin.",
773
+ "no_relay_on_domain": "Kullanıcının alanı için bir geçiş yok veya geçiş kullanılamıyor. Lütfen kullanmak için bir röle seçin."
774
}
res/values/strings_uk.arb
+5
-1
@@ -768,5 +768,9 @@
768
"confirmed_tx": "Підтверджений",
769
"transaction_details_source_address": "Адреса джерела",
770
"pause_wallet_creation": "Можливість створення гаманця Haven зараз призупинено.",
771
- "camera_consent": "Ваша камера використовуватиметься для зйомки зображення з метою ідентифікації ${provider}. Будь ласка, ознайомтеся з їхньою політикою конфіденційності, щоб дізнатися більше."
771
+ "camera_consent": "Ваша камера використовуватиметься для зйомки зображення з метою ідентифікації ${provider}. Будь ласка, ознайомтеся з їхньою політикою конфіденційності, щоб дізнатися більше.",
772
+ "no_relays": "Без реле",
773
+ "choose_relay": "Будь ласка, виберіть реле для використання",
774
+ "no_relays_message": "Ми знайшли запис Nostr NIP-05 для цього користувача, але він не містить жодних реле. Будь ласка, попросіть одержувача додати реле до свого запису Nostr.",
775
+ "no_relay_on_domain": "Немає ретранслятора для домену користувача або ретранслятор недоступний. Будь ласка, виберіть реле для використання."
776
}
res/values/strings_ur.arb
+5
-1
@@ -760,5 +760,9 @@
760
"confirmed_tx": "تصدیق",
761
"transaction_details_source_address": "ماخذ ایڈریس",
762
"pause_wallet_creation": "Haven Wallet ۔ﮯﮨ ﻑﻮﻗﻮﻣ ﻝﺎﺤﻟﺍ ﯽﻓ ﺖﯿﻠﮨﺍ ﯽﮐ ﮯﻧﺎﻨﺑ",
763
- "camera_consent": "۔ﮟﯿﮭﮑﯾﺩ ﯽﺴﯿﻟﺎﭘ ﯽﺴﯾﻮﯿﺋﺍﺮﭘ ﯽﮐ ﻥﺍ ﻡﺮﮐ ﮦﺍﺮﺑ ﮯﯿﻟ ﮯﮐ ﺕﻼ${provider}ﯿﺼﻔﺗ ۔ﺎﮔ ﮯﺋﺎﺟ ﺎﯿﮐ ﻝﺎﻤﻌﺘﺳﺍ ﮯﯿﻟ"
763
+ "camera_consent": "۔ﮟﯿﮭﮑﯾﺩ ﯽﺴﯿﻟﺎﭘ ﯽﺴﯾﻮﯿﺋﺍﺮﭘ ﯽﮐ ﻥﺍ ﻡﺮﮐ ﮦﺍﺮﺑ ﮯﯿﻟ ﮯﮐ ﺕﻼ${provider}ﯿﺼﻔﺗ ۔ﺎﮔ ﮯﺋﺎﺟ ﺎﯿﮐ ﻝﺎﻤﻌﺘﺳﺍ ﮯﯿﻟ",
764
+ "no_relays": " ۔ﮟﯿﮩﻧ ﮯﻠﯾﺭ ﯽﺋﻮﮐ",
765
+ "choose_relay": " ۔ﮟﯾﺮﮐ ﺏﺎﺨﺘﻧﺍ ﺎﮐ ﮯﻠﯾﺭ ﮯﯿﻟ ﮯﮐ ﮯﻧﺮﮐ ﻝﺎﻤﻌﺘﺳﺍ ﻡﺮﮐ ﮦﺍﺮﺑ",
766
+ "no_relays_message": "۔ﮟﯾﺮﮐ ﻞﻣﺎﺷ ﮯﻠﯾﺭ ﮟﯿﻣ ﮈﺭﺎﮑﯾﺭ ﺮﭩﺳﻮﻧ ﮯﻨﭘﺍ ﮦﻭ ﮧﮐ ﮟﯾﺩ ﺖﯾﺍﺪﮨ ﻮﮐ ﮦﺪﻨﻨﮐ ﻝﻮﺻﻭ ﻡﺮﮐ ﮦﺍﺮﺑ ۔",
767
+ "no_relay_on_domain": "۔ﮟﯾﺮﮐ ﺏﺎﺨﺘﻧﺍ ﺎﮐ ﮯﻠﯾﺭ ﮯﯿﻟ ﮯﮐ ﮯﻧﺮﮐ ﻝﺎﻤﻌﺘﺳﺍ ﻡﺮﮐ ﮦﺍﺮﺑ ۔ﮯﮨ ﮟﯿﮩﻧ ﺏﺎﯿﺘﺳﺩ ﮯﻠﯾﺭ ﺎﯾ ﮯﮨ ﮟ"
768
}
res/values/strings_yo.arb
+5
-1
@@ -762,5 +762,9 @@
762
"confirmed_tx": "Jẹrisi",
763
"transaction_details_source_address": "Adirẹsi orisun",
764
"pause_wallet_creation": "Agbara lati ṣẹda Haven Wallet ti wa ni idaduro lọwọlọwọ.",
765
- "camera_consent": "Kamẹra rẹ yoo ṣee lo lati ya aworan kan fun awọn idi idanimọ nipasẹ ${provider}. Jọwọ ṣayẹwo Ilana Aṣiri wọn fun awọn alaye."
765
+ "camera_consent": "Kamẹra rẹ yoo ṣee lo lati ya aworan kan fun awọn idi idanimọ nipasẹ ${provider}. Jọwọ ṣayẹwo Ilana Aṣiri wọn fun awọn alaye.",
766
+ "no_relays": "Ko si relays",
767
+ "choose_relay": "Jọwọ yan yii lati lo",
768
+ "no_relays_message": "A ri igbasilẹ Nostr NIP-05 fun olumulo yii, ṣugbọn ko ni eyikeyi awọn iṣipopada ninu. Jọwọ sọ fun olugba lati ṣafikun awọn isunmọ si igbasilẹ Nostr wọn.",
769
+ "no_relay_on_domain": "Ko si iṣipopada fun agbegbe olumulo tabi yiyi ko si. Jọwọ yan yii lati lo."
770
}
res/values/strings_zh.arb
+5
-1
@@ -767,5 +767,9 @@
767
"confirmed_tx": "确认的",
768
"transaction_details_source_address": "源地址",
769
"pause_wallet_creation": "创建 Haven 钱包的功能当前已暂停。",
770
- "camera_consent": "${provider} 将使用您的相机拍摄图像以供识别之用。请查看他们的隐私政策了解详情。"
770
+ "camera_consent": "${provider} 将使用您的相机拍摄图像以供识别之用。请查看他们的隐私政策了解详情。",
771
+ "no_relays": "无继电器",
772
+ "choose_relay": "请选择要使用的继电器",
773
+ "no_relays_message": "我们找到了该用户的 Nostr NIP-05 记录,但它不包含任何中继。请指示收件人将中继添加到他们的 Nostr 记录中。",
774
+ "no_relay_on_domain": "用户域没有中继或中继不可用。请选择要使用的继电器。"
775
}