Changed random seed generation for bitcoin.
M committed
May 10, 2021 at 13:06 UTC
bcd4fdd5e07800f922403995e772b8d285cf3917
23 files changed
+116
-56
android/app/src/main/java/com/cakewallet/cake_wallet/MainActivity.java
+34
@@ -1,15 +1,49 @@
1
package com.cakewallet.cake_wallet;
2
3
import androidx.annotation.NonNull;
4
+
5
import io.flutter.embedding.android.FlutterFragmentActivity;
6
import io.flutter.embedding.engine.FlutterEngine;
7
import io.flutter.plugins.GeneratedPluginRegistrant;
8
9
+import io.flutter.plugin.common.MethodCall;
10
+import io.flutter.plugin.common.MethodChannel;
11
+
12
+import android.os.AsyncTask;
13
+import android.os.Handler;
14
+import android.os.Looper;
15
+
16
+import java.security.SecureRandom;
17
18
public class MainActivity extends FlutterFragmentActivity {
19
+ final String UTILS_CHANNEL = "com.cake_wallet/native_utils";
20
21
@Override
22
public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
23
GeneratedPluginRegistrant.registerWith(flutterEngine);
24
+
25
+ MethodChannel utilsChannel =
26
+ new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(),
27
+ UTILS_CHANNEL);
28
+
29
+ utilsChannel.setMethodCallHandler(this::handle);
30
+ }
31
+
32
+ private void handle(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
33
+ Handler handler = new Handler(Looper.getMainLooper());
34
+
35
+ try {
36
+ if (call.method.equals("sec_random")) {
37
+ int count = call.argument("count");
38
+ SecureRandom random = new SecureRandom();
39
+ byte bytes[] = new byte[count];
40
+ random.nextBytes(bytes);
41
+ handler.post(() -> result.success(bytes));
42
+ } else {
43
+ handler.post(() -> result.notImplemented());
44
+ }
45
+ } catch (Exception e) {
46
+ handler.post(() -> result.error("UNCAUGHT_ERROR", e.getMessage(), null));
47
+ }
48
}
49
}
android/app/src/main/kotlin/com/cakewallet/cake_wallet/MainActivity.kt
deleted
-13
@@ -1,13 +0,0 @@
1
-package com.cakewallet.cake_wallet
2
-
3
-import androidx.annotation.NonNull;
4
-import io.flutter.embedding.android.FlutterActivity
5
-import io.flutter.embedding.android.FlutterFragmentActivity
6
-import io.flutter.embedding.engine.FlutterEngine
7
-import io.flutter.plugins.GeneratedPluginRegistrant
8
-
9
-class MainActivity: FlutterActivity() {
10
- override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine){
11
- GeneratedPluginRegistrant.registerWith(flutterEngine);
12
- }
13
-}
ios/CakeWallet/secRandom.swift
new
+12
@@ -0,0 +1,12 @@
1
+import Foundation
2
+
3
+func secRandom(count: Int) -> Data? {
4
+ var bytes = [Int8](repeating: 0, count: count)
5
+ let status = SecRandomCopyBytes(kSecRandomDefault, bytes.count, &bytes)
6
+
7
+ if status == errSecSuccess {
8
+ return Data(bytes: bytes, count: bytes.count)
9
+ }
10
+
11
+ return nil
12
+}
ios/Runner.xcodeproj/project.pbxproj
+10
-6
@@ -8,6 +8,7 @@
8
9
/* Begin PBXBuildFile section */
10
0C44A71A2518EF8000B570ED /* decrypt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C44A7192518EF8000B570ED /* decrypt.swift */; };
11
+ 0C9D68C9264854B60011B691 /* secRandom.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C9D68C8264854B60011B691 /* secRandom.swift */; };
12
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
13
20ED0868E1BD7E12278C0CB3 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B26E3F56D69167FBB1DC160A /* Pods_Runner.framework */; };
14
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
@@ -21,6 +22,7 @@
22
0C400E0F25B21ABB0025E469 /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = "<group>"; };
23
0C44A7192518EF8000B570ED /* decrypt.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = decrypt.swift; sourceTree = "<group>"; };
24
0C9986A3251A932F00D566FD /* CryptoSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = CryptoSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; };
25
+ 0C9D68C8264854B60011B691 /* secRandom.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = secRandom.swift; sourceTree = "<group>"; };
26
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
27
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
28
20F67A1B2C2FCB2A3BB048C1 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
@@ -65,6 +67,7 @@
67
isa = PBXGroup;
68
children = (
69
0C44A7192518EF8000B570ED /* decrypt.swift */,
70
+ 0C9D68C8264854B60011B691 /* secRandom.swift */,
71
);
72
path = CakeWallet;
73
sourceTree = "<group>";
@@ -274,6 +277,7 @@
277
files = (
278
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
279
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
280
+ 0C9D68C9264854B60011B691 /* secRandom.swift in Sources */,
281
0C44A71A2518EF8000B570ED /* decrypt.swift in Sources */,
282
);
283
runOnlyForDeploymentPostprocessing = 0;
@@ -358,7 +362,7 @@
362
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
363
CLANG_ENABLE_MODULES = YES;
364
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
361
- CURRENT_PROJECT_VERSION = 35;
365
+ CURRENT_PROJECT_VERSION = 36;
366
DEVELOPMENT_TEAM = 32J6BB6VUS;
367
ENABLE_BITCODE = NO;
368
FRAMEWORK_SEARCH_PATHS = (
@@ -375,7 +379,7 @@
379
"$(inherited)",
380
"$(PROJECT_DIR)/Flutter",
381
);
378
- MARKETING_VERSION = 4.1.6;
382
+ MARKETING_VERSION = 4.1.7;
383
PRODUCT_BUNDLE_IDENTIFIER = com.fotolockr.cakewallet;
384
PRODUCT_NAME = "$(TARGET_NAME)";
385
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@@ -501,7 +505,7 @@
505
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
506
CLANG_ENABLE_MODULES = YES;
507
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
504
- CURRENT_PROJECT_VERSION = 35;
508
+ CURRENT_PROJECT_VERSION = 36;
509
DEVELOPMENT_TEAM = 32J6BB6VUS;
510
ENABLE_BITCODE = NO;
511
FRAMEWORK_SEARCH_PATHS = (
@@ -518,7 +522,7 @@
522
"$(inherited)",
523
"$(PROJECT_DIR)/Flutter",
524
);
521
- MARKETING_VERSION = 4.1.6;
525
+ MARKETING_VERSION = 4.1.7;
526
PRODUCT_BUNDLE_IDENTIFIER = com.fotolockr.cakewallet;
527
PRODUCT_NAME = "$(TARGET_NAME)";
528
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@@ -536,7 +540,7 @@
540
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
541
CLANG_ENABLE_MODULES = YES;
542
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
539
- CURRENT_PROJECT_VERSION = 35;
543
+ CURRENT_PROJECT_VERSION = 36;
544
DEVELOPMENT_TEAM = 32J6BB6VUS;
545
ENABLE_BITCODE = NO;
546
FRAMEWORK_SEARCH_PATHS = (
@@ -553,7 +557,7 @@
557
"$(inherited)",
558
"$(PROJECT_DIR)/Flutter",
559
);
556
- MARKETING_VERSION = 4.1.6;
560
+ MARKETING_VERSION = 4.1.7;
561
PRODUCT_BUNDLE_IDENTIFIER = com.fotolockr.cakewallet;
562
PRODUCT_NAME = "$(TARGET_NAME)";
563
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
ios/Runner/AppDelegate.swift
+22
-3
@@ -8,9 +8,10 @@ import Flutter
8
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
9
) -> Bool {
10
let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
11
- let batteryChannel = FlutterMethodChannel(name: "com.cakewallet.cakewallet/legacy_wallet_migration",
12
- binaryMessenger: controller.binaryMessenger)
13
- batteryChannel.setMethodCallHandler({
11
+ let legacyMigrationChannel = FlutterMethodChannel(
12
+ name: "com.cakewallet.cakewallet/legacy_wallet_migration",
13
+ binaryMessenger: controller.binaryMessenger)
14
+ legacyMigrationChannel.setMethodCallHandler({
15
(call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
16
17
switch call.method {
@@ -52,6 +53,24 @@ import Flutter
53
}
54
})
55
56
+ let utilsChannel = FlutterMethodChannel(
57
+ name: "com.cake_wallet/native_utils",
58
+ binaryMessenger: controller.binaryMessenger)
59
+ utilsChannel.setMethodCallHandler({ (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
60
+ switch call.method {
61
+ case "sec_random":
62
+ guard let args = call.arguments as? Dictionary<String, Any>,
63
+ let count = args["count"] as? Int else {
64
+ result(nil)
65
+ return
66
+ }
67
+
68
+ result(secRandom(count: count))
69
+ default:
70
+ result(FlutterMethodNotImplemented)
71
+ }
72
+ })
73
+
74
GeneratedPluginRegistrant.register(with: self)
75
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
76
}
lib/bitcoin/bitcoin_mnemonic.dart
+5
-16
@@ -4,23 +4,11 @@ import 'dart:typed_data';
4
import 'package:crypto/crypto.dart';
5
import 'package:unorm_dart/unorm_dart.dart' as unorm;
6
import 'package:cryptography/cryptography.dart' as cryptography;
7
+import 'package:cake_wallet/core/sec_random_native.dart';
8
9
const segwit = '100';
10
final wordlist = englishWordlist;
11
11
-Uint8List randomBytes(int length, {bool secure = false}) {
12
- assert(length > 0);
13
-
14
- final random = secure ? Random.secure() : Random();
15
- final ret = Uint8List(length);
16
-
17
- for (var i = 0; i < length; i++) {
18
- ret[i] = random.nextInt(256);
19
- }
20
-
21
- return ret;
22
-}
23
-
12
double logBase(num x, num base) => log(x) / log(base);
13
14
String mnemonicEncode(int i) {
@@ -102,14 +90,15 @@ List<bool> prefixMatches(String source, List<String> prefixes) {
90
return prefixes.map((prefix) => hx.startsWith(prefix.toLowerCase())).toList();
91
}
92
105
-String generateMnemonic({int strength = 132, String prefix = segwit}) {
93
+Future<String> generateMnemonic(
94
+ {int strength = 264, String prefix = segwit}) async {
95
final wordBitlen = logBase(wordlist.length, 2).ceil();
96
final wordCount = strength / wordBitlen;
97
final byteCount = ((wordCount * wordBitlen).ceil() / 8).ceil();
98
var result = '';
99
100
do {
112
- final bytes = randomBytes(byteCount);
101
+ final bytes = await secRandom(byteCount);
102
maskBytes(bytes, strength);
103
result = encode(bytes);
104
} while (!prefixMatches(result, [prefix]).first);
@@ -134,7 +123,7 @@ bool matchesAnyPrefix(String mnemonic) =>
123
bool validateMnemonic(String mnemonic, {String prefix = segwit}) {
124
try {
125
return matchesAnyPrefix(mnemonic);
137
- } catch(e) {
126
+ } catch (e) {
127
return false;
128
}
129
}
lib/bitcoin/bitcoin_mnemonic_is_incorrect_exception.dart
+1
-1
@@ -1,5 +1,5 @@
1
class BitcoinMnemonicIsIncorrectException implements Exception {
2
@override
3
String toString() =>
4
- 'Bitcoin mnemonic has incorrect format. Mnemonic should contain 12 words separated by space.';
4
+ 'Bitcoin mnemonic has incorrect format. Mnemonic should contain 24 words separated by space.';
5
}
lib/bitcoin/bitcoin_wallet_service.dart
+2
-2
@@ -25,7 +25,7 @@ class BitcoinWalletService extends WalletService<
25
type: WalletType.bitcoin, name: credentials.name);
26
final wallet = BitcoinWalletBase.build(
27
dirPath: dirPath,
28
- mnemonic: generateMnemonic(),
28
+ mnemonic: await generateMnemonic(),
29
password: credentials.password,
30
name: credentials.name,
31
walletInfo: credentials.walletInfo);
@@ -47,7 +47,7 @@ class BitcoinWalletService extends WalletService<
47
final walletPath = '$walletDirPath/$name';
48
final walletJSONRaw = await read(path: walletPath, password: password);
49
final walletInfo = walletInfoSource.values.firstWhere(
50
- (info) => info.id == WalletBase.idFor(name, WalletType.bitcoin),
50
+ (info) => info.id == WalletBase.idFor(name, WalletType.bitcoin),
51
orElse: () => null);
52
final wallet = BitcoinWalletBase.fromJSON(
53
password: password,
lib/core/sec_random_native.dart
new
+13
@@ -0,0 +1,13 @@
1
+import 'dart:typed_data';
2
+
3
+import 'package:flutter/services.dart';
4
+
5
+const utils = const MethodChannel('com.cake_wallet/native_utils');
6
+
7
+Future<Uint8List> secRandom(int count) async {
8
+ try {
9
+ return await utils.invokeMethod<Uint8List>('sec_random', {'count': count});
10
+ } on PlatformException catch (_) {
11
+ return Uint8List.fromList([]);
12
+ }
13
+}
lib/monero/monero_wallet_service.dart
+1
-1
@@ -228,7 +228,7 @@ class MoneroWalletService extends WalletService<
228
final name = f.path.split('/').last;
229
final newPath = newWalletDirPath + '/$name';
230
final newFile = File(newPath);
231
- print(file.path);
231
+
232
if (!newFile.existsSync()) {
233
newFile.createSync();
234
}
lib/src/screens/seed/pre_seed_page.dart
+4
-2
@@ -13,7 +13,7 @@ class PreSeedPage extends BasePage {
13
imageDark = Image.asset('assets/images/pre_seed_dark.png'),
14
wordsCount = type == WalletType.monero
15
? 25
16
- : 12; // FIXME: Stupid fast implementation
16
+ : 24; // FIXME: Stupid fast implementation
17
18
final Image imageDark;
19
final Image imageLight;
@@ -49,7 +49,9 @@ class PreSeedPage extends BasePage {
49
Padding(
50
padding: EdgeInsets.only(top: 70, left: 16, right: 16),
51
child: Text(
52
- S.of(context).pre_seed_description(wordsCount.toString()),
52
+ S
53
+ .of(context)
54
+ .pre_seed_description(wordsCount.toString()),
55
textAlign: TextAlign.center,
56
style: TextStyle(
57
fontSize: 14,
pubspec.yaml
+1
-1
@@ -11,7 +11,7 @@ description: Cake Wallet.
11
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
12
# Read more about iOS versioning at
13
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
14
-version: 4.1.6+45
14
+version: 4.1.7+46
15
16
environment:
17
sdk: ">=2.7.0 <3.0.0"
res/values/strings_de.arb
+1
-1
@@ -170,7 +170,7 @@
170
"restore_wallet_restore_description" : "Beschreibung zur Wiederherstellung der Brieftasche",
171
"restore_new_seed" : "Neuer Seed",
172
"restore_active_seed" : "Aktives Seed",
173
- "restore_bitcoin_description_from_seed" : "Stellen Sie Ihre Brieftasche aus dem 12-Wort-Kombinationscode wieder her",
173
+ "restore_bitcoin_description_from_seed" : "Stellen Sie Ihre Brieftasche aus dem 24-Wort-Kombinationscode wieder her",
174
"restore_bitcoin_description_from_keys" : "Stellen Sie Ihre Brieftasche aus der generierten WIF-Zeichenfolge aus Ihren privaten Schlüsseln wieder her",
175
"restore_bitcoin_title_from_keys" : "Aus WIF wiederherstellen",
176
"restore_from_date_or_blockheight" : "Bitte geben Sie einige Tage vor dem Erstellen dieser Brieftasche ein Datum ein. Oder wenn Sie die Blockhöhe kennen, geben Sie sie stattdessen ein",
res/values/strings_es.arb
+1
-1
@@ -170,7 +170,7 @@
170
"restore_wallet_restore_description" : "Restaurar billetera",
171
"restore_new_seed" : "Nueva semilla",
172
"restore_active_seed" : "Semilla activa",
173
- "restore_bitcoin_description_from_seed" : "Restaure su billetera a partir del código de combinación de 12 palabras",
173
+ "restore_bitcoin_description_from_seed" : "Restaure su billetera a partir del código de combinación de 24 palabras",
174
"restore_bitcoin_description_from_keys" : "Restaure su billetera a partir de una cadena WIF generada a partir de sus claves privadas",
175
"restore_bitcoin_title_from_keys" : "Restaurar desde WIF",
176
"restore_from_date_or_blockheight" : "Ingrese una fecha unos días antes de crear esta billetera. O si conoce la altura del bloque, ingréselo en su lugar",
res/values/strings_hi.arb
+1
-1
@@ -170,7 +170,7 @@
170
"restore_wallet_restore_description" : "बटुआ विवरण पुनर्स्थापित करें",
171
"restore_new_seed" : "नया बीज",
172
"restore_active_seed" : "सक्रिय बीज",
173
- "restore_bitcoin_description_from_seed" : "12 शब्द संयोजन कोड से अपने वॉलेट को पुनर्स्थापित करें",
173
+ "restore_bitcoin_description_from_seed" : "24 शब्द संयोजन कोड से अपने वॉलेट को पुनर्स्थापित करें",
174
"restore_bitcoin_description_from_keys" : "अपने निजी कुंजी से उत्पन्न WIF स्ट्रिंग से अपने वॉलेट को पुनर्स्थापित करें",
175
"restore_bitcoin_title_from_keys" : "WIF से पुनर्स्थापित करें",
176
"restore_from_date_or_blockheight" : "कृपया इस वॉलेट को बनाने से कुछ दिन पहले एक तारीख दर्ज करें। या यदि आप ब्लॉकचेट जानते हैं, तो कृपया इसके बजाय इसे दर्ज करें",
res/values/strings_ja.arb
+1
-1
@@ -170,7 +170,7 @@
170
"restore_wallet_restore_description" : "ウォレットの復元",
171
"restore_new_seed" : "新しい種",
172
"restore_active_seed" : "アクティブシード",
173
- "restore_bitcoin_description_from_seed" : "12ワードの組み合わせコードからウォレットを復元する",
173
+ "restore_bitcoin_description_from_seed" : "24ワードの組み合わせコードからウォレットを復元する",
174
"restore_bitcoin_description_from_keys" : "秘密鍵から生成されたWIF文字列からウォレットを復元します",
175
"restore_bitcoin_title_from_keys" : "WIFから復元",
176
"restore_from_date_or_blockheight" : "このウォレットを作成する数日前に日付を入力してください。 または、ブロックの高さがわかっている場合は、代わりに入力してください",
res/values/strings_ko.arb
+1
-1
@@ -170,7 +170,7 @@
170
"restore_wallet_restore_description" : "월렛 복원 설명",
171
"restore_new_seed" : "새로운 씨앗",
172
"restore_active_seed" : "활성 종자",
173
- "restore_bitcoin_description_from_seed" : "12 단어 조합 코드에서 지갑 복원",
173
+ "restore_bitcoin_description_from_seed" : "24 단어 조합 코드에서 지갑 복원",
174
"restore_bitcoin_description_from_keys" : "개인 키에서 생성 된 WIF 문자열에서 지갑 복원",
175
"restore_bitcoin_title_from_keys" : "WIF에서 복원",
176
"restore_from_date_or_blockheight" : "이 지갑을 생성하기 며칠 전에 날짜를 입력하십시오. 또는 블록 높이를 알고있는 경우 대신 입력하십시오.",
res/values/strings_nl.arb
+1
-1
@@ -170,7 +170,7 @@
170
"restore_wallet_restore_description" : "Portemonnee-herstelbeschrijving",
171
"restore_new_seed" : "Nieuw zaad",
172
"restore_active_seed" : "Actief zaad",
173
- "restore_bitcoin_description_from_seed" : "Herstel uw portemonnee met een combinatiecode van 12 woorden",
173
+ "restore_bitcoin_description_from_seed" : "Herstel uw portemonnee met een combinatiecode van 24 woorden",
174
"restore_bitcoin_description_from_keys" : "Herstel uw portemonnee van de gegenereerde WIF-string van uw privésleutels",
175
"restore_bitcoin_title_from_keys" : "Herstel van WIF",
176
"restore_from_date_or_blockheight" : "Voer een datum in een paar dagen voordat u deze portemonnee heeft gemaakt. Of als u de blokhoogte kent, voert u deze in",
res/values/strings_pl.arb
+1
-1
@@ -170,7 +170,7 @@
170
"restore_wallet_restore_description" : "Opis przywracania portfela",
171
"restore_new_seed" : "Nowe nasienie",
172
"restore_active_seed" : "Aktywne nasiona",
173
- "restore_bitcoin_description_from_seed" : "Przywróć swój portfel z kodu złożonego z 12 słów",
173
+ "restore_bitcoin_description_from_seed" : "Przywróć swój portfel z kodu złożonego z 24 słów",
174
"restore_bitcoin_description_from_keys" : "Przywróć swój portfel z wygenerowanego ciągu WIF z kluczy prywatnych",
175
"restore_bitcoin_title_from_keys" : "Przywróć z WIF",
176
"restore_from_date_or_blockheight" : "Wprowadź datę na kilka dni przed utworzeniem tego portfela. Lub jeśli znasz wysokość bloku, wprowadź go zamiast tego",
res/values/strings_pt.arb
+1
-1
@@ -170,7 +170,7 @@
170
"restore_wallet_restore_description" : "Restauração da carteira",
171
"restore_new_seed" : "Nova semente",
172
"restore_active_seed" : "Semente ativa",
173
- "restore_bitcoin_description_from_seed" : "Restaure sua carteira a partir de um código de combinação de 12 palavras",
173
+ "restore_bitcoin_description_from_seed" : "Restaure sua carteira a partir de um código de combinação de 24 palavras",
174
"restore_bitcoin_description_from_keys" : "Restaure sua carteira a partir da string WIF gerada de suas chaves privadas",
175
"restore_bitcoin_title_from_keys" : "Restaurar de WIF",
176
"restore_from_date_or_blockheight" : "Insira uma data alguns dias antes de criar esta carteira. Ou se você souber a altura do bloco, insira-o",
res/values/strings_ru.arb
+1
-1
@@ -170,7 +170,7 @@
170
"restore_wallet_restore_description" : "Описание восстановления кошелька",
171
"restore_new_seed" : "Новая мнемоническая фраза",
172
"restore_active_seed" : "Активная мнемоническая фраза",
173
- "restore_bitcoin_description_from_seed" : "Вы можете восстановить кошелёк используя 12-ти значную мнемоническую фразу",
173
+ "restore_bitcoin_description_from_seed" : "Вы можете восстановить кошелёк используя 24-ти значную мнемоническую фразу",
174
"restore_bitcoin_description_from_keys" : "Вы можете восстановить кошелёк с помощью WIF",
175
"restore_bitcoin_title_from_keys" : "Восстановить с помощью WIF",
176
"restore_from_date_or_blockheight" : "Пожалуйста, введите дату за несколько дней до создания этого кошелька. Или, если вы знаете высоту блока, введите ее значение",
res/values/strings_uk.arb
+1
-1
@@ -170,7 +170,7 @@
170
"restore_wallet_restore_description" : "Опис відновлюваного гаманця",
171
"restore_new_seed" : "Нова мнемонічна фраза",
172
"restore_active_seed" : "Активна мнемонічна фраза",
173
- "restore_bitcoin_description_from_seed" : "Ви можете відновити гаманець використовуючи 12-ти слівну мнемонічну фразу",
173
+ "restore_bitcoin_description_from_seed" : "Ви можете відновити гаманець використовуючи 24-ти слівну мнемонічну фразу",
174
"restore_bitcoin_description_from_keys" : "Ви можете відновити гаманець за допомогою WIF",
175
"restore_bitcoin_title_from_keys" : "Відновити за допомогою WIF",
176
"restore_from_date_or_blockheight" : "Будь ласка, введіть дату за кілька днів до створення цього гаманця. Або, якщо ви знаєте висоту блоку, введіть її значення",
res/values/strings_zh.arb
+1
-1
@@ -170,7 +170,7 @@
170
"restore_wallet_restore_description" : "钱包还原说明",
171
"restore_new_seed" : "新種子",
172
"restore_active_seed" : "活性種子",
173
- "restore_bitcoin_description_from_seed" : "從12個單詞的組合碼恢復您的錢包",
173
+ "restore_bitcoin_description_from_seed" : "從24個單詞的組合碼恢復您的錢包",
174
"restore_bitcoin_description_from_keys" : "從私鑰中生成的WIF字符串還原您的錢包",
175
"restore_bitcoin_title_from_keys" : "從WIF還原",
176
"restore_from_date_or_blockheight" : "請在創建此錢包之前幾天輸入一個日期。 或者,如果您知道塊高,請改為輸入",