mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-06-28 12:29:51 +00:00
Merge remote-tracking branch 'origin/main' into electrum-sp-refactors
This commit is contained in:
commit
917d62e12f
98 changed files with 1991 additions and 1041 deletions
|
@ -55,7 +55,7 @@ jobs:
|
|||
- name: Flutter action
|
||||
uses: subosito/flutter-action@v1
|
||||
with:
|
||||
flutter-version: "3.24.0"
|
||||
flutter-version: "3.27.4"
|
||||
channel: stable
|
||||
|
||||
- name: Install package dependencies
|
||||
|
|
2
.github/workflows/pr_test_build_android.yml
vendored
2
.github/workflows/pr_test_build_android.yml
vendored
|
@ -9,7 +9,7 @@ jobs:
|
|||
PR_test_build:
|
||||
runs-on: linux-amd64
|
||||
container:
|
||||
image: ghcr.io/cake-tech/cake_wallet:3.24.4-linux
|
||||
image: ghcr.io/cake-tech/cake_wallet:3.27.4-linux
|
||||
env:
|
||||
STORE_PASS: test@cake_wallet
|
||||
KEY_PASS: test@cake_wallet
|
||||
|
|
2
.github/workflows/pr_test_build_linux.yml
vendored
2
.github/workflows/pr_test_build_linux.yml
vendored
|
@ -9,7 +9,7 @@ jobs:
|
|||
PR_test_build:
|
||||
runs-on: linux-amd64
|
||||
container:
|
||||
image: ghcr.io/cake-tech/cake_wallet:3.24.4-linux
|
||||
image: ghcr.io/cake-tech/cake_wallet:3.27.4-linux
|
||||
env:
|
||||
STORE_PASS: test@cake_wallet
|
||||
KEY_PASS: test@cake_wallet
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
# Usage:
|
||||
# docker build . -f Dockerfile -t ghcr.io/cake-tech/cake_wallet:3.24.4-linux
|
||||
# docker push ghcr.io/cake-tech/cake_wallet:3.24.4-linux
|
||||
# docker build . -f Dockerfile -t ghcr.io/cake-tech/cake_wallet:3.27.4-linux
|
||||
# docker push ghcr.io/cake-tech/cake_wallet:3.27.4-linux
|
||||
|
||||
# Heavily inspired by cirrusci images
|
||||
# https://github.com/cirruslabs/docker-images-android/blob/master/sdk/tools/Dockerfile
|
||||
|
@ -17,7 +16,7 @@ LABEL org.opencontainers.image.source=https://github.com/cake-tech/cake_wallet
|
|||
ENV GOLANG_VERSION=1.23.4
|
||||
|
||||
# Pin Flutter version to latest known-working version
|
||||
ENV FLUTTER_VERSION=3.24.4
|
||||
ENV FLUTTER_VERSION=3.27.4
|
||||
|
||||
# Pin Android Studio, platform, and build tools versions to latest known-working version
|
||||
# Comes from https://developer.android.com/studio/#command-tools
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
plugins {
|
||||
id "com.android.application"
|
||||
id "kotlin-android"
|
||||
id "dev.flutter.flutter-gradle-plugin"
|
||||
}
|
||||
|
||||
def localProperties = new Properties()
|
||||
def localPropertiesFile = rootProject.file('local.properties')
|
||||
if (localPropertiesFile.exists()) {
|
||||
|
@ -6,11 +12,6 @@ if (localPropertiesFile.exists()) {
|
|||
}
|
||||
}
|
||||
|
||||
def flutterRoot = localProperties.getProperty('flutter.sdk')
|
||||
if (flutterRoot == null) {
|
||||
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
|
||||
}
|
||||
|
||||
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
|
||||
if (flutterVersionCode == null) {
|
||||
flutterVersionCode = '1'
|
||||
|
@ -21,9 +22,6 @@ if (flutterVersionName == null) {
|
|||
flutterVersionName = '1.0'
|
||||
}
|
||||
|
||||
apply plugin: 'com.android.application'
|
||||
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
|
||||
|
||||
def keystoreProperties = new Properties()
|
||||
def keystorePropertiesFile = rootProject.file('key.properties')
|
||||
if (keystorePropertiesFile.exists()) {
|
||||
|
@ -37,8 +35,8 @@ if (appPropertiesFile.exists()) {
|
|||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 34
|
||||
buildToolsVersion "34.0.0"
|
||||
compileSdkVersion 35
|
||||
buildToolsVersion "35.0.0"
|
||||
|
||||
lintOptions {
|
||||
disable 'InvalidPackage'
|
||||
|
@ -81,6 +79,9 @@ android {
|
|||
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
debug {
|
||||
signingConfig signingConfigs.release
|
||||
}
|
||||
}
|
||||
|
||||
ndkVersion "27.0.12077973"
|
||||
|
|
|
@ -1,17 +1,3 @@
|
|||
buildscript {
|
||||
ext.kotlin_version = '2.0.21'
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:8.7.1'
|
||||
classpath 'com.google.gms:google-services:4.3.8'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
|
|
|
@ -1,15 +1,26 @@
|
|||
include ':app'
|
||||
pluginManagement {
|
||||
def flutterSdkPath = {
|
||||
def properties = new Properties()
|
||||
file("local.properties").withInputStream { properties.load(it) }
|
||||
def flutterSdkPath = properties.getProperty("flutter.sdk")
|
||||
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
|
||||
return flutterSdkPath
|
||||
}()
|
||||
|
||||
def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
|
||||
includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
|
||||
|
||||
def plugins = new Properties()
|
||||
def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
|
||||
if (pluginsFile.exists()) {
|
||||
pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
gradlePluginPortal()
|
||||
}
|
||||
}
|
||||
|
||||
plugins.each { name, path ->
|
||||
def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
|
||||
include ":$name"
|
||||
project(":$name").projectDir = pluginDirectory
|
||||
plugins {
|
||||
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
|
||||
id "com.android.application" version "8.7.1" apply false
|
||||
id "org.jetbrains.kotlin.android" version "2.0.21" apply false
|
||||
id "com.google.gms.google-services" version "4.3.8" apply false
|
||||
}
|
||||
|
||||
include ":app"
|
|
@ -17,14 +17,6 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.7.0"
|
||||
archive:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: archive
|
||||
sha256: cb6a278ef2dbb298455e1a713bda08524a175630ec643a242c399c932a0a1f7d
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.6.1"
|
||||
args:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -93,7 +85,7 @@ packages:
|
|||
source: git
|
||||
version: "5.0.0"
|
||||
blockchain_utils:
|
||||
dependency: "direct overridden"
|
||||
dependency: "direct main"
|
||||
description:
|
||||
path: "."
|
||||
ref: cake-update-v4
|
||||
|
@ -105,10 +97,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: bluez
|
||||
sha256: "203a1924e818a9dd74af2b2c7a8f375ab8e5edf0e486bba8f90a0d8a17ed9fce"
|
||||
sha256: "61a7204381925896a374301498f2f5399e59827c6498ae1e924aaa598751b545"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.8.2"
|
||||
version: "0.8.3"
|
||||
boolean_selector:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -242,10 +234,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: collection
|
||||
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
|
||||
sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.18.0"
|
||||
version: "1.19.0"
|
||||
convert:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -447,10 +439,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: grpc
|
||||
sha256: e93ee3bce45c134bf44e9728119102358c7cd69de7832d9a874e2e74eb8cab40
|
||||
sha256: "5b99b7a420937d4361ece68b798c9af8e04b5bc128a7859f2a4be87427694813"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.2.4"
|
||||
version: "4.0.1"
|
||||
hex:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -543,18 +535,18 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker
|
||||
sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05"
|
||||
sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "10.0.5"
|
||||
version: "10.0.7"
|
||||
leak_tracker_flutter_testing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker_flutter_testing
|
||||
sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806"
|
||||
sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.5"
|
||||
version: "3.0.8"
|
||||
leak_tracker_testing:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -874,10 +866,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_web
|
||||
sha256: d2ca4132d3946fec2184261726b355836a82c33d7d5b67af32692aff18a4684e
|
||||
sha256: c49bd060261c9a3f0ff445892695d6212ff603ef3115edbb448509d407600019
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.2"
|
||||
version: "2.4.3"
|
||||
shared_preferences_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -906,7 +898,7 @@ packages:
|
|||
dependency: transitive
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.99"
|
||||
version: "0.0.0"
|
||||
socks5_proxy:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -945,17 +937,17 @@ packages:
|
|||
path: "."
|
||||
ref: cake-update-v4
|
||||
resolved-ref: "888bd27c3c4495c890580ebaaba6771b4f40eff6"
|
||||
url: "https://github.com/cake-tech/sp_scanner.git"
|
||||
url: "https://github.com/cake-tech/sp_scanner"
|
||||
source: git
|
||||
version: "0.0.1"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stack_trace
|
||||
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
|
||||
sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.11.1"
|
||||
version: "1.12.0"
|
||||
stream_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -976,10 +968,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: string_scanner
|
||||
sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
|
||||
sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "1.3.0"
|
||||
term_glyph:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -992,10 +984,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb"
|
||||
sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.2"
|
||||
version: "0.7.3"
|
||||
timing:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1056,10 +1048,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: vm_service
|
||||
sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d"
|
||||
sha256: f6be3ed8bd01289b34d679c2b62226f63c0e69f9fd2e50a6b3c1c729a961041b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "14.2.5"
|
||||
version: "14.3.0"
|
||||
watcher:
|
||||
dependency: "direct overridden"
|
||||
description:
|
||||
|
@ -1072,10 +1064,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: web
|
||||
sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb
|
||||
sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "1.1.1"
|
||||
web_socket:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
|
@ -24,6 +24,10 @@ dependencies:
|
|||
git:
|
||||
url: https://github.com/cake-tech/bitcoin_base
|
||||
ref: cake-update-v15
|
||||
blockchain_utils:
|
||||
git:
|
||||
url: https://github.com/cake-tech/blockchain_utils
|
||||
ref: cake-update-v4
|
||||
bitbox:
|
||||
git:
|
||||
url: https://github.com/cake-tech/bitbox-flutter.git
|
||||
|
@ -32,10 +36,10 @@ dependencies:
|
|||
cryptography: ^2.0.5
|
||||
cw_mweb:
|
||||
path: ../cw_mweb
|
||||
grpc: ^3.2.4
|
||||
grpc: ^4.0.1
|
||||
sp_scanner:
|
||||
git:
|
||||
url: https://github.com/cake-tech/sp_scanner.git
|
||||
url: https://github.com/cake-tech/sp_scanner
|
||||
ref: cake-update-v4
|
||||
bech32:
|
||||
git:
|
||||
|
@ -61,10 +65,6 @@ dev_dependencies:
|
|||
dependency_overrides:
|
||||
watcher: ^1.1.0
|
||||
protobuf: ^3.1.0
|
||||
blockchain_utils:
|
||||
git:
|
||||
url: https://github.com/cake-tech/blockchain_utils
|
||||
ref: cake-update-v4
|
||||
pointycastle: 3.7.4
|
||||
ffi: 2.1.0
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import 'package:flutter/services.dart';
|
||||
|
||||
void setIsAppSecureNative(bool isAppSecure) {
|
||||
Future<void> setIsAppSecureNative(bool isAppSecure) async {
|
||||
try {
|
||||
final utils = const MethodChannel('com.cake_wallet/native_utils');
|
||||
|
||||
utils.invokeMethod<Uint8List>('setIsAppSecure', {'isAppSecure': isAppSecure});
|
||||
await utils.invokeMethod<Uint8List>('setIsAppSecure', {'isAppSecure': isAppSecure});
|
||||
} catch (_) {}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import 'dart:math';
|
||||
|
||||
void printV(dynamic content) {
|
||||
CustomTrace programInfo = CustomTrace(StackTrace.current);
|
||||
print("${programInfo.fileName}#${programInfo.lineNumber}:${programInfo.columnNumber} ${programInfo.callerFunctionName}: $content");
|
||||
|
@ -29,7 +31,7 @@ class CustomTrace {
|
|||
var indexOfWhiteSpace = currentTrace.indexOf(' ');
|
||||
|
||||
/* Create a substring from the first whitespace index till the end of the string */
|
||||
var subStr = currentTrace.substring(indexOfWhiteSpace);
|
||||
var subStr = currentTrace.substring(max(0, indexOfWhiteSpace));
|
||||
|
||||
/* Grab the function name using reg expr */
|
||||
var indexOfFunction = subStr.indexOf(RegExp(r'[A-Za-z0-9_]'));
|
||||
|
@ -40,7 +42,7 @@ class CustomTrace {
|
|||
indexOfWhiteSpace = subStr.indexOf(RegExp(r'[ .]'));
|
||||
|
||||
/* Create a new substring from start to the first index of a whitespace. This substring gives us the function name */
|
||||
subStr = subStr.substring(0, indexOfWhiteSpace);
|
||||
subStr = subStr.substring(0, max(0, indexOfWhiteSpace));
|
||||
|
||||
return subStr;
|
||||
}
|
||||
|
@ -61,7 +63,7 @@ class CustomTrace {
|
|||
/* Search through the string and find the index of the file name by looking for the '.dart' regex */
|
||||
var indexOfFileName = traceString.indexOf(RegExp(r'[/A-Za-z_]+.dart'), 1); // 1 to offest and not print the printV function name
|
||||
|
||||
var fileInfo = traceString.substring(indexOfFileName);
|
||||
var fileInfo = traceString.substring(max(0, indexOfFileName));
|
||||
|
||||
var listOfInfos = fileInfo.split(":");
|
||||
|
||||
|
@ -78,7 +80,7 @@ class CustomTrace {
|
|||
columnStr = columnStr.replaceFirst(")", "");
|
||||
this.columnNumber = int.tryParse(columnStr);
|
||||
} catch (e) {
|
||||
|
||||
print("Unable to parse trace (printV): $e");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,6 +70,12 @@ abstract class WalletBase<BalanceType extends Balance, HistoryType extends Trans
|
|||
// there is a default definition here because only coins with a pow node (nano based) need to override this
|
||||
Future<void> connectToPowNode({required Node node}) async {}
|
||||
|
||||
// startBackgroundSync is used to start sync in the background, without doing any
|
||||
// extra things in the background.
|
||||
// startSync is used as a fallback.
|
||||
Future<void> startBackgroundSync() => startSync();
|
||||
Future<void> stopBackgroundSync(String password) => stopSync();
|
||||
|
||||
Future<void> startSync();
|
||||
|
||||
Future<void> stopSync() async {}
|
||||
|
|
|
@ -5,23 +5,23 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: _fe_analyzer_shared
|
||||
sha256: f256b0c0ba6c7577c15e2e4e114755640a875e885099367bf6e012b19314c834
|
||||
sha256: "16e298750b6d0af7ce8a3ba7c18c69c3785d11b15ec83f6dcd0ad2a0009b3cab"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "72.0.0"
|
||||
version: "76.0.0"
|
||||
_macros:
|
||||
dependency: transitive
|
||||
description: dart
|
||||
source: sdk
|
||||
version: "0.3.2"
|
||||
version: "0.3.3"
|
||||
analyzer:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: analyzer
|
||||
sha256: b652861553cd3990d8ed361f7979dc6d7053a9ac8843fa73820ab68ce5410139
|
||||
sha256: "1f14db053a8c23e260789e9b0980fa27f2680dd640932cae5e1137cce0e46e1e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.7.0"
|
||||
version: "6.11.0"
|
||||
args:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -34,10 +34,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: asn1lib
|
||||
sha256: "6b151826fcc95ff246cd219a0bf4c753ea14f4081ad71c61939becf3aba27f70"
|
||||
sha256: "4bae5ae63e6d6dd17c4aac8086f3dec26c0236f6a0f03416c6c19d830c367cf5"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.5.5"
|
||||
version: "1.5.8"
|
||||
async:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -123,10 +123,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: built_value
|
||||
sha256: c7913a9737ee4007efedaffc968c049fd0f3d0e49109e778edc10de9426005cb
|
||||
sha256: "8b158ab94ec6913e480dc3f752418348b5ae099eb75868b5f4775f0572999c61"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "8.9.2"
|
||||
version: "8.9.4"
|
||||
cake_backup:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -164,18 +164,18 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: code_builder
|
||||
sha256: f692079e25e7869c14132d39f223f8eec9830eb76131925143b2129c4bb01b37
|
||||
sha256: "0ec10bf4a89e4c613960bf1e8b42c64127021740fb21640c29c909826a5eea3e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.10.0"
|
||||
version: "4.10.1"
|
||||
collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: collection
|
||||
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
|
||||
sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.18.0"
|
||||
version: "1.19.0"
|
||||
convert:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -273,10 +273,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_mobx
|
||||
sha256: "859fbf452fa9c2519d2700b125dd7fb14c508bbdd7fb65e26ca8ff6c92280e2e"
|
||||
sha256: ba5e93467866a2991259dc51cffd41ef45f695c667c2b8e7b087bf24118b50fe
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.1+1"
|
||||
version: "2.3.0"
|
||||
flutter_test:
|
||||
dependency: "direct dev"
|
||||
description: flutter
|
||||
|
@ -294,10 +294,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: glob
|
||||
sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63"
|
||||
sha256: c3f1ee72c96f8f78935e18aa8cecced9ab132419e8625dc187e1c2408efc20de
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.2"
|
||||
version: "2.1.3"
|
||||
graphs:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -326,18 +326,18 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: http
|
||||
sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010
|
||||
sha256: fe7ab022b76f3034adc518fb6ea04a82387620e19977665ea18d30a1cf43442f
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.2"
|
||||
version: "1.3.0"
|
||||
http_multi_server:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_multi_server
|
||||
sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b"
|
||||
sha256: aa6199f908078bb1c5efb8d8638d4ae191aac11b311132c3ef48ce352fb52ef8
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.2.1"
|
||||
version: "3.2.2"
|
||||
http_parser:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -358,10 +358,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: io
|
||||
sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e"
|
||||
sha256: dfd5a80599cf0165756e3181807ed3e77daf6dd4137caaad72d0b7931597650b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.4"
|
||||
version: "1.0.5"
|
||||
js:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -382,18 +382,18 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker
|
||||
sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05"
|
||||
sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "10.0.5"
|
||||
version: "10.0.7"
|
||||
leak_tracker_flutter_testing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker_flutter_testing
|
||||
sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806"
|
||||
sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.5"
|
||||
version: "3.0.8"
|
||||
leak_tracker_testing:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -414,10 +414,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: macros
|
||||
sha256: "0acaed5d6b7eab89f63350bccd82119e6c602df0f391260d0e32b5e23db79536"
|
||||
sha256: "1d9e801cd66f7ea3663c45fc708450db1fa57f988142c64289142c9b7ee80656"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.1.2-main.4"
|
||||
version: "0.1.3-main.0"
|
||||
matcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -454,18 +454,18 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: mobx
|
||||
sha256: "63920b27b32ad1910adfe767ab1750e4c212e8923232a1f891597b362074ea5e"
|
||||
sha256: bf1a90e5bcfd2851fc6984e20eef69557c65d9e4d0a88f5be4cf72c9819ce6b0
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.3+2"
|
||||
version: "2.5.0"
|
||||
mobx_codegen:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: mobx_codegen
|
||||
sha256: "8e0d8653a0c720ad933cd8358f6f89f740ce89203657c13f25bea772ef1fff7c"
|
||||
sha256: "990da80722f7d7c0017dec92040b31545d625b15d40204c36a1e63d167c73cdc"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.6.1"
|
||||
version: "2.7.0"
|
||||
nested:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -487,10 +487,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: package_config
|
||||
sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd"
|
||||
sha256: "92d4488434b520a62570293fbd33bb556c7d49230791c1b4bbd973baf6d2dc67"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
version: "2.1.1"
|
||||
path:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -503,26 +503,26 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: path_provider
|
||||
sha256: fec0d61223fba3154d87759e3cc27fe2c8dc498f6386c6d6fc80d1afdd1bf378
|
||||
sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.4"
|
||||
version: "2.1.5"
|
||||
path_provider_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_android
|
||||
sha256: c464428172cb986b758c6d1724c603097febb8fb855aa265aeecc9280c294d4a
|
||||
sha256: "4adf4fd5423ec60a29506c76581bc05854c55e3a0b72d35bb28d661c9686edf2"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.12"
|
||||
version: "2.2.15"
|
||||
path_provider_foundation:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_foundation
|
||||
sha256: f234384a3fdd67f989b4d54a5d73ca2a6c422fa55ae694381ae0f4375cd1ea16
|
||||
sha256: "4843174df4d288f5e29185bd6e72a6fbdf5a4a4602717eed565497429f179942"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.0"
|
||||
version: "2.4.1"
|
||||
path_provider_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -591,18 +591,18 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: pub_semver
|
||||
sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c"
|
||||
sha256: "7b3cfbf654f3edd0c6298ecd5be782ce997ddf0e00531b9464b55245185bbbbd"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.4"
|
||||
version: "2.1.5"
|
||||
pubspec_parse:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pubspec_parse
|
||||
sha256: c799b721d79eb6ee6fa56f00c04b472dcd44a30d258fac2174a6ec57302678f8
|
||||
sha256: "81876843eb50dc2e1e5b151792c9a985c5ed2536914115ed04e9c8528f6647b0"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
version: "1.4.0"
|
||||
rational:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -623,15 +623,15 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: shelf_web_socket
|
||||
sha256: "073c147238594ecd0d193f3456a5fe91c4b0abbcc68bf5cd95b36c4e194ac611"
|
||||
sha256: cc36c297b52866d203dbf9332263c94becc2fe0ceaa9681d07b6ef9807023b67
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
version: "2.0.1"
|
||||
sky_engine:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.99"
|
||||
version: "0.0.0"
|
||||
socks5_proxy:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -652,10 +652,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: source_helper
|
||||
sha256: "6adebc0006c37dd63fe05bca0a929b99f06402fc95aa35bf36d67f5c06de01fd"
|
||||
sha256: "86d247119aedce8e63f4751bd9626fc9613255935558447569ad42f9f5b48b3c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.4"
|
||||
version: "1.3.5"
|
||||
source_span:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -668,10 +668,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: stack_trace
|
||||
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
|
||||
sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.11.1"
|
||||
version: "1.12.0"
|
||||
stream_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -684,18 +684,18 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: stream_transform
|
||||
sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f"
|
||||
sha256: ad47125e588cfd37a9a7f86c7d6356dde8dfe89d071d293f80ca9e9273a33871
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
version: "2.1.1"
|
||||
string_scanner:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: string_scanner
|
||||
sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
|
||||
sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "1.3.0"
|
||||
term_glyph:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -708,18 +708,18 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb"
|
||||
sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.2"
|
||||
version: "0.7.3"
|
||||
timing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: timing
|
||||
sha256: "70a3b636575d4163c477e6de42f247a23b315ae20e86442bebe32d3cabf61c32"
|
||||
sha256: "62ee18aca144e4a9f29d212f5a4c6a053be252b895ab14b5821996cff4ed90fe"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
version: "1.0.2"
|
||||
tuple:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -756,26 +756,26 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: vm_service
|
||||
sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d"
|
||||
sha256: f6be3ed8bd01289b34d679c2b62226f63c0e69f9fd2e50a6b3c1c729a961041b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "14.2.5"
|
||||
version: "14.3.0"
|
||||
watcher:
|
||||
dependency: "direct overridden"
|
||||
description:
|
||||
name: watcher
|
||||
sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8"
|
||||
sha256: "69da27e49efa56a15f8afe8f4438c4ec02eff0a117df1b22ea4aad194fe1c104"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "1.1.1"
|
||||
web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: web
|
||||
sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb
|
||||
sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "1.1.1"
|
||||
web_socket:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -788,10 +788,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: web_socket_channel
|
||||
sha256: "9f187088ed104edd8662ca07af4b124465893caf063ba29758f97af57e61da8f"
|
||||
sha256: "0b8e2457400d8a859b7b2030786835a28a8e80836ef64402abef392ff4f1d0e5"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.1"
|
||||
version: "3.0.2"
|
||||
xdg_directories:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -804,10 +804,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: yaml
|
||||
sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5"
|
||||
sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.2"
|
||||
version: "3.1.3"
|
||||
sdks:
|
||||
dart: ">=3.5.0 <4.0.0"
|
||||
flutter: ">=3.24.0"
|
||||
|
|
|
@ -5,23 +5,23 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: _fe_analyzer_shared
|
||||
sha256: f256b0c0ba6c7577c15e2e4e114755640a875e885099367bf6e012b19314c834
|
||||
sha256: "16e298750b6d0af7ce8a3ba7c18c69c3785d11b15ec83f6dcd0ad2a0009b3cab"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "72.0.0"
|
||||
version: "76.0.0"
|
||||
_macros:
|
||||
dependency: transitive
|
||||
description: dart
|
||||
source: sdk
|
||||
version: "0.3.2"
|
||||
version: "0.3.3"
|
||||
analyzer:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: analyzer
|
||||
sha256: b652861553cd3990d8ed361f7979dc6d7053a9ac8843fa73820ab68ce5410139
|
||||
sha256: "1f14db053a8c23e260789e9b0980fa27f2680dd640932cae5e1137cce0e46e1e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.7.0"
|
||||
version: "6.11.0"
|
||||
args:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -180,10 +180,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: collection
|
||||
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
|
||||
sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.18.0"
|
||||
version: "1.19.0"
|
||||
convert:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -405,18 +405,18 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker
|
||||
sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05"
|
||||
sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "10.0.5"
|
||||
version: "10.0.7"
|
||||
leak_tracker_flutter_testing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker_flutter_testing
|
||||
sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806"
|
||||
sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.5"
|
||||
version: "3.0.8"
|
||||
leak_tracker_testing:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -437,10 +437,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: macros
|
||||
sha256: "0acaed5d6b7eab89f63350bccd82119e6c602df0f391260d0e32b5e23db79536"
|
||||
sha256: "1d9e801cd66f7ea3663c45fc708450db1fa57f988142c64289142c9b7ee80656"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.1.2-main.4"
|
||||
version: "0.1.3-main.0"
|
||||
matcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -662,7 +662,7 @@ packages:
|
|||
dependency: transitive
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.99"
|
||||
version: "0.0.0"
|
||||
socks5_proxy:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -699,10 +699,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: stack_trace
|
||||
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
|
||||
sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.11.1"
|
||||
version: "1.12.0"
|
||||
stream_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -723,10 +723,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: string_scanner
|
||||
sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
|
||||
sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "1.3.0"
|
||||
term_glyph:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -739,10 +739,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb"
|
||||
sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.2"
|
||||
version: "0.7.3"
|
||||
timing:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -787,10 +787,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: vm_service
|
||||
sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d"
|
||||
sha256: f6be3ed8bd01289b34d679c2b62226f63c0e69f9fd2e50a6b3c1c729a961041b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "14.2.5"
|
||||
version: "14.3.0"
|
||||
watcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
|
@ -37,7 +37,8 @@ List<monero.SubaddressAccountRow> getAllAccount() {
|
|||
int size = monero.SubaddressAccount_getAll_size(subaddressAccount!);
|
||||
if (size == 0) {
|
||||
monero.Wallet_addSubaddressAccount(wptr!);
|
||||
return getAllAccount();
|
||||
monero.Wallet_status(wptr!);
|
||||
return [];
|
||||
}
|
||||
return List.generate(size, (index) {
|
||||
return monero.SubaddressAccount_getAll_byIndex(subaddressAccount!, index: index);
|
||||
|
|
|
@ -2,6 +2,7 @@ import 'dart:async';
|
|||
import 'dart:ffi';
|
||||
import 'dart:isolate';
|
||||
|
||||
import 'package:cw_core/root_dir.dart';
|
||||
import 'package:cw_core/utils/print_verbose.dart';
|
||||
import 'package:cw_monero/api/account_list.dart';
|
||||
import 'package:cw_monero/api/exceptions/setup_wallet_exception.dart';
|
||||
|
@ -108,9 +109,13 @@ Map<int, Map<int, Map<int, String>>> addressCache = {};
|
|||
|
||||
String getAddress({int accountIndex = 0, int addressIndex = 0}) {
|
||||
// printV("getaddress: ${accountIndex}/${addressIndex}: ${monero.Wallet_numSubaddresses(wptr!, accountIndex: accountIndex)}: ${monero.Wallet_address(wptr!, accountIndex: accountIndex, addressIndex: addressIndex)}");
|
||||
while (monero.Wallet_numSubaddresses(wptr!, accountIndex: accountIndex)-1 < addressIndex) {
|
||||
printV("adding subaddress");
|
||||
monero.Wallet_addSubaddress(wptr!, accountIndex: accountIndex);
|
||||
// this could be a while loop, but I'm in favor of making it if to not cause freezes
|
||||
if (monero.Wallet_numSubaddresses(wptr!, accountIndex: accountIndex)-1 < addressIndex) {
|
||||
if (monero.Wallet_numSubaddressAccounts(wptr!) < accountIndex) {
|
||||
monero.Wallet_addSubaddressAccount(wptr!);
|
||||
} else {
|
||||
monero.Wallet_addSubaddress(wptr!, accountIndex: accountIndex);
|
||||
}
|
||||
}
|
||||
addressCache[wptr!.address] ??= {};
|
||||
addressCache[wptr!.address]![accountIndex] ??= {};
|
||||
|
@ -149,6 +154,7 @@ Future<bool> setupNodeSync(
|
|||
}
|
||||
''');
|
||||
final addr = wptr!.address;
|
||||
printV("init: start");
|
||||
await Isolate.run(() {
|
||||
monero.Wallet_init(Pointer.fromAddress(addr),
|
||||
daemonAddress: address,
|
||||
|
@ -157,6 +163,7 @@ Future<bool> setupNodeSync(
|
|||
daemonUsername: login ?? '',
|
||||
daemonPassword: password ?? '');
|
||||
});
|
||||
printV("init: end");
|
||||
|
||||
final status = monero.Wallet_status(wptr!);
|
||||
|
||||
|
@ -168,7 +175,7 @@ Future<bool> setupNodeSync(
|
|||
}
|
||||
}
|
||||
|
||||
if (kDebugMode && debugMonero) {
|
||||
if (true) {
|
||||
monero.Wallet_init3(
|
||||
wptr!, argv0: '',
|
||||
defaultLogBaseName: 'moneroc',
|
||||
|
@ -243,7 +250,9 @@ class SyncListener {
|
|||
SyncListener(this.onNewBlock, this.onNewTransaction)
|
||||
: _cachedBlockchainHeight = 0,
|
||||
_lastKnownBlockHeight = 0,
|
||||
_initialSyncHeight = 0;
|
||||
_initialSyncHeight = 0 {
|
||||
_start();
|
||||
}
|
||||
|
||||
void Function(int, int, double) onNewBlock;
|
||||
void Function() onNewTransaction;
|
||||
|
@ -261,7 +270,7 @@ class SyncListener {
|
|||
return _cachedBlockchainHeight;
|
||||
}
|
||||
|
||||
void start() {
|
||||
void _start() {
|
||||
_cachedBlockchainHeight = 0;
|
||||
_lastKnownBlockHeight = 0;
|
||||
_initialSyncHeight = 0;
|
||||
|
@ -282,7 +291,7 @@ class SyncListener {
|
|||
}
|
||||
|
||||
final bchHeight = await getNodeHeightOrUpdate(syncHeight);
|
||||
|
||||
// printV("syncHeight: $syncHeight, _lastKnownBlockHeight: $_lastKnownBlockHeight, bchHeight: $bchHeight");
|
||||
if (_lastKnownBlockHeight == syncHeight) {
|
||||
return;
|
||||
}
|
||||
|
@ -379,4 +388,4 @@ String signMessage(String message, {String address = ""}) {
|
|||
|
||||
bool verifyMessage(String message, String address, String signature) {
|
||||
return monero.Wallet_verifySignedMessage(wptr!, message: message, address: address, signature: signature);
|
||||
}
|
||||
}
|
|
@ -11,6 +11,7 @@ import 'package:cw_monero/api/exceptions/wallet_restore_from_seed_exception.dart
|
|||
import 'package:cw_monero/api/transaction_history.dart';
|
||||
import 'package:cw_monero/api/wallet.dart';
|
||||
import 'package:cw_monero/ledger.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:monero/monero.dart' as monero;
|
||||
|
||||
class MoneroCException implements Exception {
|
||||
|
@ -50,7 +51,13 @@ final monero.WalletManager wmPtr = Pointer.fromAddress((() {
|
|||
// codebase, so it will be easier to debug what happens. At least easier
|
||||
// than plugging gdb in. Especially on windows/android.
|
||||
monero.printStarts = false;
|
||||
if (kDebugMode && debugMonero) {
|
||||
monero.WalletManagerFactory_setLogLevel(4);
|
||||
}
|
||||
_wmPtr ??= monero.WalletManagerFactory_getWalletManager();
|
||||
if (kDebugMode && debugMonero) {
|
||||
monero.WalletManagerFactory_setLogLevel(4);
|
||||
}
|
||||
printV("ptr: $_wmPtr");
|
||||
} catch (e) {
|
||||
printV(e);
|
||||
|
@ -77,10 +84,17 @@ void createWalletSync(
|
|||
final newWptr = monero.WalletManager_createWallet(wmPtr,
|
||||
path: path, password: password, language: language, networkType: 0);
|
||||
|
||||
final status = monero.Wallet_status(newWptr);
|
||||
int status = monero.Wallet_status(newWptr);
|
||||
if (status != 0) {
|
||||
throw WalletCreationException(message: monero.Wallet_errorString(newWptr));
|
||||
}
|
||||
|
||||
monero.Wallet_setupBackgroundSync(newWptr, backgroundSyncType: 2, walletPassword: password, backgroundCachePassword: '');
|
||||
status = monero.Wallet_status(newWptr);
|
||||
if (status != 0) {
|
||||
throw WalletCreationException(message: monero.Wallet_errorString(newWptr));
|
||||
}
|
||||
|
||||
wptr = newWptr;
|
||||
monero.Wallet_setCacheAttribute(wptr!, key: "cakewallet.passphrase", value: passphrase);
|
||||
monero.Wallet_store(wptr!, path: path);
|
||||
|
@ -166,12 +180,19 @@ void restoreWalletFromKeysSync(
|
|||
nettype: 0,
|
||||
);
|
||||
|
||||
final status = monero.Wallet_status(newWptr);
|
||||
int status = monero.Wallet_status(newWptr);
|
||||
if (status != 0) {
|
||||
throw WalletRestoreFromKeysException(
|
||||
message: monero.Wallet_errorString(newWptr));
|
||||
}
|
||||
|
||||
|
||||
monero.Wallet_setupBackgroundSync(newWptr, backgroundSyncType: 2, walletPassword: password, backgroundCachePassword: '');
|
||||
status = monero.Wallet_status(newWptr);
|
||||
if (status != 0) {
|
||||
throw WalletCreationException(message: monero.Wallet_errorString(newWptr));
|
||||
}
|
||||
|
||||
// CW-712 - Try to restore deterministic wallet first, if the view key doesn't
|
||||
// match the view key provided
|
||||
if (spendKey != "") {
|
||||
|
@ -190,11 +211,17 @@ void restoreWalletFromKeysSync(
|
|||
spendKeyString: spendKey,
|
||||
nettype: 0,
|
||||
);
|
||||
final status = monero.Wallet_status(newWptr);
|
||||
int status = monero.Wallet_status(newWptr);
|
||||
if (status != 0) {
|
||||
throw WalletRestoreFromKeysException(
|
||||
message: monero.Wallet_errorString(newWptr));
|
||||
}
|
||||
|
||||
monero.Wallet_setupBackgroundSync(newWptr, backgroundSyncType: 2, walletPassword: password, backgroundCachePassword: '');
|
||||
status = monero.Wallet_status(newWptr);
|
||||
if (status != 0) {
|
||||
throw WalletCreationException(message: monero.Wallet_errorString(newWptr));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -227,7 +254,7 @@ void restoreWalletFromPolyseedWithOffset(
|
|||
kdfRounds: 1,
|
||||
);
|
||||
|
||||
final status = monero.Wallet_status(newWptr);
|
||||
int status = monero.Wallet_status(newWptr);
|
||||
|
||||
if (status != 0) {
|
||||
final err = monero.Wallet_errorString(newWptr);
|
||||
|
@ -240,6 +267,12 @@ void restoreWalletFromPolyseedWithOffset(
|
|||
monero.Wallet_setCacheAttribute(wptr!, key: "cakewallet.seed", value: seed);
|
||||
monero.Wallet_setCacheAttribute(wptr!, key: "cakewallet.passphrase", value: seedOffset);
|
||||
monero.Wallet_store(wptr!);
|
||||
|
||||
monero.Wallet_setupBackgroundSync(newWptr, backgroundSyncType: 2, walletPassword: password, backgroundCachePassword: '');
|
||||
status = monero.Wallet_status(newWptr);
|
||||
if (status != 0) {
|
||||
throw WalletCreationException(message: monero.Wallet_errorString(newWptr));
|
||||
}
|
||||
storeSync();
|
||||
|
||||
openedWalletsByPath[path] = wptr!;
|
||||
|
@ -277,7 +310,7 @@ void restoreWalletFromSpendKeySync(
|
|||
restoreHeight: restoreHeight,
|
||||
);
|
||||
|
||||
final status = monero.Wallet_status(newWptr);
|
||||
int status = monero.Wallet_status(newWptr);
|
||||
|
||||
if (status != 0) {
|
||||
final err = monero.Wallet_errorString(newWptr);
|
||||
|
@ -290,6 +323,12 @@ void restoreWalletFromSpendKeySync(
|
|||
monero.Wallet_setCacheAttribute(wptr!, key: "cakewallet.seed", value: seed);
|
||||
|
||||
storeSync();
|
||||
|
||||
monero.Wallet_setupBackgroundSync(newWptr, backgroundSyncType: 2, walletPassword: password, backgroundCachePassword: '');
|
||||
status = monero.Wallet_status(newWptr);
|
||||
if (status != 0) {
|
||||
throw WalletCreationException(message: monero.Wallet_errorString(newWptr));
|
||||
}
|
||||
|
||||
openedWalletsByPath[path] = wptr!;
|
||||
_lastOpenedWallet = path;
|
||||
|
@ -321,6 +360,14 @@ Future<void> restoreWalletFromHardwareWallet(
|
|||
final error = monero.Wallet_errorString(newWptr);
|
||||
throw WalletRestoreFromSeedException(message: error);
|
||||
}
|
||||
|
||||
// TODO: Check with upstream if we can use background sync here
|
||||
// monero.Wallet_setupBackgroundSync(newWptr, backgroundSyncType: 2, walletPassword: password, backgroundCachePassword: '');
|
||||
// status = monero.Wallet_status(newWptr);
|
||||
// if (status != 0) {
|
||||
// throw WalletCreationException(message: monero.Wallet_errorString(newWptr));
|
||||
// }
|
||||
|
||||
wptr = newWptr;
|
||||
_lastOpenedWallet = path;
|
||||
openedWalletsByPath[path] = wptr!;
|
||||
|
@ -384,7 +431,14 @@ Future<void> loadWallet(
|
|||
|
||||
final newWptr = Pointer<Void>.fromAddress(newWptrAddr);
|
||||
|
||||
final status = monero.Wallet_status(newWptr);
|
||||
int status = monero.Wallet_status(newWptr);
|
||||
if (status != 0) {
|
||||
final err = monero.Wallet_errorString(newWptr);
|
||||
printV("loadWallet:"+err);
|
||||
throw WalletOpeningException(message: err);
|
||||
}
|
||||
monero.Wallet_setupBackgroundSync(newWptr, backgroundSyncType: 2, walletPassword: password, backgroundCachePassword: '');
|
||||
status = monero.Wallet_status(newWptr);
|
||||
if (status != 0) {
|
||||
final err = monero.Wallet_errorString(newWptr);
|
||||
printV("loadWallet:"+err);
|
||||
|
|
|
@ -218,7 +218,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance, MoneroTransact
|
|||
// FIXME: hardcoded value
|
||||
socksProxyAddress: node.socksProxyAddress);
|
||||
|
||||
monero_wallet.setTrustedDaemon(node.trusted);
|
||||
await monero_wallet.setTrustedDaemon(node.trusted);
|
||||
syncStatus = ConnectedSyncStatus();
|
||||
} catch (e) {
|
||||
syncStatus = FailedSyncStatus();
|
||||
|
@ -226,6 +226,57 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance, MoneroTransact
|
|||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> startBackgroundSync() async {
|
||||
if (isBackgroundSyncRunning) {
|
||||
printV("Background sync already running");
|
||||
return;
|
||||
}
|
||||
isBackgroundSyncRunning = true;
|
||||
int status = monero.Wallet_status(wptr!);
|
||||
if (status != 0) {
|
||||
final err = monero.Wallet_errorString(wptr!);
|
||||
throw Exception("unable to setup background sync: $err");
|
||||
}
|
||||
await save();
|
||||
|
||||
monero.Wallet_startBackgroundSync(wptr!);
|
||||
status = monero.Wallet_status(wptr!);
|
||||
if (status != 0) {
|
||||
final err = monero.Wallet_errorString(wptr!);
|
||||
throw Exception("unable to start background sync: $err");
|
||||
}
|
||||
await save();
|
||||
await init();
|
||||
await startSync();
|
||||
}
|
||||
|
||||
bool isBackgroundSyncRunning = false;
|
||||
|
||||
@action
|
||||
@override
|
||||
Future<void> stopSync() async {
|
||||
if (isBackgroundSyncRunning) {
|
||||
printV("Stopping background sync");
|
||||
await save();
|
||||
monero.Wallet_stopBackgroundSync(wptr!, '');
|
||||
await save();
|
||||
isBackgroundSyncRunning = false;
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
@override
|
||||
Future<void> stopBackgroundSync(String password) async {
|
||||
if (isBackgroundSyncRunning) {
|
||||
printV("Stopping background sync");
|
||||
await save();
|
||||
monero.Wallet_stopBackgroundSync(wptr!, password);
|
||||
await save();
|
||||
isBackgroundSyncRunning = false;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> startSync() async {
|
||||
try {
|
||||
|
@ -250,7 +301,6 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance, MoneroTransact
|
|||
syncStatus = AttemptingSyncStatus();
|
||||
monero_wallet.startRefresh();
|
||||
_setListeners();
|
||||
_listener?.start();
|
||||
} catch (e) {
|
||||
syncStatus = FailedSyncStatus();
|
||||
printV(e);
|
||||
|
@ -782,6 +832,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance, MoneroTransact
|
|||
}
|
||||
|
||||
void _onNewBlock(int height, int blocksLeft, double ptc) async {
|
||||
printV("onNewBlock: $height, $blocksLeft, $ptc");
|
||||
try {
|
||||
if (walletInfo.isRecovery) {
|
||||
await _askForUpdateTransactionHistory();
|
||||
|
|
|
@ -1 +1 @@
|
|||
/home/parallels/.pub-cache/hosted/pub.dev/path_provider_linux-2.2.1/
|
||||
/home/rafael/.pub-cache/hosted/pub.dev/path_provider_linux-2.2.1/
|
|
@ -29,10 +29,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: asn1lib
|
||||
sha256: "6b151826fcc95ff246cd219a0bf4c753ea14f4081ad71c61939becf3aba27f70"
|
||||
sha256: "4bae5ae63e6d6dd17c4aac8086f3dec26c0236f6a0f03416c6c19d830c367cf5"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.5.5"
|
||||
version: "1.5.8"
|
||||
async:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -54,10 +54,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: bluez
|
||||
sha256: "203a1924e818a9dd74af2b2c7a8f375ab8e5edf0e486bba8f90a0d8a17ed9fce"
|
||||
sha256: "61a7204381925896a374301498f2f5399e59827c6498ae1e924aaa598751b545"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.8.2"
|
||||
version: "0.8.3"
|
||||
boolean_selector:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -126,10 +126,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: built_value
|
||||
sha256: c7913a9737ee4007efedaffc968c049fd0f3d0e49109e778edc10de9426005cb
|
||||
sha256: "8b158ab94ec6913e480dc3f752418348b5ae099eb75868b5f4775f0572999c61"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "8.9.2"
|
||||
version: "8.9.4"
|
||||
cake_backup:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -167,18 +167,18 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: code_builder
|
||||
sha256: f692079e25e7869c14132d39f223f8eec9830eb76131925143b2129c4bb01b37
|
||||
sha256: "0ec10bf4a89e4c613960bf1e8b42c64127021740fb21640c29c909826a5eea3e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.10.0"
|
||||
version: "4.10.1"
|
||||
collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: collection
|
||||
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
|
||||
sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.18.0"
|
||||
version: "1.19.0"
|
||||
convert:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -230,10 +230,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: dbus
|
||||
sha256: "365c771ac3b0e58845f39ec6deebc76e3276aa9922b0cc60840712094d9047ac"
|
||||
sha256: "79e0c23480ff85dc68de79e2cd6334add97e48f7f4865d17686dd6ea81a47e8c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.10"
|
||||
version: "0.7.11"
|
||||
decimal:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -291,10 +291,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_mobx
|
||||
sha256: "859fbf452fa9c2519d2700b125dd7fb14c508bbdd7fb65e26ca8ff6c92280e2e"
|
||||
sha256: ba5e93467866a2991259dc51cffd41ef45f695c667c2b8e7b087bf24118b50fe
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.1+1"
|
||||
version: "2.3.0"
|
||||
flutter_test:
|
||||
dependency: "direct dev"
|
||||
description: flutter
|
||||
|
@ -304,10 +304,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: flutter_web_bluetooth
|
||||
sha256: "52ce64f65d7321c4bf6abfe9dac02fb888731339a5e0ad6de59fb916c20c9f02"
|
||||
sha256: "1363831def5eed1e1064d1eca04e8ccb35446e8f758579c3c519e156b77926da"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.2.3"
|
||||
version: "1.0.0"
|
||||
frontend_server_client:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -320,10 +320,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: glob
|
||||
sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63"
|
||||
sha256: c3f1ee72c96f8f78935e18aa8cecced9ab132419e8625dc187e1c2408efc20de
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.2"
|
||||
version: "2.1.3"
|
||||
graphs:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -336,10 +336,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: hashlib
|
||||
sha256: f572f2abce09fc7aee53f15927052b9732ea1053e540af8cae211111ee0b99b1
|
||||
sha256: e13e8237d93fb275cd1c55fc339bb90638994d1a4f140c7ee270173b51f3d169
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.21.0"
|
||||
version: "1.21.1"
|
||||
hashlib_codecs:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -368,18 +368,18 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: http
|
||||
sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010
|
||||
sha256: fe7ab022b76f3034adc518fb6ea04a82387620e19977665ea18d30a1cf43442f
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.2"
|
||||
version: "1.3.0"
|
||||
http_multi_server:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_multi_server
|
||||
sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b"
|
||||
sha256: aa6199f908078bb1c5efb8d8638d4ae191aac11b311132c3ef48ce352fb52ef8
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.2.1"
|
||||
version: "3.2.2"
|
||||
http_parser:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -400,10 +400,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: io
|
||||
sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e"
|
||||
sha256: dfd5a80599cf0165756e3181807ed3e77daf6dd4137caaad72d0b7931597650b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.4"
|
||||
version: "1.0.5"
|
||||
js:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -424,18 +424,18 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker
|
||||
sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05"
|
||||
sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "10.0.5"
|
||||
version: "10.0.7"
|
||||
leak_tracker_flutter_testing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker_flutter_testing
|
||||
sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806"
|
||||
sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.5"
|
||||
version: "3.0.8"
|
||||
leak_tracker_testing:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -448,10 +448,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: ledger_flutter_plus
|
||||
sha256: c7b04008553193dbca7e17b430768eecc372a72b0ff3625b5e7fc5e5c8d3231b
|
||||
sha256: "1c03f3c4a9754b5f0170a9eb9552ec54fa86e985f8ee71a255ee2c5629b53d31"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.1"
|
||||
version: "1.5.1"
|
||||
ledger_usb_plus:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -504,10 +504,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: mobx
|
||||
sha256: "63920b27b32ad1910adfe767ab1750e4c212e8923232a1f891597b362074ea5e"
|
||||
sha256: bf1a90e5bcfd2851fc6984e20eef69557c65d9e4d0a88f5be4cf72c9819ce6b0
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.3+2"
|
||||
version: "2.5.0"
|
||||
mobx_codegen:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
|
@ -554,10 +554,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: package_config
|
||||
sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd"
|
||||
sha256: "92d4488434b520a62570293fbd33bb556c7d49230791c1b4bbd973baf6d2dc67"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
version: "2.1.1"
|
||||
path:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -570,26 +570,26 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: path_provider
|
||||
sha256: fec0d61223fba3154d87759e3cc27fe2c8dc498f6386c6d6fc80d1afdd1bf378
|
||||
sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.4"
|
||||
version: "2.1.5"
|
||||
path_provider_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_android
|
||||
sha256: c464428172cb986b758c6d1724c603097febb8fb855aa265aeecc9280c294d4a
|
||||
sha256: "4adf4fd5423ec60a29506c76581bc05854c55e3a0b72d35bb28d661c9686edf2"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.12"
|
||||
version: "2.2.15"
|
||||
path_provider_foundation:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_foundation
|
||||
sha256: f234384a3fdd67f989b4d54a5d73ca2a6c422fa55ae694381ae0f4375cd1ea16
|
||||
sha256: "4843174df4d288f5e29185bd6e72a6fbdf5a4a4602717eed565497429f179942"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.0"
|
||||
version: "2.4.1"
|
||||
path_provider_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -674,18 +674,18 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: pub_semver
|
||||
sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c"
|
||||
sha256: "7b3cfbf654f3edd0c6298ecd5be782ce997ddf0e00531b9464b55245185bbbbd"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.4"
|
||||
version: "2.1.5"
|
||||
pubspec_parse:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pubspec_parse
|
||||
sha256: c799b721d79eb6ee6fa56f00c04b472dcd44a30d258fac2174a6ec57302678f8
|
||||
sha256: "81876843eb50dc2e1e5b151792c9a985c5ed2536914115ed04e9c8528f6647b0"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
version: "1.4.0"
|
||||
rational:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -714,15 +714,15 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: shelf_web_socket
|
||||
sha256: "073c147238594ecd0d193f3456a5fe91c4b0abbcc68bf5cd95b36c4e194ac611"
|
||||
sha256: cc36c297b52866d203dbf9332263c94becc2fe0ceaa9681d07b6ef9807023b67
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
version: "2.0.1"
|
||||
sky_engine:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.99"
|
||||
version: "0.0.0"
|
||||
socks5_proxy:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -759,10 +759,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: stack_trace
|
||||
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
|
||||
sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.11.1"
|
||||
version: "1.12.0"
|
||||
stream_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -775,18 +775,18 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: stream_transform
|
||||
sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f"
|
||||
sha256: ad47125e588cfd37a9a7f86c7d6356dde8dfe89d071d293f80ca9e9273a33871
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
version: "2.1.1"
|
||||
string_scanner:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: string_scanner
|
||||
sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
|
||||
sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "1.3.0"
|
||||
term_glyph:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -799,18 +799,18 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb"
|
||||
sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.2"
|
||||
version: "0.7.3"
|
||||
timing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: timing
|
||||
sha256: "70a3b636575d4163c477e6de42f247a23b315ae20e86442bebe32d3cabf61c32"
|
||||
sha256: "62ee18aca144e4a9f29d212f5a4c6a053be252b895ab14b5821996cff4ed90fe"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
version: "1.0.2"
|
||||
tuple:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -831,10 +831,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: universal_ble
|
||||
sha256: "0dfbd6b64bff3ad61ed7a895c232530d9614e9b01ab261a74433a43267edb7f3"
|
||||
sha256: "1fad089150a29db82b3b7d60327e18c5ad6b3a5bb509defc1c690b0a76b9c098"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.12.0"
|
||||
version: "0.15.0"
|
||||
universal_platform:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -863,26 +863,26 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: vm_service
|
||||
sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d"
|
||||
sha256: f6be3ed8bd01289b34d679c2b62226f63c0e69f9fd2e50a6b3c1c729a961041b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "14.2.5"
|
||||
version: "14.3.0"
|
||||
watcher:
|
||||
dependency: "direct overridden"
|
||||
description:
|
||||
name: watcher
|
||||
sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8"
|
||||
sha256: "69da27e49efa56a15f8afe8f4438c4ec02eff0a117df1b22ea4aad194fe1c104"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "1.1.1"
|
||||
web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: web
|
||||
sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb
|
||||
sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "1.1.1"
|
||||
web_socket:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -895,10 +895,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: web_socket_channel
|
||||
sha256: "9f187088ed104edd8662ca07af4b124465893caf063ba29758f97af57e61da8f"
|
||||
sha256: "0b8e2457400d8a859b7b2030786835a28a8e80836ef64402abef392ff4f1d0e5"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.1"
|
||||
version: "3.0.2"
|
||||
xdg_directories:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -919,10 +919,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: yaml
|
||||
sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5"
|
||||
sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.2"
|
||||
version: "3.1.3"
|
||||
sdks:
|
||||
dart: ">=3.5.0 <4.0.0"
|
||||
flutter: ">=3.24.0"
|
||||
|
|
|
@ -10,7 +10,7 @@ environment:
|
|||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
grpc: ^3.2.4
|
||||
grpc: ^4.0.1
|
||||
path_provider: ^2.1.2
|
||||
plugin_platform_interface: ^2.0.2
|
||||
cw_core:
|
||||
|
|
|
@ -29,10 +29,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: asn1lib
|
||||
sha256: "6b151826fcc95ff246cd219a0bf4c753ea14f4081ad71c61939becf3aba27f70"
|
||||
sha256: "4bae5ae63e6d6dd17c4aac8086f3dec26c0236f6a0f03416c6c19d830c367cf5"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.5.5"
|
||||
version: "1.5.8"
|
||||
async:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -142,10 +142,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: built_value
|
||||
sha256: c7913a9737ee4007efedaffc968c049fd0f3d0e49109e778edc10de9426005cb
|
||||
sha256: "8b158ab94ec6913e480dc3f752418348b5ae099eb75868b5f4775f0572999c61"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "8.9.2"
|
||||
version: "8.9.4"
|
||||
cake_backup:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -183,18 +183,18 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: code_builder
|
||||
sha256: f692079e25e7869c14132d39f223f8eec9830eb76131925143b2129c4bb01b37
|
||||
sha256: "0ec10bf4a89e4c613960bf1e8b42c64127021740fb21640c29c909826a5eea3e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.10.0"
|
||||
version: "4.10.1"
|
||||
collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: collection
|
||||
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
|
||||
sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.18.0"
|
||||
version: "1.19.0"
|
||||
convert:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -315,10 +315,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: flutter_mobx
|
||||
sha256: "859fbf452fa9c2519d2700b125dd7fb14c508bbdd7fb65e26ca8ff6c92280e2e"
|
||||
sha256: ba5e93467866a2991259dc51cffd41ef45f695c667c2b8e7b087bf24118b50fe
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.1+1"
|
||||
version: "2.3.0"
|
||||
flutter_test:
|
||||
dependency: "direct dev"
|
||||
description: flutter
|
||||
|
@ -341,10 +341,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: glob
|
||||
sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63"
|
||||
sha256: c3f1ee72c96f8f78935e18aa8cecced9ab132419e8625dc187e1c2408efc20de
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.2"
|
||||
version: "2.1.3"
|
||||
graphs:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -381,18 +381,18 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: http
|
||||
sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010
|
||||
sha256: fe7ab022b76f3034adc518fb6ea04a82387620e19977665ea18d30a1cf43442f
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.2"
|
||||
version: "1.3.0"
|
||||
http_multi_server:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_multi_server
|
||||
sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b"
|
||||
sha256: aa6199f908078bb1c5efb8d8638d4ae191aac11b311132c3ef48ce352fb52ef8
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.2.1"
|
||||
version: "3.2.2"
|
||||
http_parser:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -413,10 +413,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: io
|
||||
sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e"
|
||||
sha256: dfd5a80599cf0165756e3181807ed3e77daf6dd4137caaad72d0b7931597650b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.4"
|
||||
version: "1.0.5"
|
||||
js:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -437,18 +437,18 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker
|
||||
sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05"
|
||||
sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "10.0.5"
|
||||
version: "10.0.7"
|
||||
leak_tracker_flutter_testing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker_flutter_testing
|
||||
sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806"
|
||||
sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.5"
|
||||
version: "3.0.8"
|
||||
leak_tracker_testing:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -509,10 +509,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: mobx
|
||||
sha256: "63920b27b32ad1910adfe767ab1750e4c212e8923232a1f891597b362074ea5e"
|
||||
sha256: bf1a90e5bcfd2851fc6984e20eef69557c65d9e4d0a88f5be4cf72c9819ce6b0
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.3+2"
|
||||
version: "2.5.0"
|
||||
mobx_codegen:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
|
@ -559,10 +559,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: package_config
|
||||
sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd"
|
||||
sha256: "92d4488434b520a62570293fbd33bb556c7d49230791c1b4bbd973baf6d2dc67"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
version: "2.1.1"
|
||||
path:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -575,26 +575,26 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: path_provider
|
||||
sha256: fec0d61223fba3154d87759e3cc27fe2c8dc498f6386c6d6fc80d1afdd1bf378
|
||||
sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.4"
|
||||
version: "2.1.5"
|
||||
path_provider_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_android
|
||||
sha256: c464428172cb986b758c6d1724c603097febb8fb855aa265aeecc9280c294d4a
|
||||
sha256: "4adf4fd5423ec60a29506c76581bc05854c55e3a0b72d35bb28d661c9686edf2"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.12"
|
||||
version: "2.2.15"
|
||||
path_provider_foundation:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_foundation
|
||||
sha256: f234384a3fdd67f989b4d54a5d73ca2a6c422fa55ae694381ae0f4375cd1ea16
|
||||
sha256: "4843174df4d288f5e29185bd6e72a6fbdf5a4a4602717eed565497429f179942"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.0"
|
||||
version: "2.4.1"
|
||||
path_provider_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -671,18 +671,18 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: pub_semver
|
||||
sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c"
|
||||
sha256: "7b3cfbf654f3edd0c6298ecd5be782ce997ddf0e00531b9464b55245185bbbbd"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.4"
|
||||
version: "2.1.5"
|
||||
pubspec_parse:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pubspec_parse
|
||||
sha256: c799b721d79eb6ee6fa56f00c04b472dcd44a30d258fac2174a6ec57302678f8
|
||||
sha256: "81876843eb50dc2e1e5b151792c9a985c5ed2536914115ed04e9c8528f6647b0"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
version: "1.4.0"
|
||||
rational:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -695,26 +695,26 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: shared_preferences
|
||||
sha256: "746e5369a43170c25816cc472ee016d3a66bc13fcf430c0bc41ad7b4b2922051"
|
||||
sha256: "846849e3e9b68f3ef4b60c60cf4b3e02e9321bc7f4d8c4692cf87ffa82fc8a3a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.2"
|
||||
version: "2.5.2"
|
||||
shared_preferences_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_android
|
||||
sha256: "3b9febd815c9ca29c9e3520d50ec32f49157711e143b7a4ca039eb87e8ade5ab"
|
||||
sha256: a768fc8ede5f0c8e6150476e14f38e2417c0864ca36bb4582be8e21925a03c22
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.3"
|
||||
version: "2.4.6"
|
||||
shared_preferences_foundation:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_foundation
|
||||
sha256: "07e050c7cd39bad516f8d64c455f04508d09df104be326d8c02551590a0d513d"
|
||||
sha256: "6a52cfcdaeac77cad8c97b539ff688ccfc458c007b4db12be584fbe5c0e49e03"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.5.3"
|
||||
version: "2.5.4"
|
||||
shared_preferences_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -735,10 +735,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_web
|
||||
sha256: d2ca4132d3946fec2184261726b355836a82c33d7d5b67af32692aff18a4684e
|
||||
sha256: c49bd060261c9a3f0ff445892695d6212ff603ef3115edbb448509d407600019
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.2"
|
||||
version: "2.4.3"
|
||||
shared_preferences_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -759,15 +759,15 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: shelf_web_socket
|
||||
sha256: "073c147238594ecd0d193f3456a5fe91c4b0abbcc68bf5cd95b36c4e194ac611"
|
||||
sha256: cc36c297b52866d203dbf9332263c94becc2fe0ceaa9681d07b6ef9807023b67
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
version: "2.0.1"
|
||||
sky_engine:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.99"
|
||||
version: "0.0.0"
|
||||
socks5_proxy:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -804,10 +804,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: stack_trace
|
||||
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
|
||||
sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.11.1"
|
||||
version: "1.12.0"
|
||||
stream_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -820,18 +820,18 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: stream_transform
|
||||
sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f"
|
||||
sha256: ad47125e588cfd37a9a7f86c7d6356dde8dfe89d071d293f80ca9e9273a33871
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
version: "2.1.1"
|
||||
string_scanner:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: string_scanner
|
||||
sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
|
||||
sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "1.3.0"
|
||||
term_glyph:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -844,18 +844,18 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb"
|
||||
sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.2"
|
||||
version: "0.7.3"
|
||||
timing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: timing
|
||||
sha256: "70a3b636575d4163c477e6de42f247a23b315ae20e86442bebe32d3cabf61c32"
|
||||
sha256: "62ee18aca144e4a9f29d212f5a4c6a053be252b895ab14b5821996cff4ed90fe"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
version: "1.0.2"
|
||||
tuple:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -892,26 +892,26 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: vm_service
|
||||
sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d"
|
||||
sha256: f6be3ed8bd01289b34d679c2b62226f63c0e69f9fd2e50a6b3c1c729a961041b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "14.2.5"
|
||||
version: "14.3.0"
|
||||
watcher:
|
||||
dependency: "direct overridden"
|
||||
description:
|
||||
name: watcher
|
||||
sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8"
|
||||
sha256: "69da27e49efa56a15f8afe8f4438c4ec02eff0a117df1b22ea4aad194fe1c104"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "1.1.1"
|
||||
web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: web
|
||||
sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb
|
||||
sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "1.1.1"
|
||||
web_socket:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -924,10 +924,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: web_socket_channel
|
||||
sha256: "9f187088ed104edd8662ca07af4b124465893caf063ba29758f97af57e61da8f"
|
||||
sha256: "0b8e2457400d8a859b7b2030786835a28a8e80836ef64402abef392ff4f1d0e5"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.1"
|
||||
version: "3.0.2"
|
||||
xdg_directories:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -940,10 +940,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: yaml
|
||||
sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5"
|
||||
sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.2"
|
||||
version: "3.1.3"
|
||||
sdks:
|
||||
dart: ">=3.5.0 <4.0.0"
|
||||
flutter: ">=3.24.0"
|
||||
|
|
|
@ -349,6 +349,7 @@ void loadWallet(
|
|||
txhistory = null;
|
||||
final newWptr = wownero.WalletManager_openWallet(wmPtr,
|
||||
path: path, password: password);
|
||||
|
||||
_lastOpenedWallet = path;
|
||||
final status = wownero.Wallet_status(newWptr);
|
||||
if (status != 0) {
|
||||
|
|
|
@ -29,10 +29,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: asn1lib
|
||||
sha256: "6b151826fcc95ff246cd219a0bf4c753ea14f4081ad71c61939becf3aba27f70"
|
||||
sha256: "4bae5ae63e6d6dd17c4aac8086f3dec26c0236f6a0f03416c6c19d830c367cf5"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.5.5"
|
||||
version: "1.5.8"
|
||||
async:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -118,10 +118,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: built_value
|
||||
sha256: c7913a9737ee4007efedaffc968c049fd0f3d0e49109e778edc10de9426005cb
|
||||
sha256: "8b158ab94ec6913e480dc3f752418348b5ae099eb75868b5f4775f0572999c61"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "8.9.2"
|
||||
version: "8.9.4"
|
||||
cake_backup:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -159,18 +159,18 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: code_builder
|
||||
sha256: f692079e25e7869c14132d39f223f8eec9830eb76131925143b2129c4bb01b37
|
||||
sha256: "0ec10bf4a89e4c613960bf1e8b42c64127021740fb21640c29c909826a5eea3e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.10.0"
|
||||
version: "4.10.1"
|
||||
collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: collection
|
||||
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
|
||||
sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.18.0"
|
||||
version: "1.19.0"
|
||||
convert:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -275,10 +275,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_mobx
|
||||
sha256: "859fbf452fa9c2519d2700b125dd7fb14c508bbdd7fb65e26ca8ff6c92280e2e"
|
||||
sha256: ba5e93467866a2991259dc51cffd41ef45f695c667c2b8e7b087bf24118b50fe
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.1+1"
|
||||
version: "2.3.0"
|
||||
flutter_test:
|
||||
dependency: "direct dev"
|
||||
description: flutter
|
||||
|
@ -296,10 +296,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: glob
|
||||
sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63"
|
||||
sha256: c3f1ee72c96f8f78935e18aa8cecced9ab132419e8625dc187e1c2408efc20de
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.2"
|
||||
version: "2.1.3"
|
||||
graphs:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -312,10 +312,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: hashlib
|
||||
sha256: f572f2abce09fc7aee53f15927052b9732ea1053e540af8cae211111ee0b99b1
|
||||
sha256: e13e8237d93fb275cd1c55fc339bb90638994d1a4f140c7ee270173b51f3d169
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.21.0"
|
||||
version: "1.21.1"
|
||||
hashlib_codecs:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -344,18 +344,18 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: http
|
||||
sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010
|
||||
sha256: fe7ab022b76f3034adc518fb6ea04a82387620e19977665ea18d30a1cf43442f
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.2"
|
||||
version: "1.3.0"
|
||||
http_multi_server:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_multi_server
|
||||
sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b"
|
||||
sha256: aa6199f908078bb1c5efb8d8638d4ae191aac11b311132c3ef48ce352fb52ef8
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.2.1"
|
||||
version: "3.2.2"
|
||||
http_parser:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -376,10 +376,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: io
|
||||
sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e"
|
||||
sha256: dfd5a80599cf0165756e3181807ed3e77daf6dd4137caaad72d0b7931597650b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.4"
|
||||
version: "1.0.5"
|
||||
js:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -400,18 +400,18 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker
|
||||
sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05"
|
||||
sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "10.0.5"
|
||||
version: "10.0.7"
|
||||
leak_tracker_flutter_testing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker_flutter_testing
|
||||
sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806"
|
||||
sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.5"
|
||||
version: "3.0.8"
|
||||
leak_tracker_testing:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -464,10 +464,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: mobx
|
||||
sha256: "63920b27b32ad1910adfe767ab1750e4c212e8923232a1f891597b362074ea5e"
|
||||
sha256: bf1a90e5bcfd2851fc6984e20eef69557c65d9e4d0a88f5be4cf72c9819ce6b0
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.3+2"
|
||||
version: "2.5.0"
|
||||
mobx_codegen:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
|
@ -514,10 +514,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: package_config
|
||||
sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd"
|
||||
sha256: "92d4488434b520a62570293fbd33bb556c7d49230791c1b4bbd973baf6d2dc67"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
version: "2.1.1"
|
||||
path:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -530,26 +530,26 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: path_provider
|
||||
sha256: fec0d61223fba3154d87759e3cc27fe2c8dc498f6386c6d6fc80d1afdd1bf378
|
||||
sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.4"
|
||||
version: "2.1.5"
|
||||
path_provider_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_android
|
||||
sha256: c464428172cb986b758c6d1724c603097febb8fb855aa265aeecc9280c294d4a
|
||||
sha256: "4adf4fd5423ec60a29506c76581bc05854c55e3a0b72d35bb28d661c9686edf2"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.12"
|
||||
version: "2.2.15"
|
||||
path_provider_foundation:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_foundation
|
||||
sha256: f234384a3fdd67f989b4d54a5d73ca2a6c422fa55ae694381ae0f4375cd1ea16
|
||||
sha256: "4843174df4d288f5e29185bd6e72a6fbdf5a4a4602717eed565497429f179942"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.0"
|
||||
version: "2.4.1"
|
||||
path_provider_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -626,18 +626,18 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: pub_semver
|
||||
sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c"
|
||||
sha256: "7b3cfbf654f3edd0c6298ecd5be782ce997ddf0e00531b9464b55245185bbbbd"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.4"
|
||||
version: "2.1.5"
|
||||
pubspec_parse:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pubspec_parse
|
||||
sha256: c799b721d79eb6ee6fa56f00c04b472dcd44a30d258fac2174a6ec57302678f8
|
||||
sha256: "81876843eb50dc2e1e5b151792c9a985c5ed2536914115ed04e9c8528f6647b0"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
version: "1.4.0"
|
||||
rational:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -658,15 +658,15 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: shelf_web_socket
|
||||
sha256: "073c147238594ecd0d193f3456a5fe91c4b0abbcc68bf5cd95b36c4e194ac611"
|
||||
sha256: cc36c297b52866d203dbf9332263c94becc2fe0ceaa9681d07b6ef9807023b67
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
version: "2.0.1"
|
||||
sky_engine:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.99"
|
||||
version: "0.0.0"
|
||||
socks5_proxy:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -703,10 +703,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: stack_trace
|
||||
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
|
||||
sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.11.1"
|
||||
version: "1.12.0"
|
||||
stream_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -719,18 +719,18 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: stream_transform
|
||||
sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f"
|
||||
sha256: ad47125e588cfd37a9a7f86c7d6356dde8dfe89d071d293f80ca9e9273a33871
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
version: "2.1.1"
|
||||
string_scanner:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: string_scanner
|
||||
sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
|
||||
sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "1.3.0"
|
||||
term_glyph:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -743,18 +743,18 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb"
|
||||
sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.2"
|
||||
version: "0.7.3"
|
||||
timing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: timing
|
||||
sha256: "70a3b636575d4163c477e6de42f247a23b315ae20e86442bebe32d3cabf61c32"
|
||||
sha256: "62ee18aca144e4a9f29d212f5a4c6a053be252b895ab14b5821996cff4ed90fe"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
version: "1.0.2"
|
||||
tuple:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -791,26 +791,26 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: vm_service
|
||||
sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d"
|
||||
sha256: f6be3ed8bd01289b34d679c2b62226f63c0e69f9fd2e50a6b3c1c729a961041b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "14.2.5"
|
||||
version: "14.3.0"
|
||||
watcher:
|
||||
dependency: "direct overridden"
|
||||
description:
|
||||
name: watcher
|
||||
sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8"
|
||||
sha256: "69da27e49efa56a15f8afe8f4438c4ec02eff0a117df1b22ea4aad194fe1c104"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "1.1.1"
|
||||
web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: web
|
||||
sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb
|
||||
sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "1.1.1"
|
||||
web_socket:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -823,10 +823,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: web_socket_channel
|
||||
sha256: "9f187088ed104edd8662ca07af4b124465893caf063ba29758f97af57e61da8f"
|
||||
sha256: "0b8e2457400d8a859b7b2030786835a28a8e80836ef64402abef392ff4f1d0e5"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.1"
|
||||
version: "3.0.2"
|
||||
xdg_directories:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -839,10 +839,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: yaml
|
||||
sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5"
|
||||
sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.2"
|
||||
version: "3.1.3"
|
||||
sdks:
|
||||
dart: ">=3.5.0 <4.0.0"
|
||||
flutter: ">=3.24.0"
|
||||
|
|
|
@ -118,10 +118,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: built_value
|
||||
sha256: c7913a9737ee4007efedaffc968c049fd0f3d0e49109e778edc10de9426005cb
|
||||
sha256: "8b158ab94ec6913e480dc3f752418348b5ae099eb75868b5f4775f0572999c61"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "8.9.2"
|
||||
version: "8.9.4"
|
||||
cake_backup:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -167,10 +167,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: collection
|
||||
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
|
||||
sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.18.0"
|
||||
version: "1.19.0"
|
||||
convert:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -275,10 +275,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_mobx
|
||||
sha256: "859fbf452fa9c2519d2700b125dd7fb14c508bbdd7fb65e26ca8ff6c92280e2e"
|
||||
sha256: ba5e93467866a2991259dc51cffd41ef45f695c667c2b8e7b087bf24118b50fe
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.1+1"
|
||||
version: "2.3.0"
|
||||
flutter_test:
|
||||
dependency: "direct dev"
|
||||
description: flutter
|
||||
|
@ -293,10 +293,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: fluttertoast
|
||||
sha256: "95f349437aeebe524ef7d6c9bde3e6b4772717cf46a0eb6a3ceaddc740b297cc"
|
||||
sha256: "25e51620424d92d3db3832464774a6143b5053f15e382d8ffbfd40b6e795dcf1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "8.2.8"
|
||||
version: "8.2.12"
|
||||
frontend_server_client:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -309,10 +309,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: glob
|
||||
sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63"
|
||||
sha256: c3f1ee72c96f8f78935e18aa8cecced9ab132419e8625dc187e1c2408efc20de
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.2"
|
||||
version: "2.1.3"
|
||||
graphs:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -341,18 +341,18 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: http
|
||||
sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010
|
||||
sha256: fe7ab022b76f3034adc518fb6ea04a82387620e19977665ea18d30a1cf43442f
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.2"
|
||||
version: "1.3.0"
|
||||
http_multi_server:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_multi_server
|
||||
sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b"
|
||||
sha256: aa6199f908078bb1c5efb8d8638d4ae191aac11b311132c3ef48ce352fb52ef8
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.2.1"
|
||||
version: "3.2.2"
|
||||
http_parser:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -405,18 +405,18 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker
|
||||
sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05"
|
||||
sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "10.0.5"
|
||||
version: "10.0.7"
|
||||
leak_tracker_flutter_testing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker_flutter_testing
|
||||
sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806"
|
||||
sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.5"
|
||||
version: "3.0.8"
|
||||
leak_tracker_testing:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -469,10 +469,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: mobx
|
||||
sha256: "1f01a429529ac55e5e80c0fcad62c60112fb91df3dec11a9113d71cf0c2e2c4c"
|
||||
sha256: bf1a90e5bcfd2851fc6984e20eef69557c65d9e4d0a88f5be4cf72c9819ce6b0
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.0"
|
||||
version: "2.5.0"
|
||||
mobx_codegen:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
|
@ -631,10 +631,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: pubspec_parse
|
||||
sha256: c799b721d79eb6ee6fa56f00c04b472dcd44a30d258fac2174a6ec57302678f8
|
||||
sha256: "81876843eb50dc2e1e5b151792c9a985c5ed2536914115ed04e9c8528f6647b0"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
version: "1.4.0"
|
||||
rational:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -663,7 +663,7 @@ packages:
|
|||
dependency: transitive
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.99"
|
||||
version: "0.0.0"
|
||||
socks5_proxy:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -700,10 +700,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: stack_trace
|
||||
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
|
||||
sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.11.1"
|
||||
version: "1.12.0"
|
||||
stream_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -716,18 +716,18 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: stream_transform
|
||||
sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f"
|
||||
sha256: ad47125e588cfd37a9a7f86c7d6356dde8dfe89d071d293f80ca9e9273a33871
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
version: "2.1.1"
|
||||
string_scanner:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: string_scanner
|
||||
sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
|
||||
sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "1.3.0"
|
||||
term_glyph:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -740,10 +740,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb"
|
||||
sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.2"
|
||||
version: "0.7.3"
|
||||
timing:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -788,26 +788,26 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: vm_service
|
||||
sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d"
|
||||
sha256: f6be3ed8bd01289b34d679c2b62226f63c0e69f9fd2e50a6b3c1c729a961041b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "14.2.5"
|
||||
version: "14.3.0"
|
||||
watcher:
|
||||
dependency: "direct overridden"
|
||||
description:
|
||||
name: watcher
|
||||
sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8"
|
||||
sha256: "69da27e49efa56a15f8afe8f4438c4ec02eff0a117df1b22ea4aad194fe1c104"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "1.1.1"
|
||||
web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: web
|
||||
sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb
|
||||
sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "1.1.1"
|
||||
web_socket:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -820,10 +820,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: web_socket_channel
|
||||
sha256: "9f187088ed104edd8662ca07af4b124465893caf063ba29758f97af57e61da8f"
|
||||
sha256: "0b8e2457400d8a859b7b2030786835a28a8e80836ef64402abef392ff4f1d0e5"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.1"
|
||||
version: "3.0.2"
|
||||
xdg_directories:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -836,10 +836,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: yaml
|
||||
sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5"
|
||||
sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.2"
|
||||
version: "3.1.3"
|
||||
sdks:
|
||||
dart: ">=3.5.0 <4.0.0"
|
||||
flutter: ">=3.24.0"
|
||||
|
|
|
@ -22,7 +22,7 @@ dependencies:
|
|||
cw_core:
|
||||
path: ../cw_core
|
||||
json_bigint: ^3.0.0
|
||||
fluttertoast: ^8.2.8
|
||||
fluttertoast: ^8.2.12
|
||||
monero:
|
||||
git:
|
||||
url: https://github.com/mrcyjanek/monero_c
|
||||
|
|
|
@ -28,6 +28,7 @@ pushd scripts/android
|
|||
# source ./app_env.sh monero.com # Uncomment this line to build monero.com
|
||||
./app_config.sh
|
||||
./build_monero_all.sh
|
||||
./build_decred.sh
|
||||
./build_mwebd.sh --dont-install
|
||||
popd
|
||||
pushd android/app
|
||||
|
|
|
@ -7,7 +7,7 @@ The following are the system requirements to build Cake Wallet for your iOS devi
|
|||
```txt
|
||||
macOS 15.3.1
|
||||
Xcode 16.2
|
||||
Flutter 3.24.4
|
||||
Flutter 3.27.4
|
||||
```
|
||||
|
||||
NOTE: Newer versions of macOS and Xcode may also work, but have not been confirmed to work by the Cake team.
|
||||
|
@ -43,9 +43,9 @@ To enable iOS build support for Xcode, perform the following:
|
|||
|
||||
### 3. Installing Flutter
|
||||
|
||||
Install Flutter, specifically version `3.24.4` by following the [official docs](https://docs.flutter.dev/get-started/install/macos/desktop?tab=download).
|
||||
Install Flutter, specifically version `3.27.4` by following the [official docs](https://docs.flutter.dev/get-started/install/macos/desktop?tab=download).
|
||||
|
||||
NOTE: as `3.24.4` is not the latest version, you'll need to download it from <https://docs.flutter.dev/release/archive> instead of the link in the docs above.
|
||||
NOTE: as `3.27.4` is not the latest version, you'll need to download it from <https://docs.flutter.dev/release/archive> instead of the link in the docs above.
|
||||
|
||||
### 4. Installing Rust
|
||||
|
||||
|
@ -65,7 +65,7 @@ The output of this command should appear like this, indicating successful instal
|
|||
|
||||
```zsh
|
||||
Doctor summary (to see all details, run flutter doctor -v):
|
||||
[✓] Flutter (Channel stable, 3.24.4, on macOS 15.x.x)
|
||||
[✓] Flutter (Channel stable, 3.27.4, on macOS 15.x.x)
|
||||
[✓] Xcode - develop for iOS and macOS (Xcode 16.2)
|
||||
```
|
||||
|
||||
|
@ -101,6 +101,7 @@ Build the necessary libraries and their dependencies:
|
|||
```zsh
|
||||
./build_monero_all.sh
|
||||
./build_mwebd.sh
|
||||
./build_decred.sh
|
||||
```
|
||||
|
||||
NOTE: This step will take quite a while, so be sure you grab a cup of coffee or a good book!
|
||||
|
|
|
@ -7,7 +7,7 @@ The following are the system requirements to build Cake Wallet for your macOS de
|
|||
```txt
|
||||
macOS 15.3.1
|
||||
Xcode 16.2
|
||||
Flutter 3.24.4
|
||||
Flutter 3.27.4
|
||||
```
|
||||
|
||||
### 1. Installing dependencies
|
||||
|
@ -34,9 +34,9 @@ sudo xcodebuild -runFirstLaunch
|
|||
|
||||
### 3. Installing Flutter
|
||||
|
||||
Install Flutter, specifically version `3.24.4` by following the [official docs](https://docs.flutter.dev/get-started/install/macos/desktop?tab=download).
|
||||
Install Flutter, specifically version `3.27.4` by following the [official docs](https://docs.flutter.dev/get-started/install/macos/desktop?tab=download).
|
||||
|
||||
NOTE: as `3.24.4` is not the latest version, you'll need to download it from <https://docs.flutter.dev/release/archive> instead of the link in the docs above.
|
||||
NOTE: as `3.27.4` is not the latest version, you'll need to download it from <https://docs.flutter.dev/release/archive> instead of the link in the docs above.
|
||||
|
||||
### 4. Installing Rust
|
||||
|
||||
|
@ -56,7 +56,7 @@ The output of this command should appear like this, indicating successful instal
|
|||
|
||||
```zsh
|
||||
Doctor summary (to see all details, run flutter doctor -v):
|
||||
[✓] Flutter (Channel stable, 3.24.4, on macOS 15.x.x)
|
||||
[✓] Flutter (Channel stable, 3.27.4, on macOS 15.x.x)
|
||||
...
|
||||
[✓] Xcode - develop for iOS and macOS (Xcode 16.2)
|
||||
...
|
||||
|
@ -93,6 +93,7 @@ Build the necessary libraries and their dependencies:
|
|||
|
||||
```zsh
|
||||
./build_monero_all.sh
|
||||
./build_decred.sh
|
||||
```
|
||||
|
||||
NOTE: This step will take quite a while, so be sure you grab a cup of coffee or a good book!
|
||||
|
|
|
@ -6,18 +6,18 @@ The following are the system requirements to build Cake Wallet for your Windows
|
|||
|
||||
```txt
|
||||
Windows 10 or later (64-bit), x86-64 based
|
||||
Flutter 3.24.4
|
||||
Flutter 3.27.4
|
||||
```
|
||||
|
||||
### 1. Installing Flutter
|
||||
|
||||
Install Flutter, specifically version `3.24.4` by following the [official docs](https://docs.flutter.dev/get-started/install/windows).
|
||||
Install Flutter, specifically version `3.27.4` by following the [official docs](https://docs.flutter.dev/get-started/install/windows).
|
||||
|
||||
In order for Flutter to function, you'll also need to enable Developer Mode:
|
||||
|
||||
Start Menu > search for "Run" > type `ms-settings:developers`, and turn on Developer Mode.
|
||||
|
||||
NOTE: as `3.24.4` is not the latest version, you'll need to download it from <https://docs.flutter.dev/release/archive> instead of the link in the docs above.
|
||||
NOTE: as `3.27.4` is not the latest version, you'll need to download it from <https://docs.flutter.dev/release/archive> instead of the link in the docs above.
|
||||
|
||||
### 2. Install Development Tools
|
||||
|
||||
|
|
103
ios/Podfile.lock
103
ios/Podfile.lock
|
@ -3,38 +3,11 @@ PODS:
|
|||
- Flutter
|
||||
- ReachabilitySwift
|
||||
- CryptoSwift (1.8.3)
|
||||
- cw_haven (0.0.1):
|
||||
- cw_haven/Boost (= 0.0.1)
|
||||
- cw_haven/Haven (= 0.0.1)
|
||||
- cw_haven/OpenSSL (= 0.0.1)
|
||||
- cw_haven/Sodium (= 0.0.1)
|
||||
- cw_shared_external
|
||||
- Flutter
|
||||
- cw_haven/Boost (0.0.1):
|
||||
- cw_shared_external
|
||||
- Flutter
|
||||
- cw_haven/Haven (0.0.1):
|
||||
- cw_shared_external
|
||||
- Flutter
|
||||
- cw_haven/OpenSSL (0.0.1):
|
||||
- cw_shared_external
|
||||
- Flutter
|
||||
- cw_haven/Sodium (0.0.1):
|
||||
- cw_shared_external
|
||||
- Flutter
|
||||
- cw_mweb (0.0.1):
|
||||
- Flutter
|
||||
- cw_decred (0.0.1):
|
||||
- cw_shared_external (0.0.1):
|
||||
- cw_shared_external/Boost (= 0.0.1)
|
||||
- cw_shared_external/OpenSSL (= 0.0.1)
|
||||
- cw_shared_external/Sodium (= 0.0.1)
|
||||
- Flutter
|
||||
- cw_shared_external/Boost (0.0.1):
|
||||
- Flutter
|
||||
- cw_shared_external/OpenSSL (0.0.1):
|
||||
- Flutter
|
||||
- cw_shared_external/Sodium (0.0.1):
|
||||
- cw_mweb (0.0.1):
|
||||
- Flutter
|
||||
- device_display_brightness (0.0.1):
|
||||
- Flutter
|
||||
|
@ -94,7 +67,6 @@ PODS:
|
|||
- Flutter
|
||||
- fluttertoast (0.0.2):
|
||||
- Flutter
|
||||
- Toast
|
||||
- in_app_review (2.0.0):
|
||||
- Flutter
|
||||
- integration_test (0.0.1):
|
||||
|
@ -105,7 +77,7 @@ PODS:
|
|||
- path_provider_foundation (0.0.1):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
- permission_handler_apple (9.1.1):
|
||||
- permission_handler_apple (9.3.0):
|
||||
- Flutter
|
||||
- ReachabilitySwift (5.2.4)
|
||||
- SDWebImage (5.19.7):
|
||||
|
@ -121,7 +93,6 @@ PODS:
|
|||
- sp_scanner (0.0.1):
|
||||
- Flutter
|
||||
- SwiftyGif (5.4.5)
|
||||
- Toast (4.1.1)
|
||||
- uni_links (0.0.1):
|
||||
- Flutter
|
||||
- universal_ble (0.0.1):
|
||||
|
@ -131,16 +102,13 @@ PODS:
|
|||
- Flutter
|
||||
- wakelock_plus (0.0.1):
|
||||
- Flutter
|
||||
- workmanager (0.0.1):
|
||||
- Flutter
|
||||
|
||||
DEPENDENCIES:
|
||||
- connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`)
|
||||
- CryptoSwift
|
||||
- cw_haven (from `.symlinks/plugins/cw_haven/ios`)
|
||||
- cw_mweb (from `.symlinks/plugins/cw_mweb/ios`)
|
||||
- cw_shared_external (from `.symlinks/plugins/cw_shared_external/ios`)
|
||||
- cw_decred (from `.symlinks/plugins/cw_decred/ios`)
|
||||
- cw_mweb (from `.symlinks/plugins/cw_mweb/ios`)
|
||||
- device_display_brightness (from `.symlinks/plugins/device_display_brightness/ios`)
|
||||
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
|
||||
- devicelocale (from `.symlinks/plugins/devicelocale/ios`)
|
||||
|
@ -165,7 +133,6 @@ DEPENDENCIES:
|
|||
- universal_ble (from `.symlinks/plugins/universal_ble/darwin`)
|
||||
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
|
||||
- wakelock_plus (from `.symlinks/plugins/wakelock_plus/ios`)
|
||||
- workmanager (from `.symlinks/plugins/workmanager/ios`)
|
||||
|
||||
SPEC REPOS:
|
||||
https://github.com/CocoaPods/Specs.git:
|
||||
|
@ -176,19 +143,16 @@ SPEC REPOS:
|
|||
- ReachabilitySwift
|
||||
- SDWebImage
|
||||
- SwiftyGif
|
||||
- Toast
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
connectivity_plus:
|
||||
:path: ".symlinks/plugins/connectivity_plus/ios"
|
||||
cw_haven:
|
||||
:path: ".symlinks/plugins/cw_haven/ios"
|
||||
cw_mweb:
|
||||
:path: ".symlinks/plugins/cw_mweb/ios"
|
||||
cw_shared_external:
|
||||
:path: ".symlinks/plugins/cw_shared_external/ios"
|
||||
cw_decred:
|
||||
:path: ".symlinks/plugins/cw_decred/ios"
|
||||
cw_mweb:
|
||||
:path: ".symlinks/plugins/cw_mweb/ios"
|
||||
device_display_brightness:
|
||||
:path: ".symlinks/plugins/device_display_brightness/ios"
|
||||
device_info_plus:
|
||||
|
@ -237,48 +201,43 @@ EXTERNAL SOURCES:
|
|||
:path: ".symlinks/plugins/url_launcher_ios/ios"
|
||||
wakelock_plus:
|
||||
:path: ".symlinks/plugins/wakelock_plus/ios"
|
||||
workmanager:
|
||||
:path: ".symlinks/plugins/workmanager/ios"
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
connectivity_plus: bf0076dd84a130856aa636df1c71ccaff908fa1d
|
||||
connectivity_plus: 481668c94744c30c53b8895afb39159d1e619bdf
|
||||
CryptoSwift: 967f37cea5a3294d9cce358f78861652155be483
|
||||
cw_haven: b3e54e1fbe7b8e6fda57a93206bc38f8e89b898a
|
||||
cw_mweb: 22cd01dfb8ad2d39b15332006f22046aaa8352a3
|
||||
cw_shared_external: 2972d872b8917603478117c9957dfca611845a92
|
||||
cw_decred: 9c0e1df74745b51a1289ec5e91fb9e24b68fa14a
|
||||
device_display_brightness: 1510e72c567a1f6ce6ffe393dcd9afd1426034f7
|
||||
device_info_plus: c6fb39579d0f423935b0c9ce7ee2f44b71b9fce6
|
||||
devicelocale: 35ba84dc7f45f527c3001535d8c8d104edd5d926
|
||||
cw_decred: a02cf30175a46971c1e2fa22c48407534541edc6
|
||||
cw_mweb: 3aea2fb35b2bd04d8b2d21b83216f3b8fb768d85
|
||||
device_display_brightness: 04374ebd653619292c1d996f00f42877ea19f17f
|
||||
device_info_plus: 335f3ce08d2e174b9fdc3db3db0f4e3b1f66bd89
|
||||
devicelocale: bd64aa714485a8afdaded0892c1e7d5b7f680cf8
|
||||
DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c
|
||||
DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60
|
||||
fast_scanner: 44c00940355a51258cd6c2085734193cd23d95bc
|
||||
file_picker: 15fd9539e4eb735dc54bae8c0534a7a9511a03de
|
||||
fast_scanner: 2cb1ad3e69e645e9980fb4961396ce5804caa3e3
|
||||
file_picker: 9b3292d7c8bc68c8a7bf8eb78f730e49c8efc517
|
||||
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
|
||||
flutter_inappwebview_ios: 6f63631e2c62a7c350263b13fa5427aedefe81d4
|
||||
flutter_local_authentication: 1172a4dd88f6306dadce067454e2c4caf07977bb
|
||||
flutter_mailer: 2ef5a67087bc8c6c4cefd04a178bf1ae2c94cd83
|
||||
flutter_secure_storage: 23fc622d89d073675f2eaa109381aefbcf5a49be
|
||||
fluttertoast: e9a18c7be5413da53898f660530c56f35edfba9c
|
||||
in_app_review: a31b5257259646ea78e0e35fc914979b0031d011
|
||||
integration_test: 252f60fa39af5e17c3aa9899d35d908a0721b573
|
||||
flutter_inappwebview_ios: b89ba3482b96fb25e00c967aae065701b66e9b99
|
||||
flutter_local_authentication: 989278c681612f1ee0e36019e149137f114b9d7f
|
||||
flutter_mailer: 3a8cd4f36c960fb04528d5471097270c19fec1c4
|
||||
flutter_secure_storage: 2c2ff13db9e0a5647389bff88b0ecac56e3f3418
|
||||
fluttertoast: 2c67e14dce98bbdb200df9e1acf610d7a6264ea1
|
||||
in_app_review: 5596fe56fab799e8edb3561c03d053363ab13457
|
||||
integration_test: 4a889634ef21a45d28d50d622cf412dc6d9f586e
|
||||
OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94
|
||||
package_info_plus: c0502532a26c7662a62a356cebe2692ec5fe4ec4
|
||||
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
|
||||
permission_handler_apple: e76247795d700c14ea09e3a2d8855d41ee80a2e6
|
||||
package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499
|
||||
path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564
|
||||
permission_handler_apple: 4ed2196e43d0651e8ff7ca3483a069d469701f2d
|
||||
ReachabilitySwift: 32793e867593cfc1177f5d16491e3a197d2fccda
|
||||
SDWebImage: 8a6b7b160b4d710e2a22b6900e25301075c34cb3
|
||||
sensitive_clipboard: d4866e5d176581536c27bb1618642ee83adca986
|
||||
share_plus: 8b6f8b3447e494cca5317c8c3073de39b3600d1f
|
||||
shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
|
||||
sp_scanner: eaa617fa827396b967116b7f1f43549ca62e9a12
|
||||
sensitive_clipboard: 161e9abc3d56b3131309d8a321eb4690a803c16b
|
||||
share_plus: 50da8cb520a8f0f65671c6c6a99b3617ed10a58a
|
||||
shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7
|
||||
sp_scanner: b1bc9321690980bdb44bba7ec85d5543e716d1b5
|
||||
SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4
|
||||
Toast: 1f5ea13423a1e6674c4abdac5be53587ae481c4e
|
||||
uni_links: d97da20c7701486ba192624d99bffaaffcfc298a
|
||||
universal_ble: cf52a7b3fd2e7c14d6d7262e9fdadb72ab6b88a6
|
||||
url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe
|
||||
wakelock_plus: 373cfe59b235a6dd5837d0fb88791d2f13a90d56
|
||||
workmanager: 0afdcf5628bbde6924c21af7836fed07b42e30e6
|
||||
uni_links: ed8c961e47ed9ce42b6d91e1de8049e38a4b3152
|
||||
universal_ble: ff19787898040d721109c6324472e5dd4bc86adc
|
||||
url_launcher_ios: 694010445543906933d732453a59da0a173ae33d
|
||||
wakelock_plus: 04623e3f525556020ebd4034310f20fe7fda8b49
|
||||
|
||||
PODFILE CHECKSUM: e448f662d4c41f0c0b1ccbb78afd57dbf895a597
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
enableGPUValidationMode = "1"
|
||||
allowLocationSimulation = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import UIKit
|
||||
import Flutter
|
||||
import workmanager
|
||||
|
||||
@main
|
||||
@objc class AppDelegate: FlutterAppDelegate {
|
||||
|
@ -12,15 +11,6 @@ import workmanager
|
|||
UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
|
||||
}
|
||||
|
||||
WorkmanagerPlugin.setPluginRegistrantCallback { registry in
|
||||
// Registry in this case is the FlutterEngine that is created in Workmanager's
|
||||
// performFetchWithCompletionHandler or BGAppRefreshTask.
|
||||
// This will make other plugins available during a background operation.
|
||||
GeneratedPluginRegistrant.register(with: registry)
|
||||
}
|
||||
|
||||
WorkmanagerPlugin.registerTask(withIdentifier: "com.fotolockr.cakewallet.monero_sync_task")
|
||||
|
||||
makeSecure()
|
||||
|
||||
let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
|
||||
|
|
110
lib/core/background_sync.dart
Normal file
110
lib/core/background_sync.dart
Normal file
|
@ -0,0 +1,110 @@
|
|||
import 'dart:async';
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:cake_wallet/core/key_service.dart';
|
||||
import 'package:cake_wallet/core/wallet_loading_service.dart';
|
||||
import 'package:cake_wallet/di.dart';
|
||||
import 'package:cake_wallet/store/settings_store.dart';
|
||||
import 'package:cake_wallet/view_model/wallet_list/wallet_list_item.dart';
|
||||
import 'package:cake_wallet/view_model/wallet_list/wallet_list_view_model.dart';
|
||||
import 'package:cw_core/sync_status.dart';
|
||||
import 'package:cw_core/utils/print_verbose.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
class BackgroundSync {
|
||||
Future<void> sync() async {
|
||||
printV("Background sync started");
|
||||
await _syncMonero();
|
||||
printV("Background sync completed");
|
||||
}
|
||||
|
||||
Future<void> _syncMonero() async {
|
||||
final walletLoadingService = getIt.get<WalletLoadingService>();
|
||||
final walletListViewModel = getIt.get<WalletListViewModel>();
|
||||
final settingsStore = getIt.get<SettingsStore>();
|
||||
|
||||
final List<WalletListItem> moneroWallets = walletListViewModel.wallets
|
||||
.where((element) => !element.isHardware)
|
||||
.where((element) => [WalletType.monero].contains(element.type))
|
||||
.toList();
|
||||
for (int i = 0; i < moneroWallets.length; i++) {
|
||||
final wallet = await walletLoadingService.load(moneroWallets[i].type, moneroWallets[i].name);
|
||||
int syncedTicks = 0;
|
||||
final keyService = getIt.get<KeyService>();
|
||||
|
||||
int stuckTicks = 0;
|
||||
|
||||
inner:
|
||||
while (true) {
|
||||
await Future.delayed(const Duration(seconds: 1));
|
||||
final syncStatus = wallet.syncStatus;
|
||||
final progress = syncStatus.progress();
|
||||
if (syncStatus is ConnectedSyncStatus ||
|
||||
syncStatus is AttemptingSyncStatus ||
|
||||
syncStatus is NotConnectedSyncStatus) {
|
||||
stuckTicks++;
|
||||
if (stuckTicks > 30) {
|
||||
printV("${wallet.name} STUCK SYNCING");
|
||||
break inner;
|
||||
}
|
||||
} else {
|
||||
stuckTicks = 0;
|
||||
}
|
||||
if (syncStatus is NotConnectedSyncStatus) {
|
||||
printV("${wallet.name} NOT CONNECTED");
|
||||
final node = settingsStore.getCurrentNode(wallet.type);
|
||||
await wallet.connectToNode(node: node);
|
||||
await wallet.startBackgroundSync();
|
||||
printV("STARTED SYNC");
|
||||
continue inner;
|
||||
}
|
||||
|
||||
if (progress > 0.999 || syncStatus is SyncedSyncStatus) {
|
||||
syncedTicks++;
|
||||
if (syncedTicks > 5) {
|
||||
syncedTicks = 0;
|
||||
printV("WALLET $i SYNCED");
|
||||
try {
|
||||
await wallet.stopBackgroundSync(
|
||||
(await keyService.getWalletPassword(walletName: wallet.name)));
|
||||
} catch (e) {
|
||||
printV("error stopping sync: $e");
|
||||
}
|
||||
break inner;
|
||||
}
|
||||
} else {
|
||||
syncedTicks = 0;
|
||||
}
|
||||
if (kDebugMode) {
|
||||
if (syncStatus is SyncingSyncStatus) {
|
||||
final blocksLeft = syncStatus.blocksLeft;
|
||||
printV("$blocksLeft Blocks Left");
|
||||
} else if (syncStatus is SyncedSyncStatus) {
|
||||
printV("Synced");
|
||||
} else if (syncStatus is SyncedTipSyncStatus) {
|
||||
printV("Scanned Tip: ${syncStatus.tip}");
|
||||
} else if (syncStatus is NotConnectedSyncStatus) {
|
||||
printV("Still Not Connected");
|
||||
} else if (syncStatus is AttemptingSyncStatus) {
|
||||
printV("Attempting Sync");
|
||||
} else if (syncStatus is StartingScanSyncStatus) {
|
||||
printV("Starting Scan");
|
||||
} else if (syncStatus is SynchronizingSyncStatus) {
|
||||
printV("Syncronizing");
|
||||
} else if (syncStatus is FailedSyncStatus) {
|
||||
printV("Failed Sync");
|
||||
} else if (syncStatus is ConnectingSyncStatus) {
|
||||
printV("Connecting");
|
||||
} else {
|
||||
printV("Unknown Sync Status ${syncStatus.runtimeType}");
|
||||
}
|
||||
}
|
||||
}
|
||||
await wallet.stopBackgroundSync(await keyService.getWalletPassword(walletName: wallet.name));
|
||||
await wallet.close(shouldCleanup: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -24,118 +24,26 @@ import 'package:cake_wallet/.secrets.g.dart' as secrets;
|
|||
import 'package:cake_wallet/wallet_types.g.dart';
|
||||
import 'package:cake_backup/backup.dart' as cake_backup;
|
||||
|
||||
class BackupService {
|
||||
BackupService(this._secureStorage, this._walletInfoSource, this._transactionDescriptionBox,
|
||||
this._keyService, this._sharedPreferences)
|
||||
: _cipher = Cryptography.instance.chacha20Poly1305Aead(),
|
||||
_correctWallets = <WalletInfo>[];
|
||||
class $BackupService {
|
||||
$BackupService(this._secureStorage, this.walletInfoSource, this.transactionDescriptionBox,
|
||||
this.keyService, this.sharedPreferences)
|
||||
: cipher = Cryptography.instance.chacha20Poly1305Aead(),
|
||||
correctWallets = <WalletInfo>[];
|
||||
|
||||
static const currentVersion = _v2;
|
||||
static const currentVersion = _v3;
|
||||
|
||||
static const _v1 = 1;
|
||||
static const _v2 = 2;
|
||||
static const _v3 = 3;
|
||||
|
||||
final Cipher _cipher;
|
||||
final Cipher cipher;
|
||||
final SecureStorage _secureStorage;
|
||||
final SharedPreferences _sharedPreferences;
|
||||
final Box<WalletInfo> _walletInfoSource;
|
||||
final Box<TransactionDescription> _transactionDescriptionBox;
|
||||
final KeyService _keyService;
|
||||
List<WalletInfo> _correctWallets;
|
||||
final SharedPreferences sharedPreferences;
|
||||
final Box<WalletInfo> walletInfoSource;
|
||||
final Box<TransactionDescription> transactionDescriptionBox;
|
||||
final KeyService keyService;
|
||||
List<WalletInfo> correctWallets;
|
||||
|
||||
Future<void> importBackup(Uint8List data, String password,
|
||||
{String nonce = secrets.backupSalt}) async {
|
||||
final version = getVersion(data);
|
||||
|
||||
switch (version) {
|
||||
case _v1:
|
||||
final backupBytes = data.toList()..removeAt(0);
|
||||
final backupData = Uint8List.fromList(backupBytes);
|
||||
await _importBackupV1(backupData, password, nonce: nonce);
|
||||
break;
|
||||
case _v2:
|
||||
await _importBackupV2(data, password);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Future<Uint8List> exportBackup(String password,
|
||||
{String nonce = secrets.backupSalt, int version = currentVersion}) async {
|
||||
switch (version) {
|
||||
case _v1:
|
||||
return await _exportBackupV1(password, nonce: nonce);
|
||||
case _v2:
|
||||
return await _exportBackupV2(password);
|
||||
default:
|
||||
throw Exception('Incorrect version: $version for exportBackup');
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated('Use v2 instead')
|
||||
Future<Uint8List> _exportBackupV1(String password, {String nonce = secrets.backupSalt}) async =>
|
||||
throw Exception('Deprecated. Export for backups v1 is deprecated. Please use export v2.');
|
||||
|
||||
Future<Uint8List> _exportBackupV2(String password) async {
|
||||
final zipEncoder = ZipFileEncoder();
|
||||
final appDir = await getAppDir();
|
||||
final now = DateTime.now();
|
||||
final tmpDir = Directory('${appDir.path}/~_BACKUP_TMP');
|
||||
final archivePath = '${tmpDir.path}/backup_${now.toString()}.zip';
|
||||
final fileEntities = appDir.listSync(recursive: false);
|
||||
final keychainDump = await _exportKeychainDumpV2(password);
|
||||
final preferencesDump = await _exportPreferencesJSON();
|
||||
final preferencesDumpFile = File('${tmpDir.path}/~_preferences_dump_TMP');
|
||||
final keychainDumpFile = File('${tmpDir.path}/~_keychain_dump_TMP');
|
||||
final transactionDescriptionDumpFile =
|
||||
File('${tmpDir.path}/~_transaction_descriptions_dump_TMP');
|
||||
|
||||
final transactionDescriptionData = _transactionDescriptionBox
|
||||
.toMap()
|
||||
.map((key, value) => MapEntry(key.toString(), value.toJson()));
|
||||
final transactionDescriptionDump = jsonEncode(transactionDescriptionData);
|
||||
|
||||
if (tmpDir.existsSync()) {
|
||||
tmpDir.deleteSync(recursive: true);
|
||||
}
|
||||
|
||||
tmpDir.createSync();
|
||||
zipEncoder.create(archivePath);
|
||||
|
||||
fileEntities.forEach((entity) {
|
||||
if (entity.path == archivePath || entity.path == tmpDir.path) {
|
||||
return;
|
||||
}
|
||||
final filename = entity.absolute;
|
||||
for (var ignore in ignoreFiles) {
|
||||
final filename = entity.absolute.path;
|
||||
if (filename.endsWith(ignore) && !filename.contains("wallets/")) {
|
||||
printV("ignoring backup file: $filename");
|
||||
return;
|
||||
}
|
||||
}
|
||||
printV("restoring: $filename");
|
||||
if (entity.statSync().type == FileSystemEntityType.directory) {
|
||||
zipEncoder.addDirectory(Directory(entity.path));
|
||||
} else {
|
||||
zipEncoder.addFile(File(entity.path));
|
||||
}
|
||||
});
|
||||
await keychainDumpFile.writeAsBytes(keychainDump.toList());
|
||||
await preferencesDumpFile.writeAsString(preferencesDump);
|
||||
await transactionDescriptionDumpFile.writeAsString(transactionDescriptionDump);
|
||||
await zipEncoder.addFile(preferencesDumpFile, '~_preferences_dump');
|
||||
await zipEncoder.addFile(keychainDumpFile, '~_keychain_dump');
|
||||
await zipEncoder.addFile(transactionDescriptionDumpFile, '~_transaction_descriptions_dump');
|
||||
zipEncoder.close();
|
||||
|
||||
final content = File(archivePath).readAsBytesSync();
|
||||
tmpDir.deleteSync(recursive: true);
|
||||
return await _encryptV2(content, password);
|
||||
}
|
||||
|
||||
Future<void> _importBackupV1(Uint8List data, String password, {required String nonce}) async {
|
||||
Future<void> importBackupV1(Uint8List data, String password, {required String nonce}) async {
|
||||
final appDir = await getAppDir();
|
||||
final decryptedData = await _decryptV1(data, password, nonce);
|
||||
final zip = ZipDecoder().decodeBytes(decryptedData);
|
||||
|
@ -153,9 +61,9 @@ class BackupService {
|
|||
}
|
||||
}
|
||||
|
||||
await _verifyWallets();
|
||||
await verifyWallets();
|
||||
await _importKeychainDumpV1(password, nonce: nonce);
|
||||
await _importPreferencesDump();
|
||||
await importPreferencesDump();
|
||||
}
|
||||
|
||||
// checked with .endsWith - so this should be the last part of the filename
|
||||
|
@ -163,12 +71,13 @@ class BackupService {
|
|||
"flutter_assets/kernel_blob.bin",
|
||||
"flutter_assets/vm_snapshot_data",
|
||||
"flutter_assets/isolate_snapshot_data",
|
||||
"README.txt",
|
||||
".lock",
|
||||
];
|
||||
|
||||
Future<void> _importBackupV2(Uint8List data, String password) async {
|
||||
Future<void> importBackupV2(Uint8List data, String password) async {
|
||||
final appDir = await getAppDir();
|
||||
final decryptedData = await _decryptV2(data, password);
|
||||
final decryptedData = await decryptV2(data, password);
|
||||
final zip = ZipDecoder().decodeBytes(decryptedData);
|
||||
|
||||
outer:
|
||||
|
@ -187,22 +96,25 @@ class BackupService {
|
|||
..createSync(recursive: true)
|
||||
..writeAsBytesSync(content, flush: true);
|
||||
} else {
|
||||
Directory('${appDir.path}/' + filename)..create(recursive: true);
|
||||
final dir = Directory('${appDir.path}/' + filename);
|
||||
if (!dir.existsSync()) {
|
||||
dir.createSync(recursive: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await _verifyWallets();
|
||||
await _importKeychainDumpV2(password);
|
||||
await _importPreferencesDump();
|
||||
await _importTransactionDescriptionDump(); // HiveError: Box has already been closed
|
||||
await verifyWallets();
|
||||
await importKeychainDumpV2(password);
|
||||
await importPreferencesDump();
|
||||
await importTransactionDescriptionDump(); // HiveError: Box has already been closed
|
||||
}
|
||||
|
||||
Future<void> _verifyWallets() async {
|
||||
Future<void> verifyWallets() async {
|
||||
final walletInfoSource = await _reloadHiveWalletInfoBox();
|
||||
_correctWallets =
|
||||
correctWallets =
|
||||
walletInfoSource.values.where((info) => availableWalletTypes.contains(info.type)).toList();
|
||||
|
||||
if (_correctWallets.isEmpty) {
|
||||
if (correctWallets.isEmpty) {
|
||||
throw Exception('Correct wallets not detected');
|
||||
}
|
||||
}
|
||||
|
@ -219,7 +131,7 @@ class BackupService {
|
|||
return await CakeHive.openBox<WalletInfo>(WalletInfo.boxName);
|
||||
}
|
||||
|
||||
Future<void> _importTransactionDescriptionDump() async {
|
||||
Future<void> importTransactionDescriptionDump() async {
|
||||
final appDir = await getAppDir();
|
||||
final transactionDescriptionFile = File('${appDir.path}/~_transaction_descriptions_dump');
|
||||
|
||||
|
@ -231,7 +143,7 @@ class BackupService {
|
|||
json.decode(transactionDescriptionFile.readAsStringSync()) as Map<String, dynamic>;
|
||||
final descriptionsMap = jsonData.map((key, value) =>
|
||||
MapEntry(key, TransactionDescription.fromJson(value as Map<String, dynamic>)));
|
||||
var box = _transactionDescriptionBox;
|
||||
var box = transactionDescriptionBox;
|
||||
if (!box.isOpen) {
|
||||
final transactionDescriptionsBoxKey = await getEncryptionKey(
|
||||
secureStorage: _secureStorage, forKey: TransactionDescription.boxKey);
|
||||
|
@ -241,7 +153,7 @@ class BackupService {
|
|||
await box.putAll(descriptionsMap);
|
||||
}
|
||||
|
||||
Future<void> _importPreferencesDump() async {
|
||||
Future<void> importPreferencesDump() async {
|
||||
final appDir = await getAppDir();
|
||||
final preferencesFile = File('${appDir.path}/~_preferences_dump');
|
||||
|
||||
|
@ -253,12 +165,12 @@ class BackupService {
|
|||
String currentWalletName = data[PreferencesKey.currentWalletName] as String;
|
||||
int currentWalletType = data[PreferencesKey.currentWalletType] as int;
|
||||
|
||||
final isCorrentCurrentWallet = _correctWallets
|
||||
final isCorrentCurrentWallet = correctWallets
|
||||
.any((info) => info.name == currentWalletName && info.type.index == currentWalletType);
|
||||
|
||||
if (!isCorrentCurrentWallet) {
|
||||
currentWalletName = _correctWallets.first.name;
|
||||
currentWalletType = serializeToInt(_correctWallets.first.type);
|
||||
currentWalletName = correctWallets.first.name;
|
||||
currentWalletType = serializeToInt(correctWallets.first.type);
|
||||
}
|
||||
|
||||
final currentNodeId = data[PreferencesKey.currentNodeIdKey] as int?;
|
||||
|
@ -297,114 +209,113 @@ class BackupService {
|
|||
final autoGenerateSubaddressStatus =
|
||||
data[PreferencesKey.autoGenerateSubaddressStatusKey] as int?;
|
||||
|
||||
await _sharedPreferences.setString(PreferencesKey.currentWalletName, currentWalletName);
|
||||
await sharedPreferences.setString(PreferencesKey.currentWalletName, currentWalletName);
|
||||
|
||||
if (currentNodeId != null)
|
||||
await _sharedPreferences.setInt(PreferencesKey.currentNodeIdKey, currentNodeId);
|
||||
await sharedPreferences.setInt(PreferencesKey.currentNodeIdKey, currentNodeId);
|
||||
|
||||
if (currentBalanceDisplayMode != null)
|
||||
await _sharedPreferences.setInt(
|
||||
await sharedPreferences.setInt(
|
||||
PreferencesKey.currentBalanceDisplayModeKey, currentBalanceDisplayMode);
|
||||
|
||||
await _sharedPreferences.setInt(PreferencesKey.currentWalletType, currentWalletType);
|
||||
await sharedPreferences.setInt(PreferencesKey.currentWalletType, currentWalletType);
|
||||
|
||||
if (currentFiatCurrency != null)
|
||||
await _sharedPreferences.setString(
|
||||
PreferencesKey.currentFiatCurrencyKey, currentFiatCurrency);
|
||||
await sharedPreferences.setString(PreferencesKey.currentFiatCurrencyKey, currentFiatCurrency);
|
||||
|
||||
if (shouldSaveRecipientAddress != null)
|
||||
await _sharedPreferences.setBool(
|
||||
await sharedPreferences.setBool(
|
||||
PreferencesKey.shouldSaveRecipientAddressKey, shouldSaveRecipientAddress);
|
||||
|
||||
if (isAppSecure != null)
|
||||
await _sharedPreferences.setBool(PreferencesKey.isAppSecureKey, isAppSecure);
|
||||
await sharedPreferences.setBool(PreferencesKey.isAppSecureKey, isAppSecure);
|
||||
|
||||
if (disableTradeOption != null)
|
||||
await _sharedPreferences.setBool(PreferencesKey.disableTradeOption, disableTradeOption);
|
||||
await sharedPreferences.setBool(PreferencesKey.disableTradeOption, disableTradeOption);
|
||||
|
||||
if (currentTransactionPriorityKeyLegacy != null)
|
||||
await _sharedPreferences.setInt(
|
||||
await sharedPreferences.setInt(
|
||||
PreferencesKey.currentTransactionPriorityKeyLegacy, currentTransactionPriorityKeyLegacy);
|
||||
|
||||
if (currentBitcoinElectrumSererId != null)
|
||||
await _sharedPreferences.setInt(
|
||||
await sharedPreferences.setInt(
|
||||
PreferencesKey.currentBitcoinElectrumSererIdKey, currentBitcoinElectrumSererId);
|
||||
|
||||
if (currentLanguageCode != null)
|
||||
await _sharedPreferences.setString(PreferencesKey.currentLanguageCode, currentLanguageCode);
|
||||
await sharedPreferences.setString(PreferencesKey.currentLanguageCode, currentLanguageCode);
|
||||
|
||||
if (displayActionListMode != null)
|
||||
await _sharedPreferences.setInt(
|
||||
await sharedPreferences.setInt(
|
||||
PreferencesKey.displayActionListModeKey, displayActionListMode);
|
||||
|
||||
if (fiatApiMode != null)
|
||||
await _sharedPreferences.setInt(PreferencesKey.currentFiatApiModeKey, fiatApiMode);
|
||||
await sharedPreferences.setInt(PreferencesKey.currentFiatApiModeKey, fiatApiMode);
|
||||
if (autoGenerateSubaddressStatus != null)
|
||||
await _sharedPreferences.setInt(
|
||||
await sharedPreferences.setInt(
|
||||
PreferencesKey.autoGenerateSubaddressStatusKey, autoGenerateSubaddressStatus);
|
||||
|
||||
if (currentTheme != null && DeviceInfo.instance.isMobile) {
|
||||
await _sharedPreferences.setInt(PreferencesKey.currentTheme, currentTheme);
|
||||
await sharedPreferences.setInt(PreferencesKey.currentTheme, currentTheme);
|
||||
// enforce dark theme on desktop platforms until the design is ready:
|
||||
} else if (DeviceInfo.instance.isDesktop) {
|
||||
await _sharedPreferences.setInt(PreferencesKey.currentTheme, ThemeList.darkTheme.raw);
|
||||
await sharedPreferences.setInt(PreferencesKey.currentTheme, ThemeList.darkTheme.raw);
|
||||
}
|
||||
|
||||
if (exchangeStatus != null)
|
||||
await _sharedPreferences.setInt(PreferencesKey.exchangeStatusKey, exchangeStatus);
|
||||
await sharedPreferences.setInt(PreferencesKey.exchangeStatusKey, exchangeStatus);
|
||||
|
||||
if (currentDefaultSettingsMigrationVersion != null)
|
||||
await _sharedPreferences.setInt(PreferencesKey.currentDefaultSettingsMigrationVersion,
|
||||
await sharedPreferences.setInt(PreferencesKey.currentDefaultSettingsMigrationVersion,
|
||||
currentDefaultSettingsMigrationVersion);
|
||||
|
||||
if (moneroTransactionPriority != null)
|
||||
await _sharedPreferences.setInt(
|
||||
await sharedPreferences.setInt(
|
||||
PreferencesKey.moneroTransactionPriority, moneroTransactionPriority);
|
||||
|
||||
if (bitcoinTransactionPriority != null)
|
||||
await _sharedPreferences.setInt(
|
||||
await sharedPreferences.setInt(
|
||||
PreferencesKey.bitcoinTransactionPriority, bitcoinTransactionPriority);
|
||||
|
||||
if (sortBalanceTokensBy != null)
|
||||
await _sharedPreferences.setInt(PreferencesKey.sortBalanceBy, sortBalanceTokensBy);
|
||||
await sharedPreferences.setInt(PreferencesKey.sortBalanceBy, sortBalanceTokensBy);
|
||||
|
||||
if (pinNativeTokenAtTop != null)
|
||||
await _sharedPreferences.setBool(PreferencesKey.pinNativeTokenAtTop, pinNativeTokenAtTop);
|
||||
await sharedPreferences.setBool(PreferencesKey.pinNativeTokenAtTop, pinNativeTokenAtTop);
|
||||
|
||||
if (useEtherscan != null)
|
||||
await _sharedPreferences.setBool(PreferencesKey.useEtherscan, useEtherscan);
|
||||
await sharedPreferences.setBool(PreferencesKey.useEtherscan, useEtherscan);
|
||||
|
||||
if (defaultNanoRep != null)
|
||||
await _sharedPreferences.setString(PreferencesKey.defaultNanoRep, defaultNanoRep);
|
||||
await sharedPreferences.setString(PreferencesKey.defaultNanoRep, defaultNanoRep);
|
||||
|
||||
if (defaultBananoRep != null)
|
||||
await _sharedPreferences.setString(PreferencesKey.defaultBananoRep, defaultBananoRep);
|
||||
await sharedPreferences.setString(PreferencesKey.defaultBananoRep, defaultBananoRep);
|
||||
|
||||
if (syncAll != null) await _sharedPreferences.setBool(PreferencesKey.syncAllKey, syncAll);
|
||||
if (syncAll != null) await sharedPreferences.setBool(PreferencesKey.syncAllKey, syncAll);
|
||||
if (lookupsTwitter != null)
|
||||
await _sharedPreferences.setBool(PreferencesKey.lookupsTwitter, lookupsTwitter);
|
||||
await sharedPreferences.setBool(PreferencesKey.lookupsTwitter, lookupsTwitter);
|
||||
|
||||
if (lookupsMastodon != null)
|
||||
await _sharedPreferences.setBool(PreferencesKey.lookupsMastodon, lookupsMastodon);
|
||||
await sharedPreferences.setBool(PreferencesKey.lookupsMastodon, lookupsMastodon);
|
||||
|
||||
if (lookupsYatService != null)
|
||||
await _sharedPreferences.setBool(PreferencesKey.lookupsYatService, lookupsYatService);
|
||||
await sharedPreferences.setBool(PreferencesKey.lookupsYatService, lookupsYatService);
|
||||
|
||||
if (lookupsUnstoppableDomains != null)
|
||||
await _sharedPreferences.setBool(
|
||||
await sharedPreferences.setBool(
|
||||
PreferencesKey.lookupsUnstoppableDomains, lookupsUnstoppableDomains);
|
||||
|
||||
if (lookupsOpenAlias != null)
|
||||
await _sharedPreferences.setBool(PreferencesKey.lookupsOpenAlias, lookupsOpenAlias);
|
||||
await sharedPreferences.setBool(PreferencesKey.lookupsOpenAlias, lookupsOpenAlias);
|
||||
|
||||
if (lookupsENS != null) await _sharedPreferences.setBool(PreferencesKey.lookupsENS, lookupsENS);
|
||||
if (lookupsENS != null) await sharedPreferences.setBool(PreferencesKey.lookupsENS, lookupsENS);
|
||||
|
||||
if (lookupsWellKnown != null)
|
||||
await _sharedPreferences.setBool(PreferencesKey.lookupsWellKnown, lookupsWellKnown);
|
||||
await sharedPreferences.setBool(PreferencesKey.lookupsWellKnown, lookupsWellKnown);
|
||||
|
||||
if (syncAll != null) await _sharedPreferences.setBool(PreferencesKey.syncAllKey, syncAll);
|
||||
if (syncAll != null) await sharedPreferences.setBool(PreferencesKey.syncAllKey, syncAll);
|
||||
|
||||
if (syncMode != null) await _sharedPreferences.setInt(PreferencesKey.syncModeKey, syncMode);
|
||||
if (syncMode != null) await sharedPreferences.setInt(PreferencesKey.syncModeKey, syncMode);
|
||||
|
||||
await preferencesFile.delete();
|
||||
}
|
||||
|
@ -435,12 +346,12 @@ class BackupService {
|
|||
keychainDumpFile.deleteSync();
|
||||
}
|
||||
|
||||
Future<void> _importKeychainDumpV2(String password,
|
||||
Future<void> importKeychainDumpV2(String password,
|
||||
{String keychainSalt = secrets.backupKeychainSalt}) async {
|
||||
final appDir = await getAppDir();
|
||||
final keychainDumpFile = File('${appDir.path}/~_keychain_dump');
|
||||
final decryptedKeychainDumpFileData =
|
||||
await _decryptV2(keychainDumpFile.readAsBytesSync(), '$keychainSalt$password');
|
||||
await decryptV2(keychainDumpFile.readAsBytesSync(), '$keychainSalt$password');
|
||||
final keychainJSON =
|
||||
json.decode(utf8.decode(decryptedKeychainDumpFileData)) as Map<String, dynamic>;
|
||||
final keychainWalletsInfo = keychainJSON['wallets'] as List;
|
||||
|
@ -461,7 +372,7 @@ class BackupService {
|
|||
final name = info['name'] as String;
|
||||
final password = info['password'] as String;
|
||||
|
||||
await _keyService.saveWalletPassword(walletName: name, password: password);
|
||||
await keyService.saveWalletPassword(walletName: name, password: password);
|
||||
}
|
||||
|
||||
@Deprecated('Use v2 instead')
|
||||
|
@ -469,14 +380,14 @@ class BackupService {
|
|||
{required String nonce, String keychainSalt = secrets.backupKeychainSalt}) async =>
|
||||
throw Exception('Deprecated');
|
||||
|
||||
Future<Uint8List> _exportKeychainDumpV2(String password,
|
||||
Future<Uint8List> exportKeychainDumpV2(String password,
|
||||
{String keychainSalt = secrets.backupKeychainSalt}) async {
|
||||
final key = generateStoreKeyFor(key: SecretStoreKey.pinCodePassword);
|
||||
final wallets = await Future.wait(_walletInfoSource.values.map((walletInfo) async {
|
||||
final wallets = await Future.wait(walletInfoSource.values.map((walletInfo) async {
|
||||
return {
|
||||
'name': walletInfo.name,
|
||||
'type': walletInfo.type.toString(),
|
||||
'password': await _keyService.getWalletPassword(walletName: walletInfo.name)
|
||||
'password': await keyService.getWalletPassword(walletName: walletInfo.name)
|
||||
};
|
||||
}));
|
||||
final backupPasswordKey = generateStoreKeyFor(key: SecretStoreKey.backupPassword);
|
||||
|
@ -487,58 +398,56 @@ class BackupService {
|
|||
return encrypted;
|
||||
}
|
||||
|
||||
Future<String> _exportPreferencesJSON() async {
|
||||
Future<String> exportPreferencesJSON() async {
|
||||
final preferences = <String, dynamic>{
|
||||
PreferencesKey.currentWalletName:
|
||||
_sharedPreferences.getString(PreferencesKey.currentWalletName),
|
||||
PreferencesKey.currentNodeIdKey: _sharedPreferences.getInt(PreferencesKey.currentNodeIdKey),
|
||||
sharedPreferences.getString(PreferencesKey.currentWalletName),
|
||||
PreferencesKey.currentNodeIdKey: sharedPreferences.getInt(PreferencesKey.currentNodeIdKey),
|
||||
PreferencesKey.currentBalanceDisplayModeKey:
|
||||
_sharedPreferences.getInt(PreferencesKey.currentBalanceDisplayModeKey),
|
||||
PreferencesKey.currentWalletType: _sharedPreferences.getInt(PreferencesKey.currentWalletType),
|
||||
sharedPreferences.getInt(PreferencesKey.currentBalanceDisplayModeKey),
|
||||
PreferencesKey.currentWalletType: sharedPreferences.getInt(PreferencesKey.currentWalletType),
|
||||
PreferencesKey.currentFiatCurrencyKey:
|
||||
_sharedPreferences.getString(PreferencesKey.currentFiatCurrencyKey),
|
||||
sharedPreferences.getString(PreferencesKey.currentFiatCurrencyKey),
|
||||
PreferencesKey.shouldSaveRecipientAddressKey:
|
||||
_sharedPreferences.getBool(PreferencesKey.shouldSaveRecipientAddressKey),
|
||||
sharedPreferences.getBool(PreferencesKey.shouldSaveRecipientAddressKey),
|
||||
PreferencesKey.disableTradeOption:
|
||||
_sharedPreferences.getBool(PreferencesKey.disableTradeOption),
|
||||
sharedPreferences.getBool(PreferencesKey.disableTradeOption),
|
||||
PreferencesKey.currentTransactionPriorityKeyLegacy:
|
||||
_sharedPreferences.getInt(PreferencesKey.currentTransactionPriorityKeyLegacy),
|
||||
sharedPreferences.getInt(PreferencesKey.currentTransactionPriorityKeyLegacy),
|
||||
PreferencesKey.currentBitcoinElectrumSererIdKey:
|
||||
_sharedPreferences.getInt(PreferencesKey.currentBitcoinElectrumSererIdKey),
|
||||
sharedPreferences.getInt(PreferencesKey.currentBitcoinElectrumSererIdKey),
|
||||
PreferencesKey.currentLanguageCode:
|
||||
_sharedPreferences.getString(PreferencesKey.currentLanguageCode),
|
||||
sharedPreferences.getString(PreferencesKey.currentLanguageCode),
|
||||
PreferencesKey.displayActionListModeKey:
|
||||
_sharedPreferences.getInt(PreferencesKey.displayActionListModeKey),
|
||||
PreferencesKey.currentTheme: _sharedPreferences.getInt(PreferencesKey.currentTheme),
|
||||
PreferencesKey.exchangeStatusKey: _sharedPreferences.getInt(PreferencesKey.exchangeStatusKey),
|
||||
sharedPreferences.getInt(PreferencesKey.displayActionListModeKey),
|
||||
PreferencesKey.currentTheme: sharedPreferences.getInt(PreferencesKey.currentTheme),
|
||||
PreferencesKey.exchangeStatusKey: sharedPreferences.getInt(PreferencesKey.exchangeStatusKey),
|
||||
PreferencesKey.currentDefaultSettingsMigrationVersion:
|
||||
_sharedPreferences.getInt(PreferencesKey.currentDefaultSettingsMigrationVersion),
|
||||
sharedPreferences.getInt(PreferencesKey.currentDefaultSettingsMigrationVersion),
|
||||
PreferencesKey.bitcoinTransactionPriority:
|
||||
_sharedPreferences.getInt(PreferencesKey.bitcoinTransactionPriority),
|
||||
sharedPreferences.getInt(PreferencesKey.bitcoinTransactionPriority),
|
||||
PreferencesKey.moneroTransactionPriority:
|
||||
_sharedPreferences.getInt(PreferencesKey.moneroTransactionPriority),
|
||||
sharedPreferences.getInt(PreferencesKey.moneroTransactionPriority),
|
||||
PreferencesKey.currentFiatApiModeKey:
|
||||
_sharedPreferences.getInt(PreferencesKey.currentFiatApiModeKey),
|
||||
PreferencesKey.sortBalanceBy: _sharedPreferences.getInt(PreferencesKey.sortBalanceBy),
|
||||
sharedPreferences.getInt(PreferencesKey.currentFiatApiModeKey),
|
||||
PreferencesKey.sortBalanceBy: sharedPreferences.getInt(PreferencesKey.sortBalanceBy),
|
||||
PreferencesKey.pinNativeTokenAtTop:
|
||||
_sharedPreferences.getBool(PreferencesKey.pinNativeTokenAtTop),
|
||||
PreferencesKey.useEtherscan: _sharedPreferences.getBool(PreferencesKey.useEtherscan),
|
||||
PreferencesKey.defaultNanoRep: _sharedPreferences.getString(PreferencesKey.defaultNanoRep),
|
||||
PreferencesKey.defaultBananoRep:
|
||||
_sharedPreferences.getString(PreferencesKey.defaultBananoRep),
|
||||
PreferencesKey.lookupsTwitter: _sharedPreferences.getBool(PreferencesKey.lookupsTwitter),
|
||||
PreferencesKey.lookupsMastodon: _sharedPreferences.getBool(PreferencesKey.lookupsMastodon),
|
||||
PreferencesKey.lookupsYatService:
|
||||
_sharedPreferences.getBool(PreferencesKey.lookupsYatService),
|
||||
sharedPreferences.getBool(PreferencesKey.pinNativeTokenAtTop),
|
||||
PreferencesKey.useEtherscan: sharedPreferences.getBool(PreferencesKey.useEtherscan),
|
||||
PreferencesKey.defaultNanoRep: sharedPreferences.getString(PreferencesKey.defaultNanoRep),
|
||||
PreferencesKey.defaultBananoRep: sharedPreferences.getString(PreferencesKey.defaultBananoRep),
|
||||
PreferencesKey.lookupsTwitter: sharedPreferences.getBool(PreferencesKey.lookupsTwitter),
|
||||
PreferencesKey.lookupsMastodon: sharedPreferences.getBool(PreferencesKey.lookupsMastodon),
|
||||
PreferencesKey.lookupsYatService: sharedPreferences.getBool(PreferencesKey.lookupsYatService),
|
||||
PreferencesKey.lookupsUnstoppableDomains:
|
||||
_sharedPreferences.getBool(PreferencesKey.lookupsUnstoppableDomains),
|
||||
PreferencesKey.lookupsOpenAlias: _sharedPreferences.getBool(PreferencesKey.lookupsOpenAlias),
|
||||
PreferencesKey.lookupsENS: _sharedPreferences.getBool(PreferencesKey.lookupsENS),
|
||||
PreferencesKey.lookupsWellKnown: _sharedPreferences.getBool(PreferencesKey.lookupsWellKnown),
|
||||
PreferencesKey.syncModeKey: _sharedPreferences.getInt(PreferencesKey.syncModeKey),
|
||||
PreferencesKey.syncAllKey: _sharedPreferences.getBool(PreferencesKey.syncAllKey),
|
||||
sharedPreferences.getBool(PreferencesKey.lookupsUnstoppableDomains),
|
||||
PreferencesKey.lookupsOpenAlias: sharedPreferences.getBool(PreferencesKey.lookupsOpenAlias),
|
||||
PreferencesKey.lookupsENS: sharedPreferences.getBool(PreferencesKey.lookupsENS),
|
||||
PreferencesKey.lookupsWellKnown: sharedPreferences.getBool(PreferencesKey.lookupsWellKnown),
|
||||
PreferencesKey.syncModeKey: sharedPreferences.getInt(PreferencesKey.syncModeKey),
|
||||
PreferencesKey.syncAllKey: sharedPreferences.getBool(PreferencesKey.syncAllKey),
|
||||
PreferencesKey.autoGenerateSubaddressStatusKey:
|
||||
_sharedPreferences.getInt(PreferencesKey.autoGenerateSubaddressStatusKey),
|
||||
sharedPreferences.getInt(PreferencesKey.autoGenerateSubaddressStatusKey),
|
||||
};
|
||||
|
||||
return json.encode(preferences);
|
||||
|
@ -562,13 +471,13 @@ class BackupService {
|
|||
final nonce = base64.decode(nonceBase64).toList();
|
||||
final box = SecretBox(Uint8List.sublistView(data, 0, data.lengthInBytes - macLength).toList(),
|
||||
nonce: nonce, mac: Mac(Uint8List.sublistView(data, data.lengthInBytes - macLength)));
|
||||
final plainData = await _cipher.decrypt(box, secretKey: secretKey);
|
||||
final plainData = await cipher.decrypt(box, secretKey: secretKey);
|
||||
return Uint8List.fromList(plainData);
|
||||
}
|
||||
|
||||
Future<Uint8List> _encryptV2(Uint8List data, String passphrase) async =>
|
||||
cake_backup.encrypt(passphrase, data, version: _v2);
|
||||
|
||||
Future<Uint8List> _decryptV2(Uint8List data, String passphrase) async =>
|
||||
Future<Uint8List> decryptV2(Uint8List data, String passphrase) async =>
|
||||
cake_backup.decrypt(passphrase, data);
|
||||
}
|
||||
|
|
470
lib/core/backup_service_v3.dart
Normal file
470
lib/core/backup_service_v3.dart
Normal file
|
@ -0,0 +1,470 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:archive/archive_io.dart';
|
||||
import 'package:cake_wallet/core/backup_service.dart';
|
||||
import 'package:cake_wallet/.secrets.g.dart' as secrets;
|
||||
import 'package:cake_backup/backup.dart' as cake_backup;
|
||||
import 'package:cake_wallet/utils/package_info.dart';
|
||||
import 'package:crypto/crypto.dart';
|
||||
import 'package:cw_core/root_dir.dart';
|
||||
import 'package:cw_core/utils/print_verbose.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
enum BackupVersion {
|
||||
unknown, // index 0
|
||||
v1,
|
||||
v2,
|
||||
v3,
|
||||
}
|
||||
|
||||
class ChunkChecksum {
|
||||
ChunkChecksum({
|
||||
required this.encrypted,
|
||||
required this.plain,
|
||||
});
|
||||
|
||||
final String encrypted;
|
||||
final String plain;
|
||||
|
||||
factory ChunkChecksum.fromJson(Map<String, dynamic> json) {
|
||||
return ChunkChecksum(
|
||||
encrypted: json['encrypted'] as String,
|
||||
plain: json['plain'] as String,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'encrypted': encrypted,
|
||||
'plain': plain,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ChunkChecksum(encrypted: $encrypted, plain: $plain)';
|
||||
}
|
||||
}
|
||||
|
||||
class ChunkLength {
|
||||
ChunkLength({
|
||||
required this.encrypted,
|
||||
required this.plain,
|
||||
});
|
||||
|
||||
final int encrypted;
|
||||
final int plain;
|
||||
|
||||
factory ChunkLength.fromJson(Map<String, dynamic> json) {
|
||||
return ChunkLength(
|
||||
encrypted: json['encrypted'] as int,
|
||||
plain: json['plain'] as int,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'encrypted': encrypted,
|
||||
'plain': plain,
|
||||
};
|
||||
}
|
||||
@override
|
||||
String toString() {
|
||||
return 'ChunkLength(encrypted: $encrypted, plain: $plain)';
|
||||
}
|
||||
}
|
||||
|
||||
class ChunkDetails {
|
||||
ChunkDetails({
|
||||
required this.sha512sum,
|
||||
required this.length,
|
||||
});
|
||||
|
||||
final ChunkChecksum sha512sum;
|
||||
final ChunkLength length;
|
||||
|
||||
factory ChunkDetails.fromJson(Map<String, dynamic> json) {
|
||||
return ChunkDetails(
|
||||
sha512sum: ChunkChecksum.fromJson(json['sha512sum'] as Map<String, dynamic>),
|
||||
length: ChunkLength.fromJson(json['length'] as Map<String, dynamic>),
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'sha512sum': sha512sum,
|
||||
'length': length,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ChunkDetails(sha512sum: $sha512sum, length: $length)';
|
||||
}
|
||||
}
|
||||
|
||||
class BackupMetadata {
|
||||
BackupMetadata({
|
||||
required this.version,
|
||||
required this.sha512sum,
|
||||
required this.chunks,
|
||||
required this.cakeVersion,
|
||||
});
|
||||
|
||||
final BackupVersion version;
|
||||
String sha512sum;
|
||||
final List<ChunkDetails> chunks;
|
||||
String cakeVersion;
|
||||
factory BackupMetadata.fromJson(Map<String, dynamic> json) {
|
||||
return BackupMetadata(
|
||||
version: BackupVersion.values[json['version'] as int],
|
||||
sha512sum: json['sha512sum'] as String,
|
||||
chunks: (json['chunks'] as List<dynamic>).map((chunk) => ChunkDetails.fromJson(chunk as Map<String, dynamic>)).toList(),
|
||||
cakeVersion: json['cakeVersion'] as String,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'version': version.index,
|
||||
'sha512sum': sha512sum,
|
||||
'chunks': chunks.map((chunk) => chunk.toJson()).toList(),
|
||||
'cakeVersion': cakeVersion,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'BackupMetadata(version: $version, sha512sum: $sha512sum, chunks: $chunks)';
|
||||
}
|
||||
}
|
||||
|
||||
class BackupServiceV3 extends $BackupService {
|
||||
BackupServiceV3(super.secureStorage, super.walletInfoSource, super.transactionDescriptionBox, super.keyService, super.sharedPreferences);
|
||||
|
||||
static BackupVersion get currentVersion => BackupVersion.v3;
|
||||
|
||||
Future<File> exportBackupFile(String password, {String nonce = secrets.backupSalt}) {
|
||||
return exportBackupFileV3(password, nonce: nonce);
|
||||
}
|
||||
|
||||
BackupVersion getVersionFile(File data) {
|
||||
final raf = data.openSync(mode: FileMode.read);
|
||||
|
||||
try {
|
||||
// Read first 4 bytes to check both version and zip signature
|
||||
final buffer = Uint8List(1);
|
||||
final bytesRead = raf.readIntoSync(buffer);
|
||||
|
||||
if (bytesRead == 0) {
|
||||
throw Exception('Invalid backup file: empty file');
|
||||
}
|
||||
|
||||
// Check if first byte is version 1 or 2
|
||||
if (buffer[0] == 1) {
|
||||
return BackupVersion.v1;
|
||||
} else if (buffer[0] == 2) {
|
||||
return BackupVersion.v2;
|
||||
} else if (buffer[0] == 0x50) {
|
||||
// $ head -c 64 test-archive.zip | hexdump -C
|
||||
// 00000000 50 4b 03 04 ....
|
||||
// Here we just check if the first byte is the zip signature
|
||||
// Inside of v3 backup we have multiple files.
|
||||
// Check metadata.json for version in v3 backup
|
||||
final inputStream = InputFileStream(data.path);
|
||||
final archive = ZipDecoder().decodeStream(inputStream);
|
||||
final metadataFile = archive.findFile('metadata.json');
|
||||
if (metadataFile == null) {
|
||||
throw Exception('Invalid v3 backup: missing metadata.json');
|
||||
}
|
||||
final metadataBytes = metadataFile.rawContent!.readBytes();
|
||||
final metadataString = utf8.decode(metadataBytes);
|
||||
final metadataJsonRaw = json.decode(metadataString) as Map<String, dynamic>;
|
||||
final metadata = BackupMetadata.fromJson(metadataJsonRaw);
|
||||
if (metadata.version == BackupVersion.v3) {
|
||||
return BackupVersion.v3;
|
||||
}
|
||||
}
|
||||
|
||||
throw Exception('Invalid backup file: unknown version');
|
||||
} finally {
|
||||
raf.closeSync();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> importBackupFile(File file, String password, {String nonce = secrets.backupSalt}) {
|
||||
final version = getVersionFile(file);
|
||||
switch (version) {
|
||||
case BackupVersion.unknown:
|
||||
throw Exception('Invalid backup file: unknown version');
|
||||
case BackupVersion.v1:
|
||||
final data = file.readAsBytesSync();
|
||||
final backupBytes = data.toList()..removeAt(0);
|
||||
final backupData = Uint8List.fromList(backupBytes);
|
||||
return super.importBackupV1(backupData, password, nonce: nonce);
|
||||
case BackupVersion.v2:
|
||||
return super.importBackupV2(file.readAsBytesSync(), password);
|
||||
case BackupVersion.v3:
|
||||
return importBackupFileV3(file, password, nonce: nonce);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> importBackupFileV3(File file, String password, {String nonce = secrets.backupSalt}) async{
|
||||
// Overall design of v3 backup is the following:
|
||||
// 1. backup.zip - plaintext zip file that user can open with any archive manager
|
||||
// 2. backup.zip/README.txt - text file to let user know what is inside of this file
|
||||
// 3. backup.zip/metadata.json - json file with metadata about backup.
|
||||
// 4. backup.zip/data.bin - v2 backup file
|
||||
|
||||
final inputStream = InputFileStream(file.path);
|
||||
final archive = ZipDecoder().decodeStream(inputStream);
|
||||
final metadataFile = archive.findFile('metadata.json');
|
||||
if (metadataFile == null) {
|
||||
throw Exception('Invalid v3 backup: missing metadata.json');
|
||||
}
|
||||
final metadataBytes = metadataFile.rawContent!.readBytes();
|
||||
final metadataString = utf8.decode(metadataBytes);
|
||||
final metadataJsonRaw = json.decode(metadataString) as Map<String, dynamic>;
|
||||
final metadata = BackupMetadata.fromJson(metadataJsonRaw);
|
||||
|
||||
final dataFile = archive.findFile('data.bin');
|
||||
if (dataFile == null) {
|
||||
throw Exception('Invalid v3 backup: missing data.bin');
|
||||
}
|
||||
final dataStream = dataFile.rawContent!.getStream();
|
||||
|
||||
final decryptedData = File('${file.path}_decrypted'); // decrypted zip file
|
||||
if (decryptedData.existsSync()) {
|
||||
decryptedData.deleteSync();
|
||||
}
|
||||
decryptedData.createSync(recursive: true);
|
||||
decryptedData.writeAsBytesSync(Uint8List(0), mode: FileMode.write, flush: true);
|
||||
|
||||
int chunkIndex = 0;
|
||||
for (var chunk in metadata.chunks) {
|
||||
chunkIndex++;
|
||||
final chunkBytes = dataStream.readBytes(chunk.length.encrypted).toUint8List();
|
||||
final chunkChecksum = (await sha512.bind(Stream.fromIterable([chunkBytes])).first).toString();
|
||||
|
||||
// readBytes stores position internally, so we don't need to think about it.
|
||||
if (chunk.sha512sum.encrypted != chunkChecksum) {
|
||||
throw Exception('Invalid v3 backup: chunk (${chunk.length.encrypted} bytes) checksum mismatch at index $chunkIndex\n'
|
||||
'expected: ${chunk.sha512sum.encrypted}\n'
|
||||
'got: $chunkChecksum');
|
||||
}
|
||||
final decryptedChunk = await cake_backup.decrypt(password, chunkBytes);
|
||||
decryptedData.writeAsBytesSync(decryptedChunk, mode: FileMode.append, flush: true);
|
||||
}
|
||||
|
||||
|
||||
final sha512sum = (await sha512.bind(decryptedData.openRead()).first).toString();
|
||||
if (sha512sum.toString() != metadata.sha512sum) {
|
||||
throw Exception('Invalid v3 backup: SHA512 checksum mismatch\n'
|
||||
'expected: ${metadata.sha512sum}\n'
|
||||
'got: $sha512sum');
|
||||
}
|
||||
|
||||
// Decryption done, now we can import the backup (that is, unzip app data)
|
||||
|
||||
// archive is **NOT** backup, it is just a zip file that contains data.bin inside.
|
||||
// We need to unzip it to get the backup.
|
||||
// data.bin after decryption is available in decryptedData.
|
||||
|
||||
final zip = ZipDecoder();
|
||||
final decryptedDataStream = InputFileStream(decryptedData.path);
|
||||
final backupArchive = zip.decodeStream(decryptedDataStream);
|
||||
|
||||
|
||||
final appDir = await getAppDir();
|
||||
|
||||
outer:
|
||||
for (var file in backupArchive.files) {
|
||||
final filename = file.name;
|
||||
for (var ignore in $BackupService.ignoreFiles) {
|
||||
if (filename.endsWith(ignore) && !filename.contains("wallets/")) {
|
||||
printV("ignoring backup file: $filename");
|
||||
continue outer;
|
||||
}
|
||||
}
|
||||
printV("restoring: $filename");
|
||||
if (file.isFile) {
|
||||
final output = File('${appDir.path}/' + filename)
|
||||
..createSync(recursive: true);
|
||||
final outputStream = OutputFileStream(output.path);
|
||||
file.writeContent(outputStream);
|
||||
outputStream.flush();
|
||||
} else {
|
||||
final dir = Directory('${appDir.path}/' + filename);
|
||||
if (!dir.existsSync()) {
|
||||
dir.createSync(recursive: true);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Continue importing the backup the old way
|
||||
await super.verifyWallets();
|
||||
await super.importKeychainDumpV2(password);
|
||||
await super.importPreferencesDump();
|
||||
await super.importTransactionDescriptionDump();
|
||||
|
||||
// Delete decrypted data file
|
||||
decryptedData.deleteSync();
|
||||
}
|
||||
|
||||
Future<File> exportBackupFileV3(String password, {String nonce = secrets.backupSalt}) async {
|
||||
final metadata = BackupMetadata(
|
||||
version: BackupVersion.v3,
|
||||
sha512sum: 'tbd',
|
||||
chunks: [],
|
||||
cakeVersion: 'tbd',
|
||||
);
|
||||
final zipEncoder = ZipFileEncoder();
|
||||
final appDir = await getAppDir();
|
||||
final now = DateTime.now().toIso8601String().replaceAll(':', '-');
|
||||
final tmpDir = Directory('${appDir.path}/~_BACKUP_TMP');
|
||||
final archivePath = '${tmpDir.path}/backup_${now}.tmp.zip';
|
||||
final archivePathExport = '${tmpDir.path}/backup_${now}.zip';
|
||||
final fileEntities = appDir.listSync(recursive: false);
|
||||
final keychainDump = await super.exportKeychainDumpV2(password);
|
||||
final preferencesDump = await super.exportPreferencesJSON();
|
||||
final preferencesDumpFile = File('${tmpDir.path}/~_preferences_dump_TMP');
|
||||
final keychainDumpFile = File('${tmpDir.path}/~_keychain_dump_TMP');
|
||||
final transactionDescriptionDumpFile =
|
||||
File('${tmpDir.path}/~_transaction_descriptions_dump_TMP');
|
||||
|
||||
final transactionDescriptionData = super.transactionDescriptionBox
|
||||
.toMap()
|
||||
.map((key, value) => MapEntry(key.toString(), value.toJson()));
|
||||
final transactionDescriptionDump = jsonEncode(transactionDescriptionData);
|
||||
|
||||
if (tmpDir.existsSync()) {
|
||||
tmpDir.deleteSync(recursive: true);
|
||||
}
|
||||
|
||||
tmpDir.createSync();
|
||||
zipEncoder.create(archivePath);
|
||||
outer:
|
||||
for (var entity in fileEntities) {
|
||||
if (entity.path == archivePath || entity.path == tmpDir.path) {
|
||||
continue;
|
||||
}
|
||||
for (var ignore in $BackupService.ignoreFiles) {
|
||||
final filename = entity.absolute.path;
|
||||
if (filename.endsWith(ignore) && !filename.contains("wallets/")) {
|
||||
printV("ignoring backup file: $filename");
|
||||
continue outer;
|
||||
}
|
||||
}
|
||||
|
||||
if (entity.statSync().type == FileSystemEntityType.directory) {
|
||||
await zipEncoder.addDirectory(Directory(entity.path));
|
||||
} else {
|
||||
await zipEncoder.addFile(File(entity.path));
|
||||
}
|
||||
}
|
||||
await keychainDumpFile.writeAsBytes(keychainDump.toList());
|
||||
await preferencesDumpFile.writeAsString(preferencesDump);
|
||||
await transactionDescriptionDumpFile.writeAsString(transactionDescriptionDump);
|
||||
await zipEncoder.addFile(preferencesDumpFile, '~_preferences_dump');
|
||||
await zipEncoder.addFile(keychainDumpFile, '~_keychain_dump');
|
||||
await zipEncoder.addFile(transactionDescriptionDumpFile, '~_transaction_descriptions_dump');
|
||||
await zipEncoder.close();
|
||||
|
||||
final dataBinUnencrypted = File(archivePath);
|
||||
|
||||
final dataBin = File('${tmpDir.path}/data.bin');
|
||||
dataBin.writeAsBytesSync(Uint8List(0), mode: FileMode.write, flush: true);
|
||||
final dataBinWriter = dataBin.openWrite();
|
||||
|
||||
printV("------ Backup stats ------");
|
||||
printV("Backup version: ${metadata.version}");
|
||||
printV("Backup size: ${await dataBinUnencrypted.length()}");
|
||||
printV("Backup chunks: ${(await dataBinUnencrypted.length()) / chunkSize}");
|
||||
printV("------ Backup stats ------");
|
||||
|
||||
int chunkIndex = 0;
|
||||
final stopwatch = Stopwatch()..start();
|
||||
printV("Starting backup encryption...");
|
||||
|
||||
metadata.sha512sum = (await sha512.bind(dataBinUnencrypted.openRead()).first).toString();
|
||||
|
||||
final raf = await dataBinUnencrypted.open();
|
||||
|
||||
|
||||
while (true) {
|
||||
printV("Reading chunk ${chunkIndex++}");
|
||||
|
||||
stopwatch.reset();
|
||||
final chunk = await raf.read(chunkSize);
|
||||
printV("Chunk read completed in ${stopwatch.elapsed}");
|
||||
printV("Chunk length: ${chunk.length} expected: $chunkSize");
|
||||
if (chunk.length == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
stopwatch.reset();
|
||||
final encryptedChunk = await cake_backup.encrypt(password, chunk);
|
||||
printV("Encryption completed in ${stopwatch.elapsed}");
|
||||
|
||||
stopwatch.reset();
|
||||
final sha512sumEncryptedChunk = await sha512.bind(Stream.fromIterable([encryptedChunk])).first;
|
||||
final sha512sumUnencryptedChunk = await sha512.bind(Stream.fromIterable([chunk])).first;
|
||||
printV("Hashing completed in ${stopwatch.elapsed}");
|
||||
|
||||
stopwatch.reset();
|
||||
dataBinWriter.add(encryptedChunk);
|
||||
metadata.chunks.add(ChunkDetails(
|
||||
sha512sum: ChunkChecksum(
|
||||
encrypted: sha512sumEncryptedChunk.toString(),
|
||||
plain: sha512sumUnencryptedChunk.toString(),
|
||||
),
|
||||
length: ChunkLength(
|
||||
encrypted: encryptedChunk.length,
|
||||
plain: chunk.length,
|
||||
),
|
||||
));
|
||||
|
||||
await dataBinWriter.flush();
|
||||
printV("Writing completed in ${stopwatch.elapsed}");
|
||||
}
|
||||
await raf.close();
|
||||
|
||||
// Give the file to the user
|
||||
|
||||
final metadataFile = File('${tmpDir.path}/metadata.json');
|
||||
final packageInfo = await PackageInfo.fromPlatform();
|
||||
metadata.cakeVersion = packageInfo.version;
|
||||
|
||||
metadataFile.writeAsStringSync(JsonEncoder.withIndent(' ').convert(metadata.toJson()));
|
||||
final readmeFile = File('${tmpDir.path}/README.txt');
|
||||
readmeFile.writeAsStringSync('''This is a ${packageInfo.appName} backup. Do not modify this archive.
|
||||
|
||||
App version: ${packageInfo.version}
|
||||
|
||||
If you have any issues with this backup, please contact our in-app support.
|
||||
This backup was created on ${DateTime.now().toIso8601String()}
|
||||
''');
|
||||
final zip = ZipFileEncoder();
|
||||
zip.create(archivePathExport, level: 9);
|
||||
await zip.addFile(dataBin, 'data.bin');
|
||||
await zip.addFile(metadataFile, 'metadata.json');
|
||||
await zip.addFile(readmeFile, 'README.txt');
|
||||
await zip.close();
|
||||
// tmpDir.deleteSync(recursive: true);
|
||||
final file = File(archivePathExport);
|
||||
return file;
|
||||
}
|
||||
|
||||
static const chunkSize = 24 * 1024 * 1024; // 24MiB
|
||||
|
||||
File setVersionFile(File file, BackupVersion version) {
|
||||
if (version == BackupVersion.v3) return file; // v3 uses
|
||||
// helper function to call super.setVersion();
|
||||
final data = file.readAsBytesSync();
|
||||
super.setVersion(data, version.index);
|
||||
file.writeAsBytesSync(data);
|
||||
return file;
|
||||
}
|
||||
}
|
19
lib/di.dart
19
lib/di.dart
|
@ -11,6 +11,7 @@ import 'package:cake_wallet/buy/dfx/dfx_buy_provider.dart';
|
|||
import 'package:cake_wallet/buy/moonpay/moonpay_provider.dart';
|
||||
import 'package:cake_wallet/buy/onramper/onramper_buy_provider.dart';
|
||||
import 'package:cake_wallet/buy/order.dart';
|
||||
import 'package:cake_wallet/core/backup_service_v3.dart';
|
||||
import 'package:cake_wallet/core/new_wallet_arguments.dart';
|
||||
import 'package:cake_wallet/buy/robinhood/robinhood_buy_provider.dart';
|
||||
import 'package:cake_wallet/core/auth_service.dart';
|
||||
|
@ -26,7 +27,6 @@ import 'package:cake_wallet/core/wallet_connect/web3wallet_service.dart';
|
|||
import 'package:cake_wallet/core/wallet_creation_service.dart';
|
||||
import 'package:cake_wallet/core/wallet_loading_service.dart';
|
||||
import 'package:cake_wallet/core/yat_service.dart';
|
||||
import 'package:cake_wallet/entities/background_tasks.dart';
|
||||
import 'package:cake_wallet/entities/biometric_auth.dart';
|
||||
import 'package:cake_wallet/entities/contact.dart';
|
||||
import 'package:cake_wallet/entities/contact_record.dart';
|
||||
|
@ -34,6 +34,9 @@ import 'package:cake_wallet/entities/exchange_api_mode.dart';
|
|||
import 'package:cake_wallet/entities/hardware_wallet/require_hardware_wallet_connection.dart';
|
||||
import 'package:cake_wallet/entities/parse_address_from_domain.dart';
|
||||
import 'package:cake_wallet/exchange/provider/trocador_exchange_provider.dart';
|
||||
import 'package:cake_wallet/src/screens/dev/monero_background_sync.dart';
|
||||
import 'package:cake_wallet/src/screens/settings/background_sync_page.dart';
|
||||
import 'package:cake_wallet/view_model/dev/monero_background_sync.dart';
|
||||
import 'package:cake_wallet/view_model/link_view_model.dart';
|
||||
import 'package:cake_wallet/tron/tron.dart';
|
||||
import 'package:cake_wallet/src/screens/transaction_details/rbf_details_page.dart';
|
||||
|
@ -310,9 +313,6 @@ Future<void> setup({
|
|||
getIt.registerSingletonAsync<SharedPreferences>(() => SharedPreferences.getInstance());
|
||||
getIt.registerSingleton<SecureStorage>(secureStorage);
|
||||
}
|
||||
if (!_isSetupFinished) {
|
||||
getIt.registerFactory(() => BackgroundTasks());
|
||||
}
|
||||
|
||||
final isBitcoinBuyEnabled = (secrets.wyreSecretKey.isNotEmpty) &&
|
||||
(secrets.wyreApiKey.isNotEmpty) &&
|
||||
|
@ -935,6 +935,8 @@ Future<void> setup({
|
|||
getIt.registerFactory<SeedSettingsViewModel>(
|
||||
() => SeedSettingsViewModel(getIt.get<AppStore>(), getIt.get<SeedSettingsStore>()));
|
||||
|
||||
getIt.registerFactory(() => DevMoneroBackgroundSync(getIt.get<AppStore>().wallet!));
|
||||
|
||||
getIt.registerFactoryParam<WalletSeedPage, bool, void>((bool isWalletCreated, _) =>
|
||||
WalletSeedPage(getIt.get<WalletSeedViewModel>(), isNewWalletCreated: isWalletCreated));
|
||||
|
||||
|
@ -1094,6 +1096,8 @@ Future<void> setup({
|
|||
getIt.registerFactory(() =>
|
||||
ExchangeTradeExternalSendPage(exchangeTradeViewModel: getIt.get<ExchangeTradeViewModel>()));
|
||||
|
||||
getIt.registerFactory(() => BackgroundSyncPage(getIt.get<DashboardViewModel>()));
|
||||
|
||||
getIt.registerFactory(() => ExchangeTemplatePage(getIt.get<ExchangeViewModel>()));
|
||||
|
||||
getIt.registerFactoryParam<WalletService, WalletType, void>((WalletType param1, __) {
|
||||
|
@ -1247,11 +1251,11 @@ Future<void> setup({
|
|||
|
||||
getIt.registerFactory(() => CakeFeaturesViewModel(getIt.get<CakePayService>()));
|
||||
|
||||
getIt.registerFactory(() => BackupService(getIt.get<SecureStorage>(), _walletInfoSource,
|
||||
getIt.registerFactory(() => BackupServiceV3(getIt.get<SecureStorage>(), _walletInfoSource,
|
||||
_transactionDescriptionBox, getIt.get<KeyService>(), getIt.get<SharedPreferences>()));
|
||||
|
||||
getIt.registerFactory(() => BackupViewModel(
|
||||
getIt.get<SecureStorage>(), getIt.get<SecretStore>(), getIt.get<BackupService>()));
|
||||
getIt.get<SecureStorage>(), getIt.get<SecretStore>(), getIt.get<BackupServiceV3>()));
|
||||
|
||||
getIt.registerFactory(() => BackupPage(getIt.get<BackupViewModel>()));
|
||||
|
||||
|
@ -1263,7 +1267,7 @@ Future<void> setup({
|
|||
getIt.registerFactoryParam<RestoreOptionsPage, bool, void>(
|
||||
(bool isNewInstall, _) => RestoreOptionsPage(isNewInstall: isNewInstall));
|
||||
|
||||
getIt.registerFactory(() => RestoreFromBackupViewModel(getIt.get<BackupService>()));
|
||||
getIt.registerFactory(() => RestoreFromBackupViewModel(getIt.get<BackupServiceV3>()));
|
||||
|
||||
getIt.registerFactory(() => RestoreFromBackupPage(getIt.get<RestoreFromBackupViewModel>()));
|
||||
|
||||
|
@ -1476,5 +1480,6 @@ Future<void> setup({
|
|||
|
||||
getIt.registerFactory(() => SeedVerificationPage(getIt.get<WalletSeedViewModel>()));
|
||||
|
||||
getIt.registerFactory(() => DevMoneroBackgroundSyncPage(getIt.get<DevMoneroBackgroundSync>()));
|
||||
_isSetupFinished = true;
|
||||
}
|
||||
|
|
|
@ -1,166 +0,0 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:cake_wallet/core/wallet_loading_service.dart';
|
||||
import 'package:cake_wallet/entities/preferences_key.dart';
|
||||
import 'package:cake_wallet/store/settings_store.dart';
|
||||
import 'package:cake_wallet/utils/device_info.dart';
|
||||
import 'package:cake_wallet/utils/feature_flag.dart';
|
||||
import 'package:cake_wallet/view_model/settings/sync_mode.dart';
|
||||
import 'package:cake_wallet/view_model/wallet_list/wallet_list_item.dart';
|
||||
import 'package:cake_wallet/view_model/wallet_list/wallet_list_view_model.dart';
|
||||
import 'package:cw_core/utils/print_verbose.dart';
|
||||
import 'package:cw_core/wallet_base.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:workmanager/workmanager.dart';
|
||||
import 'package:cake_wallet/main.dart';
|
||||
import 'package:cake_wallet/di.dart';
|
||||
|
||||
const moneroSyncTaskKey = "com.fotolockr.cakewallet.monero_sync_task";
|
||||
|
||||
@pragma('vm:entry-point')
|
||||
void callbackDispatcher() {
|
||||
Workmanager().executeTask((task, inputData) async {
|
||||
try {
|
||||
switch (task) {
|
||||
case moneroSyncTaskKey:
|
||||
|
||||
/// The work manager runs on a separate isolate from the main flutter isolate.
|
||||
/// thus we initialize app configs first; hive, getIt, etc...
|
||||
await initializeAppConfigs();
|
||||
|
||||
final walletLoadingService = getIt.get<WalletLoadingService>();
|
||||
|
||||
final typeRaw = getIt.get<SharedPreferences>().getInt(PreferencesKey.currentWalletType);
|
||||
|
||||
WalletBase? wallet;
|
||||
|
||||
if (inputData!['sync_all'] as bool) {
|
||||
/// get all Monero wallets of the user and sync them
|
||||
final List<WalletListItem> moneroWallets = getIt
|
||||
.get<WalletListViewModel>()
|
||||
.wallets
|
||||
.where((element) => [WalletType.monero, WalletType.wownero].contains(element.type))
|
||||
.toList();
|
||||
|
||||
for (int i = 0; i < moneroWallets.length; i++) {
|
||||
wallet =
|
||||
await walletLoadingService.load(moneroWallets[i].type, moneroWallets[i].name);
|
||||
final node = getIt.get<SettingsStore>().getCurrentNode(moneroWallets[i].type);
|
||||
await wallet.connectToNode(node: node);
|
||||
await wallet.startSync();
|
||||
}
|
||||
} else {
|
||||
/// if the user chose to sync only active wallet
|
||||
/// if the current wallet is monero; sync it only
|
||||
if (typeRaw == WalletType.monero.index || typeRaw == WalletType.wownero.index) {
|
||||
final name =
|
||||
getIt.get<SharedPreferences>().getString(PreferencesKey.currentWalletName);
|
||||
|
||||
wallet = await walletLoadingService.load(WalletType.values[typeRaw!], name!);
|
||||
final node = getIt.get<SettingsStore>().getCurrentNode(WalletType.values[typeRaw]);
|
||||
|
||||
await wallet.connectToNode(node: node);
|
||||
await wallet.startSync();
|
||||
}
|
||||
}
|
||||
|
||||
if (wallet?.syncStatus.progress() == null) {
|
||||
return Future.error("No Monero/Wownero wallet found");
|
||||
}
|
||||
|
||||
for (int i = 0;; i++) {
|
||||
await Future<void>.delayed(const Duration(seconds: 1));
|
||||
if (wallet?.syncStatus.progress() == 1.0) {
|
||||
break;
|
||||
}
|
||||
if (i > 600) {
|
||||
return Future.error("Synchronization Timed out");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return Future.value(true);
|
||||
} catch (error, stackTrace) {
|
||||
printV(error);
|
||||
printV(stackTrace);
|
||||
return Future.error(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
class BackgroundTasks {
|
||||
void registerSyncTask({bool changeExisting = false}) async {
|
||||
try {
|
||||
bool hasMonero = getIt
|
||||
.get<WalletListViewModel>()
|
||||
.wallets
|
||||
.any((element) => element.type == WalletType.monero);
|
||||
|
||||
/// if its not android nor ios, or the user has no monero wallets; exit
|
||||
if (!DeviceInfo.instance.isMobile || !hasMonero) {
|
||||
return;
|
||||
}
|
||||
|
||||
final settingsStore = getIt.get<SettingsStore>();
|
||||
|
||||
final SyncMode syncMode = settingsStore.currentSyncMode;
|
||||
final bool syncAll = settingsStore.currentSyncAll;
|
||||
|
||||
if (syncMode.type == SyncType.disabled || !FeatureFlag.isBackgroundSyncEnabled) {
|
||||
cancelSyncTask();
|
||||
return;
|
||||
}
|
||||
|
||||
await Workmanager().initialize(
|
||||
callbackDispatcher,
|
||||
isInDebugMode: kDebugMode,
|
||||
);
|
||||
|
||||
final inputData = <String, dynamic>{"sync_all": syncAll};
|
||||
final constraints = Constraints(
|
||||
networkType:
|
||||
syncMode.type == SyncType.unobtrusive ? NetworkType.unmetered : NetworkType.connected,
|
||||
requiresBatteryNotLow: syncMode.type == SyncType.unobtrusive,
|
||||
requiresCharging: syncMode.type == SyncType.unobtrusive,
|
||||
requiresDeviceIdle: syncMode.type == SyncType.unobtrusive,
|
||||
);
|
||||
|
||||
if (Platform.isIOS) {
|
||||
await Workmanager().registerOneOffTask(
|
||||
moneroSyncTaskKey,
|
||||
moneroSyncTaskKey,
|
||||
initialDelay: syncMode.frequency,
|
||||
existingWorkPolicy: ExistingWorkPolicy.replace,
|
||||
inputData: inputData,
|
||||
constraints: constraints,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
await Workmanager().registerPeriodicTask(
|
||||
moneroSyncTaskKey,
|
||||
moneroSyncTaskKey,
|
||||
initialDelay: syncMode.frequency,
|
||||
frequency: syncMode.frequency,
|
||||
existingWorkPolicy: changeExisting ? ExistingWorkPolicy.replace : ExistingWorkPolicy.keep,
|
||||
inputData: inputData,
|
||||
constraints: constraints,
|
||||
);
|
||||
} catch (error, stackTrace) {
|
||||
printV(error);
|
||||
printV(stackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
void cancelSyncTask() {
|
||||
try {
|
||||
Workmanager().cancelByUniqueName(moneroSyncTaskKey);
|
||||
} catch (error, stackTrace) {
|
||||
printV(error);
|
||||
printV(stackTrace);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
import 'package:cake_wallet/di.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:cake_wallet/store/app_store.dart';
|
||||
import 'package:cake_wallet/entities/background_tasks.dart';
|
||||
import 'package:cake_wallet/entities/preferences_key.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:cake_wallet/core/wallet_loading_service.dart';
|
||||
|
@ -26,6 +25,4 @@ Future<void> loadCurrentWallet({String? password}) async {
|
|||
name,
|
||||
password: password);
|
||||
await appStore.changeCurrentWallet(wallet);
|
||||
|
||||
getIt.get<BackgroundTasks>().registerSyncTask();
|
||||
}
|
||||
|
|
|
@ -825,7 +825,6 @@ class _HaCupertinoLocalizationsDelegate extends LocalizationsDelegate<CupertinoL
|
|||
patterns: haLocaleDatePatterns,
|
||||
symbols: intl.DateSymbols.deserializeFromMap(haDateSymbols),
|
||||
);
|
||||
|
||||
return SynchronousFuture<CupertinoLocalizations>(
|
||||
HaCupertinoLocalizations(
|
||||
localeName: localeName,
|
||||
|
@ -847,6 +846,7 @@ class _HaCupertinoLocalizationsDelegate extends LocalizationsDelegate<CupertinoL
|
|||
singleDigitHourFormat: intl.DateFormat('j', localeName),
|
||||
singleDigitMinuteFormat: intl.DateFormat.m(localeName),
|
||||
singleDigitSecondFormat: intl.DateFormat.s(localeName),
|
||||
weekdayFormat: intl.DateFormat.E(localeName),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -871,6 +871,7 @@ class HaCupertinoLocalizations extends GlobalCupertinoLocalizations {
|
|||
required super.singleDigitMinuteFormat,
|
||||
required super.doubleDigitMinuteFormat,
|
||||
required super.singleDigitSecondFormat,
|
||||
required super.weekdayFormat,
|
||||
});
|
||||
|
||||
@override
|
||||
|
|
|
@ -846,6 +846,7 @@ class _YoCupertinoLocalizationsDelegate extends LocalizationsDelegate<CupertinoL
|
|||
singleDigitHourFormat: intl.DateFormat('j', localeName),
|
||||
singleDigitMinuteFormat: intl.DateFormat.m(localeName),
|
||||
singleDigitSecondFormat: intl.DateFormat.s(localeName),
|
||||
weekdayFormat: intl.DateFormat.E(localeName),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -870,6 +871,7 @@ class YoCupertinoLocalizations extends GlobalCupertinoLocalizations {
|
|||
required super.singleDigitMinuteFormat,
|
||||
required super.doubleDigitMinuteFormat,
|
||||
required super.singleDigitSecondFormat,
|
||||
required super.weekdayFormat,
|
||||
});
|
||||
|
||||
@override
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
import 'dart:ui';
|
||||
import 'package:cake_wallet/anonpay/anonpay_invoice_info.dart';
|
||||
import 'package:cake_wallet/app_scroll_behavior.dart';
|
||||
import 'package:cake_wallet/buy/order.dart';
|
||||
import 'package:cake_wallet/core/auth_service.dart';
|
||||
import 'package:cake_wallet/core/background_sync.dart';
|
||||
import 'package:cake_wallet/di.dart';
|
||||
import 'package:cake_wallet/entities/contact.dart';
|
||||
import 'package:cake_wallet/entities/default_settings_migration.dart';
|
||||
|
@ -34,11 +36,13 @@ import 'package:cw_core/hive_type_ids.dart';
|
|||
import 'package:cw_core/mweb_utxo.dart';
|
||||
import 'package:cw_core/node.dart';
|
||||
import 'package:cw_core/unspent_coins_info.dart';
|
||||
import 'package:cw_core/utils/print_verbose.dart';
|
||||
import 'package:cw_core/wallet_info.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_daemon/flutter_daemon.dart';
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:cw_core/root_dir.dart';
|
||||
|
@ -68,6 +72,7 @@ Future<void> runAppWithZone({Key? topLevelKey}) async {
|
|||
|
||||
return true;
|
||||
};
|
||||
await FlutterDaemon().unmarkBackgroundSync();
|
||||
await initializeAppAtRoot();
|
||||
|
||||
if (kDebugMode) {
|
||||
|
@ -100,7 +105,7 @@ Future<void> initializeAppAtRoot({bool reInitializing = false}) async {
|
|||
await initializeAppConfigs();
|
||||
}
|
||||
|
||||
Future<void> initializeAppConfigs() async {
|
||||
Future<void> initializeAppConfigs({bool loadWallet = true}) async {
|
||||
setRootDirFromEnv();
|
||||
final appDir = await getAppDir();
|
||||
CakeHive.init(appDir.path);
|
||||
|
@ -200,6 +205,7 @@ Future<void> initializeAppConfigs() async {
|
|||
encryptionKey: havenSeedStoreBoxKey);
|
||||
|
||||
await initialSetup(
|
||||
loadWallet: loadWallet,
|
||||
sharedPreferences: await SharedPreferences.getInstance(),
|
||||
nodes: nodes,
|
||||
powNodes: powNodes,
|
||||
|
@ -220,7 +226,8 @@ Future<void> initializeAppConfigs() async {
|
|||
}
|
||||
|
||||
Future<void> initialSetup(
|
||||
{required SharedPreferences sharedPreferences,
|
||||
{required bool loadWallet,
|
||||
required SharedPreferences sharedPreferences,
|
||||
required Box<Node> nodes,
|
||||
required Box<Node> powNodes,
|
||||
required Box<WalletInfo> walletInfoSource,
|
||||
|
@ -262,7 +269,7 @@ Future<void> initialSetup(
|
|||
navigatorKey: navigatorKey,
|
||||
secureStorage: secureStorage,
|
||||
);
|
||||
await bootstrap(navigatorKey);
|
||||
await bootstrap(navigatorKey, loadWallet: loadWallet);
|
||||
}
|
||||
|
||||
class App extends StatefulWidget {
|
||||
|
@ -390,3 +397,34 @@ class TopLevelErrorWidget extends StatelessWidget {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
@pragma('vm:entry-point')
|
||||
Future<void> backgroundSync() async {
|
||||
bool shouldUnmark = false;
|
||||
try {
|
||||
printV("Background sync triggered");
|
||||
printV("- WidgetsFlutterBinding.ensureInitialized()");
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
printV("- DartPluginRegistrant.ensureInitialized()");
|
||||
DartPluginRegistrant.ensureInitialized();
|
||||
printV("- FlutterDaemon.markBackgroundSync()");
|
||||
final val = await FlutterDaemon().markBackgroundSync();
|
||||
if (val) {
|
||||
printV("Background sync already in progress");
|
||||
return;
|
||||
}
|
||||
shouldUnmark = true;
|
||||
printV("Starting background sync");
|
||||
final backgroundSync = BackgroundSync();
|
||||
await initializeAppConfigs(loadWallet: false);
|
||||
await backgroundSync.sync();
|
||||
printV("Background sync completed");
|
||||
} finally {
|
||||
if (shouldUnmark) {
|
||||
printV("Unmarking background sync");
|
||||
await FlutterDaemon().unmarkBackgroundSync();
|
||||
} else {
|
||||
printV("Not unmarking background sync");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ import 'package:cake_wallet/store/settings_store.dart';
|
|||
import 'package:cake_wallet/store/authentication_store.dart';
|
||||
import 'package:cake_wallet/store/dashboard/fiat_conversion_store.dart';
|
||||
|
||||
Future<void> bootstrap(GlobalKey<NavigatorState> navigatorKey) async {
|
||||
Future<void> bootstrap(GlobalKey<NavigatorState> navigatorKey, {required bool loadWallet}) async {
|
||||
final appStore = getIt.get<AppStore>();
|
||||
final authenticationStore = getIt.get<AuthenticationStore>();
|
||||
final settingsStore = getIt.get<SettingsStore>();
|
||||
|
@ -27,7 +27,9 @@ Future<void> bootstrap(GlobalKey<NavigatorState> navigatorKey) async {
|
|||
authenticationStore.installed();
|
||||
}
|
||||
|
||||
startAuthenticationStateChange(authenticationStore, navigatorKey);
|
||||
if (loadWallet) {
|
||||
startAuthenticationStateChange(authenticationStore, navigatorKey);
|
||||
}
|
||||
startCurrentWalletChangeReaction(appStore, settingsStore, fiatConversionStore);
|
||||
startCurrentFiatChangeReaction(appStore, settingsStore, fiatConversionStore);
|
||||
startCurrentFiatApiModeChangeReaction(appStore, settingsStore, fiatConversionStore);
|
||||
|
|
|
@ -36,6 +36,7 @@ import 'package:cake_wallet/src/screens/dashboard/pages/address_page.dart';
|
|||
import 'package:cake_wallet/src/screens/dashboard/pages/nft_details_page.dart';
|
||||
import 'package:cake_wallet/src/screens/dashboard/pages/transactions_page.dart';
|
||||
import 'package:cake_wallet/src/screens/dashboard/sign_page.dart';
|
||||
import 'package:cake_wallet/src/screens/dev/monero_background_sync.dart';
|
||||
import 'package:cake_wallet/src/screens/disclaimer/disclaimer_page.dart';
|
||||
import 'package:cake_wallet/src/screens/exchange/exchange_page.dart';
|
||||
import 'package:cake_wallet/src/screens/exchange/exchange_template_page.dart';
|
||||
|
@ -73,6 +74,7 @@ import 'package:cake_wallet/src/screens/seed/wallet_seed_page.dart';
|
|||
import 'package:cake_wallet/src/screens/send/send_page.dart';
|
||||
import 'package:cake_wallet/src/screens/send/send_template_page.dart';
|
||||
import 'package:cake_wallet/src/screens/send/transaction_success_info_page.dart';
|
||||
import 'package:cake_wallet/src/screens/settings/background_sync_page.dart';
|
||||
import 'package:cake_wallet/src/screens/settings/connection_sync_page.dart';
|
||||
import 'package:cake_wallet/src/screens/settings/desktop_settings/desktop_settings_page.dart';
|
||||
import 'package:cake_wallet/src/screens/settings/display_settings_page.dart';
|
||||
|
@ -848,6 +850,14 @@ Route<dynamic> createRoute(RouteSettings settings) {
|
|||
builder: (_) => getIt.get<ExchangeTradeExternalSendPage>(),
|
||||
);
|
||||
|
||||
case Routes.backgroundSync:
|
||||
return CupertinoPageRoute<void>(
|
||||
fullscreenDialog: true, builder: (_) => getIt.get<BackgroundSyncPage>());
|
||||
case Routes.devMoneroBackgroundSync:
|
||||
return MaterialPageRoute<void>(
|
||||
builder: (_) => getIt.get<DevMoneroBackgroundSyncPage>(),
|
||||
);
|
||||
|
||||
default:
|
||||
return MaterialPageRoute<void>(
|
||||
builder: (_) => Scaffold(
|
||||
|
|
|
@ -110,6 +110,8 @@ class Routes {
|
|||
static const nftDetailsPage = '/nft_details_page';
|
||||
static const importNFTPage = '/import_nft_page';
|
||||
static const torPage = '/tor_page';
|
||||
static const backgroundSync = '/background_sync';
|
||||
static const devMoneroBackgroundSync = '/dev/monero_background_sync';
|
||||
|
||||
static const signPage = '/sign_page';
|
||||
static const connectDevices = '/device/connect';
|
||||
|
|
|
@ -137,7 +137,7 @@ class BackupPage extends BasePage {
|
|||
leftButtonText: S.of(context).share,
|
||||
actionRightButton: () async {
|
||||
await backupViewModelBase.saveToDownload(
|
||||
backup.name, backup.content);
|
||||
backup.name, backup.file);
|
||||
Navigator.of(dialogContext).pop();
|
||||
},
|
||||
actionLeftButton: () async {
|
||||
|
@ -160,8 +160,7 @@ class BackupPage extends BasePage {
|
|||
fileName: backup.name);
|
||||
|
||||
try {
|
||||
File returnedFile = File(outputFile!);
|
||||
await returnedFile.writeAsBytes(backup.content);
|
||||
await backup.file.copy(outputFile!);
|
||||
} catch (exception, stackTrace) {
|
||||
await ExceptionHandler.onError(FlutterErrorDetails(
|
||||
exception: exception,
|
||||
|
|
|
@ -384,7 +384,7 @@ class CakePayBuyCardDetailPage extends BasePage {
|
|||
paymentId: S.of(popupContext).payment_id,
|
||||
paymentIdValue: order?.orderId,
|
||||
expirationTime: cakePayPurchaseViewModel.formattedRemainingTime,
|
||||
titleText: 'Confirm Transaction',
|
||||
titleText: S.of(popupContext).confirm_transaction,
|
||||
titleIconPath: cakePayPurchaseViewModel.sendViewModel.selectedCryptoCurrency.iconPath,
|
||||
currency: cakePayPurchaseViewModel.sendViewModel.selectedCryptoCurrency,
|
||||
amount: S.of(popupContext).send_amount,
|
||||
|
@ -432,7 +432,7 @@ class CakePayBuyCardDetailPage extends BasePage {
|
|||
builder: (BuildContext context) {
|
||||
loadingBottomSheetContext = context;
|
||||
return LoadingBottomSheet(
|
||||
titleText: 'Generating transaction',
|
||||
titleText: S.of(context).generating_transaction,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
|
112
lib/src/screens/dev/monero_background_sync.dart
Normal file
112
lib/src/screens/dev/monero_background_sync.dart
Normal file
|
@ -0,0 +1,112 @@
|
|||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
import 'package:cake_wallet/src/widgets/primary_button.dart';
|
||||
import 'package:cake_wallet/view_model/dev/monero_background_sync.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
|
||||
class DevMoneroBackgroundSyncPage extends BasePage {
|
||||
final DevMoneroBackgroundSync viewModel;
|
||||
|
||||
DevMoneroBackgroundSyncPage(this.viewModel);
|
||||
|
||||
@override
|
||||
String? get title => "[dev] xmr background sync";
|
||||
|
||||
Widget _buildSingleCell(String title, String value) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: Colors.grey),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
padding: const EdgeInsets.all(8),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(title, style: TextStyle(fontWeight: FontWeight.bold)),
|
||||
Text(value, maxLines: 1, overflow: TextOverflow.ellipsis),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget body(BuildContext context) {
|
||||
return Observer(
|
||||
builder: (_) {
|
||||
return GridView.count(
|
||||
padding: const EdgeInsets.all(16),
|
||||
crossAxisCount: 2,
|
||||
childAspectRatio: 25/9,
|
||||
crossAxisSpacing: 16,
|
||||
mainAxisSpacing: 16,
|
||||
children: [
|
||||
_buildSingleCell('Height (local)', viewModel.localBlockHeight ?? ''),
|
||||
_buildSingleCell('Height (node)', viewModel.nodeBlockHeight ?? ''),
|
||||
_buildSingleCell('Time', viewModel.tick.toString()),
|
||||
_buildSingleCell('Background Sync', viewModel.isBackgroundSyncing ? 'Enabled' : 'Disabled'),
|
||||
_buildSingleCell('Public View Key', viewModel.publicViewKey ?? ''),
|
||||
_buildSingleCell('Private View Key', viewModel.privateViewKey ?? ''),
|
||||
_buildSingleCell('Public Spend Key', viewModel.publicSpendKey ?? ''),
|
||||
_buildSingleCell('Private Spend Key', viewModel.privateSpendKey ?? ''),
|
||||
_buildSingleCell('Primary Address', viewModel.primaryAddress ?? ''),
|
||||
_buildSingleCell('Passphrase', viewModel.passphrase ?? ''),
|
||||
_buildSingleCell('Seed', viewModel.seed ?? ''),
|
||||
_buildSingleCell('Seed Legacy', viewModel.seedLegacy ?? ''),
|
||||
_enableBackgroundSyncButton(),
|
||||
_disableBackgroundSyncButton(),
|
||||
_refreshButton(),
|
||||
_manualRescanButton(),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
PrimaryButton _enableBackgroundSyncButton() {
|
||||
return PrimaryButton(
|
||||
text: "Enable background sync",
|
||||
color: Colors.purple,
|
||||
textColor: Colors.white,
|
||||
onPressed: () {
|
||||
viewModel.startBackgroundSync();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
PrimaryButton _disableBackgroundSyncButton() {
|
||||
return PrimaryButton(
|
||||
text: "Disable background sync",
|
||||
color: Colors.purple,
|
||||
textColor: Colors.white,
|
||||
onPressed: () {
|
||||
viewModel.stopBackgroundSync();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
PrimaryButton _refreshButton() {
|
||||
return PrimaryButton(
|
||||
text: viewModel.refreshTimer == null ? "Enable refresh" : "Disable refresh",
|
||||
color: Colors.purple,
|
||||
textColor: Colors.white,
|
||||
onPressed: () {
|
||||
if (viewModel.refreshTimer == null) {
|
||||
viewModel.startRefreshTimer();
|
||||
} else {
|
||||
viewModel.stopRefreshTimer();
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
PrimaryButton _manualRescanButton() {
|
||||
return PrimaryButton(
|
||||
text: "Manual rescan",
|
||||
color: Colors.purple,
|
||||
textColor: Colors.white,
|
||||
onPressed: () {
|
||||
viewModel.manualRescan();
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
|
@ -252,7 +252,7 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
|
|||
builder: (BuildContext context) {
|
||||
loadingBottomSheetContext = context;
|
||||
return LoadingBottomSheet(
|
||||
titleText: 'Generating transaction',
|
||||
titleText: S.of(context).generating_transaction,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
@ -271,7 +271,7 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
|
|||
return ConfirmSendingBottomSheet(
|
||||
key: ValueKey('exchange_trade_page_confirm_sending_bottom_sheet_key'),
|
||||
currentTheme: widget.currentTheme,
|
||||
titleText: 'Confirm Transaction',
|
||||
titleText: S.of(bottomSheetContext).confirm_transaction,
|
||||
titleIconPath: widget.exchangeTradeViewModel.sendViewModel.selectedCryptoCurrency.iconPath,
|
||||
currency: widget.exchangeTradeViewModel.sendViewModel.selectedCryptoCurrency,
|
||||
amount: S.of(bottomSheetContext).send_amount,
|
||||
|
@ -307,7 +307,7 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
|
|||
builder: (BuildContext bottomSheetContext) {
|
||||
return InfoBottomSheet(
|
||||
currentTheme: widget.currentTheme,
|
||||
titleText: 'Transaction Sent',
|
||||
titleText: S.of(bottomSheetContext).transaction_sent,
|
||||
contentImage: 'assets/images/birthday_cake.svg',
|
||||
actionButtonText: S.of(bottomSheetContext).close,
|
||||
actionButtonKey: ValueKey('send_page_sent_dialog_ok_button_key'),
|
||||
|
|
|
@ -532,7 +532,7 @@ class SendPage extends BasePage {
|
|||
builder: (BuildContext context) {
|
||||
loadingBottomSheetContext = context;
|
||||
return LoadingBottomSheet(
|
||||
titleText: 'Generating transaction',
|
||||
titleText: S.of(context).generating_transaction,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
@ -550,7 +550,7 @@ class SendPage extends BasePage {
|
|||
builder: (BuildContext bottomSheetContext) {
|
||||
return ConfirmSendingBottomSheet(
|
||||
key: ValueKey('send_page_confirm_sending_dialog_key'),
|
||||
titleText: 'Confirm Transaction',
|
||||
titleText: S.of(bottomSheetContext).confirm_transaction,
|
||||
currentTheme: currentTheme,
|
||||
titleIconPath: sendViewModel.selectedCryptoCurrency.iconPath,
|
||||
currency: sendViewModel.selectedCryptoCurrency,
|
||||
|
@ -598,7 +598,7 @@ class SendPage extends BasePage {
|
|||
currentTheme: currentTheme,
|
||||
showDontAskMeCheckbox: true,
|
||||
onCheckboxChanged: (value) => sendViewModel.setShowAddressBookPopup(!value),
|
||||
titleText: 'Transaction Sent',
|
||||
titleText: S.of(bottomSheetContext).transaction_sent,
|
||||
contentImage: 'assets/images/contact_icon.svg',
|
||||
contentImageColor: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
|
||||
content: S.of(bottomSheetContext).add_contact_to_address_book,
|
||||
|
@ -607,6 +607,8 @@ class SendPage extends BasePage {
|
|||
rightButtonText: 'Yes',
|
||||
actionLeftButton: () {
|
||||
Navigator.of(bottomSheetContext).pop();
|
||||
Navigator.of(context)
|
||||
.pushNamedAndRemoveUntil(Routes.dashboard, (route) => false);
|
||||
RequestReviewHandler.requestReview();
|
||||
newContactAddress = null;
|
||||
},
|
||||
|
@ -620,11 +622,17 @@ class SendPage extends BasePage {
|
|||
)
|
||||
: InfoBottomSheet(
|
||||
currentTheme: currentTheme,
|
||||
titleText: 'Transaction Sent',
|
||||
titleText: S.of(bottomSheetContext).transaction_sent,
|
||||
contentImage: 'assets/images/birthday_cake.svg',
|
||||
actionButtonText: S.of(bottomSheetContext).close,
|
||||
actionButtonKey: ValueKey('send_page_sent_dialog_ok_button_key'),
|
||||
actionButton: () => Navigator.of(bottomSheetContext).pop());
|
||||
actionButton: () {
|
||||
Navigator.of(bottomSheetContext).pop();
|
||||
Navigator.of(context)
|
||||
.pushNamedAndRemoveUntil(Routes.dashboard, (route) => false);
|
||||
RequestReviewHandler.requestReview();
|
||||
newContactAddress = null;
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
|
|
91
lib/src/screens/settings/background_sync_page.dart
Normal file
91
lib/src/screens/settings/background_sync_page.dart
Normal file
|
@ -0,0 +1,91 @@
|
|||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
import 'package:cake_wallet/src/screens/settings/widgets/settings_picker_cell.dart';
|
||||
import 'package:cake_wallet/src/screens/settings/widgets/settings_switcher_cell.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_with_no_action.dart.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
|
||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
|
||||
import 'package:cake_wallet/view_model/settings/sync_mode.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
|
||||
class BackgroundSyncPage extends BasePage {
|
||||
BackgroundSyncPage(this.dashboardViewModel);
|
||||
|
||||
@override
|
||||
String get title => S.current.background_sync;
|
||||
|
||||
final DashboardViewModel dashboardViewModel;
|
||||
|
||||
@override
|
||||
Widget body(BuildContext context) {
|
||||
return Container(
|
||||
padding: EdgeInsets.only(top: 10),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
if (dashboardViewModel.hasBatteryOptimization)
|
||||
Observer(builder: (context) {
|
||||
return SettingsSwitcherCell(
|
||||
title: S.current.unrestricted_background_service,
|
||||
value: !dashboardViewModel.batteryOptimizationEnabled,
|
||||
onValueChange: (_, bool value) {
|
||||
dashboardViewModel.disableBatteryOptimization();
|
||||
},
|
||||
);
|
||||
}),
|
||||
Observer(builder: (context) {
|
||||
return SettingsSwitcherCell(
|
||||
title: S.current.background_sync,
|
||||
value: dashboardViewModel.backgroundSyncEnabled,
|
||||
onValueChange: (dashboardViewModel.batteryOptimizationEnabled && dashboardViewModel.hasBatteryOptimization) ? (_, bool value) {
|
||||
unawaited(showPopUp(context: context, builder: (context) => AlertWithOneAction(
|
||||
alertTitle: S.current.background_sync,
|
||||
alertContent: S.current.unrestricted_background_service_notice,
|
||||
buttonText: S.current.ok,
|
||||
buttonAction: () => Navigator.of(context).pop(),
|
||||
)));
|
||||
} : (_, bool value) {
|
||||
if (value) {
|
||||
dashboardViewModel.enableBackgroundSync();
|
||||
} else {
|
||||
dashboardViewModel.disableBackgroundSync();
|
||||
}
|
||||
},
|
||||
);
|
||||
}),
|
||||
Observer(builder: (context) {
|
||||
return SettingsPickerCell<SyncMode>(
|
||||
title: S.current.background_sync_mode,
|
||||
items: SyncMode.all,
|
||||
displayItem: (SyncMode syncMode) => syncMode.name,
|
||||
selectedItem: dashboardViewModel.settingsStore.currentSyncMode,
|
||||
onItemSelected: (dashboardViewModel.batteryOptimizationEnabled && dashboardViewModel.hasBatteryOptimization) ? null : (syncMode) async {
|
||||
dashboardViewModel.setSyncMode(syncMode);
|
||||
});
|
||||
}),
|
||||
|
||||
// Observer(builder: (context) {
|
||||
// return SettingsSwitcherCell(
|
||||
// title: S.current.background_sync_on_battery,
|
||||
// value: dashboardViewModel.backgroundSyncOnBattery,
|
||||
// onValueChange: (_, bool value) =>
|
||||
// dashboardViewModel.setBackgroundSyncOnBattery(value),
|
||||
// );
|
||||
// }),
|
||||
// Observer(builder: (context) {
|
||||
// return SettingsSwitcherCell(
|
||||
// title: S.current.background_sync_on_data,
|
||||
// value: dashboardViewModel.backgroundSyncOnData,
|
||||
// onValueChange: (_, bool value) => dashboardViewModel.setBackgroundSyncOnData(value),
|
||||
// );
|
||||
// }),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -44,56 +44,17 @@ class ConnectionSyncPage extends BasePage {
|
|||
: S.current.rescan,
|
||||
handler: (context) => Navigator.of(context).pushNamed(Routes.rescan),
|
||||
),
|
||||
if (DeviceInfo.instance.isMobile && FeatureFlag.isBackgroundSyncEnabled) ...[
|
||||
Observer(builder: (context) {
|
||||
return SettingsPickerCell<SyncMode>(
|
||||
title: S.current.background_sync_mode,
|
||||
items: SyncMode.all,
|
||||
displayItem: (SyncMode syncMode) => syncMode.name,
|
||||
selectedItem: dashboardViewModel.syncMode,
|
||||
onItemSelected: (syncMode) async {
|
||||
dashboardViewModel.setSyncMode(syncMode);
|
||||
|
||||
if (Platform.isIOS) return;
|
||||
|
||||
if (syncMode.type != SyncType.disabled) {
|
||||
final isDisabled = await isBatteryOptimizationDisabled();
|
||||
|
||||
if (isDisabled) return;
|
||||
|
||||
await showPopUp<void>(
|
||||
context: context,
|
||||
builder: (BuildContext dialogContext) {
|
||||
return AlertWithTwoActions(
|
||||
alertTitle: S.current.disableBatteryOptimization,
|
||||
alertContent: S.current.disableBatteryOptimizationDescription,
|
||||
leftButtonText: S.of(context).cancel,
|
||||
rightButtonText: S.of(context).ok,
|
||||
actionLeftButton: () => Navigator.of(dialogContext).pop(),
|
||||
actionRightButton: () async {
|
||||
await requestDisableBatteryOptimization();
|
||||
|
||||
Navigator.of(dialogContext).pop();
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
});
|
||||
}),
|
||||
Observer(builder: (context) {
|
||||
return SettingsSwitcherCell(
|
||||
title: S.current.sync_all_wallets,
|
||||
value: dashboardViewModel.syncAll,
|
||||
onValueChange: (_, bool value) => dashboardViewModel.setSyncAll(value),
|
||||
);
|
||||
}),
|
||||
],
|
||||
],
|
||||
SettingsCellWithArrow(
|
||||
title: S.current.manage_nodes,
|
||||
handler: (context) => Navigator.of(context).pushNamed(Routes.manageNodes),
|
||||
),
|
||||
if (dashboardViewModel.hasBackgroundSync && Platform.isAndroid && FeatureFlag.isBackgroundSyncEnabled) ...[
|
||||
SettingsCellWithArrow(
|
||||
title: S.current.background_sync,
|
||||
handler: (context) => Navigator.of(context).pushNamed(Routes.backgroundSync),
|
||||
),
|
||||
],
|
||||
Observer(
|
||||
builder: (context) {
|
||||
if (!dashboardViewModel.hasPowNodes) return const SizedBox();
|
||||
|
|
|
@ -10,6 +10,7 @@ import 'package:cake_wallet/src/screens/settings/widgets/settings_switcher_cell.
|
|||
import 'package:cake_wallet/src/screens/settings/widgets/settings_version_cell.dart';
|
||||
import 'package:cake_wallet/view_model/settings/other_settings_view_model.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
|
||||
|
@ -63,6 +64,12 @@ class OtherSettingsPage extends BasePage {
|
|||
handler: (BuildContext context) =>
|
||||
Navigator.of(context).pushNamed(Routes.readDisclaimer),
|
||||
),
|
||||
if (kDebugMode && _otherSettingsViewModel.walletType == WalletType.monero)
|
||||
SettingsCellWithArrow(
|
||||
title: '[dev] monero background sync',
|
||||
handler: (BuildContext context) =>
|
||||
Navigator.of(context).pushNamed(Routes.devMoneroBackgroundSync),
|
||||
),
|
||||
Spacer(),
|
||||
SettingsVersionCell(
|
||||
title: S.of(context).version(_otherSettingsViewModel.currentVersion)),
|
||||
|
|
|
@ -170,7 +170,7 @@ class RBFDetailsPage extends BasePage {
|
|||
builder: (BuildContext context) {
|
||||
loadingBottomSheetContext = context;
|
||||
return LoadingBottomSheet(
|
||||
titleText: 'Generating transaction',
|
||||
titleText: S.of(context).generating_transaction,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
@ -188,7 +188,7 @@ class RBFDetailsPage extends BasePage {
|
|||
builder: (BuildContext bottomSheetContext) {
|
||||
return ConfirmSendingBottomSheet(
|
||||
key: ValueKey('rbf_confirm_sending_bottom_sheet'),
|
||||
titleText: 'Confirm Transaction',
|
||||
titleText: S.of(bottomSheetContext).confirm_transaction,
|
||||
currentTheme: currentTheme,
|
||||
titleIconPath: transactionDetailsViewModel.sendViewModel.selectedCryptoCurrency.iconPath,
|
||||
currency: transactionDetailsViewModel.sendViewModel.selectedCryptoCurrency,
|
||||
|
|
|
@ -276,7 +276,7 @@ class AddressTile extends StatelessWidget {
|
|||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.w600,
|
||||
color: currentTheme.type == ThemeType.bright
|
||||
? Theme.of(context).extension<BalancePageTheme>()!.labelTextColor
|
||||
? Theme.of(context).extension<CakeTextTheme>()!.titleColor.withOpacity(0.5)
|
||||
: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
|
||||
decoration: TextDecoration.none,
|
||||
);
|
||||
|
@ -298,8 +298,7 @@ class AddressTile extends StatelessWidget {
|
|||
),
|
||||
buildSegmentedAddress(
|
||||
address: address,
|
||||
evenTextStyle:
|
||||
currentTheme.type == ThemeType.bright ? itemSubTitleTextStyle : addressTextStyle,
|
||||
evenTextStyle: addressTextStyle,
|
||||
oddTextStyle: itemSubTitleTextStyle,
|
||||
),
|
||||
],
|
||||
|
@ -365,7 +364,7 @@ class AddressExpansionTile extends StatelessWidget {
|
|||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.w600,
|
||||
color: currentTheme.type == ThemeType.bright
|
||||
? Theme.of(context).extension<BalancePageTheme>()!.labelTextColor
|
||||
? Theme.of(context).extension<CakeTextTheme>()!.titleColor.withOpacity(0.5)
|
||||
: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
|
||||
decoration: TextDecoration.none,
|
||||
);
|
||||
|
@ -380,14 +379,16 @@ class AddressExpansionTile extends StatelessWidget {
|
|||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 14, vertical: isBatchSending ? 0 : 8),
|
||||
child: ExpansionTile(
|
||||
childrenPadding: EdgeInsets.zero,
|
||||
childrenPadding: isBatchSending ? const EdgeInsets.only(bottom: 8) : EdgeInsets.zero,
|
||||
tilePadding: EdgeInsets.zero,
|
||||
dense: true,
|
||||
visualDensity: VisualDensity.compact,
|
||||
title: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(isBatchSending ? name : contactType, style: itemTitleTextStyle),
|
||||
Expanded(
|
||||
child: Text(isBatchSending ? name : contactType,
|
||||
style: itemTitleTextStyle, softWrap: true)),
|
||||
Text(isBatchSending ? amount : name,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
|
@ -407,9 +408,7 @@ class AddressExpansionTile extends StatelessWidget {
|
|||
children: [
|
||||
buildSegmentedAddress(
|
||||
address: address,
|
||||
evenTextStyle: currentTheme.type == ThemeType.bright
|
||||
? itemSubTitleTextStyle
|
||||
: addressTextStyle,
|
||||
evenTextStyle: addressTextStyle,
|
||||
oddTextStyle: itemSubTitleTextStyle,
|
||||
),
|
||||
if (stealthAddressText(stealthAddress) != null)
|
||||
|
@ -417,9 +416,7 @@ class AddressExpansionTile extends StatelessWidget {
|
|||
padding: const EdgeInsets.only(top: 8.0),
|
||||
child: buildSegmentedAddress(
|
||||
address: stealthAddressText(stealthAddress)!,
|
||||
evenTextStyle: currentTheme.type == ThemeType.bright
|
||||
? itemSubTitleTextStyle
|
||||
: addressTextStyle,
|
||||
evenTextStyle: addressTextStyle,
|
||||
oddTextStyle: itemSubTitleTextStyle,
|
||||
),
|
||||
),
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
|
@ -8,7 +9,6 @@ import 'package:cake_wallet/core/secure_storage.dart';
|
|||
import 'package:cake_wallet/di.dart';
|
||||
import 'package:cake_wallet/entities/action_list_display_mode.dart';
|
||||
import 'package:cake_wallet/entities/auto_generate_subaddress_status.dart';
|
||||
import 'package:cake_wallet/entities/background_tasks.dart';
|
||||
import 'package:cake_wallet/entities/balance_display_mode.dart';
|
||||
import 'package:cake_wallet/entities/cake_2fa_preset_options.dart';
|
||||
import 'package:cake_wallet/entities/country.dart';
|
||||
|
@ -42,6 +42,7 @@ import 'package:cw_core/utils/print_verbose.dart';
|
|||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:device_info_plus/device_info_plus.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_daemon/flutter_daemon.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
@ -53,7 +54,6 @@ class SettingsStore = SettingsStoreBase with _$SettingsStore;
|
|||
abstract class SettingsStoreBase with Store {
|
||||
SettingsStoreBase(
|
||||
{required SecureStorage secureStorage,
|
||||
required BackgroundTasks backgroundTasks,
|
||||
required SharedPreferences sharedPreferences,
|
||||
required bool initialShouldShowMarketPlaceInDashboard,
|
||||
required bool initialShowAddressBookPopupEnabled,
|
||||
|
@ -141,7 +141,6 @@ abstract class SettingsStoreBase with Store {
|
|||
powNodes = ObservableMap<WalletType, Node>.of(powNodes),
|
||||
_secureStorage = secureStorage,
|
||||
_sharedPreferences = sharedPreferences,
|
||||
_backgroundTasks = backgroundTasks,
|
||||
fiatCurrency = initialFiatCurrency,
|
||||
balanceDisplayMode = initialBalanceDisplayMode,
|
||||
shouldSaveRecipientAddress = initialSaveRecipientAddress,
|
||||
|
@ -295,11 +294,11 @@ abstract class SettingsStoreBase with Store {
|
|||
PreferencesKey.shouldSaveRecipientAddressKey, shouldSaveRecipientAddress));
|
||||
|
||||
if (DeviceInfo.instance.isMobile) {
|
||||
setIsAppSecureNative(isAppSecure);
|
||||
unawaited(setIsAppSecureNative(isAppSecure));
|
||||
|
||||
reaction((_) => isAppSecure, (bool isAppSecure) {
|
||||
sharedPreferences.setBool(PreferencesKey.isAppSecureKey, isAppSecure);
|
||||
setIsAppSecureNative(isAppSecure);
|
||||
unawaited(setIsAppSecureNative(isAppSecure));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -396,14 +395,11 @@ abstract class SettingsStoreBase with Store {
|
|||
|
||||
reaction((_) => currentSyncMode, (SyncMode syncMode) {
|
||||
sharedPreferences.setInt(PreferencesKey.syncModeKey, syncMode.type.index);
|
||||
|
||||
_backgroundTasks.registerSyncTask(changeExisting: true);
|
||||
FlutterDaemon().startBackgroundSync(syncMode.frequency.inMinutes);
|
||||
});
|
||||
|
||||
reaction((_) => currentSyncAll, (bool syncAll) {
|
||||
sharedPreferences.setBool(PreferencesKey.syncAllKey, syncAll);
|
||||
|
||||
_backgroundTasks.registerSyncTask(changeExisting: true);
|
||||
});
|
||||
|
||||
reaction(
|
||||
|
@ -796,6 +792,7 @@ abstract class SettingsStoreBase with Store {
|
|||
|
||||
@observable
|
||||
bool lookupsWellKnown;
|
||||
|
||||
@observable
|
||||
SyncMode currentSyncMode;
|
||||
|
||||
|
@ -829,7 +826,6 @@ abstract class SettingsStoreBase with Store {
|
|||
|
||||
final SecureStorage _secureStorage;
|
||||
final SharedPreferences _sharedPreferences;
|
||||
final BackgroundTasks _backgroundTasks;
|
||||
|
||||
ObservableMap<WalletType, Node> nodes;
|
||||
ObservableMap<WalletType, Node> powNodes;
|
||||
|
@ -871,7 +867,6 @@ abstract class SettingsStoreBase with Store {
|
|||
ThemeBase? initialTheme}) async {
|
||||
final sharedPreferences = await getIt.getAsync<SharedPreferences>();
|
||||
final secureStorage = await getIt.get<SecureStorage>();
|
||||
final backgroundTasks = getIt.get<BackgroundTasks>();
|
||||
final currentFiatCurrency = FiatCurrency.deserialize(
|
||||
raw: sharedPreferences.getString(PreferencesKey.currentFiatCurrencyKey)!);
|
||||
final savedCakePayCountryRaw =
|
||||
|
@ -1142,7 +1137,7 @@ abstract class SettingsStoreBase with Store {
|
|||
}
|
||||
|
||||
final savedSyncMode = SyncMode.all.firstWhere((element) {
|
||||
return element.type.index == (sharedPreferences.getInt(PreferencesKey.syncModeKey) ?? 0);
|
||||
return element.type.index == (sharedPreferences.getInt(PreferencesKey.syncModeKey) ?? 2); // default to 2 - daily sync
|
||||
});
|
||||
final savedSyncAll = sharedPreferences.getBool(PreferencesKey.syncAllKey) ?? true;
|
||||
|
||||
|
@ -1323,7 +1318,6 @@ abstract class SettingsStoreBase with Store {
|
|||
shouldRequireTOTP2FAForAllSecurityAndBackupSettings,
|
||||
initialEthereumTransactionPriority: ethereumTransactionPriority,
|
||||
initialPolygonTransactionPriority: polygonTransactionPriority,
|
||||
backgroundTasks: backgroundTasks,
|
||||
initialSyncMode: savedSyncMode,
|
||||
initialSyncAll: savedSyncAll,
|
||||
shouldShowYatPopup: shouldShowYatPopup,
|
||||
|
|
|
@ -4,6 +4,6 @@ class FeatureFlag {
|
|||
static const bool isCakePayEnabled = false;
|
||||
static const bool isExolixEnabled = true;
|
||||
static const bool isInAppTorEnabled = false;
|
||||
static const bool isBackgroundSyncEnabled = false;
|
||||
static const bool isBackgroundSyncEnabled = true;
|
||||
static const int verificationWordsCount = kDebugMode ? 0 : 2;
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
import 'dart:io';
|
||||
import 'package:cake_wallet/core/backup_service.dart';
|
||||
import 'package:cake_wallet/core/backup_service_v3.dart';
|
||||
import 'package:cake_wallet/core/execution_state.dart';
|
||||
import 'package:cake_wallet/core/secure_storage.dart';
|
||||
import 'package:cake_wallet/entities/secret_store_key.dart';
|
||||
|
@ -15,10 +16,10 @@ import 'package:path_provider/path_provider.dart';
|
|||
part 'backup_view_model.g.dart';
|
||||
|
||||
class BackupExportFile {
|
||||
BackupExportFile(this.content, {required this.name});
|
||||
BackupExportFile(this.file, {required this.name});
|
||||
|
||||
final String name;
|
||||
final List<int> content;
|
||||
final File file;
|
||||
}
|
||||
|
||||
class BackupViewModel = BackupViewModelBase with _$BackupViewModel;
|
||||
|
@ -38,7 +39,7 @@ abstract class BackupViewModelBase with Store {
|
|||
|
||||
final SecureStorage secureStorage;
|
||||
final SecretStore secretStore;
|
||||
final BackupService backupService;
|
||||
final BackupServiceV3 backupService;
|
||||
|
||||
@observable
|
||||
ExecutionState state;
|
||||
|
@ -59,14 +60,14 @@ abstract class BackupViewModelBase with Store {
|
|||
Future<BackupExportFile?> exportBackup() async {
|
||||
try {
|
||||
state = IsExecutingState();
|
||||
final backupContent = await backupService.exportBackup(backupPassword);
|
||||
final backupFile = await backupService.exportBackupFile(backupPassword);
|
||||
state = ExecutedSuccessfullyState();
|
||||
final now = DateTime.now();
|
||||
final formatter = DateFormat('yyyy-MM-dd_Hm');
|
||||
final snakeAppName = approximatedAppName.replaceAll(' ', '_').toLowerCase();
|
||||
final fileName = '${snakeAppName}_backup_${formatter.format(now)}';
|
||||
final fileName = '${snakeAppName}_backup_${formatter.format(now)}.zip';
|
||||
|
||||
return BackupExportFile(backupContent.toList(), name: fileName);
|
||||
return BackupExportFile(backupFile, name: fileName);
|
||||
} catch (e) {
|
||||
printV(e.toString());
|
||||
state = FailureState(e.toString());
|
||||
|
@ -77,26 +78,35 @@ abstract class BackupViewModelBase with Store {
|
|||
Future<String> saveBackupFileLocally(BackupExportFile backup) async {
|
||||
final appDir = await getAppDir();
|
||||
final path = '${appDir.path}/${backup.name}';
|
||||
final backupFile = File(path);
|
||||
await backupFile.writeAsBytes(backup.content);
|
||||
if (File(path).existsSync()) {
|
||||
File(path).deleteSync();
|
||||
}
|
||||
await backup.file.copy(path);
|
||||
return path;
|
||||
}
|
||||
|
||||
Future<void> removeBackupFileLocally(BackupExportFile backup) async {
|
||||
final appDir = await getAppDir();
|
||||
final path = '${appDir.path}/${backup.name}';
|
||||
final backupFile = File(path);
|
||||
await backupFile.delete();
|
||||
if (File(path).existsSync()) {
|
||||
File(path).deleteSync();
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
void showMasterPassword() => isBackupPasswordVisible = true;
|
||||
|
||||
@action
|
||||
Future<void> saveToDownload(String name, List<int> content) async {
|
||||
Future<void> saveToDownload(String name, File file) async {
|
||||
if (!Platform.isAndroid) {
|
||||
return;
|
||||
}
|
||||
const downloadDirPath = '/storage/emulated/0/Download'; // For Android
|
||||
final filePath = '$downloadDirPath/${name}';
|
||||
final file = File(filePath);
|
||||
await file.writeAsBytes(content);
|
||||
final downloadFile = File(filePath);
|
||||
if (downloadFile.existsSync()) {
|
||||
downloadFile.deleteSync();
|
||||
}
|
||||
await file.copy(filePath);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import 'dart:io' show Platform;
|
|||
|
||||
import 'package:cake_wallet/.secrets.g.dart' as secrets;
|
||||
import 'package:cake_wallet/bitcoin/bitcoin.dart';
|
||||
import 'package:cake_wallet/core/background_sync.dart';
|
||||
import 'package:cake_wallet/core/key_service.dart';
|
||||
import 'package:cake_wallet/entities/auto_generate_subaddress_status.dart';
|
||||
import 'package:cake_wallet/entities/balance_display_mode.dart';
|
||||
|
@ -41,12 +42,14 @@ import 'package:cw_core/sync_status.dart';
|
|||
import 'package:cw_core/transaction_history.dart';
|
||||
import 'package:cw_core/transaction_info.dart';
|
||||
import 'package:cw_core/utils/file.dart';
|
||||
import 'package:cw_core/utils/print_verbose.dart';
|
||||
import 'package:cw_core/wallet_base.dart';
|
||||
import 'package:cw_core/wallet_info.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:eth_sig_util/util/utils.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_daemon/flutter_daemon.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
@ -179,6 +182,8 @@ abstract class DashboardViewModelBase with Store {
|
|||
isShowFirstYatIntroduction = false;
|
||||
isShowSecondYatIntroduction = false;
|
||||
isShowThirdYatIntroduction = false;
|
||||
unawaited(isBackgroundSyncEnabled());
|
||||
unawaited(isBatteryOptimizationEnabled());
|
||||
|
||||
final _wallet = wallet;
|
||||
|
||||
|
@ -404,6 +409,11 @@ abstract class DashboardViewModelBase with Store {
|
|||
@computed
|
||||
bool get hasRescan => wallet.hasRescan;
|
||||
|
||||
@computed
|
||||
bool get hasBackgroundSync => [
|
||||
WalletType.monero,
|
||||
].contains(wallet.type);
|
||||
|
||||
@computed
|
||||
bool get isMoneroViewOnly {
|
||||
if (wallet.type != WalletType.monero) return false;
|
||||
|
@ -496,6 +506,69 @@ abstract class DashboardViewModelBase with Store {
|
|||
@observable
|
||||
late bool showDecredInfoCard;
|
||||
|
||||
@observable
|
||||
bool backgroundSyncEnabled = false;
|
||||
|
||||
@action
|
||||
Future<bool> isBackgroundSyncEnabled() async {
|
||||
if (!Platform.isAndroid) {
|
||||
return false;
|
||||
}
|
||||
final resp = await FlutterDaemon().getBackgroundSyncStatus();
|
||||
backgroundSyncEnabled = resp;
|
||||
return resp;
|
||||
}
|
||||
|
||||
bool get hasBatteryOptimization => Platform.isAndroid;
|
||||
|
||||
@observable
|
||||
bool batteryOptimizationEnabled = false;
|
||||
|
||||
@action
|
||||
Future<bool> isBatteryOptimizationEnabled() async {
|
||||
if (!hasBatteryOptimization) {
|
||||
return false;
|
||||
}
|
||||
final resp = await FlutterDaemon().isBatteryOptimizationDisabled();
|
||||
batteryOptimizationEnabled = !resp;
|
||||
if (batteryOptimizationEnabled && await isBackgroundSyncEnabled()) {
|
||||
// If the battery optimization is enabled, we need to disable the background sync
|
||||
await disableBackgroundSync();
|
||||
}
|
||||
return resp;
|
||||
}
|
||||
|
||||
@action
|
||||
Future<void> disableBatteryOptimization() async {
|
||||
final resp = await FlutterDaemon().requestDisableBatteryOptimization();
|
||||
unawaited((() async {
|
||||
// android doesn't return if the permission was granted, so we need to poll it,
|
||||
// minute should be enough for the fallback method (opening settings and changing the permission)
|
||||
for (var i = 0; i < 4 * 60; i++) {
|
||||
await Future.delayed(Duration(milliseconds: 250));
|
||||
await isBatteryOptimizationEnabled();
|
||||
}
|
||||
})());
|
||||
}
|
||||
|
||||
@action
|
||||
Future<void> enableBackgroundSync() async {
|
||||
if (hasBatteryOptimization && batteryOptimizationEnabled) {
|
||||
disableBackgroundSync();
|
||||
return;
|
||||
}
|
||||
final resp = await FlutterDaemon().startBackgroundSync(settingsStore.currentSyncMode.frequency.inMinutes);
|
||||
printV("Background sync enabled: $resp");
|
||||
backgroundSyncEnabled = true;
|
||||
}
|
||||
|
||||
@action
|
||||
Future<void> disableBackgroundSync() async {
|
||||
final resp = await FlutterDaemon().stopBackgroundSync();
|
||||
printV("Background sync disabled: $resp");
|
||||
backgroundSyncEnabled = false;
|
||||
}
|
||||
|
||||
@computed
|
||||
bool get hasEnabledMwebBefore => settingsStore.hasEnabledMwebBefore;
|
||||
|
||||
|
@ -800,11 +873,11 @@ abstract class DashboardViewModelBase with Store {
|
|||
}
|
||||
}
|
||||
|
||||
@computed
|
||||
SyncMode get syncMode => settingsStore.currentSyncMode;
|
||||
|
||||
@action
|
||||
void setSyncMode(SyncMode syncMode) => settingsStore.currentSyncMode = syncMode;
|
||||
Future<void> setSyncMode(SyncMode syncMode) async {
|
||||
settingsStore.currentSyncMode = syncMode;
|
||||
await enableBackgroundSync();
|
||||
}
|
||||
|
||||
@computed
|
||||
bool get syncAll => settingsStore.currentSyncAll;
|
||||
|
|
106
lib/view_model/dev/monero_background_sync.dart
Normal file
106
lib/view_model/dev/monero_background_sync.dart
Normal file
|
@ -0,0 +1,106 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:cake_wallet/core/key_service.dart';
|
||||
import 'package:cake_wallet/di.dart';
|
||||
import 'package:cake_wallet/monero/monero.dart';
|
||||
import 'package:cw_monero/monero_wallet.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:cw_core/wallet_base.dart';
|
||||
|
||||
part 'monero_background_sync.g.dart';
|
||||
|
||||
class DevMoneroBackgroundSync = DevMoneroBackgroundSyncBase with _$DevMoneroBackgroundSync;
|
||||
|
||||
abstract class DevMoneroBackgroundSyncBase with Store {
|
||||
DevMoneroBackgroundSyncBase(WalletBase wallet) : wallet = wallet;
|
||||
|
||||
final WalletBase wallet;
|
||||
|
||||
@observable
|
||||
Timer? refreshTimer;
|
||||
|
||||
@observable
|
||||
String? localBlockHeight;
|
||||
|
||||
@observable
|
||||
String? nodeBlockHeight;
|
||||
|
||||
@observable
|
||||
String? primaryAddress;
|
||||
|
||||
@observable
|
||||
String? publicViewKey;
|
||||
|
||||
@observable
|
||||
String? privateViewKey;
|
||||
|
||||
@observable
|
||||
String? publicSpendKey;
|
||||
|
||||
@observable
|
||||
String? privateSpendKey;
|
||||
|
||||
@observable
|
||||
String? passphrase;
|
||||
|
||||
@observable
|
||||
String? seed;
|
||||
|
||||
@observable
|
||||
String? seedLegacy;
|
||||
|
||||
@observable
|
||||
int tick = -1;
|
||||
|
||||
@observable
|
||||
bool isBackgroundSyncing = false;
|
||||
|
||||
Future<void> _setValues() async {
|
||||
final w = (wallet as MoneroWallet);
|
||||
localBlockHeight = (await monero!.getCurrentHeight()).toString();
|
||||
nodeBlockHeight = (await w.getNodeHeight()).toString();
|
||||
final keys = w.keys;
|
||||
primaryAddress = keys.primaryAddress;
|
||||
publicViewKey = keys.publicViewKey;
|
||||
privateViewKey = keys.privateViewKey;
|
||||
publicSpendKey = keys.publicSpendKey;
|
||||
privateSpendKey = keys.privateSpendKey;
|
||||
passphrase = keys.passphrase;
|
||||
seed = w.seed;
|
||||
seedLegacy = w.seedLegacy("English");
|
||||
tick = refreshTimer?.tick ?? -1;
|
||||
isBackgroundSyncing = w.isBackgroundSyncRunning;
|
||||
}
|
||||
|
||||
@action
|
||||
Future<void> manualRescan() async {
|
||||
final w = (wallet as MoneroWallet);
|
||||
await wallet.rescan(height: await w.getNodeHeight() - 10000);
|
||||
}
|
||||
|
||||
@action
|
||||
void startRefreshTimer() {
|
||||
refreshTimer = Timer.periodic(Duration(seconds: 1), (timer) async {
|
||||
await _setValues();
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
void stopRefreshTimer() {
|
||||
refreshTimer?.cancel();
|
||||
refreshTimer = null;
|
||||
}
|
||||
|
||||
@action
|
||||
void startBackgroundSync() {
|
||||
final w = (wallet as MoneroWallet);
|
||||
w.startBackgroundSync();
|
||||
}
|
||||
|
||||
@action
|
||||
Future<void> stopBackgroundSync() async {
|
||||
final w = (wallet as MoneroWallet);
|
||||
final keyService = getIt.get<KeyService>();
|
||||
await w.stopBackgroundSync(await keyService.getWalletPassword(walletName: wallet.name));
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
import 'dart:io';
|
||||
import 'package:cake_wallet/core/backup_service_v3.dart';
|
||||
import 'package:cake_wallet/core/execution_state.dart';
|
||||
import 'package:cake_wallet/utils/exception_handler.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
@ -20,7 +21,7 @@ abstract class RestoreFromBackupViewModelBase with Store {
|
|||
: state = InitialExecutionState(),
|
||||
filePath = '';
|
||||
|
||||
final BackupService backupService;
|
||||
final BackupServiceV3 backupService;
|
||||
|
||||
@observable
|
||||
String filePath;
|
||||
|
@ -42,10 +43,9 @@ abstract class RestoreFromBackupViewModelBase with Store {
|
|||
}
|
||||
|
||||
final file = File(filePath);
|
||||
final data = await file.readAsBytes();
|
||||
|
||||
|
||||
await backupService.importBackup(data, password);
|
||||
await backupService.importBackupFile(file, password);
|
||||
|
||||
try {
|
||||
await initializeAppAtRoot(reInitializing: true);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
enum SyncType { disabled, unobtrusive, aggressive }
|
||||
enum SyncType { aggresive, hourly, daily }
|
||||
|
||||
class SyncMode {
|
||||
SyncMode(this.name, this.type, this.frequency);
|
||||
|
@ -8,8 +8,10 @@ class SyncMode {
|
|||
final Duration frequency;
|
||||
|
||||
static final all = [
|
||||
SyncMode("Disabled", SyncType.disabled, Duration.zero),
|
||||
SyncMode("Unobtrusive", SyncType.unobtrusive, Duration(hours: 12)),
|
||||
SyncMode("Aggressive", SyncType.aggressive, Duration(hours: 3)),
|
||||
// **Technically** we could call aggressive option "15 minutes" but OS may "not feel like it",
|
||||
// so instead we will call it aggressive so user knows that it will be as frequent as possible.
|
||||
SyncMode("Aggressive", SyncType.aggresive, Duration(minutes: 15)),
|
||||
SyncMode("Hourly", SyncType.hourly, Duration(hours: 1)),
|
||||
SyncMode("Daily", SyncType.daily, Duration(hours: 18)), // yes this is straight up lie.
|
||||
];
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@ import 'package:cake_wallet/bitcoin/bitcoin.dart';
|
|||
import 'package:cake_wallet/core/execution_state.dart';
|
||||
import 'package:cake_wallet/core/wallet_creation_service.dart';
|
||||
import 'package:cake_wallet/di.dart';
|
||||
import 'package:cake_wallet/entities/background_tasks.dart';
|
||||
import 'package:cake_wallet/entities/generate_name.dart';
|
||||
import 'package:cake_wallet/entities/hash_wallet_identifier.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
|
@ -113,7 +112,6 @@ abstract class WalletCreationVMBase with Store {
|
|||
walletInfo.address = wallet.walletAddresses.address;
|
||||
await _walletInfoSource.add(walletInfo);
|
||||
await _appStore.changeCurrentWallet(wallet);
|
||||
getIt.get<BackgroundTasks>().registerSyncTask();
|
||||
_appStore.authenticationStore.allowedCreate();
|
||||
state = ExecutedSuccessfullyState();
|
||||
} catch (e, s) {
|
||||
|
|
|
@ -158,6 +158,7 @@ abstract class WalletGroupsDisplayViewModelBase with Store {
|
|||
isCurrent: info.name == _appStore.wallet?.name && info.type == _appStore.wallet?.type,
|
||||
isEnabled: availableWalletTypes.contains(info.type),
|
||||
isTestnet: info.network?.toLowerCase().contains('testnet') ?? false,
|
||||
isHardware: info.isHardwareWallet,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ class WalletListItem {
|
|||
required this.name,
|
||||
required this.type,
|
||||
required this.key,
|
||||
required this.isHardware,
|
||||
this.isCurrent = false,
|
||||
this.isEnabled = true,
|
||||
this.isTestnet = false,
|
||||
|
@ -16,4 +17,5 @@ class WalletListItem {
|
|||
final dynamic key;
|
||||
final bool isEnabled;
|
||||
final bool isTestnet;
|
||||
final bool isHardware;
|
||||
}
|
||||
|
|
|
@ -265,6 +265,7 @@ abstract class WalletListViewModelBase with Store {
|
|||
info.type == _appStore.wallet?.type,
|
||||
isEnabled: availableWalletTypes.contains(info.type),
|
||||
isTestnet: info.network?.toLowerCase().contains('testnet') ?? false,
|
||||
isHardware: info.isHardwareWallet,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ dependencies:
|
|||
url: https://github.com/MrCyjaneK/uni_links
|
||||
ref: 8e9efa4d9beb19e4ac44009576337f1ce51c22e2
|
||||
path: uni_links
|
||||
lottie: ^1.3.0
|
||||
lottie: ^3.3.1
|
||||
animate_do: ^2.1.0
|
||||
cupertino_icons: ^1.0.5
|
||||
encrypt: 5.0.2
|
||||
|
@ -57,23 +57,22 @@ dependencies:
|
|||
connectivity_plus: ^5.0.2
|
||||
keyboard_actions: ^4.0.1
|
||||
another_flushbar: ^1.12.29
|
||||
archive: ^3.3.0
|
||||
archive: ^4.0.3
|
||||
cryptography: ^2.0.5
|
||||
file_picker:
|
||||
git:
|
||||
url: https://github.com/cake-tech/flutter_file_picker.git
|
||||
ref: master
|
||||
permission_handler: ^10.0.0
|
||||
ref: c414574bc5ac349450f601e7f72c7b9f31b4d087
|
||||
permission_handler: 11.4.0
|
||||
device_display_brightness:
|
||||
git:
|
||||
url: https://github.com/MrCyjaneK/device_display_brightness.git
|
||||
ref: 4cac18c446ce686f3d75b1565badbd7da439bbd9
|
||||
workmanager: ^0.5.2
|
||||
wakelock_plus: ^1.2.5
|
||||
flutter_mailer:
|
||||
git:
|
||||
url: https://github.com/taljacobson/flutter_mailer
|
||||
ref: 2a7d04d61f56e1ca166ab42e91e0daf1bfddfaf2
|
||||
ref: 9c4ed111a9151a2bbfb9afe2c18a37599c6f84f3
|
||||
device_info_plus: ^9.1.0
|
||||
base32: 2.1.3
|
||||
in_app_review: ^2.0.6
|
||||
|
@ -97,7 +96,7 @@ dependencies:
|
|||
git:
|
||||
url: https://github.com/cake-tech/ens_dart.git
|
||||
ref: main
|
||||
fluttertoast: 8.2.8
|
||||
fluttertoast: 8.2.12
|
||||
# tor:
|
||||
# git:
|
||||
# url: https://github.com/cake-tech/tor.git
|
||||
|
@ -119,6 +118,10 @@ dependencies:
|
|||
git:
|
||||
url: https://github.com/cake-tech/blockchain_utils
|
||||
ref: cake-update-v4
|
||||
flutter_daemon:
|
||||
git:
|
||||
url: https://github.com/MrCyjaneK/flutter_daemon
|
||||
ref: 5c369e0e69e6f459357b9802bc694a221397298a
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
@ -139,7 +142,6 @@ dev_dependencies:
|
|||
git:
|
||||
url: https://github.com/cake-tech/google-translator.git
|
||||
version: 1.0.0
|
||||
archive: ^3.6.1
|
||||
|
||||
dependency_overrides:
|
||||
bech32:
|
||||
|
|
|
@ -69,6 +69,7 @@
|
|||
"avg_savings": "متوسط مدخرات",
|
||||
"awaitDAppProcessing": ".ﺔﺠﻟﺎﻌﻤﻟﺍ ﻦﻣ dApp ﻲﻬﺘﻨﻳ ﻰﺘﺣ ﺭﺎﻈﺘﻧﻻﺍ ﻰﺟﺮﻳ",
|
||||
"awaiting_payment_confirmation": "في انتظار تأكيد الدفع",
|
||||
"background_sync": "مزامنة الخلفية",
|
||||
"background_sync_mode": "وضع مزامنة الخلفية",
|
||||
"backup": "نسخ الاحتياطي",
|
||||
"backup_file": "ملف النسخ الاحتياطي",
|
||||
|
@ -161,6 +162,7 @@
|
|||
"confirm_passphrase": "تأكيد عبارة المرور",
|
||||
"confirm_sending": "تأكيد الإرسال",
|
||||
"confirm_silent_payments_switch_node": "العقدة الحالية لا تدعم المدفوعات الصامتة \\ ncake wallet سوف تتحول إلى عقدة متوافقة ، فقط للمسح الضوئي",
|
||||
"confirm_transaction": "تأكيد المعاملة",
|
||||
"confirmations": "التأكيدات",
|
||||
"confirmed": "رصيد مؤكد",
|
||||
"confirmed_tx": "مؤكد",
|
||||
|
@ -344,6 +346,7 @@
|
|||
"gas_exceeds_allowance": "الغاز المطلوب بالمعاملة يتجاوز البدل.",
|
||||
"generate_name": "توليد الاسم",
|
||||
"generating_gift_card": "يتم توليد بطاقة هدية",
|
||||
"generating_transaction": "توليد معاملة",
|
||||
"get_a": "احصل على",
|
||||
"get_card_note": " يمكنك إعادة تحميلها بالعملات الرقمية. لا توجد معلومات إضافية مطلوبة!",
|
||||
"get_your_yat": "احصل على Yat",
|
||||
|
@ -928,6 +931,8 @@
|
|||
"understand": "لقد فهمت",
|
||||
"unlock": "الغاء القفل",
|
||||
"unmatched_currencies": "عملة محفظتك الحالية لا تتطابق مع عملة QR الممسوحة ضوئيًا",
|
||||
"unrestricted_background_service": "خدمة خلفية غير مقيدة",
|
||||
"unrestricted_background_service_notice": "من أجل تمكين مزامنة الخلفية ، تحتاج إلى تمكين خدمة الخلفية غير المقيدة",
|
||||
"unspent_change": "يتغير",
|
||||
"unspent_coins_details_title": "تفاصيل العملات الغير المنفقة",
|
||||
"unspent_coins_title": "العملات الغير المنفقة",
|
||||
|
|
|
@ -69,6 +69,7 @@
|
|||
"avg_savings": "Средни спестявания",
|
||||
"awaitDAppProcessing": "Моля, изчакайте dApp да завърши обработката.",
|
||||
"awaiting_payment_confirmation": "Чака се потвърждение на плащането",
|
||||
"background_sync": "Фон Синхх",
|
||||
"background_sync_mode": "Режим на синхронизиране на фона",
|
||||
"backup": "Резервно копие",
|
||||
"backup_file": "Резервно копие",
|
||||
|
@ -161,6 +162,7 @@
|
|||
"confirm_passphrase": "Потвърдете парола",
|
||||
"confirm_sending": "Потвърждаване на изпращането",
|
||||
"confirm_silent_payments_switch_node": "Текущият ви възел не поддържа Silent Payments \\ Ncake Wallet ще премине към съвместим възел, само за сканиране",
|
||||
"confirm_transaction": "Потвърдете транзакцията",
|
||||
"confirmations": "потвърждения",
|
||||
"confirmed": "Потвърден баланс",
|
||||
"confirmed_tx": "Потвърдено",
|
||||
|
@ -344,6 +346,7 @@
|
|||
"gas_exceeds_allowance": "Газът, изискван от транзакцията, надвишава надбавката.",
|
||||
"generate_name": "Генериране на име",
|
||||
"generating_gift_card": "Създаване на Gift Card",
|
||||
"generating_transaction": "Генериране на транзакция",
|
||||
"get_a": "Вземете ",
|
||||
"get_card_note": ", която можете да заредите с дигитална валута. Без нужда от допълнителна информация!",
|
||||
"get_your_yat": "Получете своя Yat",
|
||||
|
@ -928,6 +931,8 @@
|
|||
"understand": "Разбирам",
|
||||
"unlock": "Отключване",
|
||||
"unmatched_currencies": "Валутата на този портфейл не съвпада с тази от сканирания QR код",
|
||||
"unrestricted_background_service": "Неограничена фонова услуга",
|
||||
"unrestricted_background_service_notice": "За да активирате синхронизирането на фона, трябва да активирате неограничена фонова услуга",
|
||||
"unspent_change": "Промяна",
|
||||
"unspent_coins_details_title": "Подробности за неизползваните монети",
|
||||
"unspent_coins_title": "Неизползвани монети",
|
||||
|
|
|
@ -69,6 +69,7 @@
|
|||
"avg_savings": "Prům. ušetřeno",
|
||||
"awaitDAppProcessing": "Počkejte, až dApp dokončí zpracování.",
|
||||
"awaiting_payment_confirmation": "Čeká se na potvrzení platby",
|
||||
"background_sync": "Synchronizace pozadí",
|
||||
"background_sync_mode": "Režim synchronizace pozadí",
|
||||
"backup": "Záloha",
|
||||
"backup_file": "Soubor se zálohou",
|
||||
|
@ -161,6 +162,7 @@
|
|||
"confirm_passphrase": "Potvrďte přístupovou frázi",
|
||||
"confirm_sending": "Potvrdit odeslání",
|
||||
"confirm_silent_payments_switch_node": "Váš aktuální uzel nepodporuje tiché platby \\ Ncake peněženka se přepne na kompatibilní uzel, pouze pro skenování",
|
||||
"confirm_transaction": "Potvrďte transakci",
|
||||
"confirmations": "Potvrzení",
|
||||
"confirmed": "Potvrzený zůstatek",
|
||||
"confirmed_tx": "Potvrzeno",
|
||||
|
@ -344,6 +346,7 @@
|
|||
"gas_exceeds_allowance": "Plyn vyžadovaný transakcí přesahuje příspěvek.",
|
||||
"generate_name": "Generovat jméno",
|
||||
"generating_gift_card": "Generuji dárkovou kartu",
|
||||
"generating_transaction": "Generování transakce",
|
||||
"get_a": "Získejte ",
|
||||
"get_card_note": " které můžete nabít digitální měnou. Žádné další informace nejsou vyžadovány!",
|
||||
"get_your_yat": "Získat Yat",
|
||||
|
@ -928,6 +931,8 @@
|
|||
"understand": "Rozumím",
|
||||
"unlock": "Odemknout",
|
||||
"unmatched_currencies": "Měna vaší současné peněženky neodpovídá té v naskenovaném QR kódu",
|
||||
"unrestricted_background_service": "Neomezená služba na pozadí",
|
||||
"unrestricted_background_service_notice": "Chcete -li povolit synchronizaci pozadí, musíte povolit neomezenou službu na pozadí",
|
||||
"unspent_change": "Změna",
|
||||
"unspent_coins_details_title": "Podrobnosti o neutracených mincích",
|
||||
"unspent_coins_title": "Neutracené mince",
|
||||
|
|
|
@ -69,6 +69,7 @@
|
|||
"avg_savings": "Durchschn. Einsparungen",
|
||||
"awaitDAppProcessing": "Bitte warten Sie, bis die dApp die Verarbeitung abgeschlossen hat.",
|
||||
"awaiting_payment_confirmation": "Warten auf Zahlungsbestätigung",
|
||||
"background_sync": "Hintergrundsynchronisation",
|
||||
"background_sync_mode": "Hintergrundsynchronisierungsmodus",
|
||||
"backup": "Sicherung",
|
||||
"backup_file": "Sicherungsdatei",
|
||||
|
@ -161,6 +162,7 @@
|
|||
"confirm_passphrase": "Passphrase bestätigen",
|
||||
"confirm_sending": "Senden bestätigen",
|
||||
"confirm_silent_payments_switch_node": "Ihr aktueller Knoten unterstützt keine Silent Payments.\\n\\nCake Wallet wechselt zu einem kompatiblen Knoten, nur zum Scannen",
|
||||
"confirm_transaction": "Transaktion bestätigen",
|
||||
"confirmations": "Bestätigungen",
|
||||
"confirmed": "Bestätigter Saldo",
|
||||
"confirmed_tx": "Bestätigt",
|
||||
|
@ -344,6 +346,7 @@
|
|||
"gas_exceeds_allowance": "Die durch Transaktion erforderliche Gas übertrifft die Zulage.",
|
||||
"generate_name": "Namen generieren",
|
||||
"generating_gift_card": "Geschenkkarte wird erstellt",
|
||||
"generating_transaction": "Transaktion erzeugen",
|
||||
"get_a": "Hole ein",
|
||||
"get_card_note": " die Sie mit digitaler Währung aufladen können. Keine zusätzlichen Informationen erforderlich!",
|
||||
"get_your_yat": "Holen Sie sich Ihre Yat",
|
||||
|
@ -528,8 +531,8 @@
|
|||
"please_choose_one": "Bitte wählen Sie einen",
|
||||
"please_fill_totp": "Bitte geben Sie den 8-stelligen Code ein, der auf Ihrem anderen Gerät vorhanden ist",
|
||||
"please_make_selection": "Bitte treffen Sie unten eine Auswahl zum Erstellen oder Wiederherstellen Ihrer Wallet.",
|
||||
"please_reference_document": "Bitte verweisen Sie auf die folgenden Dokumente, um weitere Informationen zu erhalten.",
|
||||
"Please_reference_document": "Weitere Informationen finden Sie in den Dokumenten unten.",
|
||||
"please_reference_document": "Bitte verweisen Sie auf die folgenden Dokumente, um weitere Informationen zu erhalten.",
|
||||
"please_select": "Bitte auswählen:",
|
||||
"please_select_backup_file": "Bitte wählen Sie die Sicherungsdatei und geben Sie das Sicherungskennwort ein.",
|
||||
"please_try_to_connect_to_another_node": "Bitte versuchen Sie, sich mit einem anderen Knoten zu verbinden",
|
||||
|
@ -930,6 +933,8 @@
|
|||
"understand": "Ich verstehe",
|
||||
"unlock": "Freischalten",
|
||||
"unmatched_currencies": "Die Währung Ihres aktuellen Wallets stimmt nicht mit der des gescannten QR überein",
|
||||
"unrestricted_background_service": "Uneingeschränkter Hintergrunddienst",
|
||||
"unrestricted_background_service_notice": "Um die Hintergrundsynchronisierung zu ermöglichen, müssen Sie einen uneingeschränkten Hintergrundservice aktivieren",
|
||||
"unspent_change": "Wechselgeld",
|
||||
"unspent_coins_details_title": "Details zu nicht ausgegebenen Coins",
|
||||
"unspent_coins_title": "Nicht ausgegebene Coins",
|
||||
|
|
|
@ -69,6 +69,7 @@
|
|||
"avg_savings": "Avg. Savings",
|
||||
"awaitDAppProcessing": "Kindly wait for the dApp to finish processing.",
|
||||
"awaiting_payment_confirmation": "Awaiting Payment Confirmation",
|
||||
"background_sync": "Background sync",
|
||||
"background_sync_mode": "Background sync mode",
|
||||
"backup": "Backup",
|
||||
"backup_file": "Backup file",
|
||||
|
@ -161,6 +162,7 @@
|
|||
"confirm_passphrase": "Confirm passphrase",
|
||||
"confirm_sending": "Confirm sending",
|
||||
"confirm_silent_payments_switch_node": "Your current node does not support Silent Payments.\\n\\nCake Wallet will switch to a compatible node while scanning.",
|
||||
"confirm_transaction": "Confirm transaction",
|
||||
"confirmations": "Confirmations",
|
||||
"confirmed": "Confirmed Balance",
|
||||
"confirmed_tx": "Confirmed",
|
||||
|
@ -344,6 +346,7 @@
|
|||
"gas_exceeds_allowance": "Gas required by transaction exceeds allowance.",
|
||||
"generate_name": "Generate Name",
|
||||
"generating_gift_card": "Generating Gift Card",
|
||||
"generating_transaction": "Generating transaction",
|
||||
"get_a": "Get a ",
|
||||
"get_card_note": " that you can reload with digital currencies. No additional information needed!",
|
||||
"get_your_yat": "Get your Yat",
|
||||
|
@ -929,6 +932,8 @@
|
|||
"understand": "I understand",
|
||||
"unlock": "Unlock",
|
||||
"unmatched_currencies": "Your current wallet's currency does not match that of the scanned QR",
|
||||
"unrestricted_background_service": "Unrestricted background service",
|
||||
"unrestricted_background_service_notice": "In order to enable background sync you need to enable unrestricted background service",
|
||||
"unspent_change": "Change",
|
||||
"unspent_coins_details_title": "Unspent coins details",
|
||||
"unspent_coins_title": "Unspent coins",
|
||||
|
|
|
@ -69,6 +69,7 @@
|
|||
"avg_savings": "Ahorro promedio",
|
||||
"awaitDAppProcessing": "Espere a que la dApp termine de procesarse.",
|
||||
"awaiting_payment_confirmation": "Esperando confirmación de pago",
|
||||
"background_sync": "Sincronización de fondo",
|
||||
"background_sync_mode": "Modo de sincronización en segundo plano",
|
||||
"backup": "Apoyo",
|
||||
"backup_file": "Archivo de respaldo",
|
||||
|
@ -161,6 +162,7 @@
|
|||
"confirm_passphrase": "Confirmar la contraseña",
|
||||
"confirm_sending": "Confirmar envío",
|
||||
"confirm_silent_payments_switch_node": "Tu nodo actual no admite pagos silenciosos \\ nCake cambiará a un nodo compatible, solo para escanear",
|
||||
"confirm_transaction": "Confirmar transacción",
|
||||
"confirmations": "Confirmaciones",
|
||||
"confirmed": "Saldo confirmado",
|
||||
"confirmed_tx": "Confirmado",
|
||||
|
@ -344,6 +346,7 @@
|
|||
"gas_exceeds_allowance": "El gas requerido por la transacción excede la asignación.",
|
||||
"generate_name": "Generar nombre",
|
||||
"generating_gift_card": "Generando tarjeta de regalo",
|
||||
"generating_transaction": "Generación de transacciones",
|
||||
"get_a": "Obtener un",
|
||||
"get_card_note": " que puedes recargar con monedas digitales. ¡No se necesita información adicional!",
|
||||
"get_your_yat": "Obtén tu Yat",
|
||||
|
@ -929,6 +932,8 @@
|
|||
"understand": "Entiendo",
|
||||
"unlock": "desbloquear",
|
||||
"unmatched_currencies": "La moneda de tu billetera actual no coincide con la del QR escaneado",
|
||||
"unrestricted_background_service": "Servicio de antecedentes sin restricciones",
|
||||
"unrestricted_background_service_notice": "Para habilitar la sincronización de antecedentes, debe habilitar el servicio de fondo sin restricciones",
|
||||
"unspent_change": "Cambiar",
|
||||
"unspent_coins_details_title": "Detalles de monedas no gastadas",
|
||||
"unspent_coins_title": "Monedas no gastadas",
|
||||
|
|
|
@ -69,6 +69,7 @@
|
|||
"avg_savings": "Économies moy.",
|
||||
"awaitDAppProcessing": "Veuillez attendre que l'application décentralisée (dApp) termine le traitement.",
|
||||
"awaiting_payment_confirmation": "En attente de confirmation de paiement",
|
||||
"background_sync": "Synchronisation de fond",
|
||||
"background_sync_mode": "Mode de synchronisation en arrière-plan",
|
||||
"backup": "Sauvegarde",
|
||||
"backup_file": "Fichier de sauvegarde",
|
||||
|
@ -161,6 +162,7 @@
|
|||
"confirm_passphrase": "Confirmer la phrase passante",
|
||||
"confirm_sending": "Confirmer l'envoi",
|
||||
"confirm_silent_payments_switch_node": "Votre nœud actuel ne prend pas en charge les paiements silencieux.\n\nCake Wallet passera à un nœud compatible pendant l'analyse.",
|
||||
"confirm_transaction": "Confirmer la transaction",
|
||||
"confirmations": "Confirmations",
|
||||
"confirmed": "Solde confirmé",
|
||||
"confirmed_tx": "Confirmé",
|
||||
|
@ -344,6 +346,7 @@
|
|||
"gas_exceeds_allowance": "Le gaz requis par la transaction dépasse l'allocation.",
|
||||
"generate_name": "Générer un nom",
|
||||
"generating_gift_card": "Génération d'une carte-cadeau",
|
||||
"generating_transaction": "Transaction de génération",
|
||||
"get_a": "Obtenir un ",
|
||||
"get_card_note": " que vous pouvez recharger avec des devises numériques. Aucune information supplémentaire n'est nécessaire !",
|
||||
"get_your_yat": "Obtenir votre Yat",
|
||||
|
@ -928,6 +931,8 @@
|
|||
"understand": "J'ai compris",
|
||||
"unlock": "Ouvrir",
|
||||
"unmatched_currencies": "La devise de votre portefeuille (wallet) actuel ne correspond pas à celle du QR code scanné",
|
||||
"unrestricted_background_service": "Service de fond sans restriction",
|
||||
"unrestricted_background_service_notice": "Afin d'activer la synchronisation des antécédents, vous devez activer le service de fond sans restriction",
|
||||
"unspent_change": "Monnaie",
|
||||
"unspent_coins_details_title": "Détails des pièces (coins) non dépensées",
|
||||
"unspent_coins_title": "Pièces (coins) non dépensées",
|
||||
|
|
|
@ -69,6 +69,7 @@
|
|||
"avg_savings": "Matsakaici Adana",
|
||||
"awaitDAppProcessing": "Da fatan za a jira dApp ya gama aiki.",
|
||||
"awaiting_payment_confirmation": "Ana jiran Tabbacin Biyan Kuɗi",
|
||||
"background_sync": "Tunawa da Setc",
|
||||
"background_sync_mode": "Yanayin Sync",
|
||||
"backup": "Ajiyayyen",
|
||||
"backup_file": "Ajiyayyen fayil",
|
||||
|
@ -161,6 +162,7 @@
|
|||
"confirm_passphrase": "Tabbatar da kalmar wucewa",
|
||||
"confirm_sending": "Tabbatar da aikawa",
|
||||
"confirm_silent_payments_switch_node": "Kumburinku na yanzu ba ya goyan bayan biyan shiru da shiru \\ NCADA Wallet zai canza zuwa kumburi mai dacewa, don bincika",
|
||||
"confirm_transaction": "Tabbatar da ma'amala",
|
||||
"confirmations": "Tabbatar",
|
||||
"confirmed": "An tabbatar",
|
||||
"confirmed_tx": "Tabbatar",
|
||||
|
@ -344,6 +346,7 @@
|
|||
"gas_exceeds_allowance": "Gas da ake buƙata ta hanyar ma'amala ya wuce izini.",
|
||||
"generate_name": "Ƙirƙirar Suna",
|
||||
"generating_gift_card": "Samar da Katin Kyauta",
|
||||
"generating_transaction": "Ma'amala samar da ma'amala",
|
||||
"get_a": "Samu a",
|
||||
"get_card_note": "cewa zaku iya sake lodawa tare da kudaden dijital. Babu ƙarin bayani da ake buƙata!",
|
||||
"get_your_yat": "Samun Yat ka",
|
||||
|
@ -930,6 +933,8 @@
|
|||
"understand": "na gane",
|
||||
"unlock": "Buɗe",
|
||||
"unmatched_currencies": "Nau'in walat ɗin ku na yanzu bai dace da na lambar QR da aka bincika ba",
|
||||
"unrestricted_background_service": "Sabis na baya",
|
||||
"unrestricted_background_service_notice": "Don ba da damar Sync na asali kuna buƙatar kunna sabis na baya da ba a santa ba",
|
||||
"unspent_change": "Canza",
|
||||
"unspent_coins_details_title": "Bayanan tsabar kudi da ba a kashe ba",
|
||||
"unspent_coins_title": "Tsabar da ba a kashe ba",
|
||||
|
|
|
@ -69,6 +69,7 @@
|
|||
"avg_savings": "औसत बचत",
|
||||
"awaitDAppProcessing": "कृपया डीएपी की प्रोसेसिंग पूरी होने तक प्रतीक्षा करें।",
|
||||
"awaiting_payment_confirmation": "भुगतान की पुष्टि की प्रतीक्षा में",
|
||||
"background_sync": "पृष्ठभूमि सिंक",
|
||||
"background_sync_mode": "बैकग्राउंड सिंक मोड",
|
||||
"backup": "बैकअप",
|
||||
"backup_file": "बैकअपफ़ाइल",
|
||||
|
@ -161,6 +162,7 @@
|
|||
"confirm_passphrase": "पासफ़्रेज़ की पुष्टि करें",
|
||||
"confirm_sending": "भेजने की पुष्टि करें",
|
||||
"confirm_silent_payments_switch_node": "आपका वर्तमान नोड मूक भुगतान का समर्थन नहीं करता है \\ ncake वॉलेट एक संगत नोड पर स्विच करेगा, बस स्कैनिंग के लिए",
|
||||
"confirm_transaction": "लेनदेन की पुष्टि करें",
|
||||
"confirmations": "पुष्टिकरण",
|
||||
"confirmed": "पुष्टि की गई शेष राशिी",
|
||||
"confirmed_tx": "की पुष्टि",
|
||||
|
@ -344,6 +346,7 @@
|
|||
"gas_exceeds_allowance": "लेनदेन द्वारा आवश्यक गैस भत्ता से अधिक है।",
|
||||
"generate_name": "नाम जनरेट करें",
|
||||
"generating_gift_card": "गिफ्ट कार्ड जनरेट कर रहा है",
|
||||
"generating_transaction": "सृजन लेन -देन",
|
||||
"get_a": "एक प्राप्त करें",
|
||||
"get_card_note": " कि आप डिजिटल मुद्राओं के साथ पुनः लोड कर सकते हैं। कोई अतिरिक्त जानकारी की आवश्यकता नहीं है!",
|
||||
"get_your_yat": "अपना प्राप्त करें Yat",
|
||||
|
@ -517,8 +520,8 @@
|
|||
"paste": "पेस्ट करें",
|
||||
"pause_wallet_creation": "हेवन वॉलेट बनाने की क्षमता फिलहाल रुकी हुई है।",
|
||||
"payment_id": "भुगतान ID: ",
|
||||
"Payment_was_received": "आपका भुगतान प्राप्त हो गया था।",
|
||||
"payment_was_received": "आपका भुगतान प्राप्त हुआ था।",
|
||||
"Payment_was_received": "आपका भुगतान प्राप्त हो गया था।",
|
||||
"pending": " (अपूर्ण)",
|
||||
"percentageOf": "${amount} का",
|
||||
"pin_at_top": "शीर्ष पर ${token} पिन करें",
|
||||
|
@ -930,6 +933,8 @@
|
|||
"understand": "मुझे समझ",
|
||||
"unlock": "अनलॉक",
|
||||
"unmatched_currencies": "आपके वर्तमान वॉलेट की मुद्रा स्कैन किए गए क्यूआर से मेल नहीं खाती",
|
||||
"unrestricted_background_service": "अप्रतिबंधित पृष्ठभूमि सेवा",
|
||||
"unrestricted_background_service_notice": "पृष्ठभूमि सिंक को सक्षम करने के लिए आपको अप्रतिबंधित पृष्ठभूमि सेवा को सक्षम करने की आवश्यकता है",
|
||||
"unspent_change": "परिवर्तन",
|
||||
"unspent_coins_details_title": "अव्ययित सिक्कों का विवरण",
|
||||
"unspent_coins_title": "खर्च न किए गए सिक्के",
|
||||
|
|
|
@ -69,6 +69,7 @@
|
|||
"avg_savings": "Prosj. ušteda",
|
||||
"awaitDAppProcessing": "Molimo pričekajte da dApp završi obradu.",
|
||||
"awaiting_payment_confirmation": "Čeka se potvrda plaćanja",
|
||||
"background_sync": "Sinkronizacija pozadine",
|
||||
"background_sync_mode": "Sinkronizacija u pozadini",
|
||||
"backup": "Sigurnosna kopija",
|
||||
"backup_file": "Sigurnosna kopija datoteke",
|
||||
|
@ -161,6 +162,7 @@
|
|||
"confirm_passphrase": "Potvrdite prolaznu frazu",
|
||||
"confirm_sending": "Potvrdi slanje",
|
||||
"confirm_silent_payments_switch_node": "Vaš trenutni čvor ne podržava tiha plaćanja \\ ncake novčanik prebacit će se na kompatibilni čvor, samo za skeniranje",
|
||||
"confirm_transaction": "Potvrdite transakciju",
|
||||
"confirmations": "Potvrde",
|
||||
"confirmed": "Potvrđeno stanje",
|
||||
"confirmed_tx": "Potvrđen",
|
||||
|
@ -344,6 +346,7 @@
|
|||
"gas_exceeds_allowance": "Plin potreban transakcijom premašuje dodatak.",
|
||||
"generate_name": "Generiraj ime",
|
||||
"generating_gift_card": "Generiranje darovne kartice",
|
||||
"generating_transaction": "Generiranje transakcije",
|
||||
"get_a": "Nabavite ",
|
||||
"get_card_note": " koju možete ponovno napuniti digitalnim valutama. Nisu potrebne dodatne informacije!",
|
||||
"get_your_yat": "Uzmi svoj Yat",
|
||||
|
@ -928,6 +931,8 @@
|
|||
"understand": "Razumijem",
|
||||
"unlock": "Otključati",
|
||||
"unmatched_currencies": "Valuta vašeg trenutnog novčanika ne odgovara onoj na skeniranom QR-u",
|
||||
"unrestricted_background_service": "Neograničena pozadinska usluga",
|
||||
"unrestricted_background_service_notice": "Da biste omogućili sinkronizaciju pozadine, morate omogućiti neograničenu pozadinsku uslugu",
|
||||
"unspent_change": "Promijeniti",
|
||||
"unspent_coins_details_title": "Nepotrošeni detalji o novčićima",
|
||||
"unspent_coins_title": "Nepotrošeni novčići",
|
||||
|
|
|
@ -69,6 +69,7 @@
|
|||
"avg_savings": "Միջին խնայողություն",
|
||||
"awaitDAppProcessing": "Խնդրեմ սպասեք, մինչև դիմումը կավարտի մշակումը։",
|
||||
"awaiting_payment_confirmation": "Վճարման հաստատման սպասում",
|
||||
"background_sync": "Ֆոնային համաժամեցում",
|
||||
"background_sync_mode": "Հետին պլանի համաժամացման ռեժիմ",
|
||||
"backup": "Կրկնօրինակ",
|
||||
"backup_file": "Կրկնօրինակի ֆայլ",
|
||||
|
@ -161,6 +162,7 @@
|
|||
"confirm_passphrase": "Հաստատեք գաղտնաբառը",
|
||||
"confirm_sending": "Հաստատեք ուղարկումը",
|
||||
"confirm_silent_payments_switch_node": "Ձեր ընթացիկ հանգույցը չի աջակցում Լուռ վճարումներին\nCake Wallet-ը կանցնի համատեղելի հանգույց, միայն սկանավորման համար",
|
||||
"confirm_transaction": "Հաստատեք գործարքը",
|
||||
"confirmations": "Հաստատումներ",
|
||||
"confirmed": "Հաստատված մնացորդ",
|
||||
"confirmed_tx": "Հաստատված",
|
||||
|
@ -344,6 +346,7 @@
|
|||
"gas_exceeds_allowance": "Գործարքով պահանջվող գազը գերազանցում է նպաստը:",
|
||||
"generate_name": "Գեներացնել անուն",
|
||||
"generating_gift_card": "Գեներացնում է նվեր քարտ",
|
||||
"generating_transaction": "Ստեղծող գործարք",
|
||||
"get_a": "Ստանալ ",
|
||||
"get_card_note": " որը կարող եք լրացնել թվային արժույթներով: Հավելյալ տեղեկատվություն պետք չէ!",
|
||||
"get_your_yat": "Ստանալ ձեր Yat",
|
||||
|
@ -926,6 +929,8 @@
|
|||
"understand": "Ես հասկանում եմ",
|
||||
"unlock": "Բացել",
|
||||
"unmatched_currencies": "Ձեր ընթացիկ դրամապանակի արժույթը չի համապատասխանում սկանավորված QR կոդի արժույթին",
|
||||
"unrestricted_background_service": "Անսահմանափակ ֆոնային ծառայություն",
|
||||
"unrestricted_background_service_notice": "Ֆոնային համաժամացման համար անհրաժեշտ է միացնել անսահմանափակ ֆոնային ծառայություն",
|
||||
"unspent_change": "Մնացորդ",
|
||||
"unspent_coins_details_title": "Չծախսված արժույթների մանրամասները",
|
||||
"unspent_coins_title": "Չծախսված արժույթներ",
|
||||
|
|
|
@ -69,6 +69,7 @@
|
|||
"avg_savings": "Rata-rata Pembayaran",
|
||||
"awaitDAppProcessing": "Mohon tunggu hingga dApp menyelesaikan pemrosesan.",
|
||||
"awaiting_payment_confirmation": "Menunggu Konfirmasi Pembayaran",
|
||||
"background_sync": "Sinkronisasi Latar Belakang",
|
||||
"background_sync_mode": "Mode Sinkronisasi Latar Belakang",
|
||||
"backup": "Cadangan",
|
||||
"backup_file": "File cadangan",
|
||||
|
@ -161,6 +162,7 @@
|
|||
"confirm_passphrase": "Konfirmasi frasa sandi",
|
||||
"confirm_sending": "Konfirmasi pengiriman",
|
||||
"confirm_silent_payments_switch_node": "Node Anda saat ini tidak mendukung pembayaran diam \\ ncake Wallet akan beralih ke simpul yang kompatibel, hanya untuk pemindaian",
|
||||
"confirm_transaction": "Konfirmasi transaksi",
|
||||
"confirmations": "Konfirmasi",
|
||||
"confirmed": "Saldo Terkonfirmasi",
|
||||
"confirmed_tx": "Dikonfirmasi",
|
||||
|
@ -344,6 +346,7 @@
|
|||
"gas_exceeds_allowance": "Gas yang dibutuhkan oleh transaksi melebihi tunjangan.",
|
||||
"generate_name": "Hasilkan Nama",
|
||||
"generating_gift_card": "Membuat Kartu Hadiah",
|
||||
"generating_transaction": "Menghasilkan transaksi",
|
||||
"get_a": "Dapatkan ",
|
||||
"get_card_note": " yang dapat Anda muat ulang dengan mata uang digital. Tidak perlu informasi tambahan!",
|
||||
"get_your_yat": "Dapatkan Yat Anda",
|
||||
|
@ -931,6 +934,8 @@
|
|||
"understand": "Saya mengerti",
|
||||
"unlock": "Membuka kunci",
|
||||
"unmatched_currencies": "Mata uang dompet Anda saat ini tidak cocok dengan yang ditandai QR",
|
||||
"unrestricted_background_service": "Layanan latar belakang tidak terbatas",
|
||||
"unrestricted_background_service_notice": "Untuk mengaktifkan sinkronisasi latar belakang, Anda perlu mengaktifkan layanan latar belakang yang tidak dibatasi",
|
||||
"unspent_change": "Mengubah",
|
||||
"unspent_coins_details_title": "Rincian koin yang tidak terpakai",
|
||||
"unspent_coins_title": "Koin yang tidak terpakai",
|
||||
|
|
|
@ -69,6 +69,7 @@
|
|||
"avg_savings": "Risparmio medio",
|
||||
"awaitDAppProcessing": "Attendi gentilmente che la dApp termini l'elaborazione.",
|
||||
"awaiting_payment_confirmation": "In attesa di conferma del pagamento",
|
||||
"background_sync": "Sincronizzazione in background",
|
||||
"background_sync_mode": "Modalità di sincronizzazione in background",
|
||||
"backup": "Backup",
|
||||
"backup_file": "Backup file",
|
||||
|
@ -161,6 +162,7 @@
|
|||
"confirm_passphrase": "Conferma passphrase",
|
||||
"confirm_sending": "Conferma l'invio",
|
||||
"confirm_silent_payments_switch_node": "Il tuo nodo corrente non supporta Silent Payments\\n\\nCake Wallet passerà a un nodo compatibile durante la scansione.",
|
||||
"confirm_transaction": "Conferma la transazione",
|
||||
"confirmations": "Conferme",
|
||||
"confirmed": "Saldo Confermato",
|
||||
"confirmed_tx": "Confermato",
|
||||
|
@ -344,6 +346,7 @@
|
|||
"gas_exceeds_allowance": "Il Gas richiesto dalla transazione supera il limite consentito.",
|
||||
"generate_name": "Genera nome",
|
||||
"generating_gift_card": "Generazione carta regalo",
|
||||
"generating_transaction": "Generazione di transazione",
|
||||
"get_a": "Prendi un ",
|
||||
"get_card_note": "che puoi ricaricare con le valute digitali. Non sono necessarie informazioni aggiuntive!",
|
||||
"get_your_yat": "Ottieni il tuo Yat",
|
||||
|
@ -928,6 +931,8 @@
|
|||
"understand": "Capisco",
|
||||
"unlock": "Sblocca",
|
||||
"unmatched_currencies": "La valuta del tuo portafoglio attuale non corrisponde a quella del QR scansionato",
|
||||
"unrestricted_background_service": "Servizio di background senza restrizioni",
|
||||
"unrestricted_background_service_notice": "Per abilitare la sincronizzazione in background è necessario abilitare il servizio di background senza restrizioni",
|
||||
"unspent_change": "Resto",
|
||||
"unspent_coins_details_title": "Dettagli sulle monete non spese",
|
||||
"unspent_coins_title": "Monete non spese",
|
||||
|
|
|
@ -69,6 +69,7 @@
|
|||
"avg_savings": "平均節約額",
|
||||
"awaitDAppProcessing": "dAppの処理が完了するまでお待ちください。",
|
||||
"awaiting_payment_confirmation": "支払い確認を待っています",
|
||||
"background_sync": "背景同期",
|
||||
"background_sync_mode": "バックグラウンド同期モード",
|
||||
"backup": "バックアップ",
|
||||
"backup_file": "バックアップファイル",
|
||||
|
@ -161,6 +162,7 @@
|
|||
"confirm_passphrase": "パスフレーズを確認します",
|
||||
"confirm_sending": "送信を確認",
|
||||
"confirm_silent_payments_switch_node": "現在のノードはサイレントペイメントをサポートしていません\\ ncakeウォレットは、スキャン用に互換性のあるノードに切り替えます",
|
||||
"confirm_transaction": "トランザクションを確認します",
|
||||
"confirmations": "確認",
|
||||
"confirmed": "確認済み残高",
|
||||
"confirmed_tx": "確認済み",
|
||||
|
@ -345,6 +347,7 @@
|
|||
"generate_name": "名前の生成",
|
||||
"generated_gift_card": "ギフトカードの生成",
|
||||
"generating_gift_card": "ギフトカードの生成",
|
||||
"generating_transaction": "トランザクションの生成",
|
||||
"get_a": "Get a",
|
||||
"get_card_note": "デジタル通貨でリロードできます。追加情報は必要ありません!",
|
||||
"get_your_yat": "あなたのYatを入手してください",
|
||||
|
@ -929,6 +932,8 @@
|
|||
"understand": "わかります",
|
||||
"unlock": "ロックを解除します",
|
||||
"unmatched_currencies": "現在のウォレットの通貨がスキャンされたQRの通貨と一致しません",
|
||||
"unrestricted_background_service": "無制限のバックグラウンドサービス",
|
||||
"unrestricted_background_service_notice": "バックグラウンドの同期を有効にするには、無制限のバックグラウンドサービスを有効にする必要があります",
|
||||
"unspent_change": "変化",
|
||||
"unspent_coins_details_title": "未使用のコインの詳細",
|
||||
"unspent_coins_title": "未使用のコイン",
|
||||
|
|
|
@ -69,6 +69,7 @@
|
|||
"avg_savings": "평균 절감액",
|
||||
"awaitDAppProcessing": "dApp이 처리를 마칠 때까지 기다려주세요.",
|
||||
"awaiting_payment_confirmation": "결제 확인 대기 중",
|
||||
"background_sync": "배경 동기화",
|
||||
"background_sync_mode": "백그라운드 동기화 모드",
|
||||
"backup": "지원",
|
||||
"backup_file": "백업 파일",
|
||||
|
@ -161,6 +162,7 @@
|
|||
"confirm_passphrase": "암호를 확인하십시오",
|
||||
"confirm_sending": "전송 확인",
|
||||
"confirm_silent_payments_switch_node": "현재 노드는 무음 지불을 지원하지 않습니다 \\ ncake 지갑은 스캔을 위해 호환 가능한 노드로 전환됩니다.",
|
||||
"confirm_transaction": "거래 확인",
|
||||
"confirmations": "확인",
|
||||
"confirmed": "확인된 잔액",
|
||||
"confirmed_tx": "확인",
|
||||
|
@ -344,6 +346,7 @@
|
|||
"gas_exceeds_allowance": "거래에 필요한 가스는 수당을 초과합니다.",
|
||||
"generate_name": "이름 생성",
|
||||
"generating_gift_card": "기프트 카드 생성 중",
|
||||
"generating_transaction": "거래 생성",
|
||||
"get_a": "가져오기",
|
||||
"get_card_note": " 디지털 통화로 충전할 수 있습니다. 추가 정보가 필요하지 않습니다!",
|
||||
"get_your_yat": "당신의 Yat를 얻으십시오",
|
||||
|
@ -928,6 +931,8 @@
|
|||
"understand": "이해 했어요",
|
||||
"unlock": "터놓다",
|
||||
"unmatched_currencies": "현재 지갑의 통화가 스캔한 QR의 통화와 일치하지 않습니다.",
|
||||
"unrestricted_background_service": "무제한 배경 서비스",
|
||||
"unrestricted_background_service_notice": "배경 동기화를 활성화하려면 무제한 배경 서비스를 활성화해야합니다.",
|
||||
"unspent_change": "변화",
|
||||
"unspent_coins_details_title": "사용하지 않은 동전 세부 정보",
|
||||
"unspent_coins_title": "사용하지 않은 동전",
|
||||
|
|
|
@ -69,6 +69,7 @@
|
|||
"avg_savings": "ပျမ်းမျှ စုဆောင်းငွေ",
|
||||
"awaitDAppProcessing": "ကျေးဇူးပြု၍ dApp ကို စီမံလုပ်ဆောင်ခြင်း အပြီးသတ်ရန် စောင့်ပါ။",
|
||||
"awaiting_payment_confirmation": "ငွေပေးချေမှု အတည်ပြုချက်ကို စောင့်မျှော်နေပါသည်။",
|
||||
"background_sync": "နောက်ခံထပ်တူပြုခြင်း",
|
||||
"background_sync_mode": "နောက်ခံထပ်တူပြုခြင်း mode ကို",
|
||||
"backup": "မိတ္တူ",
|
||||
"backup_file": "အရန်ဖိုင်",
|
||||
|
@ -161,6 +162,7 @@
|
|||
"confirm_passphrase": "passphrase အတည်ပြုပါ",
|
||||
"confirm_sending": "ပေးပို့အတည်ပြုပါ။",
|
||||
"confirm_silent_payments_switch_node": "သင်၏လက်ရှိ node သည်အသံတိတ်ငွေပေးချေမှုကိုမပံ့ပိုးပါဟု \\ t",
|
||||
"confirm_transaction": "ငွေပေးငွေယူအတည်ပြုပါ",
|
||||
"confirmations": "အတည်ပြုချက်များ",
|
||||
"confirmed": "အတည်ပြုထားသော လက်ကျန်ငွေ",
|
||||
"confirmed_tx": "အတည်ပြုသည်",
|
||||
|
@ -344,6 +346,7 @@
|
|||
"gas_exceeds_allowance": "ငွေပေးငွေယူမှလိုအပ်သောဓာတ်ငွေ့ထောက်ပံ့ကြေးကျော်လွန်။",
|
||||
"generate_name": "အမည်ဖန်တီးပါ။",
|
||||
"generating_gift_card": "လက်ဆောင်ကတ်ထုတ်ပေးခြင်း။",
|
||||
"generating_transaction": "ငွေပေးငွေယူကိုထုတ်လုပ်",
|
||||
"get_a": "တစ်ခုရယူပါ။",
|
||||
"get_card_note": " ဒစ်ဂျစ်တယ်ငွေကြေးများဖြင့် ပြန်လည်စတင်နိုင်သည်။ နောက်ထပ် အချက်အလက် မလိုအပ်ပါ။",
|
||||
"get_your_yat": "မင်းရဲ့ Yat ကိုယူလိုက်ပါ။",
|
||||
|
@ -928,6 +931,8 @@
|
|||
"understand": "ကျွန်တော်နားလည်ပါတယ်",
|
||||
"unlock": "သော့ဖွင့်",
|
||||
"unmatched_currencies": "သင့်လက်ရှိပိုက်ဆံအိတ်၏ငွေကြေးသည် စကင်ဖတ်ထားသော QR နှင့် မကိုက်ညီပါ။",
|
||||
"unrestricted_background_service": "အကန့်အသတ်မရှိနောက်ခံဝန်ဆောင်မှု",
|
||||
"unrestricted_background_service_notice": "နောက်ခံထပ်တူပြုခြင်းကို Enable လုပ်ရန်သင်ကန့်သတ်ထားသောနောက်ခံဝန်ဆောင်မှုကိုဖွင့်ရန်လိုအပ်သည်",
|
||||
"unspent_change": "ပေြာင်းလဲခြင်း",
|
||||
"unspent_coins_details_title": "အသုံးမဝင်သော အကြွေစေ့အသေးစိတ်များ",
|
||||
"unspent_coins_title": "အသုံးမဝင်သော အကြွေစေ့များ",
|
||||
|
|
|
@ -69,6 +69,7 @@
|
|||
"avg_savings": "Gem. besparingen",
|
||||
"awaitDAppProcessing": "Wacht tot de dApp klaar is met verwerken.",
|
||||
"awaiting_payment_confirmation": "In afwachting van betalingsbevestiging",
|
||||
"background_sync": "Achtergrondsynchronisatie",
|
||||
"background_sync_mode": "Achtergrondsynchronisatiemodus",
|
||||
"backup": "Back-up",
|
||||
"backup_file": "Backup bestand",
|
||||
|
@ -161,6 +162,7 @@
|
|||
"confirm_passphrase": "Bevestig Passaspherase",
|
||||
"confirm_sending": "Bevestig verzending",
|
||||
"confirm_silent_payments_switch_node": "Uw huidige knooppunt ondersteunt geen stille betalingen \\ ncake -portemonnee schakelt over naar een compatibele knoop",
|
||||
"confirm_transaction": "Bevestig transactie",
|
||||
"confirmations": "Bevestigingen",
|
||||
"confirmed": "Bevestigd saldo",
|
||||
"confirmed_tx": "Bevestigd",
|
||||
|
@ -344,6 +346,7 @@
|
|||
"gas_exceeds_allowance": "Gas vereist door transactie overschrijdt de vergoeding.",
|
||||
"generate_name": "Naam genereren",
|
||||
"generating_gift_card": "Cadeaubon genereren",
|
||||
"generating_transaction": "Transactie genereren",
|
||||
"get_a": "Krijg een ",
|
||||
"get_card_note": " die u kunt herladen met digitale valuta. Geen aanvullende informatie nodig!",
|
||||
"get_your_yat": "Haal je Yato",
|
||||
|
@ -928,6 +931,8 @@
|
|||
"understand": "Ik begrijp het",
|
||||
"unlock": "Ontgrendelen",
|
||||
"unmatched_currencies": "De valuta van uw huidige portemonnee komt niet overeen met die van de gescande QR",
|
||||
"unrestricted_background_service": "Onbeperkte achtergrondservice",
|
||||
"unrestricted_background_service_notice": "Om achtergrondsynchronisatie in te schakelen, moet u onbeperkte achtergrondservice inschakelen",
|
||||
"unspent_change": "Wijziging",
|
||||
"unspent_coins_details_title": "Details van niet-uitgegeven munten",
|
||||
"unspent_coins_title": "Ongebruikte munten",
|
||||
|
|
|
@ -69,6 +69,7 @@
|
|||
"avg_savings": "Śr. oszczędności",
|
||||
"awaitDAppProcessing": "Poczekaj, aż dApp zakończy przetwarzanie.",
|
||||
"awaiting_payment_confirmation": "Oczekiwanie na potwierdzenie płatności",
|
||||
"background_sync": "Synchronizacja tła",
|
||||
"background_sync_mode": "Tryb synchronizacji w tle",
|
||||
"backup": "Kopia zapasowa",
|
||||
"backup_file": "Plik kopii zapasowej",
|
||||
|
@ -161,6 +162,7 @@
|
|||
"confirm_passphrase": "Potwierdź hasło",
|
||||
"confirm_sending": "Potwierdź wysłanie",
|
||||
"confirm_silent_payments_switch_node": "Twój obecny węzeł nie obsługuje cichych płatności \\ NCAKE Portfel przełączy się na kompatybilny węzeł, tylko do skanowania",
|
||||
"confirm_transaction": "Potwierdź transakcję",
|
||||
"confirmations": "Potwierdzenia",
|
||||
"confirmed": "Potwierdzone saldo",
|
||||
"confirmed_tx": "Potwierdzony",
|
||||
|
@ -344,6 +346,7 @@
|
|||
"gas_exceeds_allowance": "Gaz wymagany przez transakcję przekracza dodatek.",
|
||||
"generate_name": "Wygeneruj nazwę",
|
||||
"generating_gift_card": "Generowanie karty podarunkowej",
|
||||
"generating_transaction": "Generowanie transakcji",
|
||||
"get_a": "Zdobądź ",
|
||||
"get_card_note": " które możesz doładować walutami cyfrowymi. Nie są potrzebne żadne dodatkowe informacje!",
|
||||
"get_your_yat": "Zdobądź swój Yat",
|
||||
|
@ -928,6 +931,8 @@
|
|||
"understand": "Rozumiem",
|
||||
"unlock": "Odblokować",
|
||||
"unmatched_currencies": "Waluta Twojego obecnego portfela nie zgadza się z waluctą zeskanowanego kodu QR",
|
||||
"unrestricted_background_service": "Nieograniczona usługa w tle",
|
||||
"unrestricted_background_service_notice": "Aby włączyć synchronizację tła, musisz włączyć nieograniczoną usługę w tle",
|
||||
"unspent_change": "Zmiana",
|
||||
"unspent_coins_details_title": "Szczegóły niewydanych monet",
|
||||
"unspent_coins_title": "Niewydane monety",
|
||||
|
|
|
@ -69,6 +69,7 @@
|
|||
"avg_savings": "Poupança média",
|
||||
"awaitDAppProcessing": "Aguarde até que o dApp termine o processamento.",
|
||||
"awaiting_payment_confirmation": "Aguardando confirmação de pagamento",
|
||||
"background_sync": "Sincronização de fundo",
|
||||
"background_sync_mode": "Modo de sincronização em segundo plano",
|
||||
"backup": "Cópia de segurança",
|
||||
"backup_file": "Arquivo de backup",
|
||||
|
@ -161,6 +162,7 @@
|
|||
"confirm_passphrase": "Confirme a senha",
|
||||
"confirm_sending": "Confirmar o envio",
|
||||
"confirm_silent_payments_switch_node": "Seu nó atual não suporta pagamentos silenciosos \n A Cake Wallet mudará para um nó compatível, apenas para escanear",
|
||||
"confirm_transaction": "Confirme a transação",
|
||||
"confirmations": "Confirmações",
|
||||
"confirmed": "Saldo Confirmado",
|
||||
"confirmed_tx": "Confirmado",
|
||||
|
@ -344,6 +346,7 @@
|
|||
"gas_exceeds_allowance": "O gás exigido pela transação excede o subsídio.",
|
||||
"generate_name": "Gerar nome",
|
||||
"generating_gift_card": "Gerando Cartão Presente",
|
||||
"generating_transaction": "Gerando transação",
|
||||
"get_a": "Obter um ",
|
||||
"get_card_note": " que você pode recarregar com moedas digitais. Nenhuma informação adicional é necessária!",
|
||||
"get_your_yat": "Pegue seu Yat",
|
||||
|
@ -930,6 +933,8 @@
|
|||
"understand": "Entendo",
|
||||
"unlock": "Desbloquear",
|
||||
"unmatched_currencies": "A moeda da sua carteira atual não corresponde à do QR digitalizado",
|
||||
"unrestricted_background_service": "Serviço de fundo irrestrito",
|
||||
"unrestricted_background_service_notice": "Para ativar a sincronização de fundo, você precisa ativar o serviço de fundo irrestrito",
|
||||
"unspent_change": "Troco",
|
||||
"unspent_coins_details_title": "Detalhes de moedas não gastas",
|
||||
"unspent_coins_title": "Moedas não gastas",
|
||||
|
|
|
@ -69,6 +69,7 @@
|
|||
"avg_savings": "Средняя экономия",
|
||||
"awaitDAppProcessing": "Пожалуйста, подождите, пока dApp завершит обработку.",
|
||||
"awaiting_payment_confirmation": "Ожидается подтверждения платежа",
|
||||
"background_sync": "Фоновая синхронизация",
|
||||
"background_sync_mode": "Режим фоновой синхронизации",
|
||||
"backup": "Резервная копия",
|
||||
"backup_file": "Файл резервной копии",
|
||||
|
@ -161,6 +162,7 @@
|
|||
"confirm_passphrase": "Подтвердите Passfrase",
|
||||
"confirm_sending": "Подтвердить отправку",
|
||||
"confirm_silent_payments_switch_node": "Ваш текущий узел не поддерживает Silent Payments \\ ncake Wallet переключится на совместимый узел, только для сканирования",
|
||||
"confirm_transaction": "Подтвердите транзакцию",
|
||||
"confirmations": "Подтверждения",
|
||||
"confirmed": "Подтвержденный баланс",
|
||||
"confirmed_tx": "Подтвержденный",
|
||||
|
@ -344,6 +346,7 @@
|
|||
"gas_exceeds_allowance": "Газ, требуемый в результате транзакции, превышает пособие.",
|
||||
"generate_name": "Создать имя",
|
||||
"generating_gift_card": "Создание подарочной карты",
|
||||
"generating_transaction": "Генерирующая транзакция",
|
||||
"get_a": "Получить ",
|
||||
"get_card_note": " которую вы можете пополнить цифровой валютой. Дополнительная информация не требуется!",
|
||||
"get_your_yat": "Получить свой Yat",
|
||||
|
@ -929,6 +932,8 @@
|
|||
"understand": "Понятно",
|
||||
"unlock": "Разблокировать",
|
||||
"unmatched_currencies": "Валюта вашего текущего кошелька не соответствует валюте отсканированного QR-кода.",
|
||||
"unrestricted_background_service": "Неограниченная фоновая служба",
|
||||
"unrestricted_background_service_notice": "Чтобы включить фона синхронизации, необходимо включить неограниченную фоновую службу",
|
||||
"unspent_change": "Изменять",
|
||||
"unspent_coins_details_title": "Сведения о неизрасходованных монетах",
|
||||
"unspent_coins_title": "Неизрасходованные монеты",
|
||||
|
|
|
@ -69,6 +69,7 @@
|
|||
"avg_savings": "ประหยัดเฉลี่ย",
|
||||
"awaitDAppProcessing": "โปรดรอให้ dApp ประมวลผลเสร็จสิ้น",
|
||||
"awaiting_payment_confirmation": "รอการยืนยันการชำระเงิน",
|
||||
"background_sync": "การซิงค์พื้นหลัง",
|
||||
"background_sync_mode": "โหมดซิงค์พื้นหลัง",
|
||||
"backup": "สำรองข้อมูล",
|
||||
"backup_file": "ไฟล์สำรองข้อมูล",
|
||||
|
@ -161,6 +162,7 @@
|
|||
"confirm_passphrase": "ยืนยันวลีรหัสผ่าน",
|
||||
"confirm_sending": "ยืนยันการส่ง",
|
||||
"confirm_silent_payments_switch_node": "โหนดปัจจุบันของคุณไม่รองรับการชำระเงินแบบเงียบ \\ ncake กระเป๋าเงินจะเปลี่ยนเป็นโหนดที่เข้ากันได้เพียงเพื่อการสแกน",
|
||||
"confirm_transaction": "ยืนยันการทำธุรกรรม",
|
||||
"confirmations": "การยืนยัน",
|
||||
"confirmed": "ยอดคงเหลือที่ยืนยันแล้ว",
|
||||
"confirmed_tx": "ซึ่งยืนยันแล้ว",
|
||||
|
@ -344,6 +346,7 @@
|
|||
"gas_exceeds_allowance": "ก๊าซที่ต้องการโดยการทำธุรกรรมเกินค่าเผื่อ",
|
||||
"generate_name": "สร้างชื่อ",
|
||||
"generating_gift_card": "กำลังสร้างบัตรของขวัญ",
|
||||
"generating_transaction": "การสร้างธุรกรรม",
|
||||
"get_a": "รับ ",
|
||||
"get_card_note": "ที่คุณสามารถเติมเงินด้วยสกุลเงินดิจิตอล ไม่จำเป็นต้องใส่ข้อมูลเพิ่มเติม!",
|
||||
"get_your_yat": "รับ Yat ของคุณ",
|
||||
|
@ -928,6 +931,8 @@
|
|||
"understand": "ฉันเข้าใจ",
|
||||
"unlock": "ปลดล็อค",
|
||||
"unmatched_currencies": "สกุลเงินของกระเป๋าปัจจุบันของคุณไม่ตรงกับของ QR ที่สแกน",
|
||||
"unrestricted_background_service": "บริการพื้นหลังที่ไม่ จำกัด",
|
||||
"unrestricted_background_service_notice": "ในการเปิดใช้งานการซิงค์พื้นหลังคุณต้องเปิดใช้งานบริการพื้นหลังที่ไม่ จำกัด",
|
||||
"unspent_change": "เปลี่ยน",
|
||||
"unspent_coins_details_title": "รายละเอียดเหรียญที่ไม่ได้ใช้",
|
||||
"unspent_coins_title": "เหรียญที่ไม่ได้ใช้",
|
||||
|
|
|
@ -69,6 +69,7 @@
|
|||
"avg_savings": "Avg. Matitipid",
|
||||
"awaitDAppProcessing": "Pakihintay na matapos ang pagproseso ng dApp.",
|
||||
"awaiting_payment_confirmation": "Nanghihintay ng Kumpirmasyon sa Pagbabayad",
|
||||
"background_sync": "Pag -sync ng background",
|
||||
"background_sync_mode": "Background sync mode",
|
||||
"backup": "Backup",
|
||||
"backup_file": "Backup na file",
|
||||
|
@ -161,6 +162,7 @@
|
|||
"confirm_passphrase": "Kumpirma ang passphrase",
|
||||
"confirm_sending": "Kumpirmahin ang pagpapadala",
|
||||
"confirm_silent_payments_switch_node": "Ang iyong kasalukuyang node ay hindi sumusuporta sa tahimik na pagbabayad \\ nCake Wallet ay lilipat sa isang katugmang node, para lamang sa pag-scan",
|
||||
"confirm_transaction": "Kumpirmahin ang transaksyon",
|
||||
"confirmations": "Mga kumpirmasyon",
|
||||
"confirmed": "Nakumpirma na Balanse",
|
||||
"confirmed_tx": "Nakumpirma",
|
||||
|
@ -344,6 +346,7 @@
|
|||
"gas_exceeds_allowance": "Ang gas na kinakailangan ng transaksyon ay lumampas sa allowance.",
|
||||
"generate_name": "Bumuo ng pangalan",
|
||||
"generating_gift_card": "Bumubuo ng Gift Card",
|
||||
"generating_transaction": "Bumubuo ng transaksyon",
|
||||
"get_a": "Kumuha ng ",
|
||||
"get_card_note": " na maaari mong i-load gamit ang mga digital na pera. Walang karagdagang impormasyon na kailangan!",
|
||||
"get_your_yat": "Kunin ang iyong Yat",
|
||||
|
@ -928,6 +931,8 @@
|
|||
"understand": "Naiitindihan ko",
|
||||
"unlock": "I-unlock",
|
||||
"unmatched_currencies": "Hindi tumutugma ang pera ng iyong kasalukuyang wallet sa na-scan na QR",
|
||||
"unrestricted_background_service": "Hindi pinigilan na serbisyo sa background",
|
||||
"unrestricted_background_service_notice": "Upang paganahin ang pag -sync ng background kailangan mong paganahin ang hindi pinigilan na serbisyo sa background",
|
||||
"unspent_change": "Sukli",
|
||||
"unspent_coins_details_title": "Mga detalye ng mga hindi nagastos na barya",
|
||||
"unspent_coins_title": "Mga hindi nagamit na barya",
|
||||
|
|
|
@ -69,6 +69,7 @@
|
|||
"avg_savings": "Ortalama Tasarruf",
|
||||
"awaitDAppProcessing": "Lütfen dApp'in işlemeyi bitirmesini bekleyin.",
|
||||
"awaiting_payment_confirmation": "Ödemenin onaylanması bekleniyor",
|
||||
"background_sync": "Arka plan senkronizasyonu",
|
||||
"background_sync_mode": "Arka Plan Senkronizasyon Modu",
|
||||
"backup": "Yedek",
|
||||
"backup_file": "Yedek dosyası",
|
||||
|
@ -161,6 +162,7 @@
|
|||
"confirm_passphrase": "Parola onaylayın",
|
||||
"confirm_sending": "Göndermeyi onayla",
|
||||
"confirm_silent_payments_switch_node": "Mevcut düğümünüz sessiz ödemeleri desteklemiyor \\ nCake cüzdanı, sadece tarama için uyumlu bir düğüme geçecektir",
|
||||
"confirm_transaction": "İşlemi onaylayın",
|
||||
"confirmations": "Onay",
|
||||
"confirmed": "Onaylanmış Bakiye",
|
||||
"confirmed_tx": "Onaylanmış",
|
||||
|
@ -344,6 +346,7 @@
|
|||
"gas_exceeds_allowance": "İşlemin gerektirdiği gaz ödeneği aşar.",
|
||||
"generate_name": "İsim Oluştur",
|
||||
"generating_gift_card": "Hediye Kartı Oluşturuluyor",
|
||||
"generating_transaction": "İşlem Oluşturma",
|
||||
"get_a": "Bir ",
|
||||
"get_card_note": " dijital ve fiziksel ön ödemeli banka kartı edinin!",
|
||||
"get_your_yat": "Yat'ını al",
|
||||
|
@ -928,6 +931,8 @@
|
|||
"understand": "Anladım",
|
||||
"unlock": "Kilidini aç",
|
||||
"unmatched_currencies": "Mevcut cüzdanınızın para birimi taranan QR ile eşleşmiyor",
|
||||
"unrestricted_background_service": "Sınırsız arka plan hizmeti",
|
||||
"unrestricted_background_service_notice": "Arka plan senkronizasyonunu etkinleştirmek için sınırsız arka plan hizmetini etkinleştirmeniz gerekir",
|
||||
"unspent_change": "Değiştirmek",
|
||||
"unspent_coins_details_title": "Harcanmamış koin detayları",
|
||||
"unspent_coins_title": "Harcanmamış koinler",
|
||||
|
|
|
@ -69,6 +69,7 @@
|
|||
"avg_savings": "Середня економія",
|
||||
"awaitDAppProcessing": "Зачекайте, доки dApp завершить обробку.",
|
||||
"awaiting_payment_confirmation": "Очікується підтвердження платежу",
|
||||
"background_sync": "Фонове синхронізація",
|
||||
"background_sync_mode": "Фоновий режим синхронізації",
|
||||
"backup": "Резервна копія",
|
||||
"backup_file": "Файл резервної копії",
|
||||
|
@ -161,6 +162,7 @@
|
|||
"confirm_passphrase": "Підтвердьте пасфрази",
|
||||
"confirm_sending": "Підтвердити відправлення",
|
||||
"confirm_silent_payments_switch_node": "Ваш поточний вузол не підтримує мовчазні платежі \\ ncake Wallet перейде на сумісний вузол, лише для сканування",
|
||||
"confirm_transaction": "Підтвердити транзакцію",
|
||||
"confirmations": "Підтвердження",
|
||||
"confirmed": "Підтверджений баланс",
|
||||
"confirmed_tx": "Підтверджений",
|
||||
|
@ -344,6 +346,7 @@
|
|||
"gas_exceeds_allowance": "Газ, необхідний транзакціям, перевищує надбавку.",
|
||||
"generate_name": "Згенерувати назву",
|
||||
"generating_gift_card": "Створення подарункової картки",
|
||||
"generating_transaction": "Генерування транзакції",
|
||||
"get_a": "Отримати ",
|
||||
"get_card_note": " яку можна перезавантажувати цифровими валютами. Додаткова інформація не потрібна!",
|
||||
"get_your_yat": "Одержати свій Yat",
|
||||
|
@ -929,6 +932,8 @@
|
|||
"understand": "Зрозуміло",
|
||||
"unlock": "Розблокувати",
|
||||
"unmatched_currencies": "Валюта вашого гаманця не збігається з валютою сканованого QR-коду",
|
||||
"unrestricted_background_service": "Необмежена фонова послуга",
|
||||
"unrestricted_background_service_notice": "Для того, щоб увімкнути фонову синхронізацію, вам потрібно ввімкнути необмежену фонову послугу",
|
||||
"unspent_change": "Зміна",
|
||||
"unspent_coins_details_title": "Відомості про невитрачені монети",
|
||||
"unspent_coins_title": "Невитрачені монети",
|
||||
|
|
|
@ -69,6 +69,7 @@
|
|||
"avg_savings": "اوسط بچت",
|
||||
"awaitDAppProcessing": "۔ﮟﯾﺮﮐ ﺭﺎﻈﺘﻧﺍ ﺎﮐ ﮯﻧﻮﮨ ﻞﻤﮑﻣ ﮓﻨﺴﯿﺳﻭﺮﭘ ﮯﮐ dApp ﻡﺮﮐ ﮦﺍﺮﺑ",
|
||||
"awaiting_payment_confirmation": "ادائیگی کی تصدیق کے منتظر",
|
||||
"background_sync": "پس منظر کی ہم آہنگی",
|
||||
"background_sync_mode": "پس منظر کی مطابقت پذیری کا موڈ",
|
||||
"backup": "بیک اپ",
|
||||
"backup_file": "بیک اپ فائل",
|
||||
|
@ -161,6 +162,7 @@
|
|||
"confirm_passphrase": "پاسفریز کی تصدیق کریں",
|
||||
"confirm_sending": "بھیجنے کی تصدیق کریں۔",
|
||||
"confirm_silent_payments_switch_node": "آپ کا موجودہ نوڈ خاموش ادائیگیوں کی حمایت نہیں کرتا ہے۔",
|
||||
"confirm_transaction": "لین دین کی تصدیق کریں",
|
||||
"confirmations": "تصدیقات",
|
||||
"confirmed": "تصدیق شدہ بیلنس",
|
||||
"confirmed_tx": "تصدیق",
|
||||
|
@ -344,6 +346,7 @@
|
|||
"gas_exceeds_allowance": "لین دین کے ذریعہ درکار گیس الاؤنس سے زیادہ ہے۔",
|
||||
"generate_name": "نام پیدا کریں۔",
|
||||
"generating_gift_card": "گفٹ کارڈ تیار کرنا",
|
||||
"generating_transaction": "ٹرانزیکشن پیدا کرنا",
|
||||
"get_a": "حاصل",
|
||||
"get_card_note": " جسے آپ ڈیجیٹل کرنسیوں کے ساتھ دوبارہ لوڈ کر سکتے ہیں۔ کوئی اضافی معلومات کی ضرورت نہیں!",
|
||||
"get_your_yat": "اپنی Yat حاصل کریں۔",
|
||||
|
@ -930,6 +933,8 @@
|
|||
"understand": "میں سمجھتا ہوں۔",
|
||||
"unlock": "غیر مقفل",
|
||||
"unmatched_currencies": "آپ کے پرس کی موجودہ کرنسی اسکین شدہ QR سے مماثل نہیں ہے۔",
|
||||
"unrestricted_background_service": "غیر محدود پس منظر کی خدمت",
|
||||
"unrestricted_background_service_notice": "پس منظر کی مطابقت پذیری کو قابل بنانے کے ل you آپ کو غیر محدود پس منظر کی خدمت کو فعال کرنے کی ضرورت ہے",
|
||||
"unspent_change": "تبدیل کریں",
|
||||
"unspent_coins_details_title": "غیر خرچ شدہ سککوں کی تفصیلات",
|
||||
"unspent_coins_title": "غیر خرچ شدہ سکے ۔",
|
||||
|
|
|
@ -69,6 +69,7 @@
|
|||
"avg_savings": "Tiết kiệm trung bình",
|
||||
"awaitDAppProcessing": "Vui lòng đợi ứng dụng phi tập trung hoàn thành xử lý.",
|
||||
"awaiting_payment_confirmation": "Đang chờ xác nhận thanh toán",
|
||||
"background_sync": "Đồng bộ nền",
|
||||
"background_sync_mode": "Chế độ đồng bộ nền",
|
||||
"backup": "Sao lưu",
|
||||
"backup_file": "Tập tin sao lưu",
|
||||
|
@ -160,6 +161,7 @@
|
|||
"confirm_passphrase": "Xác nhận cụm mật khẩu",
|
||||
"confirm_sending": "Xác nhận gửi",
|
||||
"confirm_silent_payments_switch_node": "Nút hiện tại của bạn không hỗ trợ thanh toán im lặng\\nCake Wallet sẽ chuyển sang một nút tương thích chỉ để quét",
|
||||
"confirm_transaction": "Xác nhận giao dịch",
|
||||
"confirmations": "Xác nhận",
|
||||
"confirmed": "Số dư đã xác nhận",
|
||||
"confirmed_tx": "Đã xác nhận",
|
||||
|
@ -343,6 +345,7 @@
|
|||
"gas_exceeds_allowance": "Gas theo yêu cầu của giao dịch vượt quá trợ cấp.",
|
||||
"generate_name": "Tạo tên",
|
||||
"generating_gift_card": "Đang tạo thẻ quà tặng",
|
||||
"generating_transaction": "Tạo giao dịch",
|
||||
"get_a": "Nhận một ",
|
||||
"get_card_note": " mà bạn có thể nạp lại bằng tiền điện tử. Không cần thêm thông tin!",
|
||||
"get_your_yat": "Nhận Yat của bạn",
|
||||
|
@ -925,6 +928,8 @@
|
|||
"understand": "Tôi hiểu",
|
||||
"unlock": "Mở khóa",
|
||||
"unmatched_currencies": "Tiền tệ của ví hiện tại của bạn không khớp với QR đã quét",
|
||||
"unrestricted_background_service": "Dịch vụ nền không giới hạn",
|
||||
"unrestricted_background_service_notice": "Để cho phép đồng bộ hóa nền, bạn cần bật dịch vụ nền không giới hạn",
|
||||
"unspent_change": "Tiền thối",
|
||||
"unspent_coins_details_title": "Chi tiết các đồng tiền chưa chi tiêu",
|
||||
"unspent_coins_title": "Các đồng tiền chưa chi tiêu",
|
||||
|
|
|
@ -69,6 +69,7 @@
|
|||
"avg_savings": "Ìpamọ́ l’óòrèkóòrè",
|
||||
"awaitDAppProcessing": "Fi inurere duro fun dApp lati pari sisẹ.",
|
||||
"awaiting_payment_confirmation": "À ń dúró de ìjẹ́rìísí àránṣẹ́",
|
||||
"background_sync": "Imuṣiṣẹ Labẹ",
|
||||
"background_sync_mode": "Ipo amuṣiṣẹpọ abẹlẹ",
|
||||
"backup": "Ṣẹ̀dà",
|
||||
"backup_file": "Ṣẹ̀dà akọsílẹ̀",
|
||||
|
@ -161,6 +162,7 @@
|
|||
"confirm_passphrase": "Jẹrisi kọwe",
|
||||
"confirm_sending": "Jẹ́rìí sí ránṣẹ́",
|
||||
"confirm_silent_payments_switch_node": "Ilode rẹ ti lọwọlọwọ ko ṣe atilẹyin awọn sisanwo ti o dakẹ \\ owet apamọwọ yoo yipada si oju-ọrọ ibaramu, o kan fun Scning",
|
||||
"confirm_transaction": "Jẹrisi iṣowo naa",
|
||||
"confirmations": "Àwọn ẹ̀rí",
|
||||
"confirmed": "A ti jẹ́rìí ẹ̀",
|
||||
"confirmed_tx": "Jẹrisi",
|
||||
|
@ -345,6 +347,7 @@
|
|||
"gas_exceeds_allowance": "Gaasi ti a beere nipasẹ idunadura ju lọ.",
|
||||
"generate_name": "Ṣẹda Orukọ",
|
||||
"generating_gift_card": "À ń dá káàdì ìrajà t'á lò nínú irú kan ìtajà",
|
||||
"generating_transaction": "Ifọwọsi Iṣowo",
|
||||
"get_a": "Gba ",
|
||||
"get_card_note": " t'ẹ lè fikún owó ayélujára. Ẹ kò nílò ìṣofúnni àfikún!",
|
||||
"get_your_yat": "Gba Yat yín",
|
||||
|
@ -929,6 +932,8 @@
|
|||
"understand": "Ó ye mi",
|
||||
"unlock": "Sisalẹ",
|
||||
"unmatched_currencies": "Irú owó ti àpamọ́wọ́ yín kì í ṣe irú ti yíya àmì ìlujá",
|
||||
"unrestricted_background_service": "Iṣẹ ipilẹṣẹ ti ko nilẹ",
|
||||
"unrestricted_background_service_notice": "Ni ibere lati mu ṣiṣẹpọ lẹhin ti o nilo lati ṣiṣẹ iṣẹ iṣẹ ti ko ni ibatan",
|
||||
"unspent_change": "Yipada",
|
||||
"unspent_coins_details_title": "Àwọn owó ẹyọ t'á kò tí ì san",
|
||||
"unspent_coins_title": "Àwọn owó ẹyọ t'á kò tí ì san",
|
||||
|
|
|
@ -69,6 +69,7 @@
|
|||
"avg_savings": "平均储蓄",
|
||||
"awaitDAppProcessing": "请等待 dApp 处理完成。",
|
||||
"awaiting_payment_confirmation": "等待付款确认",
|
||||
"background_sync": "背景同步",
|
||||
"background_sync_mode": "后台同步模式",
|
||||
"backup": "备份",
|
||||
"backup_file": "备份文件",
|
||||
|
@ -161,6 +162,7 @@
|
|||
"confirm_passphrase": "确认密码",
|
||||
"confirm_sending": "确认发送",
|
||||
"confirm_silent_payments_switch_node": "您当前的节点不支持无声付款\\ ncake钱包将切换到兼容节点,仅用于扫描",
|
||||
"confirm_transaction": "确认交易",
|
||||
"confirmations": "确认",
|
||||
"confirmed": "确认余额",
|
||||
"confirmed_tx": "确认的",
|
||||
|
@ -344,6 +346,7 @@
|
|||
"gas_exceeds_allowance": "交易要求的气体超出了津贴。",
|
||||
"generate_name": "生成名称",
|
||||
"generating_gift_card": "生成礼品卡",
|
||||
"generating_transaction": "生成交易",
|
||||
"get_a": "得到一个",
|
||||
"get_card_note": "你可以用数字货币重新加载。不需要额外的信息!",
|
||||
"get_your_yat": "得到你的 Yat",
|
||||
|
@ -928,6 +931,8 @@
|
|||
"understand": "我已知晓",
|
||||
"unlock": "开锁",
|
||||
"unmatched_currencies": "您当前钱包的货币与扫描的 QR 的货币不匹配",
|
||||
"unrestricted_background_service": "不受限制的背景服务",
|
||||
"unrestricted_background_service_notice": "为了启用背景同步,您需要启用无限制的背景服务",
|
||||
"unspent_change": "改变",
|
||||
"unspent_coins_details_title": "未使用代幣詳情",
|
||||
"unspent_coins_title": "未使用的硬幣",
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
{
|
||||
"flutter": "3.24.0"
|
||||
"flutter": "3.27.4"
|
||||
}
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
FROM mcr.microsoft.com/windows/servercore:ltsc2022
|
||||
|
||||
ENV FLUTTER_VERSION=3.24.0
|
||||
ENV FLUTTER_VERSION=3.27.4
|
||||
ENV GIT_VERSION=2.47.1
|
||||
ENV VS_INSTALLED_DIR="C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools"
|
||||
ENV PATH="C:\Users\ContainerAdministrator\.cargo\bin;C:\ProgramData\chocolatey\bin;C:\flutter\flutter\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Users\ContainerAdministrator\AppData\Local\Microsoft\WindowsApps"
|
||||
|
|
|
@ -47,7 +47,7 @@ Future<void> main() async {
|
|||
if (localFilename.endsWith(".xz")) {
|
||||
printV(" extracting $localFilename");
|
||||
final inputStream = InputFileStream(localFilename);
|
||||
final archive = XZDecoder().decodeBuffer(inputStream);
|
||||
final archive = XZDecoder().decodeBytes(inputStream.toUint8List());
|
||||
final outputStream = OutputFileStream(localFilename.replaceAll(".xz", ""));
|
||||
outputStream.writeBytes(archive);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue