diff --git a/.metadata b/.metadata
new file mode 100644
index 000000000..e0236519d
--- /dev/null
+++ b/.metadata
@@ -0,0 +1,10 @@
+# This file tracks properties of this Flutter project.
+# Used by Flutter tool to assess capabilities and perform upgrades etc.
+#
+# This file should be version controlled and should not be manually edited.
+
+version:
+ revision: 20e59316b8b8474554b38493b8ca888794b0234a
+ channel: stable
+
+project_type: app
diff --git a/LICENSE.md b/LICENSE.md
new file mode 100644
index 000000000..ef51a8e6b
--- /dev/null
+++ b/LICENSE.md
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2020 Cake Technologies LLC
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 000000000..e5cc260ba
--- /dev/null
+++ b/README.md
@@ -0,0 +1,5 @@
+# Cake Wallet
+
+The project description, motivation, build scripts, instructions, tests will be added soon (Jan-Feb 2020);
+
+Copyright (c) 2020 Cake Technologies LLC.
\ No newline at end of file
diff --git a/analysis_options.yaml b/analysis_options.yaml
new file mode 100644
index 000000000..4c0b97735
--- /dev/null
+++ b/analysis_options.yaml
@@ -0,0 +1,64 @@
+include: package:pedantic/analysis_options.yaml
+
+analyzer:
+ strong-mode:
+ implicit-casts: false
+ implicit-dynamic: false
+ exclude:
+ - **/*.yaml
+ - build/**
+ - **/*.g.dart
+ - lib/generated/*.dart
+
+linter:
+ rules:
+ - always_declare_return_types
+ - always_specify_types
+ - annotate_overrides
+ - avoid_as
+ - avoid_empty_else
+ - avoid_init_to_null
+ - avoid_return_types_on_setters
+ - await_only_futures
+ - camel_case_types
+ - cancel_subscriptions
+ - close_sinks
+ - comment_references
+ - constant_identifier_names
+ - control_flow_in_finally
+ - empty_catches
+ - empty_constructor_bodies
+ - empty_statements
+ - hash_and_equals
+ - implementation_imports
+ - invariant_booleans
+ - iterable_contains_unrelated_type
+ - library_names
+ - library_prefixes
+ - list_remove_unrelated_type
+ - literal_only_boolean_expressions
+ - non_constant_identifier_names
+ - one_member_abstracts
+ - only_throw_errors
+ - overridden_fields
+ - package_api_docs
+ - package_names
+ - package_prefixed_library_names
+ - parameter_assignments
+ - prefer_final_fields
+ - prefer_final_locals
+ - prefer_is_not_empty
+ - public_member_api_docs
+ - slash_for_doc_comments
+ - sort_constructors_first
+ - sort_unnamed_constructors_first
+ - super_goes_last
+ - test_types_in_equals
+ - throw_in_finally
+ - type_annotate_public_apis
+ - type_init_formals
+ - unawaited_futures
+ - unnecessary_brace_in_string_interp
+ - unnecessary_getters_setters
+ - unrelated_type_equality_checks
+ - valid_regexps
\ No newline at end of file
diff --git a/android/.gitignore b/android/.gitignore
new file mode 100644
index 000000000..bc2100d8f
--- /dev/null
+++ b/android/.gitignore
@@ -0,0 +1,7 @@
+gradle-wrapper.jar
+/.gradle
+/captures/
+/gradlew
+/gradlew.bat
+/local.properties
+GeneratedPluginRegistrant.java
diff --git a/android/app/build.gradle b/android/app/build.gradle
new file mode 100644
index 000000000..878eb27cf
--- /dev/null
+++ b/android/app/build.gradle
@@ -0,0 +1,86 @@
+def localProperties = new Properties()
+def localPropertiesFile = rootProject.file('local.properties')
+if (localPropertiesFile.exists()) {
+ localPropertiesFile.withReader('UTF-8') { reader ->
+ localProperties.load(reader)
+ }
+}
+
+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'
+}
+
+def flutterVersionName = localProperties.getProperty('flutter.versionName')
+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()) {
+ keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
+}
+
+android {
+ compileSdkVersion 28
+
+ lintOptions {
+ disable 'InvalidPackage'
+ }
+
+ defaultConfig {
+ // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
+ applicationId "com.cakewallet.cake_wallet"
+ minSdkVersion 21
+ targetSdkVersion 28
+ versionCode flutterVersionCode.toInteger()
+ versionName flutterVersionName
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+
+ externalNativeBuild {
+ cmake {
+ cppFlags "-std=c++11"
+ arguments '-DANDROID_STL=c++_shared', '-DBUILD_TESTING=OFF'
+ version "3.10.2"
+ }
+ }
+ }
+
+ signingConfigs {
+ release {
+ keyAlias keystoreProperties['keyAlias']
+ keyPassword keystoreProperties['keyPassword']
+ storeFile file(keystoreProperties['storeFile'])
+ storePassword keystoreProperties['storePassword']
+ }
+ }
+ buildTypes {
+ release {
+ signingConfig signingConfigs.release
+
+ minifyEnabled true
+ useProguard true
+
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+flutter {
+ source '../..'
+}
+
+dependencies {
+ testImplementation 'junit:junit:4.12'
+ androidTestImplementation 'androidx.test:runner:1.1.1'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
+}
diff --git a/android/app/proguard-rules.pro b/android/app/proguard-rules.pro
new file mode 100644
index 000000000..d24d7f10a
--- /dev/null
+++ b/android/app/proguard-rules.pro
@@ -0,0 +1,8 @@
+## Flutter wrapper
+-keep class io.flutter.app.** { *; }
+-keep class io.flutter.plugin.** { *; }
+-keep class io.flutter.util.** { *; }
+-keep class io.flutter.view.** { *; }
+-keep class io.flutter.** { *; }
+-keep class io.flutter.plugins.** { *; }
+-dontwarn io.flutter.embedding.**
\ No newline at end of file
diff --git a/android/app/src/debug/AndroidManifest.xml b/android/app/src/debug/AndroidManifest.xml
new file mode 100644
index 000000000..dc767a55d
--- /dev/null
+++ b/android/app/src/debug/AndroidManifest.xml
@@ -0,0 +1,7 @@
+
+
+
+
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
new file mode 100644
index 000000000..86893fd1b
--- /dev/null
+++ b/android/app/src/main/AndroidManifest.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/app/src/main/java/com/cakewallet/cake_wallet/MainActivity.java b/android/app/src/main/java/com/cakewallet/cake_wallet/MainActivity.java
new file mode 100644
index 000000000..69c9866af
--- /dev/null
+++ b/android/app/src/main/java/com/cakewallet/cake_wallet/MainActivity.java
@@ -0,0 +1,13 @@
+package com.cakewallet.cake_wallet;
+
+import android.os.Bundle;
+import io.flutter.app.FlutterActivity;
+import io.flutter.plugins.GeneratedPluginRegistrant;
+
+public class MainActivity extends FlutterActivity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ GeneratedPluginRegistrant.registerWith(this);
+ }
+}
diff --git a/android/app/src/main/res/drawable/launch_background.xml b/android/app/src/main/res/drawable/launch_background.xml
new file mode 100644
index 000000000..304732f88
--- /dev/null
+++ b/android/app/src/main/res/drawable/launch_background.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 000000000..5d9200d0a
Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 000000000..83a98b56d
Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 000000000..c8cbe84dd
Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 000000000..c4352f579
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 000000000..73fe04234
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/android/app/src/main/res/values/styles.xml b/android/app/src/main/res/values/styles.xml
new file mode 100644
index 000000000..00fa4417c
--- /dev/null
+++ b/android/app/src/main/res/values/styles.xml
@@ -0,0 +1,8 @@
+
+
+
+
diff --git a/android/app/src/profile/AndroidManifest.xml b/android/app/src/profile/AndroidManifest.xml
new file mode 100644
index 000000000..dc767a55d
--- /dev/null
+++ b/android/app/src/profile/AndroidManifest.xml
@@ -0,0 +1,7 @@
+
+
+
+
diff --git a/android/build.gradle b/android/build.gradle
new file mode 100644
index 000000000..e0d7ae2c1
--- /dev/null
+++ b/android/build.gradle
@@ -0,0 +1,29 @@
+buildscript {
+ repositories {
+ google()
+ jcenter()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:3.5.0'
+ }
+}
+
+allprojects {
+ repositories {
+ google()
+ jcenter()
+ }
+}
+
+rootProject.buildDir = '../build'
+subprojects {
+ project.buildDir = "${rootProject.buildDir}/${project.name}"
+}
+subprojects {
+ project.evaluationDependsOn(':app')
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
diff --git a/android/gradle.properties b/android/gradle.properties
new file mode 100644
index 000000000..38c8d4544
--- /dev/null
+++ b/android/gradle.properties
@@ -0,0 +1,4 @@
+org.gradle.jvmargs=-Xmx1536M
+android.enableR8=true
+android.useAndroidX=true
+android.enableJetifier=true
diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 000000000..296b146b7
--- /dev/null
+++ b/android/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Fri Jun 23 08:50:38 CEST 2017
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip
diff --git a/android/settings.gradle b/android/settings.gradle
new file mode 100644
index 000000000..5a2f14fb1
--- /dev/null
+++ b/android/settings.gradle
@@ -0,0 +1,15 @@
+include ':app'
+
+def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
+
+def plugins = new Properties()
+def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
+if (pluginsFile.exists()) {
+ pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
+}
+
+plugins.each { name, path ->
+ def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
+ include ":$name"
+ project(":$name").projectDir = pluginDirectory
+}
diff --git a/assets/faq/faq_de.json b/assets/faq/faq_de.json
new file mode 100644
index 000000000..5caeaf422
--- /dev/null
+++ b/assets/faq/faq_de.json
@@ -0,0 +1,58 @@
+[
+ {
+ "question" : "Was ist der Unterschied zwischen verfügbarem Guthaben und vollständigem Guthaben?",
+ "answer" : "Nachdem Sie eine Transaktion getätigt oder Monero erhalten haben, muss die Transaktion noch bestätigt werden. In ungefähr 20 Minuten sollte Ihr \"verfügbares Guthaben\" aktualisiert werden!\nWenn Sie Monero senden, verringert sich manchmal Ihr verfügbares Guthaben um mehr als den Betrag, den Sie gesendet haben. Dies ist normal und zum Schutz Ihrer Privatsphäre erforderlich. Ihr \"vollständiges Gleichgewicht\" sollte in 20 Minuten wieder normal sein.\n"
+ },
+ {
+ "question" : "Wie sende ich Monero an eine Börse, für die eine Zahlungs-ID erforderlich ist?",
+ "answer" : "Tippen Sie auf dem Wallet-Bildschirm auf die Schaltfläche \"Senden\". Kopieren Sie anschließend die Einzahlungsadresse der Börse und fügen Sie sie in das Feld \"Adresse\" ein. Kopieren Sie dann die vom Umtausch bereitgestellte Zahlungs-ID und fügen Sie sie in das Feld Zahlungs-ID ein. Geben Sie zum Schluss den Betrag ein, den Sie senden möchten, und los geht's!\n"
+ },
+ {
+ "question" : "Was kann ich tun, wenn ich beim Senden von Monero an eine Börse vergessen habe, die Zahlungs-ID einzugeben?",
+ "answer" : "Obwohl unser Support Sie bei diesem Problem nicht direkt unterstützen kann, ist es ein sehr häufiges Problem, mit dem die meisten Börsen vertraut sind. Wenden Sie sich einfach an den Support der Börse, erklären Sie, dass Sie vergessen haben, Ihre Zahlungs-ID anzugeben, und senden Sie ihnen dann Ihre Transaktions-ID als Nachweis. Sie finden die Transaktions-ID, indem Sie auf die Transaktion in Ihrem Wallet-Bildschirm tippen.\n"
+ },
+ {
+ "question" : "Was bedeuten \"Samen\" und \"Schlüssel\"?",
+ "answer" : "Ihre Schlüssel verschlüsseln die privaten Informationen in Ihrer Brieftasche und ermöglichen es Ihnen, Münzen auszugeben und eingehende Transaktionen anzuzeigen.\nIhr Startwert ist nur eine Version Ihres privaten Schlüssels, die so geschrieben wurde, dass Sie sie leichter notieren können. Ihr Same und Schlüssel sind tatsächlich dasselbe, nur in verschiedenen Formen!\nGeben Sie niemals Ihren Samen oder Schlüssel an jemanden weiter. Ihr Geld wird gestohlen, wenn Sie Ihren Samen oder Schlüssel herausgeben. Bitte notieren Sie sich jedoch Ihren Samen und bewahren Sie ihn an einem sicheren Ort auf (so können Sie Ihre Brieftasche wiederherstellen, wenn Sie Ihr Telefon verlieren.)\n"
+ },
+ {
+ "question" : "Wie viele Geldbörsen kann ich erstellen?",
+ "answer" : "Es gibt keine Grenzen! Sie können so viele Brieftaschen erstellen, wie Sie möchten.\n"
+ },
+ {
+ "question" : "Wie kann ich meine Brieftasche wiederherstellen?",
+ "answer" : "Tippen Sie auf das Menü •••, wählen Sie „Brieftaschen“ und dann „Brieftasche wiederherstellen“. Geben Sie dann Ihren Startwert (oder Ihre Schlüssel) und optional ein Datum vor der ersten Transaktion in Ihrer Brieftasche ein (dies beschleunigt den Synchronisierungsvorgang) .) Möglicherweise müssen Sie die App 15 bis 30 Minuten geöffnet lassen, um Ihr Portemonnaie vollständig wiederherzustellen.\n"
+ },
+ {
+ "question" : "Was kann ich tun, wenn ich meinen Samen verliere?",
+ "answer" : "Wenn Sie Ihren Samen vergessen haben, haben Sie ihn wahrscheinlich irgendwo aufgeschrieben. Bitte überprüfen Sie Ihre Notizen und schauen Sie sich auf Ihrem Computer um. Wenn Sie es nirgendwo finden, haben Sie möglicherweise Cake Wallet gesichert (in diesem Fall können Sie es aus diesem Backup wiederherstellen.) Wenn keines dieser Probleme auftritt, können wir leider nichts tun.\n"
+ },
+ {
+ "question" : "Sammeln Sie Informationen zu meiner Brieftasche?",
+ "answer" : "Cake Wallet sammelt oder zeichnet keine Informationen über Ihre Brieftasche auf. Ihre Privatsphäre ist uns wichtig.\n"
+ },
+ {
+ "question" : "Kann ich eine Transaktion stornieren?",
+ "answer" : "Sobald eine Transaktion an die Blockchain gesendet wurde, kann sie leider nicht mehr rückgängig gemacht werden. Sie können die Transaktion jederzeit abbrechen, bevor sie gesendet wird. Überprüfen Sie die Adresse daher immer, bevor Sie eine Transaktion senden.\n"
+ },
+ {
+ "question" : "Was sind Subadressen und wie verwende ich sie?",
+ "answer" : "Eine Unteradresse ist im Grunde eine eindeutige Adresse, die Sie jederzeit generieren können. An sie gesendete Münzen landen weiterhin in Ihrer Hauptbrieftasche, aber die Person, die die Münzen sendet, kann Ihre Hauptadresse nicht ermitteln. Unteradressen beginnen immer mit „8“.\nSie können eine neue Unteradresse im Empfangsbildschirm erstellen, indem Sie auf das „+“ neben der Schaltfläche Unteradressen tippen. Geben Sie einen Namen für die Unteradresse ein und tippen Sie auf \"Hinzufügen\". Dann tippen Sie einfach auf den Namen der Subadresse, wenn Sie ihn verwenden möchten!\nWenn Sie paranoid sind, sollten Sie wahrscheinlich jedes Mal, wenn Sie Monero erhalten, eine neue Unteradresse erstellen.\n"
+ },
+ {
+ "question" : "Was ist eine Transaktions-ID?",
+ "answer" : "Ein Transaktions-Hash oder eine Transaktions-ID ist eine eindeutige Methode, um eine Transaktion zu identifizieren. Jede Transaktion hat einen eigenen Hash. Wenn Sie jemandem einen Transaktions-Hash zur Verfügung stellen müssen, gehen Sie einfach zum Hauptbildschirm der Brieftasche, tippen Sie auf die Transaktion, halten Sie im oberen Bereich die Taste gedrückt und wählen Sie Kopieren.\n"
+ },
+ {
+ "question" : "Ich habe meine XMR nicht erhalten! Was kann ich tun?",
+ "answer" : "Wenn Sie Ihren Monero nicht erhalten haben, möchten Sie möglicherweise auf das Menü ••• tippen und auf Reconnect (Neu verbinden) klicken. Wenn dies nicht funktioniert, gehen Sie in das Einstellungsmenü, tippen Sie auf das Feld \"Aktueller Knoten\" und wählen Sie einen Knoten mit einem grünen Punkt daneben aus.\n"
+ },
+ {
+ "question" : "Ich habe in der App keine Münzen aus dem Umtausch erhalten. Was kann ich tun?",
+ "answer" : "Wenn Sie Probleme mit einem Austausch haben, wenden Sie sich am besten an den Austausch. Wir sind eine Partnerschaft mit XMR.TO, Morph und ChangeNow eingegangen. Rufen Sie daher am besten http://xmr.to, http://changenow.io oder http://morphtoken.com auf und wenden Sie sich an deren Support.\n"
+ },
+ {
+ "question" : "Wie kontaktiere ich den Cake Wallet-Support?",
+ "answer" : "Senden Sie eine E-Mail an support@cakewallet.io, schließen Sie sich dem Telegramm unter @cake_wallet an oder twittern Sie @CakeWalletXMR!\n"
+ }
+]
\ No newline at end of file
diff --git a/assets/faq/faq_en.json b/assets/faq/faq_en.json
new file mode 100644
index 000000000..8624b6ee9
--- /dev/null
+++ b/assets/faq/faq_en.json
@@ -0,0 +1,58 @@
+[
+ {
+ "question" : "What’s the difference between Available Balance and Full Balance?",
+ "answer" : "After you make a transaction or receive some Monero, the transaction still needs to be confirmed. In about 20 minutes your available balance should update!\nSometimes, when you send Monero, your available balance will decrease by more than the amount you’ve sent. This is normal, and it’s necessary in order to protect your privacy. Your full balance should be back to normal in 20 minutes.\n"
+ },
+ {
+ "question" : "How do I send Monero to an exchange that requires a Payment ID?",
+ "answer" : "Tap the send button on the Wallet screen. Next, copy the exchange deposit address and paste it into the address box. Then, copy the Payment ID provided by the exchange and paste it into the Payment ID box. Finally, enter the amount you’d like to send, and you’re good to go!\n"
+ },
+ {
+ "question" : "What do I do if I forgot to enter the Payment ID when sending Monero to an exchange?",
+ "answer" : "While our support can’t directly help you with this issue, it’s a very common problem that most exchanges are used to dealing with. Just contact the exchange support, explain that you forgot to include your Payment ID, and then send them your Transaction ID as proof. You can find the Transaction ID by tapping on the transaction in your Wallet screen.\n"
+ },
+ {
+ "question" : "What do \"seed\" and \"keys\" mean?",
+ "answer" : "Your keys encode the private information in your wallet, and are what allow you to spend coins and see incoming transactions.\nYour seed is just a version of your private key written in a way that’s easier for you to write down. Your seed and keys are actually the same thing, just in different forms!\nDO NOT ever give your seed or keys to anyone. Your funds will be stolen if you give out your seed or keys. Please write down your seed, however, and store it in a safe place (this will allow you to restore your wallet if you lose your phone.)\n"
+ },
+ {
+ "question" : "How many wallets can I create?",
+ "answer" : "There is no limit! You can create as many wallets as you want.\n"
+ },
+ {
+ "question" : "How can I restore my wallet?",
+ "answer" : "Tap the ••• menu, select Wallets, and then choose Restore Wallet. Then enter your seed (or your keys), and optionally enter a date before the first transaction in your wallet (this will speed up the syncing process.) You may need to keep the app open for 15-30 minutes in order to completely restore your wallet.\n"
+ },
+ {
+ "question" : "What can I do if I lose my seed?",
+ "answer" : "If you forgot your seed, you likely wrote it down somewhere. Please check your notes and look around on your computer. If you can’t find it anywhere, you may have backed up Cake Wallet (in which case you would be able to restore from that backup.) If none of these work, there is unfortunately nothing that we can do.\n"
+ },
+ {
+ "question" : "Do you collect any information about my wallet?",
+ "answer" : "Cake Wallet DOES NOT collect or record any information about your wallet. We care about your privacy.\n"
+ },
+ {
+ "question" : "Is it possible to reverse a transaction?",
+ "answer" : "Unfortunately, as soon as a transaction has been submitted to the blockchain, there is no way to undo it. You can always cancel the transaction before it’s sent though, so always double-check the address before you send a transaction.\n"
+ },
+ {
+ "question" : "What are subaddresses, and how do I use them?",
+ "answer" : "A subaddress is basically a unique address that you can generate at any time. Coins sent to it will still arrive in your main wallet, but the person sending the coins can’t tell what your main address is. Subaddresses always start with 8.\nYou can make a new subaddress in the Receive screen by tapping the + next to the Subaddresses button. Enter a name for the subaddress and tap Add. Then just tap on the subaddress name when you want to use it!\nIf you’re paranoid, you should probably create a new subaddress every time you receive Monero.\n"
+ },
+ {
+ "question" : "What is a transaction ID?",
+ "answer" : "A transaction hash, or transaction ID, is a unique way to identify any transaction. Each transaction has its own hash. If you need to provide a transaction hash to somebody, just go to the main Wallet screen, tap on the transaction, long-press on the top section, and select Copy.\n"
+ },
+ {
+ "question" : "I didn't receive my XMR! What can I do?",
+ "answer" : "If you didn't receive your Monero, you might want to tap the ••• menu and hit Reconnect. If that doesn't work, go into the settings menu, tap the 'Current Node' box, and select a node with a green dot next to it.\n"
+ },
+ {
+ "question" : "I didn't receive my coins from the exchange in the app. What can I do?",
+ "answer" : "If you're having issues with an exchange, the best option is to contact the exchange itself. We're partnered with XMR.TO, Morph and ChangeNow, so your best bet is to go to http://xmr.to, http://changenow.io, or http://morphtoken.com and contact their support.\n"
+ },
+ {
+ "question" : "How do I contact Cake Wallet support?",
+ "answer" : "Email support@cakewallet.io, join the Telegram at @cake_wallet, or tweet @CakeWalletXMR!\n"
+ }
+]
\ No newline at end of file
diff --git a/assets/faq/faq_es.json b/assets/faq/faq_es.json
new file mode 100644
index 000000000..438592839
--- /dev/null
+++ b/assets/faq/faq_es.json
@@ -0,0 +1,58 @@
+[
+ {
+ "question" : "¿Cuál es la diferencia entre el saldo disponible y el saldo total?",
+ "answer" : "Después de realizar una transacción o recibir algo de Monero, la transacción aún debe confirmarse. ¡En unos 20 minutos su \"saldo disponible\" debería actualizarse!\nA veces, cuando envía Monero, su saldo disponible disminuirá en más de la cantidad que envió. Esto es normal y es necesario para proteger su privacidad. Su \"saldo total\" debería volver a la normalidad en 20 minutos.\n"
+ },
+ {
+ "question" : "¿Cómo envío a Monero a un intercambio que requiere una ID de pago?",
+ "answer" : "Toque el botón \"enviar\" en la pantalla de Wallet. A continuación, copie la dirección de depósito del intercambio y péguela en el cuadro \"dirección\". Luego, copie la ID de pago proporcionada por el intercambio y péguela en el cuadro de ID de pago. Finalmente, ingrese la cantidad que desea enviar, ¡y listo!\n"
+ },
+ {
+ "question" : "¿Qué debo hacer si olvidé ingresar la ID de pago al enviar Monero a un intercambio?",
+ "answer" : "Si bien nuestro soporte no puede ayudarlo directamente con este problema, es un problema muy común que la mayoría de los intercambios están acostumbrados a resolver. Simplemente comuníquese con el soporte del intercambio, explique que olvidó incluir su ID de pago y luego envíeles su ID de transacción como prueba. Puede encontrar la ID de la transacción tocando la transacción en la pantalla de su billetera.\n"
+ },
+ {
+ "question" : "¿Qué significan \"semilla\" y \"claves\"?",
+ "answer" : "Sus claves codifican la información privada en su billetera y son las que le permiten gastar monedas y ver las transacciones entrantes.\nSu semilla es solo una versión de su clave privada escrita de una manera que le resulta más fácil de anotar. ¡Tu semilla y tus llaves son en realidad la misma cosa, solo que en diferentes formas!\nNunca le des tu semilla o llaves a nadie. Sus fondos serán robados si entrega su semilla o llaves. Sin embargo, escriba su semilla y guárdela en un lugar seguro (esto le permitirá restaurar su billetera si pierde su teléfono).\n"
+ },
+ {
+ "question" : "¿Cuántas billeteras puedo crear?",
+ "answer" : "¡No hay límite! Puede crear tantas billeteras como desee.\n"
+ },
+ {
+ "question" : "¿Cómo puedo restaurar mi billetera?",
+ "answer" : "Toque el menú •••, seleccione \"Carteras\", y luego elija \"Restaurar billetera\". Luego ingrese su semilla (o sus claves), y opcionalmente ingrese una fecha antes de la primera transacción en su billetera (esto acelerará el proceso de sincronización .) Es posible que deba mantener la aplicación abierta durante 15-30 minutos para restaurar completamente su billetera.\n"
+ },
+ {
+ "question" : "¿Qué puedo hacer si pierdo mi semilla?",
+ "answer" : "Si olvidó su semilla, probablemente la escribió en alguna parte. Verifique sus notas y mire a su alrededor en su computadora. Si no puede encontrarlo en ninguna parte, es posible que haya realizado una copia de seguridad de Cake Wallet (en cuyo caso podría restaurar desde esa copia de seguridad). Si ninguno de estos funciona, desafortunadamente no hay nada que podamos hacer.\n"
+ },
+ {
+ "question" : "¿Recopila información sobre mi billetera?",
+ "answer" : "Cake Wallet NO recopila ni registra ninguna información sobre su billetera. Nos preocupamos por su privacidad.\n"
+ },
+ {
+ "question" : "¿Es posible revertir una transacción?",
+ "answer" : "Desafortunadamente, tan pronto como se haya enviado una transacción a la cadena de bloques, no hay forma de deshacerla. Sin embargo, siempre puede cancelar la transacción antes de enviarla, así que siempre verifique la dirección antes de enviar una transacción.\n"
+ },
+ {
+ "question" : "¿Qué son las \"subdirecciones\" y cómo las uso?",
+ "answer" : "Una subdirección es básicamente una dirección única que puede generar en cualquier momento. Las monedas que se le envíen seguirán llegando a su billetera principal, pero la persona que envía las monedas no puede decir cuál es su dirección principal. Las subdirecciones siempre comienzan con \"8\".\nPuede hacer una nueva subdirección en la pantalla Recibir tocando el \"+\" al lado del botón Subdirecciones. Ingrese un nombre para la subdirección y toque “Agregar”. Luego, solo toca el nombre de la subdirección cuando quieras usarlo.\nSi eres paranoico, probablemente deberías crear una nueva subdirección cada vez que recibas Monero.\n"
+ },
+ {
+ "question" : "¿Qué es una ID de transacción?",
+ "answer" : "Un hash de transacción, o ID de transacción, es una forma única de identificar cualquier transacción. Cada transacción tiene su propio hash. Si necesita proporcionar un hash de transacción a alguien, simplemente vaya a la pantalla principal de Wallet, toque la transacción, mantenga presionada la sección superior y seleccione Copiar.\n"
+ },
+ {
+ "question" : "¡No recibí mi XMR! ¿Que puedo hacer?",
+ "answer" : "Si no recibió su Monero, puede tocar el menú ••• y presionar Volver a conectar. Si eso no funciona, vaya al menú de configuración, toque el cuadro 'Nodo actual' y seleccione un nodo con un punto verde al lado.\n"
+ },
+ {
+ "question" : "No recibí mis monedas del intercambio en la aplicación. ¿Que puedo hacer?",
+ "answer" : "Si tiene problemas con un intercambio, la mejor opción es ponerse en contacto con el intercambio en sí. Estamos asociados con XMR.TO, Morph y ChangeNow, por lo que su mejor opción es ir a http://xmr.to, http://changenow.io o http://morphtoken.com y contactar a su soporte.\n"
+ },
+ {
+ "question" : "¿Cómo contacto al soporte de Cake Wallet?",
+ "answer" : "¡Envíe un correo electrónico a support@cakewallet.io, únase al Telegram en @cake_wallet o envíe un tweet a @CakeWalletXMR!\n"
+ }
+]
\ No newline at end of file
diff --git a/assets/faq/faq_hi.json b/assets/faq/faq_hi.json
new file mode 100644
index 000000000..e9b87083d
--- /dev/null
+++ b/assets/faq/faq_hi.json
@@ -0,0 +1,58 @@
+[
+ {
+ "question" : "उपलब्ध शेष और पूर्ण शेष के बीच क्या अंतर है?",
+ "answer" : "आपके द्वारा लेन-देन करने या कुछ मोनरो प्राप्त करने के बाद, लेन-देन की पुष्टि करने की आवश्यकता है। लगभग 20 मिनट में आपका \"उपलब्ध शेष\" अपडेट होना चाहिए!\nकभी-कभी, जब आप Monero भेजते हैं, तो आपका उपलब्ध शेष राशि आपके द्वारा भेजी गई राशि से अधिक घट जाएगी। यह सामान्य है, और आपकी गोपनीयता की सुरक्षा के लिए यह आवश्यक है। आपका \"पूर्ण संतुलन\" 20 मिनट में वापस सामान्य हो जाना चाहिए।\n"
+ },
+ {
+ "question" : "मैं एक एक्सचेंज को एक भुगतान आईडी के लिए मोनेरो को कैसे भेजूं?",
+ "answer" : "वॉलेट स्क्रीन पर \"भेजें\" बटन पर टैप करें। इसके बाद, एक्सचेंज के जमा पते को कॉपी करें और इसे \"एड्रेस\" बॉक्स में पेस्ट करें। फिर, एक्सचेंज द्वारा प्रदान की गई भुगतान आईडी को कॉपी करें और भुगतान आईडी बॉक्स में पेस्ट करें। अंत में, वह राशि दर्ज करें जिसे आप भेजना चाहते हैं, और आप जाना चाहते हैं!\n"
+ },
+ {
+ "question" : "यदि मैं एक मुद्रा में मोनरो भेजते समय भुगतान आईडी दर्ज करना भूल गया तो मैं क्या करूँ?",
+ "answer" : "जबकि हमारा समर्थन सीधे इस मुद्दे पर आपकी सहायता नहीं कर सकता है, यह एक बहुत ही आम समस्या है जिससे निपटने के लिए ज्यादातर एक्सचेंजों का उपयोग किया जाता है। एक्सचेंज के समर्थन से संपर्क करें, समझाएं कि आप अपनी भुगतान आईडी को शामिल करना भूल गए हैं, और फिर उन्हें प्रमाण के रूप में अपनी लेन-देन आईडी भेजें। आप अपने वॉलेट स्क्रीन में लेनदेन पर टैप करके ट्रांजेक्शन आईडी पा सकते हैं।\n"
+ },
+ {
+ "question" : "\"बीज\" और \"कुंजियाँ\" का क्या अर्थ है?",
+ "answer" : "आपकी कुंजी आपके बटुए में निजी जानकारी को कूटबद्ध करती है, और जो आपको सिक्के खर्च करने और आने वाले लेनदेन को देखने की अनुमति देती है।\nआपका बीज आपकी निजी कुंजी का एक संस्करण है जो इस तरह से लिखा गया है कि आपको लिखना आसान है। आपके बीज और चाबियाँ वास्तव में एक ही चीज़ हैं, बस अलग-अलग रूपों में!\nकभी भी अपना बीज या चाबी किसी को न दें। यदि आप अपना बीज या चाबियां देते हैं तो आपके धन की चोरी हो जाएगी। कृपया, अपने बीज को नीचे लिखें, और इसे एक सुरक्षित स्थान पर संग्रहीत करें (यदि आप अपना फोन खो देते हैं तो यह आपको अपने बटुए को पुनर्स्थापित करने की अनुमति देगा।)\n"
+ },
+ {
+ "question" : "मैं कितने वॉलेट बना सकता हूं?",
+ "answer" : "कोई सीमा नही है! आप जितने चाहें उतने पर्स बना सकते हैं।\n"
+ },
+ {
+ "question" : "मैं अपना बटुआ कैसे पुनर्स्थापित कर सकता हूं?",
+ "answer" : "••• मेनू पर टैप करें, \"वॉलेट्स\" चुनें, और फिर \"रिस्टोर वॉलेट\" चुनें। फिर अपना बीज (या अपनी चाबियाँ) दर्ज करें, और वैकल्पिक रूप से अपने वॉलेट में पहले लेनदेन से पहले एक तिथि दर्ज करें (यह सिंकिंग प्रक्रिया को गति देगा। ।) आपको अपने वॉलेट को पूरी तरह से बहाल करने के लिए ऐप को 15-30 मिनट तक खुला रखने की आवश्यकता हो सकती है।\n"
+ },
+ {
+ "question" : "अगर मैं अपना बीज खो देता हूं तो मैं क्या कर सकता हूं?",
+ "answer" : "यदि आप अपना बीज भूल गए हैं, तो आप इसे कहीं न कहीं लिख सकते हैं। कृपया अपने नोट्स देखें और अपने कंप्यूटर पर देखें। यदि आप इसे कहीं भी नहीं पा सकते हैं, तो आपने केक वॉलेट का बैकअप ले लिया होगा (जिस स्थिति में आप उस बैकअप से पुनर्स्थापित कर पाएंगे।) यदि इनमें से कोई भी काम नहीं है, तो दुर्भाग्य से ऐसा कुछ भी नहीं है जो हम कर सकते हैं।\n"
+ },
+ {
+ "question" : "क्या आप मेरे बटुए के बारे में कोई जानकारी एकत्र करते हैं?",
+ "answer" : "केक वॉलेट आपके बटुए के बारे में कोई जानकारी एकत्र या रिकॉर्ड नहीं करता है। हमें आपकी गोपनीयता का ख्याल है।\n"
+ },
+ {
+ "question" : "क्या किसी लेनदेन को उल्टा करना संभव है?",
+ "answer" : "दुर्भाग्य से, जैसे ही एक लेन-देन ब्लॉकचैन को सबमिट किया गया है, इसे पूर्ववत करने का कोई तरीका नहीं है। आप इसे भेजे जाने से पहले लेनदेन को हमेशा रद्द कर सकते हैं, इसलिए लेन-देन भेजने से पहले हमेशा पते की दोबारा जांच करें।\n"
+ },
+ {
+ "question" : "\"उप-प्रजातियां\" क्या हैं, और मैं उनका उपयोग कैसे करूं?",
+ "answer" : "एक सबड्रेस मूल रूप से एक अनूठा पता है जिसे आप किसी भी समय उत्पन्न कर सकते हैं। इसके लिए भेजे गए सिक्के अभी भी आपके मुख्य वॉलेट में आएंगे, लेकिन सिक्के भेजने वाला व्यक्ति यह नहीं बता सकता है कि आपका मुख्य पता क्या है। Subaddresses हमेशा \"8\" से शुरू होता है।\nआप Subaddresses बटन के बगल में \"+\" टैप करके प्राप्त स्क्रीन में एक नई उप-प्रसंग बना सकते हैं। सबड्रेस के लिए एक नाम दर्ज करें और \"जोड़ें\" पर टैप करें। फिर जब आप इसका उपयोग करना चाहते हैं तो बस सबड्रेस नाम पर टैप करें!\nयदि आप अपाहिज हैं, तो आपको हर बार मोनरो प्राप्त करने के लिए एक नया सबड्रेस बनाना चाहिए।\n"
+ },
+ {
+ "question" : "लेनदेन आईडी क्या है?",
+ "answer" : "लेन-देन हैश, या लेनदेन आईडी, किसी भी लेनदेन की पहचान करने का एक अनूठा तरीका है। प्रत्येक लेनदेन का अपना हैश होता है। यदि आपको किसी को लेन-देन हैश प्रदान करने की आवश्यकता है, तो बस मुख्य वॉलेट स्क्रीन पर जाएं, लेन-देन पर टैप करें, शीर्ष अनुभाग पर लंबे समय तक दबाएं और प्रतिलिपि का चयन करें।\n"
+ },
+ {
+ "question" : "मैं अपने XMR प्राप्त नहीं किया! मैं क्या कर सकता हूँ?",
+ "answer" : "यदि आपको अपना मोनरो प्राप्त नहीं हुआ, तो आप ••• मेनू पर टैप कर सकते हैं और रीकनेक्ट को हिट कर सकते हैं। यदि वह काम नहीं करता है, तो सेटिंग मेनू में जाएं, 'करंट नोड' बॉक्स पर टैप करें, और उसके बगल में हरे रंग की डॉट के साथ एक नोड चुनें।\n"
+ },
+ {
+ "question" : "मुझे ऐप में एक्सचेंज से मेरे सिक्के नहीं मिले। मैं क्या कर सकता हूँ?",
+ "answer" : "यदि आप एक एक्सचेंज के साथ समस्या कर रहे हैं, तो सबसे अच्छा विकल्प एक्सचेंज से संपर्क करना है। हम XMR.TO, Morph और ChangeNow के साथ भागीदारी कर रहे हैं, इसलिए आपका सबसे अच्छा दांव http://xmr.to, http://changenow.io, या http://morphtoken.com पर जाना है और उनके समर्थन से संपर्क करना है।\n"
+ },
+ {
+ "question" : "मैं केक वॉलेट से कैसे संपर्क करूं?",
+ "answer" : "ईमेल support@cakewallet.io, @cake_wallet पर टेलीग्राम में शामिल हों, या @CakeWalletXMR पर ट्वीट करें!\n"
+ }
+]
\ No newline at end of file
diff --git a/assets/faq/faq_ja.json b/assets/faq/faq_ja.json
new file mode 100644
index 000000000..cdae6aea6
--- /dev/null
+++ b/assets/faq/faq_ja.json
@@ -0,0 +1,58 @@
+[
+ {
+ "question" : "Available BalanceとFull Balanceの違いは何ですか?",
+ "answer" : "取引を行うか、Moneroを受け取った後でも、取引を確認する必要があります。 約20分で「利用可能残高」が更新されます!\nMoneroを送信すると、利用可能な残高が送信した金額よりも少なくなる場合があります。 これは正常な動作であり、プライバシーを保護するために必要です。 「フルバランス」は20分で通常に戻ります。\n"
+ },
+ {
+ "question" : "支払いIDが必要な取引所にMoneroを送信するにはどうすればよいですか?",
+ "answer" : "ウォレット画面の「送信」ボタンをタップします。 次に、取引所のデポジットアドレスをコピーして、「アドレス」ボックスに貼り付けます。 次に、取引所から提供された支払いIDをコピーして、[支払いID]ボックスに貼り付けます。 最後に、送信したい金額を入力すると、準備完了です!\n"
+ },
+ {
+ "question" : "Moneroを取引所に送信するときに支払いIDの入力を忘れた場合はどうすればよいですか?",
+ "answer" : "のサポートはこの問題を直接支援することはできませんが、ほとんどの取引所が対処に慣れている非常に一般的な問題です。交換サポートに連絡し、支払いIDを含めるのを忘れたことを説明してから、証拠としてトランザクションIDを送信してください。ウォレット画面でトランザクションをタップすると、トランザクションIDを見つけることができます。\n"
+ },
+ {
+ "question" : "「シード」と「キー」はどういう意味ですか?",
+ "answer" : "キーはウォレットの個人情報をエンコードし、コインを使って着信トランザクションを確認できるようにします。\nシードは、書きやすいように書かれた秘密鍵の単なるバージョンです。 シードとキーは実際には同じもので、異なる形式になっています!\nシードやキーを誰にも渡さないでください。 シードまたはキーを渡すと、資金が盗まれます。 ただし、シードを書き留めて安全な場所に保管してください(これにより、携帯電話を紛失した場合にウォレットを復元できます。\n"
+ },
+ {
+ "question" : "いくつのウォレットを作成できますか?",
+ "answer" : "制限はありません! ウォレットはいくつでも作成できます。\n"
+ },
+ {
+ "question" : "ウォレットを復元するにはどうすればよいですか?",
+ "answer" : "•••メニューをタップし、「ウォレット」を選択し、「ウォレットの復元」を選択します。次に、シード(またはキー)を入力し、オプションでウォレットの最初のトランザクションの前に日付を入力します(これにより同期プロセスが高速化されます) 。)ウォレットを完全に復元するには、アプリを15〜30分間開いたままにする必要がある場合があります。\n"
+ },
+ {
+ "question" : "種を失ったらどうすればいいですか?",
+ "answer" : "種を忘れた場合は、どこかに書き留めている可能性があります。 のメモを確認して、コンピューターを見てください。 どこにも見つからない場合は、Cake Walletをバックアップしている可能性があります(この場合、そのバックアップから復元できます)。これらのいずれも機能しない場合、残念ながら何もできません。\n"
+ },
+ {
+ "question" : "ウォレットに関する情報を収集しますか?",
+ "answer" : "Cake Walletは、ウォレットに関する情報を収集または記録しません。 私たちはあなたのプライバシーを大切にします。\n"
+ },
+ {
+ "question" : "トランザクションを取り消すことは可能ですか?",
+ "answer" : "残念ながら、トランザクションがブロックチェーンに送信されるとすぐに、元に戻す方法はありません。 ただし、トランザクションは送信前にいつでもキャンセルできます。したがって、トランザクションを送信する前に必ずアドレスを再確認してください。\n"
+ },
+ {
+ "question" : "「サブアドレス」とは何ですか。どのように使用しますか?",
+ "answer" : "サブアドレスは基本的に、いつでも生成できる一意のアドレスです。 送られたコインはメインのウォレットに届きますが、コインを送った人はメインの住所を知ることができません。 サブアドレスは常に「8」で始まります。\n[サブアドレス]ボタンの横にある[+]をタップすると、受信画面で新しいサブアドレスを作成できます。 サブアドレスの名前を入力し、「追加」をタップします。 次に、使用したいサブアドレス名をタップします!\n妄想している場合は、Moneroを受信するたびに新しいサブアドレスを作成する必要があります。\n"
+ },
+ {
+ "question" : "トランザクションIDとは何ですか?",
+ "answer" : "トランザクションハッシュ、またはトランザクションIDは、トランザクションを識別するユニークな方法です。 各トランザクションには独自のハッシュがあります。 誰かにトランザクションハッシュを提供する必要がある場合は、ウォレットのメイン画面に移動し、トランザクションをタップして、上部セクションを長押しし、[コピー]を選択します。\n"
+ },
+ {
+ "question" : "XMRを受け取りませんでした! 私に何ができる?",
+ "answer" : "Moneroを受け取っていない場合は、•••メニューをタップして、[再接続]を押します。 それでもうまくいかない場合は、設定メニューに移動し、「現在のノード」ボックスをタップして、横に緑色の点があるノードを選択します。\n"
+ },
+ {
+ "question" : "アプリの取引所からコインを受け取りませんでした。 私に何ができる?",
+ "answer" : "取引所に問題がある場合、最良の選択肢は取引所自体に連絡することです。 XMR.TO、Morph、ChangeNowと提携しているため、最善の策はhttp://xmr.to、http://changenow.io、またはhttp://morphtoken.comにアクセスしてサポートに連絡することです。\n"
+ },
+ {
+ "question" : "Cake Walletサポートに連絡するにはどうすればよいですか?",
+ "answer" : "support@cakewallet.ioにメールを送信するか、@ cake_walletで電報に参加するか、@ CakeWalletXMRにツイートしてください。\n"
+ }
+]
\ No newline at end of file
diff --git a/assets/faq/faq_ko.json b/assets/faq/faq_ko.json
new file mode 100644
index 000000000..1e2c39b9f
--- /dev/null
+++ b/assets/faq/faq_ko.json
@@ -0,0 +1,58 @@
+[
+ {
+ "question" : "가용 잔액과 전체 잔액의 차이점은 무엇입니까?",
+ "answer" : "거래를하거나 일부 Monero를받은 후에도 거래를 확인해야합니다. 약 20 분 후에“사용 가능한 잔액”이 업데이트됩니다!\n때로는 Monero를 보낼 때 사용 가능한 잔액이 보낸 금액보다 많이 줄어 듭니다. 이는 정상적인 현상이며 개인 정보를 보호하기 위해 필요합니다. \"풀 밸런스\"는 20 분 후에 정상으로 돌아옵니다.\n"
+ },
+ {
+ "question" : "지불 ID가 필요한 거래소에 Monero를 보내려면 어떻게해야합니까?",
+ "answer" : "월렛 화면에서 \"보내기\"버튼을 누릅니다. 그런 다음 교환기 예금 주소를 복사하여 \"주소\"상자에 붙여 넣습니다. 그런 다음 교환에서 제공 한 지불 ID를 복사하여 지불 ID 상자에 붙여 넣으십시오. 마지막으로 송금 할 금액을 입력하면 좋습니다.\n"
+ },
+ {
+ "question" : "Monero를 교환소에 보낼 때 지불 ID를 입력하지 않은 경우 어떻게해야합니까?",
+ "answer" : "의 지원으로이 문제를 직접 해결할 수는 없지만 대부분의 거래소에서 처리하는 데 매우 일반적인 문제입니다. 거래소의 지원팀에 연락하여 결제 ID를 잊어 버렸다고 설명하고 거래 ID를 증거로 보내십시오. 월렛 화면에서 거래를 탭하여 거래 ID를 찾을 수 있습니다.\n"
+ },
+ {
+ "question" : "\"씨\"와 \"키\"는 무엇을 의미합니까?",
+ "answer" : "열쇠는 지갑에 개인 정보를 암호화하여 동전을 사용하고 들어오는 거래를 볼 수있게 해줍니다.\n귀하의 시드는 귀하가 쉽게 기록 할 수있는 방식으로 작성된 개인 키 버전입니다. 당신의 씨앗과 열쇠는 실제로는 다른 형태로 동일합니다!\n씨앗이나 열쇠를 다른 사람에게주지 마십시오. 씨앗이나 열쇠를 내면 자금이 도용됩니다. 그러나 씨앗을 기록하여 안전한 곳에 보관하십시오 (휴대 전화를 분실 한 경우 지갑을 복원 할 수 있습니다).\n"
+ },
+ {
+ "question" : "몇 개의 지갑을 만들 수 있습니까?",
+ "answer" : "제한이 없습니다! 원하는만큼 지갑을 만들 수 있습니다.\n"
+ },
+ {
+ "question" : "지갑을 어떻게 복원 할 수 있습니까?",
+ "answer" : "••• 메뉴를 탭하고 \"월렛\"을 선택한 다음 \"지갑 복원\"을 선택하십시오. 그런 다음 시드 (또는 키)를 입력하고 선택적으로 지갑의 첫 거래 전에 날짜를 입력하십시오 (동기화 속도가 빨라집니다) .) 지갑을 완전히 복원하려면 앱을 15-30 분 동안 열어 두어야합니다.\n"
+ },
+ {
+ "question" : "씨앗을 잃어 버리면 어떻게해야합니까?",
+ "answer" : "씨앗을 잊어 버렸다면 아마 어딘가에 썼을 것입니다. 메모를 확인하고 컴퓨터를 둘러보십시오. 어디에서나 찾을 수 없다면 Cake Wallet을 백업했을 수 있습니다 (이 경우 해당 백업에서 복원 할 수 있습니다). 이러한 작업이 없으면 불행히도 우리가 할 수있는 일이 없습니다.\n"
+ },
+ {
+ "question" : "내 지갑에 대한 정보를 수집합니까?",
+ "answer" : "케이크 지갑은 지갑에 대한 정보를 수집하거나 기록하지 않습니다. 우리는 당신의 프라이버시를 걱정합니다.\n"
+ },
+ {
+ "question" : "거래를 취소 할 수 있습니까?",
+ "answer" : "불행히도, 거래가 블록 체인에 제출 되 자마자 취소 할 수있는 방법이 없습니다. 거래가 전송되기 전에 언제든지 취소 할 수 있으므로 거래를 보내기 전에 항상 주소를 다시 확인하십시오.\n"
+ },
+ {
+ "question" : "하위 주소 란 무엇이며 어떻게 사용합니까?",
+ "answer" : "하위 주소는 기본적으로 언제든지 생성 할 수있는 고유 한 주소입니다. 동전은 여전히 주 지갑에 도착하지만 동전을 보낸 사람은 자신의 주 주소가 무엇인지 알 수 없습니다. 하위 주소는 항상 \"8\"로 시작합니다.\n하위 주소 버튼 옆에있는 \"+\"를 누르면 수신 화면에서 새 하위 주소를 만들 수 있습니다. 하위 주소의 이름을 입력하고 \"추가\"를 누릅니다. 그런 다음 사용하려는 하위 주소 이름을 탭하십시오!\n편집증이라면 Monero를받을 때마다 새 하위 주소를 만들어야합니다.\n"
+ },
+ {
+ "question" : "거래 ID는 무엇입니까?",
+ "answer" : "트랜잭션 해시 또는 트랜잭션 ID는 트랜잭션을 식별하는 고유 한 방법입니다. 각 트랜잭션에는 자체 해시가 있습니다. 누군가에게 거래 해시를 제공해야하는 경우 주 지갑 화면으로 이동하여 거래를 탭하고 상단 섹션을 길게 누른 다음 복사를 선택하십시오.\n"
+ },
+ {
+ "question" : "XMR을받지 못했습니다! 내가 무엇을 할 수 있을지?",
+ "answer" : "Monero를받지 못했다면 ••• 메뉴를 누르고 다시 연결을 누르십시오. 그래도 작동하지 않으면 설정 메뉴로 이동하여 '현재 노드'상자를 누르고 옆에 녹색 점이있는 노드를 선택하십시오.\n"
+ },
+ {
+ "question" : "앱의 거래소에서 동전을받지 못했습니다. 내가 무엇을 할 수 있을지?",
+ "answer" : "교환에 문제가있는 경우 교환기에 연락하는 것이 가장 좋습니다. 우리는 XMR.TO, Morph 및 ChangeNow와 파트너 관계를 맺고 있으므로 가장 좋은 방법은 http://xmr.to, http://changenow.io 또는 http://morphtoken.com으로 이동하여 지원 부서에 문의하는 것입니다.\n"
+ },
+ {
+ "question" : "Cake Wallet 지원팀에 연락하려면 어떻게해야합니까?",
+ "answer" : "support@cakewallet.io로 이메일을 보내거나 @cake_wallet에서 전보에 가입하거나 @CakeWalletXMR을 트윗하십시오!\n"
+ }
+]
\ No newline at end of file
diff --git a/assets/faq/faq_nl.json b/assets/faq/faq_nl.json
new file mode 100644
index 000000000..a080a9bbc
--- /dev/null
+++ b/assets/faq/faq_nl.json
@@ -0,0 +1,58 @@
+[
+ {
+ "question" : "Wat is het verschil tussen beschikbaar saldo en volledig saldo?",
+ "answer" : "Nadat u een transactie heeft uitgevoerd of wat Monero heeft ontvangen, moet de transactie nog worden bevestigd. Over ongeveer 20 minuten zou uw \"beschikbare saldo\" moeten zijn bijgewerkt!\nWanneer u Monero verzendt, daalt uw beschikbare saldo soms met meer dan het bedrag dat u heeft verzonden. Dit is normaal en dit is noodzakelijk om uw privacy te beschermen. Uw \"volledige balans\" zou binnen 20 minuten weer normaal moeten zijn.\n"
+ },
+ {
+ "question" : "Hoe stuur ik Monero naar een beurs die een betalings-ID vereist?",
+ "answer" : "Tik op de knop \"Verzenden\" op het Wallet-scherm. Kopieer vervolgens het stortingsadres van de uitwisseling en plak het in het vak \"adres\". Kopieer vervolgens de betalings-ID van de centrale en plak deze in het vak Betalings-ID. Voer ten slotte het bedrag in dat u wilt verzenden en u bent klaar om te gaan!\n"
+ },
+ {
+ "question" : "Wat moet ik doen als ik ben vergeten de betalings-ID in te voeren wanneer ik Monero naar een beurs stuur?",
+ "answer" : "Hoewel onze ondersteuning u niet rechtstreeks met dit probleem kan helpen, is het een veel voorkomend probleem dat de meeste beurzen gewend zijn aan te pakken. Neem contact op met de ondersteuning van de beurs, leg uit dat u bent vergeten uw betalings-ID op te nemen en stuur ze vervolgens uw transactie-ID als bewijs. U kunt de transactie-ID vinden door op de transactie in uw Wallet-scherm te tikken.\n"
+ },
+ {
+ "question" : "Wat betekenen zaad en sleutels?",
+ "answer" : "Uw sleutels coderen de privé-informatie in uw portemonnee en stellen u in staat munten uit te geven en inkomende transacties te bekijken.\nUw seed is slechts een versie van uw privésleutel die zo is geschreven dat u deze gemakkelijker kunt opschrijven. Je zaad en sleutels zijn eigenlijk hetzelfde, alleen in verschillende vormen!\nGeef NOOIT uw zaad of sleutels aan iemand. Je geld wordt gestolen als je je zaad of sleutels weggeeft. Schrijf uw zaad echter op en bewaar het op een veilige plaats (hiermee kunt u uw portemonnee herstellen als u uw telefoon verliest.)\n"
+ },
+ {
+ "question" : "Hoeveel portefeuilles kan ik maken?",
+ "answer" : "Er is geen limiet! U kunt zoveel portefeuilles maken als u wilt.\n"
+ },
+ {
+ "question" : "Hoe kan ik mijn portemonnee herstellen?",
+ "answer" : "Tik op het ••• menu, selecteer \"Portefeuilles\" en kies vervolgens \"Portemonnee herstellen\". Voer vervolgens uw seed (of uw sleutels) in en voer optioneel een datum in vóór de eerste transactie in uw portefeuille (dit versnelt het synchronisatieproces .) Mogelijk moet u de app 15-30 minuten open houden om uw portemonnee volledig te herstellen.\n"
+ },
+ {
+ "question" : "Wat kan ik doen als ik mijn zaad verlies?",
+ "answer" : "Als je je zaad bent vergeten, heb je het waarschijnlijk ergens opgeschreven. Controleer uw aantekeningen en kijk rond op uw computer. Als je het nergens kunt vinden, heb je misschien een back-up gemaakt van Cake Wallet (in welk geval je in staat zou zijn om vanuit die back-up te herstellen.) Als geen van deze werken, kunnen we helaas niets doen.\n"
+ },
+ {
+ "question" : "Verzamel je informatie over mijn portemonnee?",
+ "answer" : "Cake Wallet verzamelt of registreert GEEN informatie over uw portemonnee. Wij geven om uw privacy.\n"
+ },
+ {
+ "question" : "Is het mogelijk om een transactie ongedaan te maken?",
+ "answer" : "Helaas is het niet mogelijk om een transactie ongedaan te maken zodra een transactie bij de blockchain is ingediend. U kunt de transactie echter altijd annuleren voordat deze wordt verzonden, dus controleer altijd het adres voordat u een transactie verzendt.\n"
+ },
+ {
+ "question" : "Wat zijn \"subadressen\" en hoe gebruik ik deze?",
+ "answer" : "Een subadres is eigenlijk een uniek adres dat u op elk gewenst moment kunt genereren. Munten die er naartoe worden verzonden, komen nog steeds in uw hoofdportemonnee, maar de persoon die de munten verzendt, kan niet zien wat uw hoofdadres is. Subadressen beginnen altijd met \"8\".\nU kunt een nieuw subadres maken in het scherm Ontvangen door te tikken op de \"+\" naast de knop Subadressen. Voer een naam in voor het subadres en tik op \"Toevoegen\". Tik vervolgens op de naam van het subadres wanneer u deze wilt gebruiken!\nAls u paranoïde bent, moet u waarschijnlijk elke keer dat u Monero ontvangt een nieuw subadres maken.\n"
+ },
+ {
+ "question" : "Wat is een transactie-ID?",
+ "answer" : "Een transactie-hash of transactie-ID is een unieke manier om een transactie te identificeren. Elke transactie heeft zijn eigen hash. Als u iemand een transactie-hash moet geven, gaat u gewoon naar het hoofdscherm van Wallet, tikt u op de transactie, drukt u lang op het bovenste gedeelte en selecteert u Kopiëren.\n"
+ },
+ {
+ "question" : "Ik heb mijn XMR niet ontvangen! Wat kan ik doen?",
+ "answer" : "Als u uw Monero niet hebt ontvangen, wilt u misschien op het ••• menu tikken en op Opnieuw verbinden klikken. Als dat niet werkt, gaat u naar het instellingenmenu, tikt u op het vak 'Huidige knooppunt' en selecteert u een knooppunt met een groene stip ernaast.\n"
+ },
+ {
+ "question" : "Ik heb mijn munten niet ontvangen van de beurs in de app. Wat kan ik doen?",
+ "answer" : "Als u problemen ondervindt met een uitwisseling, kunt u het beste contact opnemen met de uitwisseling zelf. We werken samen met XMR.TO, Morph en ChangeNow, dus u kunt het beste naar http://xmr.to, http://changenow.io of http://morphtoken.com gaan en contact opnemen met hun ondersteuning.\n"
+ },
+ {
+ "question" : "Hoe neem ik contact op met Cake Wallet-ondersteuning?",
+ "answer" : "E-mail support@cakewallet.io, word lid van het Telegram op @cake_wallet of tweet @CakeWalletXMR!\n"
+ }
+]
\ No newline at end of file
diff --git a/assets/faq/faq_pl.json b/assets/faq/faq_pl.json
new file mode 100644
index 000000000..a3af8deb6
--- /dev/null
+++ b/assets/faq/faq_pl.json
@@ -0,0 +1,58 @@
+[
+ {
+ "question" : "Jaka jest różnica między dostępnym saldem a pełnym saldem?",
+ "answer" : "Po dokonaniu transakcji lub otrzymaniu Monero transakcja nadal musi zostać potwierdzona. Za około 20 minut Twoje „dostępne saldo” powinno się zaktualizować!\nCzasami po wysłaniu Monero dostępne saldo zmniejsza się o więcej niż kwota wysłana. Jest to normalne i konieczne w celu ochrony Twojej prywatności. Twoja „pełna równowaga” powinna wrócić do normy za 20 minut.\n"
+ },
+ {
+ "question" : "Jak wysłać Monero na giełdę, która wymaga płatności ID?",
+ "answer" : "Naciśnij przycisk „wyślij” na ekranie portfela. Następnie skopiuj adres depozytu giełdy i wklej go w polu „adres”. Następnie skopiuj identyfikator płatności podany przez giełdę i wklej go w polu ID płatności. Na koniec wprowadź kwotę, którą chcesz wysłać, i możesz zacząć!\n"
+ },
+ {
+ "question" : "Co mam zrobić, jeśli zapomniałem wprowadzić ID płatności podczas wysyłania Monero na giełdę?",
+ "answer" : "Chociaż nasze wsparcie nie może bezpośrednio pomóc w rozwiązaniu tego problemu, jest to bardzo częsty problem, z którym korzysta większość giełd. Wystarczy skontaktować się z obsługą giełdy, wyjaśnić, że zapomniałeś podać ID płatności, a następnie przesłać im dowód transakcji. Możesz znaleźć ID transakcji, dotykając transakcji na ekranie portfela.\n"
+ },
+ {
+ "question" : "Co oznaczają słowa „seed” i „keys”?",
+ "answer" : "Twoje klucze kodują prywatne informacje w twoim portfelu i pozwalają wydać monety i zobaczyć przychodzące transakcje.\nTwoje ziarno to tylko wersja twojego klucza prywatnego napisana w sposób, który łatwiej Ci zapisać. Wasze nasiona i klucze są w rzeczywistości takie same, tylko w różnych formach!\nNigdy nie dawaj nikomu swojego ziarna ani kluczy. Twoje fundusze zostaną skradzione, jeśli wydasz swoje nasiona lub klucze. Zapisz jednak swoje ziarno i przechowuj je w bezpiecznym miejscu (pozwoli to przywrócić portfel, jeśli zgubisz telefon).\n"
+ },
+ {
+ "question" : "Ile portfeli mogę utworzyć?",
+ "answer" : "Tu nie ma limitu! Możesz utworzyć dowolną liczbę portfeli.\n"
+ },
+ {
+ "question" : "Jak mogę przywrócić mój portfel?",
+ "answer" : "Stuknij menu •••, wybierz „Portfele”, a następnie „Przywróć portfel”. Następnie wprowadź dane początkowe (lub klucze) i opcjonalnie wprowadź datę przed pierwszą transakcją w portfelu (przyspieszy to proces synchronizacji .) Może być konieczne pozostawienie aplikacji otwartej przez 15-30 minut, aby całkowicie przywrócić portfel.\n"
+ },
+ {
+ "question" : "Co mogę zrobić, jeśli stracę nasiona?",
+ "answer" : "Jeśli zapomniałeś o nasieniu, prawdopodobnie gdzieś je zapisałeś. Sprawdź swoje notatki i rozejrzyj się po komputerze. Jeśli nie możesz go nigdzie znaleźć, być może utworzono kopię zapasową Cake Wallet (w takim przypadku będziesz mógł przywrócić dane z tej kopii zapasowej). Jeśli żadna z tych czynności nie działa, niestety nic nie możemy zrobić.\n"
+ },
+ {
+ "question" : "Czy zbierasz jakieś informacje o moim portfelu?",
+ "answer" : "Portfel Cake NIE gromadzi ani nie rejestruje żadnych informacji o Twoim portfelu. Dbamy o Twoją prywatność.\n"
+ },
+ {
+ "question" : "Czy można cofnąć transakcję?",
+ "answer" : "Niestety, jak tylko transakcja zostanie przesłana do blockchain, nie ma możliwości jej cofnięcia. Zawsze możesz jednak anulować transakcję przed jej wysłaniem, dlatego zawsze dokładnie sprawdź adres przed wysłaniem transakcji.\n"
+ },
+ {
+ "question" : "Co to są „podadresy” i jak z nich korzystać?",
+ "answer" : "Podadres jest w zasadzie unikalnym adresem, który można wygenerować w dowolnym momencie. Monety wysłane do niego nadal będą pojawiać się w głównym portfelu, ale osoba wysyłająca monety nie może podać Twojego głównego adresu. Podadresy zawsze zaczynają się od „8”.\nMożesz utworzyć nowy podadres na ekranie Odbieranie, dotykając „+” obok przycisku Podadresy. Wprowadź nazwę podadresu i dotknij „Dodaj”. Następnie dotknij nazwy podadresu, gdy chcesz go użyć!\nJeśli jesteś paranoikiem, prawdopodobnie za każdym razem, gdy otrzymasz Monero, powinieneś utworzyć nowy podadres.\n"
+ },
+ {
+ "question" : "Co to jest ID transakcji?",
+ "answer" : "Skrót transakcji lub ID transakcji to unikalny sposób identyfikowania każdej transakcji. Każda transakcja ma swój własny skrót. Jeśli chcesz podać komuś skrót transakcji, po prostu przejdź do głównego ekranu Portfela, dotknij transakcji, naciśnij długo w górnej części i wybierz Kopiuj.\n"
+ },
+ {
+ "question" : "Nie otrzymałem mojego XMR! Co mogę zrobić?",
+ "answer" : "Jeśli nie otrzymałeś Monero, możesz dotknąć menu ••• i nacisnąć Połącz ponownie. Jeśli to nie zadziała, przejdź do menu ustawień, dotknij pola „Bieżący węzeł” i wybierz węzeł z zieloną kropką obok niego.\n"
+ },
+ {
+ "question" : "Nie otrzymałem moich monet z wymiany w aplikacji. Co mogę zrobić?",
+ "answer" : "Jeśli masz problemy z wymianą, najlepszym rozwiązaniem jest skontaktowanie się z samą giełdą. Współpracujemy z XMR.TO, Morph i ChangeNow, więc najlepiej postawić się na stronie http://xmr.to, http://changenow.io lub http://morphtoken.com i skontaktować się z ich wsparciem.\n"
+ },
+ {
+ "question" : "Jak skontaktować się z obsługą Cake Wallet?",
+ "answer" : "Wyślij e-mail na adres support@cakewallet.io, dołącz do telegramu na @cake_wallet lub tweet @CakeWalletXMR!\n"
+ }
+]
\ No newline at end of file
diff --git a/assets/faq/faq_pt.json b/assets/faq/faq_pt.json
new file mode 100644
index 000000000..210ec5896
--- /dev/null
+++ b/assets/faq/faq_pt.json
@@ -0,0 +1,58 @@
+[
+ {
+ "question" : "Qual é a diferença entre Saldo disponível e Saldo total?",
+ "answer" : "Depois de fazer uma transação ou receber alguns Monero, a transação ainda precisa ser confirmada. Em cerca de 20 minutos, seu \"saldo disponível\" deve ser atualizado!\nÀs vezes, quando você envia o Monero, seu saldo disponível diminui em mais do que o valor enviado. Isso é normal e é necessário para proteger sua privacidade. Seu \"equilíbrio total\" deve voltar ao normal em 20 minutos.\n"
+ },
+ {
+ "question" : "Como envio o Monero para uma troca que exige um ID de pagamento?",
+ "answer" : "Toque no botão \"enviar\" na tela da Carteira virtual. Em seguida, copie o endereço de depósito da bolsa e cole-o na caixa \"endereço\". Em seguida, copie o ID do pagamento fornecido pela central e cole-o na caixa ID do pagamento. Por fim, insira a quantia que você deseja enviar e pronto!\n"
+ },
+ {
+ "question" : "O que devo fazer se me esquecer do código de pagamento ao enviar o Monero para uma troca?",
+ "answer" : "Embora nosso suporte não possa ajudá-lo diretamente com esse problema, é um problema muito comum com o qual a maioria das trocas está acostumada. Basta entrar em contato com o suporte da bolsa, explicar que você esqueceu de incluir seu ID de pagamento e enviar a ele seu ID de transação como prova. Você pode encontrar o ID da transação tocando na transação na tela da Carteira virtual.\n"
+ },
+ {
+ "question" : "O que significam \"semente\" e \"chaves\"?",
+ "answer" : "Suas chaves codificam as informações privadas da sua carteira e são o que permite gastar moedas e ver as transações recebidas.\nSua semente é apenas uma versão da sua chave privada escrita de uma maneira mais fácil para você escrever. Suas sementes e chaves são na verdade a mesma coisa, apenas em formas diferentes!\nNunca dê sua semente ou chave a ninguém. Seus fundos serão roubados se você der suas sementes ou chaves. No entanto, anote sua semente e guarde-a em um local seguro (isso permitirá que você restaure sua carteira se perder o telefone.)\n"
+ },
+ {
+ "question" : "Quantas carteiras posso criar?",
+ "answer" : "Não há limite! Você pode criar quantas carteiras quiser.\n"
+ },
+ {
+ "question" : "Como posso restaurar minha carteira?",
+ "answer" : "Toque no menu •••, selecione \"Carteiras\" e escolha \"Restaurar carteira\". Em seguida, insira sua semente (ou suas chaves) e, opcionalmente, insira uma data antes da primeira transação na sua carteira (isso acelerará o processo de sincronização .) Pode ser necessário manter o aplicativo aberto por 15 a 30 minutos para restaurar completamente sua carteira.\n"
+ },
+ {
+ "question" : "O que posso fazer se perder minha semente?",
+ "answer" : "Se você esqueceu sua semente, provavelmente a anotou em algum lugar. Por favor, verifique suas anotações e olhe em volta no seu computador. Se você não conseguir encontrá-lo em nenhum lugar, pode ter feito o backup da Cake Wallet (nesse caso, poderá restaurar a partir desse backup.) Se nada disso funcionar, infelizmente não há nada que possamos fazer.\n"
+ },
+ {
+ "question" : "Você coleta alguma informação sobre minha carteira?",
+ "answer" : "Cake Wallet NÃO coleta nem registra nenhuma informação sobre sua carteira. Nós nos preocupamos com sua privacidade.\n"
+ },
+ {
+ "question" : "É possível reverter uma transação?",
+ "answer" : "Infelizmente, assim que uma transação foi enviada ao blockchain, não há como desfazê-lo. No entanto, você sempre pode cancelar a transação antes de ser enviada. Verifique sempre o endereço antes de enviar uma transação.\n"
+ },
+ {
+ "question" : "O que são \"sub-endereços\" e como os usamos?",
+ "answer" : "Um sub-endereço é basicamente um endereço exclusivo que você pode gerar a qualquer momento. As moedas enviadas ainda chegarão à sua carteira principal, mas a pessoa que está enviando as moedas não sabe qual é o seu endereço principal. Os sub-endereços sempre começam com \"8\".\nVocê pode criar um novo sub-endereço na tela Receber, tocando no botão \"+\" ao lado do botão Sub-endereços. Digite um nome para o sub-endereço e toque em \"Adicionar\". Em seguida, basta tocar no nome do sub-endereço quando quiser usá-lo!\nSe você é paranóico, provavelmente deve criar um novo sub-endereço toda vez que receber o Monero.\n"
+ },
+ {
+ "question" : "O que é um ID de transação?",
+ "answer" : "Um hash de transação, ou ID da transação, é uma maneira exclusiva de identificar qualquer transação. Cada transação possui seu próprio hash. Se você precisar fornecer um hash de transação a alguém, vá para a tela principal da Carteira virtual, toque na transação, pressione e segure na seção superior e selecione Copiar.\n"
+ },
+ {
+ "question" : "Não recebi meu XMR! O que eu posso fazer?",
+ "answer" : "Se você não recebeu seu Monero, toque no menu ••• e clique em Reconectar. Se isso não funcionar, entre no menu de configurações, toque na caixa 'Nó atual' e selecione um nó com um ponto verde próximo a ele.\n"
+ },
+ {
+ "question" : "Não recebi minhas moedas da troca no aplicativo. O que eu posso fazer?",
+ "answer" : "Se você estiver tendo problemas com uma troca, a melhor opção é entrar em contato com a troca. Somos parceiros do XMR.TO, Morph e ChangeNow, portanto, sua melhor aposta é ir para http://xmr.to, http://changenow.io ou http://morphtoken.com e entrar em contato com o suporte deles.\n"
+ },
+ {
+ "question" : "Como entro em contato com o suporte da Cake Wallet?",
+ "answer" : "Envie um e-mail para support@cakewallet.io, participe do Telegram em @cake_wallet ou envie um tweet para @CakeWalletXMR!\n"
+ }
+]
\ No newline at end of file
diff --git a/assets/faq/faq_ru.json b/assets/faq/faq_ru.json
new file mode 100644
index 000000000..77b1bf53e
--- /dev/null
+++ b/assets/faq/faq_ru.json
@@ -0,0 +1,58 @@
+[
+ {
+ "question" : "В чем разница между доступным балансом и полным балансом?",
+ "answer" : "После того, как вы совершите транзакцию или получите какой-либо Monero, транзакция все еще нуждается в подтверждении. Примерно через 20 минут ваш «доступный баланс» должен обновиться.\nИногда, когда вы отправляете Monero, ваш доступный баланс уменьшается более чем на сумму, которую вы отправили. Это нормально и необходимо для защиты вашей конфиденциальности. Ваш «полный баланс» должен вернуться к норме через 20 минут.\n"
+ },
+ {
+ "question" : "Как отправить Monero на обмен, для которого требуется идентификатор платежа?",
+ "answer" : "Нажмите кнопку «Отправить» на экране кошелька. Затем скопируйте адрес депозита биржи и вставьте его в поле «адрес». Затем скопируйте идентификатор платежа, предоставленный провайдером обмена и вставьте его в поле идентификатора платежа. Затем ведите сумму, которую вы хотите отправить и все готово!\n"
+ },
+ {
+ "question" : "Что мне делать, если я забыл ввести идентификатор платежа при отправке Monero на обмен?",
+ "answer" : "Хотя наша поддержка не может напрямую помочь вам в этом вопросе, это очень распространенная проблема, с которой большинство бирж привыкли иметь дело. Просто свяжитесь со службой поддержки провайдера обмена и объясните, что вы забыли указать свой идентификатор платежа, а затем отправьте им свой идентификатор транзакции в качестве доказательства. Вы можете найти идентификатор транзакции, нажав на транзакцию на экране своего кошелька.\n"
+ },
+ {
+ "question" : "Что означают «семена» и «ключи»?",
+ "answer" : "Ваши ключи кодируют личную информацию в вашем кошельке и позволяют вам тратить монеты и видеть входящие транзакции.Ваше семя (код-фраза) - это просто версия вашего личного ключа, написанная так, чтобы вам было легче ее записать. Ваше семя и ключи на самом деле одно и то же, только в разных формах! Никому не передавайте свою код-фразу или ключи иначе ваши средства могут быть украдены. Однако, пожалуйста, запишите их и храните в безопасном месте (это позволит вам восстановить свой кошелек, если вы потеряете свой телефон.)\n"
+ },
+ {
+ "question" : "Сколько кошельков я могу создать?",
+ "answer" : "Там нет предела! Вы можете создать столько кошельков, сколько захотите.\n"
+ },
+ {
+ "question" : "Как я могу восстановить свой кошелек?",
+ "answer" : "Коснитесь ••• меню, выберите «Кошельки», а затем выберите «Восстановить кошелек». Затем введите свою код-фразу (или ключи) и при необходимости введите дату до первой транзакции в вашем кошельке (это ускорит процесс синхронизации .) Вам может понадобиться держать приложение открытым в течение 15-30 минут, чтобы полностью восстановить свой кошелек.\n"
+ },
+ {
+ "question" : "Что мне делать, если я потеряю свою код-фразу?",
+ "answer" : "Если вы забыли свою код-фразу, вы вероятно, где-то записали ее. Пожалуйста, проверьте свои заметки и осмотрите свой компьютер. Если вы нигде не можете найти ее, возможно, вы создали резервную копию Cake Wallet (в этом случае вы сможете восстановить данные из этой резервной копии.) К сожалению если вышеуказанные способы вам не помогли, мы ничего не можем сделать.\n"
+ },
+ {
+ "question" : "Собираете ли вы какую-либо информацию о моем кошельке?",
+ "answer" : "Cake Wallet не собирает и не записывает какую-либо информацию о вашем кошельке. Мы заботимся о вашей конфиденциальности.\n"
+ },
+ {
+ "question" : "Возможно ли отменить транзакцию?",
+ "answer" : "К сожалению, как только транзакция была передана в блокчейн, отменить ее невозможно. Вы всегда можете отменить транзакцию до ее отправки, поэтому всегда дважды проверяйте адрес перед отправкой транзакции.\n"
+ },
+ {
+ "question" : "Что такое «сабадреса» и как их использовать?",
+ "answer" : "Сабадрес - это уникальный адрес, который вы можете сгенерировать в любое время. Монеты, отправленные на него, все равно поступят на ваш основной кошелек, но человек отправляющий монеты, не может узнать ваш основной адрес. Сабадреса всегда начинаются с «8».\nВы можете создать новый сабадрес на экране получения, нажав «+» рядом с кнопкой «Сабадреса». Введите имя для дополнительного адреса и нажмите «Добавить». Затем просто нажмите на имя сабадреса, когда вы хотите его использовать!\nЕсли вы переживаете за конфединциальность, вероятно вам следует создавать новый сабадрес каждый раз, когда вы хотите получить Monero.\n"
+ },
+ {
+ "question" : "Что такое ID транзакции?",
+ "answer" : "Хэш транзакции (или ID транзакции), является уникальным способом идентификации любой транзакции. Каждая транзакция имеет свой ID. Если вам нужно предоставить ID транзакции кому-то, просто перейдите на главный экран кошелька, нажмите на транзакцию, нажмите и удерживайте поле с ID транзакции для копирования.\n"
+ },
+ {
+ "question" : "Я не получил свои XMR! Что я могу сделать?",
+ "answer" : "Если вы не получили Monero, вы можете нажать ••• меню и нажать «Переподключиться». Если это не сработает, перейдите в меню настроек, коснитесь поля «Текущий узел» и выберите узел с зеленой точкой рядом с ним.\n"
+ },
+ {
+ "question" : "Я не получил свои монеты после обмена в приложении. Что я могу сделать?",
+ "answer" : "Если у вас возникли проблемы с обменом, лучше всего связаться с провайдером обмена. Мы сотрудничаем с XMR.TO, Morph и ChangeNow, поэтому вам лучше всего зайти на http://xmr.to, http://changenow.io или http://morphtoken.com и связаться с их поддержкой.\n"
+ },
+ {
+ "question" : "Как мне связаться со службой поддержки Cake Wallet?",
+ "answer" : "По электронной почте support@cakewallet.io, присоединитесь к Telegram по адресу @cake_wallet или отправьте твит @CakeWalletXMR!\n"
+ }
+]
\ No newline at end of file
diff --git a/assets/faq/faq_zh.json b/assets/faq/faq_zh.json
new file mode 100644
index 000000000..1f9d3242a
--- /dev/null
+++ b/assets/faq/faq_zh.json
@@ -0,0 +1,58 @@
+[
+ {
+ "question" : "可用余额和全额余额有什么区别?",
+ "answer" : "在您进行交易或收到一些门罗币后,仍然需要确认交易。 在大约20分钟内,您的“可用余额”应该会更新!\n有时,当您发送Monero时,可用余额会减少,超过所发送的金额。 这是正常现象,因此有必要保护您的隐私。 您的“全部余额”应在20分钟内恢复正常。\n"
+ },
+ {
+ "question" : "如何将Monero发送到需要付款ID的交易所?",
+ "answer" : "点击电子钱包屏幕上的“发送”按钮。 接下来,复制交易所的存款地址,并将其粘贴到“地址”框中。 然后,复制交易所提供的付款ID,并将其粘贴到“付款ID”框中。 最后,输入您要发送的金额,一切顺利!\n"
+ },
+ {
+ "question" : "如果将Monero发送到交易所时忘记输入付款ID,该怎么办?",
+ "answer" : "尽管我们的支持无法直接为您解决此问题,但大多数交易所都习惯于处理这个非常普遍的问题。 只需联系交易所的支持人员,说明您忘记包含付款ID,然后将其交易ID发送给他们即可作为证明。 您可以通过在电子钱包屏幕中点击交易找到交易ID。\n"
+ },
+ {
+ "question" : "“种子”和“钥匙”是什么意思?",
+ "answer" : "您的密钥对钱包中的私人信息进行编码,这些密钥使您可以花费硬币并查看传入的交易。\n您的种子只是私钥的一种版本,以更容易记下来的方式编写。 您的种子和密钥实际上是同一件事,只是形式不同!\n永远不要将您的种子或钥匙交给任何人。 如果您提供种子或钥匙,您的资金将被盗。 但是,请写下您的种子,并将其存储在安全的地方(如果您丢失手机,这将使您可以恢复钱包。)\n"
+ },
+ {
+ "question" : "我可以创建多少个钱包?",
+ "answer" : "没有限制! 您可以根据需要创建任意数量的钱包。\n"
+ },
+ {
+ "question" : "如何恢复我的钱包?",
+ "answer" : "点击•••菜单,选择“钱包”,然后选择“还原钱包”。然后输入您的种子(或密钥),还可以选择在您的钱包中进行第一笔交易之前输入日期(这将加快同步过程) 。)您可能需要将应用保持打开状态15-30分钟,以完全恢复您的钱包。\n"
+ },
+ {
+ "question" : "如果我种下种子了怎么办?",
+ "answer" : "如果您忘记了种子,则可能将其写下来。 请检查笔记并在计算机上四处张望。 如果您在任何地方都找不到它,则可能已经备份了Cake Wallet(在这种情况下,您可以从该备份中还原。)如果这些都不起作用,那么很遗憾,我们无能为力。\n"
+ },
+ {
+ "question" : "您是否收集有关我的钱包的任何信息?",
+ "answer" : "Cake Wallet不会收集或记录有关您钱包的任何信息。 我们关心您的隐私。\n"
+ },
+ {
+ "question" : "是否可以撤消交易?",
+ "answer" : "不幸的是,一旦将交易提交到区块链,就无法撤消它。 不过,您始终可以在发送交易之前取消交易,因此请务必在发送交易之前仔细检查地址。\n"
+ },
+ {
+ "question" : "什么是“子地址”,我该如何使用它们?",
+ "answer" : "子地址基本上是您可以随时生成的唯一地址。 发送给它的硬币仍然会到达您的主钱包中,但是发送硬币的人无法告知您的主要地址是什么。 子地址始终以“ 8”开头。\n您可以通过点击“子地址”按钮旁边的“ +”在“接收”屏幕中创建一个新的子地址。 输入子地址的名称,然后点击“添加”。 然后,当您要使用子地址名称时,只需点击它即可!\n如果您偏执狂,您可能应该在每次收到门罗币时创建一个新的子地址。\n"
+ },
+ {
+ "question" : "什么是交易编号?",
+ "answer" : "交易哈希或交易ID是识别任何交易的唯一方式。 每个交易都有自己的哈希。 如果您需要向某人提供交易哈希,只需转到电子钱包主屏幕,点击交易,长按顶部,然后选择复制。\n"
+ },
+ {
+ "question" : "我没有收到我的XMR! 我能做什么?",
+ "answer" : "如果您未收到门罗币,则可能需要点击•••菜单,然后点击重新连接。 如果这不起作用,请进入设置菜单,点击“当前节点”框,然后选择旁边带有绿点的节点。\n"
+ },
+ {
+ "question" : "我没有从应用程序中的交易所收到硬币。 我能做什么?",
+ "answer" : "如果您对交易所有疑问,最好的选择是与交易所本身联系。 我们与XMR.TO,Morph和ChangeNow合作,因此最好的选择是访问http://xmr.to、http://changenow.io或http://morphtoken.com,并与他们的支持部门联系。\n"
+ },
+ {
+ "question" : "如何联系蛋糕钱包支持?",
+ "answer" : "电子邮件support@cakewallet.io,通过@cake_wallet加入电报,或在@CakeWalletXMR上发布推文!\n"
+ }
+]
\ No newline at end of file
diff --git a/assets/fonts/Lato-Bold.ttf b/assets/fonts/Lato-Bold.ttf
new file mode 100644
index 000000000..ef5ae3b43
Binary files /dev/null and b/assets/fonts/Lato-Bold.ttf differ
diff --git a/assets/fonts/Lato-Regular.ttf b/assets/fonts/Lato-Regular.ttf
new file mode 100644
index 000000000..adbfc467d
Binary files /dev/null and b/assets/fonts/Lato-Regular.ttf differ
diff --git a/assets/fonts/Lato-Semibold.ttf b/assets/fonts/Lato-Semibold.ttf
new file mode 100644
index 000000000..60ac82d65
Binary files /dev/null and b/assets/fonts/Lato-Semibold.ttf differ
diff --git a/assets/images/2.0x/Telegram.png b/assets/images/2.0x/Telegram.png
new file mode 100644
index 000000000..b8f8cce3d
Binary files /dev/null and b/assets/images/2.0x/Telegram.png differ
diff --git a/assets/images/2.0x/Twitter.png b/assets/images/2.0x/Twitter.png
new file mode 100644
index 000000000..642e8eb72
Binary files /dev/null and b/assets/images/2.0x/Twitter.png differ
diff --git a/assets/images/2.0x/arrow_bottom_cake_green.png b/assets/images/2.0x/arrow_bottom_cake_green.png
new file mode 100644
index 000000000..67c523951
Binary files /dev/null and b/assets/images/2.0x/arrow_bottom_cake_green.png differ
diff --git a/assets/images/2.0x/back_arrow.png b/assets/images/2.0x/back_arrow.png
new file mode 100644
index 000000000..065eecf7f
Binary files /dev/null and b/assets/images/2.0x/back_arrow.png differ
diff --git a/assets/images/2.0x/back_arrow_dark_theme.png b/assets/images/2.0x/back_arrow_dark_theme.png
new file mode 100644
index 000000000..f1e790fcd
Binary files /dev/null and b/assets/images/2.0x/back_arrow_dark_theme.png differ
diff --git a/assets/images/2.0x/bitmap.png b/assets/images/2.0x/bitmap.png
new file mode 100644
index 000000000..b08091847
Binary files /dev/null and b/assets/images/2.0x/bitmap.png differ
diff --git a/assets/images/2.0x/cake_arrow.png b/assets/images/2.0x/cake_arrow.png
new file mode 100644
index 000000000..cb72693ce
Binary files /dev/null and b/assets/images/2.0x/cake_arrow.png differ
diff --git a/assets/images/2.0x/cake_logo.png b/assets/images/2.0x/cake_logo.png
new file mode 100644
index 000000000..c464cdcd4
Binary files /dev/null and b/assets/images/2.0x/cake_logo.png differ
diff --git a/assets/images/2.0x/change_now.png b/assets/images/2.0x/change_now.png
new file mode 100644
index 000000000..37593c419
Binary files /dev/null and b/assets/images/2.0x/change_now.png differ
diff --git a/assets/images/2.0x/close_button.png b/assets/images/2.0x/close_button.png
new file mode 100644
index 000000000..8e74c751f
Binary files /dev/null and b/assets/images/2.0x/close_button.png differ
diff --git a/assets/images/2.0x/close_button_dark_theme.png b/assets/images/2.0x/close_button_dark_theme.png
new file mode 100644
index 000000000..9fd5cb080
Binary files /dev/null and b/assets/images/2.0x/close_button_dark_theme.png differ
diff --git a/assets/images/2.0x/delete_icon.png b/assets/images/2.0x/delete_icon.png
new file mode 100644
index 000000000..8d5889f8a
Binary files /dev/null and b/assets/images/2.0x/delete_icon.png differ
diff --git a/assets/images/2.0x/keysIco.png b/assets/images/2.0x/keysIco.png
new file mode 100644
index 000000000..00c2879a6
Binary files /dev/null and b/assets/images/2.0x/keysIco.png differ
diff --git a/assets/images/2.0x/qr_code_icon.png b/assets/images/2.0x/qr_code_icon.png
new file mode 100644
index 000000000..c8b121d10
Binary files /dev/null and b/assets/images/2.0x/qr_code_icon.png differ
diff --git a/assets/images/2.0x/qr_icon.png b/assets/images/2.0x/qr_icon.png
new file mode 100644
index 000000000..6c448bcc2
Binary files /dev/null and b/assets/images/2.0x/qr_icon.png differ
diff --git a/assets/images/2.0x/refresh_icon.png b/assets/images/2.0x/refresh_icon.png
new file mode 100644
index 000000000..b7cf225a6
Binary files /dev/null and b/assets/images/2.0x/refresh_icon.png differ
diff --git a/assets/images/2.0x/restoreSeed.png b/assets/images/2.0x/restoreSeed.png
new file mode 100644
index 000000000..c25928f6c
Binary files /dev/null and b/assets/images/2.0x/restoreSeed.png differ
diff --git a/assets/images/2.0x/seedIco.png b/assets/images/2.0x/seedIco.png
new file mode 100644
index 000000000..650f2fe05
Binary files /dev/null and b/assets/images/2.0x/seedIco.png differ
diff --git a/assets/images/2.0x/seedKeys.png b/assets/images/2.0x/seedKeys.png
new file mode 100644
index 000000000..10bee8b37
Binary files /dev/null and b/assets/images/2.0x/seedKeys.png differ
diff --git a/assets/images/2.0x/seed_image.png b/assets/images/2.0x/seed_image.png
new file mode 100644
index 000000000..795b0aba5
Binary files /dev/null and b/assets/images/2.0x/seed_image.png differ
diff --git a/assets/images/2.0x/welcomeImg.png b/assets/images/2.0x/welcomeImg.png
new file mode 100644
index 000000000..d4c76fc4f
Binary files /dev/null and b/assets/images/2.0x/welcomeImg.png differ
diff --git a/assets/images/2.0x/xmr_btc.png b/assets/images/2.0x/xmr_btc.png
new file mode 100644
index 000000000..1a68e24cf
Binary files /dev/null and b/assets/images/2.0x/xmr_btc.png differ
diff --git a/assets/images/3.0x/Telegram.png b/assets/images/3.0x/Telegram.png
new file mode 100644
index 000000000..a5d85fd53
Binary files /dev/null and b/assets/images/3.0x/Telegram.png differ
diff --git a/assets/images/3.0x/Twitter.png b/assets/images/3.0x/Twitter.png
new file mode 100644
index 000000000..6a6b5f3a8
Binary files /dev/null and b/assets/images/3.0x/Twitter.png differ
diff --git a/assets/images/3.0x/arrow_bottom_cake_green.png b/assets/images/3.0x/arrow_bottom_cake_green.png
new file mode 100644
index 000000000..d37dccf71
Binary files /dev/null and b/assets/images/3.0x/arrow_bottom_cake_green.png differ
diff --git a/assets/images/3.0x/back_arrow.png b/assets/images/3.0x/back_arrow.png
new file mode 100644
index 000000000..b5b7fde8e
Binary files /dev/null and b/assets/images/3.0x/back_arrow.png differ
diff --git a/assets/images/3.0x/back_arrow_dark_theme.png b/assets/images/3.0x/back_arrow_dark_theme.png
new file mode 100644
index 000000000..724ed23f2
Binary files /dev/null and b/assets/images/3.0x/back_arrow_dark_theme.png differ
diff --git a/assets/images/3.0x/bitmap.png b/assets/images/3.0x/bitmap.png
new file mode 100644
index 000000000..337bcf027
Binary files /dev/null and b/assets/images/3.0x/bitmap.png differ
diff --git a/assets/images/3.0x/cake_arrow.png b/assets/images/3.0x/cake_arrow.png
new file mode 100644
index 000000000..b92ec35c0
Binary files /dev/null and b/assets/images/3.0x/cake_arrow.png differ
diff --git a/assets/images/3.0x/cake_logo.png b/assets/images/3.0x/cake_logo.png
new file mode 100644
index 000000000..5da47a539
Binary files /dev/null and b/assets/images/3.0x/cake_logo.png differ
diff --git a/assets/images/3.0x/change_now.png b/assets/images/3.0x/change_now.png
new file mode 100644
index 000000000..ac2d564e3
Binary files /dev/null and b/assets/images/3.0x/change_now.png differ
diff --git a/assets/images/3.0x/close_button.png b/assets/images/3.0x/close_button.png
new file mode 100644
index 000000000..ad9586348
Binary files /dev/null and b/assets/images/3.0x/close_button.png differ
diff --git a/assets/images/3.0x/close_button_dark_theme.png b/assets/images/3.0x/close_button_dark_theme.png
new file mode 100644
index 000000000..98482a870
Binary files /dev/null and b/assets/images/3.0x/close_button_dark_theme.png differ
diff --git a/assets/images/3.0x/delete_icon.png b/assets/images/3.0x/delete_icon.png
new file mode 100644
index 000000000..c3d8b990b
Binary files /dev/null and b/assets/images/3.0x/delete_icon.png differ
diff --git a/assets/images/3.0x/keysIco.png b/assets/images/3.0x/keysIco.png
new file mode 100644
index 000000000..a44186dcc
Binary files /dev/null and b/assets/images/3.0x/keysIco.png differ
diff --git a/assets/images/3.0x/qr_code_icon.png b/assets/images/3.0x/qr_code_icon.png
new file mode 100644
index 000000000..918041c04
Binary files /dev/null and b/assets/images/3.0x/qr_code_icon.png differ
diff --git a/assets/images/3.0x/qr_icon.png b/assets/images/3.0x/qr_icon.png
new file mode 100644
index 000000000..a9e8e604a
Binary files /dev/null and b/assets/images/3.0x/qr_icon.png differ
diff --git a/assets/images/3.0x/refresh_icon.png b/assets/images/3.0x/refresh_icon.png
new file mode 100644
index 000000000..9ccb8f171
Binary files /dev/null and b/assets/images/3.0x/refresh_icon.png differ
diff --git a/assets/images/3.0x/restoreSeed.png b/assets/images/3.0x/restoreSeed.png
new file mode 100644
index 000000000..8fc5b1f14
Binary files /dev/null and b/assets/images/3.0x/restoreSeed.png differ
diff --git a/assets/images/3.0x/seedIco.png b/assets/images/3.0x/seedIco.png
new file mode 100644
index 000000000..174a943b6
Binary files /dev/null and b/assets/images/3.0x/seedIco.png differ
diff --git a/assets/images/3.0x/seedKeys.png b/assets/images/3.0x/seedKeys.png
new file mode 100644
index 000000000..50b31c2e8
Binary files /dev/null and b/assets/images/3.0x/seedKeys.png differ
diff --git a/assets/images/3.0x/seed_image.png b/assets/images/3.0x/seed_image.png
new file mode 100644
index 000000000..0431af18d
Binary files /dev/null and b/assets/images/3.0x/seed_image.png differ
diff --git a/assets/images/3.0x/welcomeImg.png b/assets/images/3.0x/welcomeImg.png
new file mode 100644
index 000000000..d78387d67
Binary files /dev/null and b/assets/images/3.0x/welcomeImg.png differ
diff --git a/assets/images/3.0x/xmr_btc.png b/assets/images/3.0x/xmr_btc.png
new file mode 100644
index 000000000..241831594
Binary files /dev/null and b/assets/images/3.0x/xmr_btc.png differ
diff --git a/assets/images/Telegram.png b/assets/images/Telegram.png
new file mode 100644
index 000000000..e734ab987
Binary files /dev/null and b/assets/images/Telegram.png differ
diff --git a/assets/images/Twitter.png b/assets/images/Twitter.png
new file mode 100644
index 000000000..4821abfd3
Binary files /dev/null and b/assets/images/Twitter.png differ
diff --git a/assets/images/address_book_icon.png b/assets/images/address_book_icon.png
new file mode 100644
index 000000000..0e9219814
Binary files /dev/null and b/assets/images/address_book_icon.png differ
diff --git a/assets/images/app_logo.png b/assets/images/app_logo.png
new file mode 100644
index 000000000..4540659cf
Binary files /dev/null and b/assets/images/app_logo.png differ
diff --git a/assets/images/arrow_bottom_cake_green.png b/assets/images/arrow_bottom_cake_green.png
new file mode 100644
index 000000000..594eb7de2
Binary files /dev/null and b/assets/images/arrow_bottom_cake_green.png differ
diff --git a/assets/images/arrow_bottom_purple_icon.png b/assets/images/arrow_bottom_purple_icon.png
new file mode 100644
index 000000000..5a0d5918d
Binary files /dev/null and b/assets/images/arrow_bottom_purple_icon.png differ
diff --git a/assets/images/back_arrow.png b/assets/images/back_arrow.png
new file mode 100644
index 000000000..30e599b3f
Binary files /dev/null and b/assets/images/back_arrow.png differ
diff --git a/assets/images/back_arrow_dark_theme.png b/assets/images/back_arrow_dark_theme.png
new file mode 100644
index 000000000..e78cf34c8
Binary files /dev/null and b/assets/images/back_arrow_dark_theme.png differ
diff --git a/assets/images/bitmap.png b/assets/images/bitmap.png
new file mode 100644
index 000000000..525522b3f
Binary files /dev/null and b/assets/images/bitmap.png differ
diff --git a/assets/images/cake_arrow.png b/assets/images/cake_arrow.png
new file mode 100644
index 000000000..26648d373
Binary files /dev/null and b/assets/images/cake_arrow.png differ
diff --git a/assets/images/cake_logo.png b/assets/images/cake_logo.png
new file mode 100644
index 000000000..fb5267a79
Binary files /dev/null and b/assets/images/cake_logo.png differ
diff --git a/assets/images/change_now.png b/assets/images/change_now.png
new file mode 100644
index 000000000..132525743
Binary files /dev/null and b/assets/images/change_now.png differ
diff --git a/assets/images/close_button.png b/assets/images/close_button.png
new file mode 100644
index 000000000..50d31ed5e
Binary files /dev/null and b/assets/images/close_button.png differ
diff --git a/assets/images/close_button_dark_theme.png b/assets/images/close_button_dark_theme.png
new file mode 100644
index 000000000..a5334a9a2
Binary files /dev/null and b/assets/images/close_button_dark_theme.png differ
diff --git a/assets/images/delete_icon.png b/assets/images/delete_icon.png
new file mode 100644
index 000000000..0abb30292
Binary files /dev/null and b/assets/images/delete_icon.png differ
diff --git a/assets/images/exchange_icon.png b/assets/images/exchange_icon.png
new file mode 100644
index 000000000..47db4c585
Binary files /dev/null and b/assets/images/exchange_icon.png differ
diff --git a/assets/images/keysIco.png b/assets/images/keysIco.png
new file mode 100644
index 000000000..16e73a4b8
Binary files /dev/null and b/assets/images/keysIco.png differ
diff --git a/assets/images/more.png b/assets/images/more.png
new file mode 100644
index 000000000..6b1a916ff
Binary files /dev/null and b/assets/images/more.png differ
diff --git a/assets/images/paste_button.png b/assets/images/paste_button.png
new file mode 100644
index 000000000..c856c8e72
Binary files /dev/null and b/assets/images/paste_button.png differ
diff --git a/assets/images/qr_code_icon.png b/assets/images/qr_code_icon.png
new file mode 100644
index 000000000..ad1b3631e
Binary files /dev/null and b/assets/images/qr_code_icon.png differ
diff --git a/assets/images/qr_icon.png b/assets/images/qr_icon.png
new file mode 100644
index 000000000..ea0c1eea6
Binary files /dev/null and b/assets/images/qr_icon.png differ
diff --git a/assets/images/receive_icon.png b/assets/images/receive_icon.png
new file mode 100755
index 000000000..8701cc643
Binary files /dev/null and b/assets/images/receive_icon.png differ
diff --git a/assets/images/receive_icon_raw.png b/assets/images/receive_icon_raw.png
new file mode 100644
index 000000000..741ed4e4f
Binary files /dev/null and b/assets/images/receive_icon_raw.png differ
diff --git a/assets/images/refresh_icon.png b/assets/images/refresh_icon.png
new file mode 100644
index 000000000..65e9e06ee
Binary files /dev/null and b/assets/images/refresh_icon.png differ
diff --git a/assets/images/restoreSeed.png b/assets/images/restoreSeed.png
new file mode 100644
index 000000000..a51ea1193
Binary files /dev/null and b/assets/images/restoreSeed.png differ
diff --git a/assets/images/seedIco.png b/assets/images/seedIco.png
new file mode 100644
index 000000000..d40fe1f2f
Binary files /dev/null and b/assets/images/seedIco.png differ
diff --git a/assets/images/seedKeys.png b/assets/images/seedKeys.png
new file mode 100644
index 000000000..7cdc42d3f
Binary files /dev/null and b/assets/images/seedKeys.png differ
diff --git a/assets/images/seed_image.png b/assets/images/seed_image.png
new file mode 100644
index 000000000..7399c38cc
Binary files /dev/null and b/assets/images/seed_image.png differ
diff --git a/assets/images/send_icon.png b/assets/images/send_icon.png
new file mode 100755
index 000000000..e9774c4a7
Binary files /dev/null and b/assets/images/send_icon.png differ
diff --git a/assets/images/settings_icon.png b/assets/images/settings_icon.png
new file mode 100644
index 000000000..cf6f55053
Binary files /dev/null and b/assets/images/settings_icon.png differ
diff --git a/assets/images/transaction_incoming.png b/assets/images/transaction_incoming.png
new file mode 100644
index 000000000..76356e161
Binary files /dev/null and b/assets/images/transaction_incoming.png differ
diff --git a/assets/images/transaction_outgoing.png b/assets/images/transaction_outgoing.png
new file mode 100644
index 000000000..8a28ae6fc
Binary files /dev/null and b/assets/images/transaction_outgoing.png differ
diff --git a/assets/images/wallet_icon.png b/assets/images/wallet_icon.png
new file mode 100644
index 000000000..793ac22d0
Binary files /dev/null and b/assets/images/wallet_icon.png differ
diff --git a/assets/images/welcomeImg.png b/assets/images/welcomeImg.png
new file mode 100644
index 000000000..419f61a80
Binary files /dev/null and b/assets/images/welcomeImg.png differ
diff --git a/assets/images/x.png b/assets/images/x.png
new file mode 100755
index 000000000..2c89f94c8
Binary files /dev/null and b/assets/images/x.png differ
diff --git a/assets/images/xmr_btc.png b/assets/images/xmr_btc.png
new file mode 100644
index 000000000..858664265
Binary files /dev/null and b/assets/images/xmr_btc.png differ
diff --git a/assets/node_list.yml b/assets/node_list.yml
new file mode 100644
index 000000000..70c114f57
--- /dev/null
+++ b/assets/node_list.yml
@@ -0,0 +1,25 @@
+-
+ uri: xmr-node-uk.cakewallet.com:18081
+ is_default: true
+-
+ uri: eu-node.cakewallet.io:18081
+ login: cake
+ password: public_node
+ is_default: false
+-
+ uri: node.cakewallet.io:18081
+ login: cake
+ password: public_node
+ is_default: false
+-
+ uri: node.moneroworld.com:18089
+ is_default: false
+-
+ uri: node.xmr.pt:18081
+ is_default: false
+-
+ uri: node.xmr.ru:13666
+ is_default: false
+-
+ uri: opennode.xmr-tw.org:18089
+ is_default: false
\ No newline at end of file
diff --git a/assets/text/Terms_of_Use.txt b/assets/text/Terms_of_Use.txt
new file mode 100644
index 000000000..b5cd5a4a5
--- /dev/null
+++ b/assets/text/Terms_of_Use.txt
@@ -0,0 +1,25 @@
+1. Use of Cake Wallet
+The Cake Wallet app (hereinafter, referred to as the "App") allows the use of accessing the Monero Blockchain/network. You are not authorized, and nor should you rely on the App for legal advice, business advice, or advice of any kind. You act at your own risk in reliance on the contents of the App. Should you make a decision to act or not act you should contact a licensed attorney in the relevant jurisdiction in which you want or need help. In no way are the owners of, or contributors to, the App responsible for the actions, decisions, or other behavior taken or not taken by you in reliance upon the App.
+2. Translations
+The App may contain translations of the English version of the content available on the App. These translations are provided only as a convenience. In the event of any conflict between the English language version and the translated version, the English language version shall take precedence. If you notice any inconsistency, please report them on GitHub.
+3. Risks related to the use of Cake Wallet.
+The App, the App’s owner Cake Technologies LLC and Cake Technologies owners, partners, employees, contributors, and any affiliates will not be responsible for any losses, damages or claims arising from events falling within the scope of the following five categories:
+1. (1) Mistakes made by the user of any Monero-related software or service, e.g., forgotten passwords, payments sent to wrong Monero addresses, and accidental deletion of wallets.
+2. (2) Software problems of the App and/or any Monero-related software or service, e.g., corrupted wallet file, incorrectly constructed transactions, unsafe cryptographic libraries, malware affecting the App and/or any Monero-related software or service.
+3. (3) Technical failures in the hardware of the user of any Monero-related software or service, e.g., data loss due to a faulty or damaged storage device.
+4. (4) Security problems experienced by the user of any Monero-related software or service, e.g., unauthorized access to users' wallets and/or accounts.
+5. (5) Actions or inactions of third parties and/or events experienced by third parties, e.g., bankruptcy of service providers, information security attacks on service providers, and fraud conducted by third parties.
+4. Investment risks
+The investment in Monero can lead to loss of money over short or even long periods. The investors in Monero should expect prices to have large range fluctuations.
+5. Compliance with tax obligations
+The users of the App are solely responsible to determinate what, if any, taxes apply to their Monero transactions. The owners of, or contributors to, the App are NOT responsible for determining the taxes that apply to Monero transactions.
+6. The App does not store, send, or receive Moneros
+The App does not store, send or receive Monero. This is because Monero exists only by virtue of the ownership record maintained in the Monero network. Any transfer of title in Moneros occurs within a decentralized Monero network, and not on the App.
+7. No warranties
+The App is provided on an "as is" basis without any warranties of any kind regarding the App and/or any content, data, materials and/or services provided on the App.
+8. Limitation of liability
+Unless otherwise required by law, in no event shall the owners of, or contributors to, the App be liable for any damages of any kind, including, but not limited to, loss of use, loss of profits, or loss of data arising out of or in any way connected with the use of the App.
+9. Arbitration
+The user of the App agrees to arbitrate any dispute arising from or in connection with the App or this disclaimer, except for disputes related to copyrights, logos, trademarks, trade names, trade secrets or patents.
+10. Last amendment
+This disclaimer was amended for the last time on January 15, 2018.
\ No newline at end of file
diff --git a/cw_monero/.gitignore b/cw_monero/.gitignore
new file mode 100644
index 000000000..c8bb78494
--- /dev/null
+++ b/cw_monero/.gitignore
@@ -0,0 +1,11 @@
+.DS_Store
+.dart_tool/
+
+.packages
+.pub/
+
+build/
+
+ios/External/
+android/.externalNativeBuild/
+android/.cxx/
\ No newline at end of file
diff --git a/cw_monero/.metadata b/cw_monero/.metadata
new file mode 100644
index 000000000..36ba765ff
--- /dev/null
+++ b/cw_monero/.metadata
@@ -0,0 +1,10 @@
+# This file tracks properties of this Flutter project.
+# Used by Flutter tool to assess capabilities and perform upgrades etc.
+#
+# This file should be version controlled and should not be manually edited.
+
+version:
+ revision: 798e4272a2e43d7daab75f225a13442e384ee0cd
+ channel: dev
+
+project_type: plugin
diff --git a/cw_monero/CHANGELOG.md b/cw_monero/CHANGELOG.md
new file mode 100644
index 000000000..41cc7d819
--- /dev/null
+++ b/cw_monero/CHANGELOG.md
@@ -0,0 +1,3 @@
+## 0.0.1
+
+* TODO: Describe initial release.
diff --git a/cw_monero/LICENSE b/cw_monero/LICENSE
new file mode 100644
index 000000000..ba75c69f7
--- /dev/null
+++ b/cw_monero/LICENSE
@@ -0,0 +1 @@
+TODO: Add your license here.
diff --git a/cw_monero/README.md b/cw_monero/README.md
new file mode 100644
index 000000000..8a79e0360
--- /dev/null
+++ b/cw_monero/README.md
@@ -0,0 +1,14 @@
+# cw_monero
+
+A new flutter plugin project.
+
+## Getting Started
+
+This project is a starting point for a Flutter
+[plug-in package](https://flutter.dev/developing-packages/),
+a specialized package that includes platform-specific implementation code for
+Android and/or iOS.
+
+For help getting started with Flutter, view our
+[online documentation](https://flutter.dev/docs), which offers tutorials,
+samples, guidance on mobile development, and a full API reference.
diff --git a/cw_monero/android/.gitignore b/cw_monero/android/.gitignore
new file mode 100644
index 000000000..c6cbe562a
--- /dev/null
+++ b/cw_monero/android/.gitignore
@@ -0,0 +1,8 @@
+*.iml
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
+/captures
diff --git a/cw_monero/android/CMakeLists.txt b/cw_monero/android/CMakeLists.txt
new file mode 100644
index 000000000..0b812409b
--- /dev/null
+++ b/cw_monero/android/CMakeLists.txt
@@ -0,0 +1,218 @@
+cmake_minimum_required(VERSION 3.4.1)
+
+add_library( cw_monero
+ SHARED
+ ./jni/monero_jni.cpp
+ ../ios/Classes/monero_api.cpp)
+
+ find_library( log-lib log )
+
+set(CMAKE_BUILD_TYPE Debug)
+
+set(EXTERNAL_LIBS_DIR ${CMAKE_SOURCE_DIR}/../ios/External/android)
+
+############
+# libsodium
+############
+
+add_library(sodium STATIC IMPORTED)
+set_target_properties(sodium PROPERTIES IMPORTED_LOCATION
+ ${EXTERNAL_LIBS_DIR}/libsodium/lib/${ANDROID_ABI}/libsodium.a)
+
+############
+# OpenSSL
+############
+
+add_library(crypto STATIC IMPORTED)
+set_target_properties(crypto PROPERTIES IMPORTED_LOCATION
+ ${EXTERNAL_LIBS_DIR}/openssl/lib/${ANDROID_ABI}/libcrypto.a)
+
+add_library(ssl STATIC IMPORTED)
+set_target_properties(ssl PROPERTIES IMPORTED_LOCATION
+ ${EXTERNAL_LIBS_DIR}/openssl/lib/${ANDROID_ABI}/libssl.a)
+
+############
+# Boost
+############
+
+add_library(boost_chrono STATIC IMPORTED)
+set_target_properties(boost_chrono PROPERTIES IMPORTED_LOCATION
+ ${EXTERNAL_LIBS_DIR}/boost/lib/${ANDROID_ABI}/libboost_chrono.a)
+
+add_library(boost_date_time STATIC IMPORTED)
+set_target_properties(boost_date_time PROPERTIES IMPORTED_LOCATION
+ ${EXTERNAL_LIBS_DIR}/boost/lib/${ANDROID_ABI}/libboost_date_time.a)
+
+add_library(boost_filesystem STATIC IMPORTED)
+set_target_properties(boost_filesystem PROPERTIES IMPORTED_LOCATION
+ ${EXTERNAL_LIBS_DIR}/boost/lib/${ANDROID_ABI}/libboost_filesystem.a)
+
+add_library(boost_program_options STATIC IMPORTED)
+set_target_properties(boost_program_options PROPERTIES IMPORTED_LOCATION
+ ${EXTERNAL_LIBS_DIR}/boost/lib/${ANDROID_ABI}/libboost_program_options.a)
+
+add_library(boost_regex STATIC IMPORTED)
+set_target_properties(boost_regex PROPERTIES IMPORTED_LOCATION
+ ${EXTERNAL_LIBS_DIR}/boost/lib/${ANDROID_ABI}/libboost_regex.a)
+
+add_library(boost_serialization STATIC IMPORTED)
+set_target_properties(boost_serialization PROPERTIES IMPORTED_LOCATION
+ ${EXTERNAL_LIBS_DIR}/boost/lib/${ANDROID_ABI}/libboost_serialization.a)
+
+add_library(boost_system STATIC IMPORTED)
+set_target_properties(boost_system PROPERTIES IMPORTED_LOCATION
+ ${EXTERNAL_LIBS_DIR}/boost/lib/${ANDROID_ABI}/libboost_system.a)
+
+add_library(boost_thread STATIC IMPORTED)
+set_target_properties(boost_thread PROPERTIES IMPORTED_LOCATION
+ ${EXTERNAL_LIBS_DIR}/boost/lib/${ANDROID_ABI}/libboost_thread.a)
+
+add_library(boost_wserialization STATIC IMPORTED)
+set_target_properties(boost_wserialization PROPERTIES IMPORTED_LOCATION
+ ${EXTERNAL_LIBS_DIR}/boost/lib/${ANDROID_ABI}/libboost_wserialization.a)
+
+#############
+# Monero
+#############
+
+add_library(wallet_api STATIC IMPORTED)
+set_target_properties(wallet_api PROPERTIES IMPORTED_LOCATION
+ ${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libwallet_api.a)
+
+add_library(wallet STATIC IMPORTED)
+set_target_properties(wallet PROPERTIES IMPORTED_LOCATION
+ ${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libwallet.a)
+
+add_library(cryptonote_core STATIC IMPORTED)
+set_target_properties(cryptonote_core PROPERTIES IMPORTED_LOCATION
+ ${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libcryptonote_core.a)
+
+add_library(cryptonote_basic STATIC IMPORTED)
+set_target_properties(cryptonote_basic PROPERTIES IMPORTED_LOCATION
+ ${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libcryptonote_basic.a)
+
+add_library(mnemonics STATIC IMPORTED)
+set_target_properties(mnemonics PROPERTIES IMPORTED_LOCATION
+ ${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libmnemonics.a)
+
+add_library(common STATIC IMPORTED)
+set_target_properties(common PROPERTIES IMPORTED_LOCATION
+ ${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libcommon.a)
+
+add_library(cncrypto STATIC IMPORTED)
+set_target_properties(cncrypto PROPERTIES IMPORTED_LOCATION
+ ${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libcncrypto.a)
+
+add_library(ringct STATIC IMPORTED)
+set_target_properties(ringct PROPERTIES IMPORTED_LOCATION
+ ${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libringct.a)
+
+add_library(ringct_basic STATIC IMPORTED)
+set_target_properties(ringct_basic PROPERTIES IMPORTED_LOCATION
+ ${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libringct_basic.a)
+
+add_library(blockchain_db STATIC IMPORTED)
+set_target_properties(blockchain_db PROPERTIES IMPORTED_LOCATION
+ ${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libblockchain_db.a)
+
+add_library(lmdb STATIC IMPORTED)
+set_target_properties(lmdb PROPERTIES IMPORTED_LOCATION
+ ${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/liblmdb.a)
+
+add_library(easylogging STATIC IMPORTED)
+set_target_properties(easylogging PROPERTIES IMPORTED_LOCATION
+ ${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libeasylogging.a)
+
+add_library(unbound STATIC IMPORTED)
+set_target_properties(unbound PROPERTIES IMPORTED_LOCATION
+ ${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libunbound.a)
+
+add_library(epee STATIC IMPORTED)
+set_target_properties(epee PROPERTIES IMPORTED_LOCATION
+ ${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libepee.a)
+
+add_library(blocks STATIC IMPORTED)
+set_target_properties(blocks PROPERTIES IMPORTED_LOCATION
+ ${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libblocks.a)
+
+add_library(checkpoints STATIC IMPORTED)
+set_target_properties(checkpoints PROPERTIES IMPORTED_LOCATION
+ ${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libcheckpoints.a)
+
+add_library(device STATIC IMPORTED)
+set_target_properties(device PROPERTIES IMPORTED_LOCATION
+ ${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libdevice.a)
+
+add_library(device_trezor STATIC IMPORTED)
+set_target_properties(device_trezor PROPERTIES IMPORTED_LOCATION
+ ${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libdevice_trezor.a)
+
+add_library(multisig STATIC IMPORTED)
+set_target_properties(multisig PROPERTIES IMPORTED_LOCATION
+ ${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libmultisig.a)
+
+add_library(version STATIC IMPORTED)
+set_target_properties(version PROPERTIES IMPORTED_LOCATION
+ ${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libversion.a)
+
+add_library(net STATIC IMPORTED)
+set_target_properties(net PROPERTIES IMPORTED_LOCATION
+ ${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libnet.a)
+
+add_library(hardforks STATIC IMPORTED)
+set_target_properties(hardforks PROPERTIES IMPORTED_LOCATION
+ ${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libhardforks.a)
+
+add_library(randomx STATIC IMPORTED)
+set_target_properties(randomx PROPERTIES IMPORTED_LOCATION
+ ${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/librandomx.a)
+
+add_library(rpc_base STATIC IMPORTED)
+set_target_properties(rpc_base PROPERTIES IMPORTED_LOCATION
+ ${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/librpc_base.a)
+
+include_directories( ${EXTERNAL_LIBS_DIR}/monero/include )
+
+target_link_libraries( cw_monero
+
+ wallet_api
+ wallet
+ cryptonote_core
+ cryptonote_basic
+ mnemonics
+ ringct
+ ringct_basic
+ net
+ common
+ cncrypto
+ blockchain_db
+ lmdb
+ easylogging
+ unbound
+ epee
+ blocks
+ checkpoints
+ device
+ device_trezor
+ multisig
+ version
+ randomx
+ hardforks
+ rpc_base
+
+ boost_chrono
+ boost_date_time
+ boost_filesystem
+ boost_program_options
+ boost_regex
+ boost_serialization
+ boost_system
+ boost_thread
+ boost_wserialization
+
+ ssl
+ crypto
+
+ sodium
+
+ ${log-lib} )
\ No newline at end of file
diff --git a/cw_monero/android/build.gradle b/cw_monero/android/build.gradle
new file mode 100644
index 000000000..ed8c40213
--- /dev/null
+++ b/cw_monero/android/build.gradle
@@ -0,0 +1,51 @@
+group 'com.cakewallet.monero'
+version '1.0-SNAPSHOT'
+
+buildscript {
+ ext.kotlin_version = '1.3.50'
+ repositories {
+ google()
+ jcenter()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:3.5.0'
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ }
+}
+
+rootProject.allprojects {
+ repositories {
+ google()
+ jcenter()
+ }
+}
+
+apply plugin: 'com.android.library'
+apply plugin: 'kotlin-android'
+
+android {
+ compileSdkVersion 28
+
+ sourceSets {
+ main.java.srcDirs += 'src/main/kotlin'
+ }
+ defaultConfig {
+ minSdkVersion 21
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ }
+ lintOptions {
+ disable 'InvalidPackage'
+ }
+ externalNativeBuild {
+ // Encapsulates your CMake build configurations.
+ cmake {
+ // Provides a relative path to your CMake build script.
+ path "CMakeLists.txt"
+ }
+ }
+}
+
+dependencies {
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
+}
diff --git a/cw_monero/android/gradle.properties b/cw_monero/android/gradle.properties
new file mode 100644
index 000000000..38c8d4544
--- /dev/null
+++ b/cw_monero/android/gradle.properties
@@ -0,0 +1,4 @@
+org.gradle.jvmargs=-Xmx1536M
+android.enableR8=true
+android.useAndroidX=true
+android.enableJetifier=true
diff --git a/cw_monero/android/gradle/wrapper/gradle-wrapper.properties b/cw_monero/android/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 000000000..019065d1d
--- /dev/null
+++ b/cw_monero/android/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip
diff --git a/cw_monero/android/jni/monero_jni.cpp b/cw_monero/android/jni/monero_jni.cpp
new file mode 100644
index 000000000..83e06a41f
--- /dev/null
+++ b/cw_monero/android/jni/monero_jni.cpp
@@ -0,0 +1,74 @@
+#include
+#include
+#include "../../ios/Classes/monero_api.h"
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+JNIEXPORT void JNICALL
+Java_com_cakewallet_monero_MoneroApi_setNodeAddressJNI(
+ JNIEnv *env,
+ jobject inst,
+ jstring uri,
+ jstring login,
+ jstring password,
+ jboolean use_ssl,
+ jboolean is_light_wallet) {
+ const char *_uri = env->GetStringUTFChars(uri, 0);
+ const char *_login = "";
+ const char *_password = "";
+ char *error;
+
+ if (login != NULL) {
+ _login = env->GetStringUTFChars(login, 0);
+ }
+
+ if (password != NULL) {
+ _password = env->GetStringUTFChars(password, 0);
+ }
+ char *__uri = (char*) _uri;
+ char *__login = (char*) _login;
+ char *__password = (char*) _password;
+ bool inited = setup_node(__uri, __login, __password, false, false, error);
+
+ if (!inited) {
+ env->ThrowNew(env->FindClass("java/lang/Exception"), error);
+ }
+}
+
+JNIEXPORT void JNICALL
+Java_com_cakewallet_monero_MoneroApi_connectToNodeJNI(
+ JNIEnv *env,
+ jobject inst) {
+ char *error;
+ bool is_connected = connect_to_node(error);
+
+ if (!is_connected) {
+ env->ThrowNew(env->FindClass("java/lang/Exception"), error);
+ }
+}
+
+JNIEXPORT void JNICALL
+Java_com_cakewallet_monero_MoneroApi_startSyncJNI(
+ JNIEnv *env,
+ jobject inst) {
+ start_refresh();
+}
+
+JNIEXPORT void JNICALL
+Java_com_cakewallet_monero_MoneroApi_loadWalletJNI(
+ JNIEnv *env,
+ jobject inst,
+ jstring path,
+ jstring password) {
+ char *_path = (char *) env->GetStringUTFChars(path, 0);
+ char *_password = (char *) env->GetStringUTFChars(password, 0);
+
+ load_wallet(_path, _password, 0);
+}
+
+#ifdef __cplusplus
+}
+#endif
\ No newline at end of file
diff --git a/cw_monero/android/settings.gradle b/cw_monero/android/settings.gradle
new file mode 100644
index 000000000..1f9e2a39d
--- /dev/null
+++ b/cw_monero/android/settings.gradle
@@ -0,0 +1 @@
+rootProject.name = 'cw_monero'
diff --git a/cw_monero/android/src/main/AndroidManifest.xml b/cw_monero/android/src/main/AndroidManifest.xml
new file mode 100644
index 000000000..8152415a2
--- /dev/null
+++ b/cw_monero/android/src/main/AndroidManifest.xml
@@ -0,0 +1,4 @@
+
+
+
diff --git a/cw_monero/android/src/main/kotlin/com/cakewallet/monero/CwMoneroPlugin.kt b/cw_monero/android/src/main/kotlin/com/cakewallet/monero/CwMoneroPlugin.kt
new file mode 100644
index 000000000..593627078
--- /dev/null
+++ b/cw_monero/android/src/main/kotlin/com/cakewallet/monero/CwMoneroPlugin.kt
@@ -0,0 +1,74 @@
+package com.cakewallet.monero
+
+import android.app.Activity
+import android.os.AsyncTask
+import android.os.Looper
+import android.os.Handler
+import android.os.Process
+
+import io.flutter.plugin.common.MethodCall
+import io.flutter.plugin.common.MethodChannel
+import io.flutter.plugin.common.MethodChannel.MethodCallHandler
+import io.flutter.plugin.common.MethodChannel.Result
+import io.flutter.plugin.common.PluginRegistry.Registrar
+
+class doAsync(val handler: () -> Unit) : AsyncTask() {
+ override fun doInBackground(vararg params: Void?): Void? {
+ Process.setThreadPriority(Process.THREAD_PRIORITY_AUDIO);
+ handler()
+ return null
+ }
+}
+
+class CwMoneroPlugin: MethodCallHandler {
+ companion object {
+ val moneroApi = MoneroApi()
+ val main = Handler(Looper.getMainLooper());
+
+ init {
+ System.loadLibrary("cw_monero")
+ }
+
+ @JvmStatic
+ fun registerWith(registrar: Registrar) {
+ val channel = MethodChannel(registrar.messenger(), "cw_monero")
+ channel.setMethodCallHandler(CwMoneroPlugin())
+ }
+ }
+
+ override fun onMethodCall(call: MethodCall, result: Result) {
+ if (call.method == "setupNode") {
+ val uri = call.argument("address") ?: ""
+ val login = call.argument("login") ?: ""
+ val password = call.argument("password") ?: ""
+ val useSSL = false
+ val isLightWallet = false
+ doAsync {
+ try {
+ moneroApi.setNodeAddressJNI(uri, login, password, useSSL, isLightWallet)
+ main.post({
+ result.success(true)
+ });
+ } catch(e: Throwable) {
+ main.post({
+ result.error("CONNECTION_ERROR", e.message, null)
+ });
+ }
+ }.execute()
+ }
+ if (call.method == "startSync") {
+ doAsync {
+ moneroApi.startSyncJNI()
+ main.post({
+ result.success(true)
+ });
+ }.execute()
+ }
+ if (call.method == "loadWallet") {
+ val path = call.argument("path") ?: ""
+ val password = call.argument("password") ?: ""
+ moneroApi.loadWalletJNI(path, password)
+ result.success(true)
+ }
+ }
+}
diff --git a/cw_monero/android/src/main/kotlin/com/cakewallet/monero/MoneroApi.kt b/cw_monero/android/src/main/kotlin/com/cakewallet/monero/MoneroApi.kt
new file mode 100644
index 000000000..071577ad3
--- /dev/null
+++ b/cw_monero/android/src/main/kotlin/com/cakewallet/monero/MoneroApi.kt
@@ -0,0 +1,14 @@
+package com.cakewallet.monero
+
+class MoneroApi {
+ external fun setNodeAddressJNI(uri: String, login: String, password: String, use_ssl: Boolean, is_light_wallet: Boolean)
+ external fun connectToNodeJNI()
+ external fun startSyncJNI()
+ external fun loadWalletJNI(path: String, password: String)
+
+ companion object {
+ init {
+ System.loadLibrary("cw_monero")
+ }
+ }
+}
\ No newline at end of file
diff --git a/cw_monero/ios/.gitignore b/cw_monero/ios/.gitignore
new file mode 100644
index 000000000..aa479fd3c
--- /dev/null
+++ b/cw_monero/ios/.gitignore
@@ -0,0 +1,37 @@
+.idea/
+.vagrant/
+.sconsign.dblite
+.svn/
+
+.DS_Store
+*.swp
+profile
+
+DerivedData/
+build/
+GeneratedPluginRegistrant.h
+GeneratedPluginRegistrant.m
+
+.generated/
+
+*.pbxuser
+*.mode1v3
+*.mode2v3
+*.perspectivev3
+
+!default.pbxuser
+!default.mode1v3
+!default.mode2v3
+!default.perspectivev3
+
+xcuserdata
+
+*.moved-aside
+
+*.pyc
+*sync/
+Icon?
+.tags*
+
+/Flutter/Generated.xcconfig
+/Flutter/flutter_export_environment.sh
\ No newline at end of file
diff --git a/cw_monero/ios/Assets/.gitkeep b/cw_monero/ios/Assets/.gitkeep
new file mode 100644
index 000000000..e69de29bb
diff --git a/cw_monero/ios/Classes/CwMoneroPlugin.h b/cw_monero/ios/Classes/CwMoneroPlugin.h
new file mode 100644
index 000000000..a42018098
--- /dev/null
+++ b/cw_monero/ios/Classes/CwMoneroPlugin.h
@@ -0,0 +1,4 @@
+#import
+
+@interface CwMoneroPlugin : NSObject
+@end
diff --git a/cw_monero/ios/Classes/CwMoneroPlugin.m b/cw_monero/ios/Classes/CwMoneroPlugin.m
new file mode 100644
index 000000000..eee251212
--- /dev/null
+++ b/cw_monero/ios/Classes/CwMoneroPlugin.m
@@ -0,0 +1,8 @@
+#import "CwMoneroPlugin.h"
+#import
+
+@implementation CwMoneroPlugin
++ (void)registerWithRegistrar:(NSObject*)registrar {
+ [SwiftCwMoneroPlugin registerWithRegistrar:registrar];
+}
+@end
diff --git a/cw_monero/ios/Classes/CwWalletListener.h b/cw_monero/ios/Classes/CwWalletListener.h
new file mode 100644
index 000000000..cbfcb0c4e
--- /dev/null
+++ b/cw_monero/ios/Classes/CwWalletListener.h
@@ -0,0 +1,23 @@
+#include
+
+struct CWMoneroWalletListener;
+
+typedef int8_t (*on_new_block_callback)(uint64_t height);
+typedef int8_t (*on_need_to_refresh_callback)();
+
+typedef struct CWMoneroWalletListener
+{
+ // on_money_spent_callback *on_money_spent;
+ // on_money_received_callback *on_money_received;
+ // on_unconfirmed_money_received_callback *on_unconfirmed_money_received;
+ // on_new_block_callback *on_new_block;
+ // on_updated_callback *on_updated;
+ // on_refreshed_callback *on_refreshed;
+
+ on_new_block_callback on_new_block;
+} CWMoneroWalletListener;
+
+struct TestListener {
+ // int8_t x;
+ on_new_block_callback on_new_block;
+};
\ No newline at end of file
diff --git a/cw_monero/ios/Classes/SwiftCwMoneroPlugin.swift b/cw_monero/ios/Classes/SwiftCwMoneroPlugin.swift
new file mode 100644
index 000000000..4c03a3e44
--- /dev/null
+++ b/cw_monero/ios/Classes/SwiftCwMoneroPlugin.swift
@@ -0,0 +1,14 @@
+import Flutter
+import UIKit
+
+public class SwiftCwMoneroPlugin: NSObject, FlutterPlugin {
+ public static func register(with registrar: FlutterPluginRegistrar) {
+ let channel = FlutterMethodChannel(name: "cw_monero", binaryMessenger: registrar.messenger())
+ let instance = SwiftCwMoneroPlugin()
+ registrar.addMethodCallDelegate(instance, channel: channel)
+ }
+
+ public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
+ result("iOS " + UIDevice.current.systemVersion)
+ }
+}
diff --git a/cw_monero/ios/Classes/monero_api.cpp b/cw_monero/ios/Classes/monero_api.cpp
new file mode 100644
index 000000000..757f05d8d
--- /dev/null
+++ b/cw_monero/ios/Classes/monero_api.cpp
@@ -0,0 +1,671 @@
+#include
+#include "cstdlib"
+#include
+#include
+#include
+#include
+#include "thread"
+#include "../External/android/monero/include/wallet2_api.h"
+#include "CwWalletListener.h"
+
+using namespace std::chrono_literals;
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ struct Utf8Box
+ {
+ char *value;
+
+ Utf8Box(char *_value)
+ {
+ value = _value;
+ }
+ };
+
+ struct SubaddressRow
+ {
+ uint64_t id;
+ char *address;
+ char *label;
+
+ SubaddressRow(std::size_t _id, char *_address, char *_label)
+ {
+ id = static_cast(_id);
+ address = _address;
+ label = _label;
+ }
+ };
+
+ struct AccountRow
+ {
+ uint64_t id;
+ char *label;
+
+ AccountRow(std::size_t _id, char *_label)
+ {
+ id = static_cast(_id);
+ label = _label;
+ }
+ };
+
+ struct MoneroWalletListener : Monero::WalletListener
+ {
+ uint64_t m_height;
+ bool m_need_to_refresh;
+ bool m_new_transaction;
+
+ MoneroWalletListener()
+ {
+ m_height = 0;
+ m_need_to_refresh = false;
+ m_new_transaction = false;
+ }
+
+ void moneySpent(const std::string &txId, uint64_t amount)
+ {
+ m_new_transaction = true;
+ }
+
+ void moneyReceived(const std::string &txId, uint64_t amount)
+ {
+ m_new_transaction = true;
+ }
+
+ void unconfirmedMoneyReceived(const std::string &txId, uint64_t amount)
+ {
+ m_new_transaction = true;
+ }
+
+ void newBlock(uint64_t height)
+ {
+ m_height = height;
+ }
+
+ void updated()
+ {
+ m_need_to_refresh = true;
+ }
+
+ void refreshed()
+ {
+ m_need_to_refresh = true;
+ }
+
+ void resetNeedToRefresh()
+ {
+ m_need_to_refresh = false;
+ }
+
+ bool isNeedToRefresh()
+ {
+ return m_need_to_refresh;
+ }
+
+ bool isNewTransactionExist()
+ {
+ return m_new_transaction;
+ }
+
+ void resetIsNewTransactionExist()
+ {
+ m_new_transaction = false;
+ }
+
+ uint64_t height()
+ {
+ return m_height;
+ }
+ };
+
+ struct TransactionInfoRow
+ {
+ uint64_t amount;
+ uint64_t fee;
+ uint64_t blockHeight;
+ uint64_t confirmations;
+ uint32_t subaddrAccount;
+ int8_t direction;
+ int8_t isPending;
+
+ char *hash;
+ char *paymentId;
+
+ int64_t datetime;
+
+ TransactionInfoRow(Monero::TransactionInfo *transaction)
+ {
+ amount = transaction->amount();
+ fee = transaction->fee();
+ blockHeight = transaction->blockHeight();
+ subaddrAccount = transaction->subaddrAccount();
+ confirmations = transaction->confirmations();
+ datetime = static_cast(transaction->timestamp());
+ direction = transaction->direction();
+ isPending = static_cast(transaction->isPending());
+ std::string *hash_str = new std::string(transaction->hash());
+ hash = strdup(hash_str->c_str());
+ paymentId = strdup(transaction->paymentId().c_str());
+ }
+ };
+
+ struct PendingTransactionRaw
+ {
+ uint64_t amount;
+ uint64_t fee;
+ char *hash;
+ Monero::PendingTransaction *transaction;
+
+ PendingTransactionRaw(Monero::PendingTransaction *_transaction)
+ {
+ transaction = _transaction;
+ amount = _transaction->amount();
+ fee = _transaction->fee();
+ hash = strdup(_transaction->txid()[0].c_str());
+ }
+ };
+
+ Monero::Wallet *m_wallet;
+ Monero::TransactionHistory *m_transaction_history;
+ MoneroWalletListener *m_listener;
+ Monero::Subaddress *m_subaddress;
+ Monero::SubaddressAccount *m_account;
+ uint64_t m_last_known_wallet_height;
+
+ void change_current_wallet(Monero::Wallet *wallet)
+ {
+ m_wallet = wallet;
+ // m_listener = nullptr;
+
+
+ if (wallet != nullptr)
+ {
+ m_transaction_history = wallet->history();
+ }
+ else
+ {
+ m_transaction_history = nullptr;
+ }
+
+ if (wallet != nullptr)
+ {
+ m_account = wallet->subaddressAccount();
+ }
+ else
+ {
+ m_account = nullptr;
+ }
+
+ if (wallet != nullptr)
+ {
+ m_subaddress = wallet->subaddress();
+ }
+ else
+ {
+ m_subaddress = nullptr;
+ }
+ }
+
+ Monero::Wallet *get_current_wallet()
+ {
+ return m_wallet;
+ }
+
+ bool create_wallet(char *path, char *password, char *language, int32_t networkType, char *error)
+ {
+ Monero::NetworkType _networkType = static_cast(networkType);
+ Monero::WalletManager *walletManager = Monero::WalletManagerFactory::getWalletManager();
+ Monero::Wallet *wallet = walletManager->createWallet(path, password, language, _networkType);
+
+ int status;
+ std::string errorString;
+
+ wallet->statusWithErrorString(status, errorString);
+
+ if (status != Monero::Wallet::Status_Ok)
+ {
+ error = strdup(errorString.c_str());
+ return false;
+ }
+
+ change_current_wallet(wallet);
+
+ return true;
+ }
+
+ bool restore_wallet_from_seed(char *path, char *password, char *seed, int32_t networkType, uint64_t restoreHeight, char *error)
+ {
+ Monero::NetworkType _networkType = static_cast(networkType);
+ Monero::Wallet *wallet = Monero::WalletManagerFactory::getWalletManager()->recoveryWallet(
+ std::string(path),
+ std::string(password),
+ std::string(seed),
+ _networkType,
+ (uint64_t)restoreHeight);
+
+ int status;
+ std::string errorString;
+
+ wallet->statusWithErrorString(status, errorString);
+
+ if (status != Monero::Wallet::Status_Ok)
+ {
+ error = strdup(errorString.c_str());
+ return false;
+ }
+
+ change_current_wallet(wallet);
+ return true;
+ }
+
+ bool restore_wallet_from_keys(char *path, char *password, char *language, char *address, char *viewKey, char *spendKey, int32_t networkType, uint64_t restoreHeight, char *error)
+ {
+ Monero::NetworkType _networkType = static_cast(networkType);
+ Monero::Wallet *wallet = Monero::WalletManagerFactory::getWalletManager()->createWalletFromKeys(
+ std::string(path),
+ std::string(password),
+ std::string(language),
+ _networkType,
+ (uint64_t)restoreHeight,
+ std::string(address),
+ std::string(viewKey),
+ std::string(spendKey));
+
+ int status;
+ std::string errorString;
+
+ wallet->statusWithErrorString(status, errorString);
+
+ if (status != Monero::Wallet::Status_Ok)
+ {
+ error = strdup(errorString.c_str());
+ return false;
+ }
+
+ change_current_wallet(wallet);
+ return true;
+ }
+
+ void load_wallet(char *path, char *password, int32_t nettype)
+ {
+ Monero::NetworkType networkType = static_cast(nettype);
+ Monero::Wallet *wallet = Monero::WalletManagerFactory::getWalletManager()->openWallet(std::string(path), std::string(password), networkType);
+ change_current_wallet(wallet);
+ }
+
+ bool is_wallet_exist(char *path)
+ {
+ return Monero::WalletManagerFactory::getWalletManager()->walletExists(std::string(path));
+ }
+
+ void close_current_wallet()
+ {
+ Monero::WalletManagerFactory::getWalletManager()->closeWallet(get_current_wallet());
+ change_current_wallet(nullptr);
+ }
+
+ char *get_filename()
+ {
+ return strdup(get_current_wallet()->filename().c_str());
+ }
+
+ char *secret_view_key()
+ {
+ return strdup(get_current_wallet()->secretViewKey().c_str());
+ }
+
+ char *public_view_key()
+ {
+ return strdup(get_current_wallet()->publicViewKey().c_str());
+ }
+
+ char *secret_spend_key()
+ {
+ return strdup(get_current_wallet()->secretSpendKey().c_str());
+ }
+
+ char *public_spend_key()
+ {
+ return strdup(get_current_wallet()->publicSpendKey().c_str());
+ }
+
+ char *get_address(uint32_t account_index, uint32_t address_index)
+ {
+ return strdup(get_current_wallet()->address(account_index, address_index).c_str());
+ }
+
+
+ const char *seed()
+ {
+ return strdup(get_current_wallet()->seed().c_str());
+ }
+
+ uint64_t get_full_balance(uint32_t account_index)
+ {
+ return get_current_wallet()->balance(account_index);
+ }
+
+ uint64_t get_unlocked_balance(uint32_t account_index)
+ {
+ return get_current_wallet()->unlockedBalance(account_index);
+ }
+
+ uint64_t get_current_height()
+ {
+ return get_current_wallet()->blockChainHeight();
+ }
+
+ uint64_t get_node_height()
+ {
+ return get_current_wallet()->daemonBlockChainHeight();
+ }
+
+ bool connect_to_node(char *error)
+ {
+ bool is_connected = get_current_wallet()->connectToDaemon();
+
+ if (!is_connected)
+ {
+ error = strdup(get_current_wallet()->errorString().c_str());
+ }
+
+ return is_connected;
+ }
+
+ bool setup_node(char *address, char *login, char *password, bool use_ssl, bool is_light_wallet, char *error)
+ {
+ Monero::Wallet *wallet = get_current_wallet();
+
+ std::string _login = "";
+ std::string _password = "";
+
+ if (login != nullptr)
+ {
+ _login = std::string(login);
+ }
+
+ if (password != nullptr)
+ {
+ _password = std::string(password);
+ }
+
+ bool inited = wallet->init(std::string(address), 0, _login, _password, use_ssl, is_light_wallet);
+
+ if (!inited)
+ {
+ error = strdup(wallet->errorString().c_str());
+ } else if (!wallet->connectToDaemon()) {
+ error = strdup(wallet->errorString().c_str());
+ }
+
+ return inited;
+ }
+
+ bool is_connected()
+ {
+ return get_current_wallet()->connected();
+ }
+
+ void start_refresh()
+ {
+ get_current_wallet()->refreshAsync();
+ get_current_wallet()->startRefresh();
+ }
+
+ void set_refresh_from_block_height(uint64_t height)
+ {
+ get_current_wallet()->setRefreshFromBlockHeight(height);
+ }
+
+ void set_recovering_from_seed(bool is_recovery)
+ {
+ get_current_wallet()->setRecoveringFromSeed(is_recovery);
+ }
+
+ void store(char *path)
+ {
+ get_current_wallet()->store(std::string(path));
+ }
+
+ bool transaction_create(char *address, char *payment_id, char *amount,
+ uint8_t priority_raw, uint32_t subaddr_account, Utf8Box &error, PendingTransactionRaw &pendingTransaction)
+ {
+ nice(19);
+
+ auto priority = static_cast(priority_raw);
+ std::string _payment_id;
+ Monero::PendingTransaction *transaction;
+
+ if (payment_id != nullptr)
+ {
+ _payment_id = std::string(payment_id);
+ }
+
+ if (amount != nullptr)
+ {
+ uint64_t _amount = Monero::Wallet::amountFromString(std::string(amount));
+ transaction = m_wallet->createTransaction(std::string(address), _payment_id, _amount, m_wallet->defaultMixin(), priority, subaddr_account);
+ }
+ else
+ {
+ transaction = m_wallet->createTransaction(std::string(address), _payment_id, Monero::optional(), m_wallet->defaultMixin(), priority, subaddr_account);
+ }
+
+ int status = transaction->status();
+
+ if (status == Monero::PendingTransaction::Status::Status_Error || status == Monero::PendingTransaction::Status::Status_Critical)
+ {
+ error = Utf8Box(strdup(transaction->errorString().c_str()));
+ return false;
+ }
+
+ m_listener->m_new_transaction = true;
+
+ pendingTransaction = PendingTransactionRaw(transaction);
+ return true;
+ }
+
+ bool transaction_commit(PendingTransactionRaw *transaction, Utf8Box &error)
+ {
+ bool committed = transaction->transaction->commit();
+
+ if (!committed)
+ {
+ error = Utf8Box(strdup(transaction->transaction->errorString().c_str()));
+ } else {
+ m_listener->m_new_transaction = true;
+ }
+
+ return committed;
+ }
+
+ uint64_t get_syncing_height()
+ {
+ if (m_listener == nullptr) {
+ return 0;
+ }
+
+ uint64_t _height = m_listener->height();
+
+ if (_height != m_last_known_wallet_height)
+ {
+ m_last_known_wallet_height = _height;
+ }
+
+ return _height;
+ }
+
+ uint64_t is_needed_to_refresh()
+ {
+ if (m_listener == nullptr) {
+ return false;
+ }
+
+ bool should_refresh = m_listener->isNeedToRefresh();
+
+ if (should_refresh)
+ {
+ m_listener->resetNeedToRefresh();
+ }
+
+ return should_refresh;
+ }
+
+ uint8_t is_new_transaction_exist()
+ {
+ if (m_listener == nullptr) {
+ return false;
+ }
+
+ bool is_new_transaction_exist = m_listener->isNewTransactionExist();
+
+ if (is_new_transaction_exist)
+ {
+ m_listener->resetIsNewTransactionExist();
+ }
+
+ return is_new_transaction_exist;
+ }
+
+ void set_listener()
+ {
+ m_last_known_wallet_height = 0;
+
+ if (m_listener != nullptr)
+ {
+ free(m_listener);
+ }
+
+ m_listener = new MoneroWalletListener();
+ get_current_wallet()->setListener(m_listener);
+ }
+
+ int64_t *subaddrress_get_all()
+ {
+ std::vector _subaddresses = m_subaddress->getAll();
+ size_t size = _subaddresses.size();
+ int64_t *subaddresses = (int64_t *)malloc(size * sizeof(int64_t));
+
+ for (int i = 0; i < size; i++)
+ {
+ Monero::SubaddressRow *row = _subaddresses[i];
+ SubaddressRow *_row = new SubaddressRow(row->getRowId(), strdup(row->getAddress().c_str()), strdup(row->getLabel().c_str()));
+ subaddresses[i] = reinterpret_cast(_row);
+ }
+
+ return subaddresses;
+ }
+
+ int32_t subaddrress_size()
+ {
+ std::vector _subaddresses = m_subaddress->getAll();
+ return _subaddresses.size();
+ }
+
+ void subaddress_add_row(uint32_t accountIndex, char *label)
+ {
+ m_subaddress->addRow(accountIndex, std::string(label));
+ }
+
+ void subaddress_set_label(uint32_t accountIndex, uint32_t addressIndex, char *label)
+ {
+ m_subaddress->setLabel(accountIndex, addressIndex, std::string(label));
+ }
+
+ void subaddress_refresh(uint32_t accountIndex)
+ {
+ m_subaddress->refresh(accountIndex);
+ }
+
+ int32_t account_size()
+ {
+ std::vector _accocunts = m_account->getAll();
+ return _accocunts.size();
+ }
+
+ int64_t *account_get_all()
+ {
+ std::vector _accocunts = m_account->getAll();
+ size_t size = _accocunts.size();
+ int64_t *accocunts = (int64_t *)malloc(size * sizeof(int64_t));
+
+ for (int i = 0; i < size; i++)
+ {
+ Monero::SubaddressAccountRow *row = _accocunts[i];
+ AccountRow *_row = new AccountRow(row->getRowId(), strdup(row->getLabel().c_str()));
+ accocunts[i] = reinterpret_cast(_row);
+ }
+
+ return accocunts;
+ }
+
+ void account_add_row(char *label)
+ {
+ m_account->addRow(std::string(label));
+ }
+
+ void account_set_label_row(uint32_t account_index, char *label)
+ {
+ m_account->setLabel(account_index, label);
+ }
+
+ void account_refresh()
+ {
+ m_account->refresh();
+ }
+
+ int64_t *transactions_get_all()
+ {
+ std::vector transactions = m_transaction_history->getAll();
+ size_t size = transactions.size();
+ int64_t *transactionAddresses = (int64_t *)malloc(size * sizeof(int64_t));
+
+ for (int i = 0; i < size; i++)
+ {
+ Monero::TransactionInfo *row = transactions[i];
+ TransactionInfoRow *tx = new TransactionInfoRow(row);
+ transactionAddresses[i] = reinterpret_cast(tx);
+ }
+
+ return transactionAddresses;
+ }
+
+ void transactions_refresh()
+ {
+ m_transaction_history->refresh();
+ }
+
+ int64_t transactions_count()
+ {
+ return m_transaction_history->count();
+ }
+
+ int LedgerExchange(
+ unsigned char *command,
+ unsigned int cmd_len,
+ unsigned char *response,
+ unsigned int max_resp_len)
+ {
+ return -1;
+ }
+
+ int LedgerFind(char *buffer, size_t len)
+ {
+ return -1;
+ }
+
+ void on_startup()
+ {
+ Monero::Utils::onStartup();
+ }
+
+ void rescan_blockchain()
+ {
+ m_wallet->rescanBlockchainAsync();
+ }
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/cw_monero/ios/Classes/monero_api.h b/cw_monero/ios/Classes/monero_api.h
new file mode 100644
index 000000000..3e2ebcff2
--- /dev/null
+++ b/cw_monero/ios/Classes/monero_api.h
@@ -0,0 +1,35 @@
+#include
+#include
+#include
+#include "CwWalletListener.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+bool create_wallet(char *path, char *password, char *language, int32_t networkType, char *error);
+bool restore_wallet_from_seed(char *path, char *password, char *seed, int32_t networkType, uint64_t restoreHeight, char *error);
+bool restore_wallet_from_keys(char *path, char *password, char *language, char *address, char *viewKey, char *spendKey, int32_t networkType, uint64_t restoreHeight, char *error);
+void load_wallet(char *path, char *password, int32_t nettype);
+bool is_wallet_exist(char *path);
+
+char *get_filename();
+const char *seed();
+char *get_address(uint32_t account_index, uint32_t address_index);
+uint64_t get_full_balance(uint32_t account_index);
+uint64_t get_unlocked_balance(uint32_t account_index);
+uint64_t get_current_height();
+uint64_t get_node_height();
+
+bool is_connected();
+
+bool setup_node(char *address, char *login, char *password, bool use_ssl, bool is_light_wallet, char *error);
+bool connect_to_node(char *error);
+void start_refresh();
+void set_refresh_from_block_height(uint64_t height);
+void set_recovering_from_seed(bool is_recovery);
+void store(char *path);
+
+#ifdef __cplusplus
+}
+#endif
\ No newline at end of file
diff --git a/cw_monero/ios/cw_monero.podspec b/cw_monero/ios/cw_monero.podspec
new file mode 100644
index 000000000..1fd4a89c2
--- /dev/null
+++ b/cw_monero/ios/cw_monero.podspec
@@ -0,0 +1,51 @@
+#
+# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html.
+# Run `pod lib lint cw_monero.podspec' to validate before publishing.
+#
+Pod::Spec.new do |s|
+ s.name = 'cw_monero'
+ s.version = '0.0.2'
+ s.summary = 'A new flutter plugin project.'
+ s.description = <<-DESC
+A new flutter plugin project.
+ DESC
+ s.homepage = 'http://example.com'
+ s.license = { :file => '../LICENSE' }
+ s.author = { 'Your Company' => 'email@example.com' }
+ s.source = { :path => '.' }
+ s.source_files = 'Classes/**/*'
+ s.public_header_files = 'Classes/**/*.h, Classes/*.h, External/ios/libs/monero/include/src/**/*.h, External/ios/libs/monero/include/contrib/**/*.h, External/ios/libs/monero/include/External/ios/**/*.h'
+ s.dependency 'Flutter'
+ s.platform = :ios, '9.0'
+ s.swift_version = '4.0'
+ s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS' => 'arm64' }
+ s.xcconfig = { 'HEADER_SEARCH_PATHS' => "${PODS_ROOT}/#{s.name}/Classes/*.h" }
+
+ s.subspec 'OpenSSL' do |openssl|
+ openssl.preserve_paths = 'External/ios/libs/OpenSSL/include/openssl/*.h', 'External/ios/libs/OpenSSL/include/LICENSE'
+ openssl.vendored_libraries = 'External/ios/libs/OpenSSL/lib/libcrypto.a', 'External/ios/libs/OpenSSL/lib/libssl.a'
+ openssl.libraries = 'ssl', 'crypto'
+ openssl.xcconfig = { 'HEADER_SEARCH_PATHS' => "${PODS_ROOT}/#{s.name}/External/ios/libs/OpenSSL/include/**" }
+ end
+
+ s.subspec 'Monero' do |monero|
+ monero.preserve_paths = 'External/ios/libs/monero/include/src/**/*.h', 'External/ios/libs/monero/include/External/ios/**/*.h', 'External/ios/libs/monero/include/contrib/**/*.h'
+ monero.vendored_libraries = 'External/ios/libs/monero/libs/lib-ios/*.a'
+ monero.libraries = 'easylogging', 'epee', 'unbound', 'wallet_merged', 'lmdb', 'randomx'
+ monero.xcconfig = { 'HEADER_SEARCH_PATHS' => "${PODS_ROOT}/#{s.name}/External/ios/libs/monero/include/src/**" }
+ end
+
+ s.subspec 'Boost' do |boost|
+ boost.preserve_paths = 'External/ios/libs/boost/include/**/*.h', 'External/ios/libs/boost/include/**/*.h'
+ boost.vendored_libraries = 'External/ios/libs/boost/build/libs/universal/*.a'
+ boost.libraries = 'boost', 'boost_wserialization', 'boost_thread', 'boost_system', 'boost_signals', 'boost_serialization', 'boost_regex', 'boost_random', 'boost_program_options', 'boost_locale', 'boost_graph', 'boost_filesystem', 'boost_date_time', 'boost_chrono'
+ boost.xcconfig = { 'HEADER_SEARCH_PATHS' => "${PODS_ROOT}/#{s.name}/External/ios/libs/boost/include/**" }
+ end
+
+ s.subspec 'Sodium' do |sodium|
+ sodium.preserve_paths = 'External/ios/libs/sodium/include/**/*.h'
+ sodium.vendored_libraries = 'External/ios/libs/sodium/lib/libsodium.a'
+ sodium.libraries = 'sodium'
+ sodium.xcconfig = { 'HEADER_SEARCH_PATHS' => "${PODS_ROOT}/#{s.name}/External/ios/libs/sodium/include/**" }
+ end
+end
\ No newline at end of file
diff --git a/cw_monero/lib/account_list.dart b/cw_monero/lib/account_list.dart
new file mode 100644
index 000000000..f72c57ae2
--- /dev/null
+++ b/cw_monero/lib/account_list.dart
@@ -0,0 +1,61 @@
+import 'dart:ffi';
+import 'package:ffi/ffi.dart';
+import 'package:cw_monero/signatures.dart';
+import 'package:cw_monero/types.dart';
+import 'package:cw_monero/monero_api.dart';
+import 'package:cw_monero/structs/account_row.dart';
+import 'package:flutter/foundation.dart';
+
+final accountSizeNative = moneroApi
+ .lookup>('account_size')
+ .asFunction();
+
+final accountRefreshNative = moneroApi
+ .lookup>('account_refresh')
+ .asFunction();
+
+final accountGetAllNative = moneroApi
+ .lookup>('account_get_all')
+ .asFunction();
+
+final accountAddNewNative = moneroApi
+ .lookup>('account_add_row')
+ .asFunction();
+
+final accountSetLabelNative = moneroApi
+ .lookup>('account_set_label_row')
+ .asFunction();
+
+refreshAccounts() => accountRefreshNative();
+
+List getAllAccount() {
+ final size = accountSizeNative();
+ final accountAddressesPointer = accountGetAllNative();
+ final accountAddresses = accountAddressesPointer.asTypedList(size);
+
+ return accountAddresses
+ .map((addr) => Pointer.fromAddress(addr).ref)
+ .toList();
+}
+
+addAccountSync({String label}) {
+ final labelPointer = Utf8.toUtf8(label);
+ accountAddNewNative(labelPointer);
+ free(labelPointer);
+}
+
+setLabelForAccountSync({int accountIndex, String label}) {
+ final labelPointer = Utf8.toUtf8(label);
+ accountSetLabelNative(accountIndex, labelPointer);
+ free(labelPointer);
+}
+
+_addAccount(String label) => addAccountSync(label: label);
+
+_setLabelForAccount(Map args) => setLabelForAccountSync(
+ label: args['label'], accountIndex: args['accountIndex']);
+
+Future addAccount({String label}) async => compute(_addAccount, label);
+
+Future setLabelForAccount({int accountIndex, String label}) async => compute(
+ _setLabelForAccount, {'accountIndex': accountIndex, 'label': label});
diff --git a/cw_monero/lib/convert_utf8_to_string.dart b/cw_monero/lib/convert_utf8_to_string.dart
new file mode 100644
index 000000000..7fa5a68df
--- /dev/null
+++ b/cw_monero/lib/convert_utf8_to_string.dart
@@ -0,0 +1,8 @@
+import 'dart:ffi';
+import 'package:ffi/ffi.dart';
+
+String convertUTF8ToString({Pointer pointer}) {
+ final str = Utf8.fromUtf8(pointer);
+ free(pointer);
+ return str;
+}
\ No newline at end of file
diff --git a/cw_monero/lib/exceptions/connection_to_node_exception.dart b/cw_monero/lib/exceptions/connection_to_node_exception.dart
new file mode 100644
index 000000000..4a3733f52
--- /dev/null
+++ b/cw_monero/lib/exceptions/connection_to_node_exception.dart
@@ -0,0 +1,5 @@
+class ConnectionToNodeException implements Exception {
+ final String message;
+
+ ConnectionToNodeException({this.message});
+}
\ No newline at end of file
diff --git a/cw_monero/lib/exceptions/creation_transaction_exception.dart b/cw_monero/lib/exceptions/creation_transaction_exception.dart
new file mode 100644
index 000000000..94bb2a53f
--- /dev/null
+++ b/cw_monero/lib/exceptions/creation_transaction_exception.dart
@@ -0,0 +1,8 @@
+class CreationTransactionException implements Exception {
+ final String message;
+
+ CreationTransactionException({this.message});
+
+ @override
+ String toString() => message;
+}
\ No newline at end of file
diff --git a/cw_monero/lib/exceptions/setup_wallet_exception.dart b/cw_monero/lib/exceptions/setup_wallet_exception.dart
new file mode 100644
index 000000000..0c044fe67
--- /dev/null
+++ b/cw_monero/lib/exceptions/setup_wallet_exception.dart
@@ -0,0 +1,5 @@
+class SetupWalletException implements Exception {
+ final String message;
+
+ SetupWalletException({this.message});
+}
\ No newline at end of file
diff --git a/cw_monero/lib/exceptions/wallet_creation_exception.dart b/cw_monero/lib/exceptions/wallet_creation_exception.dart
new file mode 100644
index 000000000..cb1984ab6
--- /dev/null
+++ b/cw_monero/lib/exceptions/wallet_creation_exception.dart
@@ -0,0 +1,5 @@
+class WalletCreationException implements Exception {
+ final String message;
+
+ WalletCreationException({this.message});
+}
\ No newline at end of file
diff --git a/cw_monero/lib/exceptions/wallet_restore_from_keys_exception.dart b/cw_monero/lib/exceptions/wallet_restore_from_keys_exception.dart
new file mode 100644
index 000000000..bf16c1cae
--- /dev/null
+++ b/cw_monero/lib/exceptions/wallet_restore_from_keys_exception.dart
@@ -0,0 +1,5 @@
+class WalletRestoreFromKeysException implements Exception {
+ final String message;
+
+ WalletRestoreFromKeysException({this.message});
+}
\ No newline at end of file
diff --git a/cw_monero/lib/exceptions/wallet_restore_from_seed_exception.dart b/cw_monero/lib/exceptions/wallet_restore_from_seed_exception.dart
new file mode 100644
index 000000000..6d48684ff
--- /dev/null
+++ b/cw_monero/lib/exceptions/wallet_restore_from_seed_exception.dart
@@ -0,0 +1,5 @@
+class WalletRestoreFromSeedException implements Exception {
+ final String message;
+
+ WalletRestoreFromSeedException({this.message});
+}
\ No newline at end of file
diff --git a/cw_monero/lib/monero_api.dart b/cw_monero/lib/monero_api.dart
new file mode 100644
index 000000000..398d737d1
--- /dev/null
+++ b/cw_monero/lib/monero_api.dart
@@ -0,0 +1,6 @@
+import 'dart:ffi';
+import 'dart:io';
+
+final DynamicLibrary moneroApi = Platform.isAndroid
+ ? DynamicLibrary.open("libcw_monero.so")
+ : DynamicLibrary.open("cw_monero.framework/cw_monero");
\ No newline at end of file
diff --git a/cw_monero/lib/signatures.dart b/cw_monero/lib/signatures.dart
new file mode 100644
index 000000000..c7db41159
--- /dev/null
+++ b/cw_monero/lib/signatures.dart
@@ -0,0 +1,108 @@
+import 'dart:ffi';
+import 'package:cw_monero/structs/pending_transaction.dart';
+import 'package:cw_monero/structs/ut8_box.dart';
+import 'package:ffi/ffi.dart';
+
+typedef create_wallet = Int8 Function(
+ Pointer, Pointer, Pointer, Int32, Pointer);
+
+typedef restore_wallet_from_seed = Int8 Function(
+ Pointer, Pointer, Pointer, Int32, Int64, Pointer);
+
+typedef restore_wallet_from_keys = Int8 Function(Pointer, Pointer,
+ Pointer, Pointer, Pointer, Pointer, Int32, Int64, Pointer);
+
+typedef is_wallet_exist = Int8 Function(Pointer);
+
+typedef load_wallet = Void Function(Pointer, Pointer, Int8);
+
+typedef get_filename = Pointer Function();
+
+typedef get_seed = Pointer Function();
+
+typedef get_address = Pointer Function(Int32, Int32);
+
+typedef get_full_balanace = Int64 Function(Int32);
+
+typedef get_unlocked_balanace = Int64 Function(Int32);
+
+typedef get_current_height = Int64 Function();
+
+typedef get_node_height = Int64 Function();
+
+typedef is_connected = Int8 Function();
+
+typedef setup_node = Int8 Function(
+ Pointer, Pointer, Pointer, Int8, Int8, Pointer);
+
+typedef start_refresh = Void Function();
+
+typedef connect_to_node = Int8 Function();
+
+typedef set_refresh_from_block_height = Void Function(Int64);
+
+typedef set_recovering_from_seed = Void Function(Int8);
+
+typedef store_c = Void Function(Pointer);
+
+typedef set_listener = Void Function();
+
+typedef get_syncing_height = Int64 Function();
+
+typedef is_needed_to_refresh = Int8 Function();
+
+typedef is_new_transaction_exist = Int8 Function();
+
+typedef subaddrress_size = Int32 Function();
+
+typedef subaddrress_refresh = Void Function(Int32);
+
+typedef subaddress_get_all = Pointer Function();
+
+typedef subaddress_add_new = Void Function(
+ Int32 accountIndex, Pointer label);
+
+typedef subaddress_set_label = Void Function(
+ Int32 accountIndex, Int32 addressIndex, Pointer label);
+
+typedef account_size = Int32 Function();
+
+typedef account_refresh = Void Function();
+
+typedef account_get_all = Pointer Function();
+
+typedef account_add_new = Void Function(Pointer label);
+
+typedef account_set_label = Void Function(
+ Int32 accountIndex, Pointer label);
+
+ typedef transactions_refresh = Void Function();
+
+typedef transactions_count = Int64 Function();
+
+typedef transactions_get_all = Pointer Function();
+
+typedef transaction_create = Int8 Function(
+ Pointer address,
+ Pointer paymentId,
+ Pointer amount,
+ Int8 priorityRaw,
+ Int32 subaddrAccount,
+ Pointer error,
+ Pointer pendingTransaction);
+
+typedef transaction_commit = Int8 Function(Pointer, Pointer);
+
+typedef secret_view_key = Pointer Function();
+
+typedef public_view_key = Pointer Function();
+
+typedef secret_spend_key = Pointer Function();
+
+typedef public_spend_key = Pointer Function();
+
+typedef close_current_wallet = Void Function();
+
+typedef on_startup = Void Function();
+
+typedef rescan_blockchain = Void Function();
diff --git a/cw_monero/lib/structs/account_row.dart b/cw_monero/lib/structs/account_row.dart
new file mode 100644
index 000000000..c3fc22de1
--- /dev/null
+++ b/cw_monero/lib/structs/account_row.dart
@@ -0,0 +1,11 @@
+import 'dart:ffi';
+import 'package:ffi/ffi.dart';
+
+class AccountRow extends Struct {
+ @Int64()
+ int id;
+ Pointer label;
+
+ String getLabel() => Utf8.fromUtf8(label);
+ int getId() => id;
+}
diff --git a/cw_monero/lib/structs/pending_transaction.dart b/cw_monero/lib/structs/pending_transaction.dart
new file mode 100644
index 000000000..fa88a9faa
--- /dev/null
+++ b/cw_monero/lib/structs/pending_transaction.dart
@@ -0,0 +1,23 @@
+import 'dart:ffi';
+import 'package:ffi/ffi.dart';
+
+class PendingTransactionRaw extends Struct {
+ @Int64()
+ int amount;
+
+ @Int64()
+ int fee;
+
+ Pointer hash;
+
+ String getHash() => Utf8.fromUtf8(hash);
+}
+
+class PendingTransactionDescription {
+ final int amount;
+ final int fee;
+ final String hash;
+ final int pointerAddress;
+
+ PendingTransactionDescription({this.amount, this.fee, this.hash, this.pointerAddress});
+}
\ No newline at end of file
diff --git a/cw_monero/lib/structs/subaddress_row.dart b/cw_monero/lib/structs/subaddress_row.dart
new file mode 100644
index 000000000..1673e00c7
--- /dev/null
+++ b/cw_monero/lib/structs/subaddress_row.dart
@@ -0,0 +1,13 @@
+import 'dart:ffi';
+import 'package:ffi/ffi.dart';
+
+class SubaddressRow extends Struct {
+ @Int64()
+ int id;
+ Pointer address;
+ Pointer label;
+
+ String getLabel() => Utf8.fromUtf8(label);
+ String getAddress() => Utf8.fromUtf8(address);
+ int getId() => id;
+}
\ No newline at end of file
diff --git a/cw_monero/lib/structs/transaction_info_row.dart b/cw_monero/lib/structs/transaction_info_row.dart
new file mode 100644
index 000000000..0a0613a42
--- /dev/null
+++ b/cw_monero/lib/structs/transaction_info_row.dart
@@ -0,0 +1,38 @@
+import 'dart:ffi';
+import 'package:ffi/ffi.dart';
+
+class TransactionInfoRow extends Struct {
+ @Uint64()
+ int amount;
+
+ @Uint64()
+ int fee;
+
+ @Uint64()
+ int blockHeight;
+
+ @Uint64()
+ int confirmations;
+
+ @Uint32()
+ int subaddrAccount;
+
+ @Int8()
+ int direction;
+
+ @Int8()
+ int isPending;
+
+ Pointer hash;
+
+ Pointer paymentId;
+
+ @Int64()
+ int datetime;
+
+ int getDatetime() => datetime;
+ int getAmount() => amount >= 0 ? amount : amount * -1;
+ bool getIsPending() => isPending != 0;
+ String getHash() => Utf8.fromUtf8(hash);
+ String getPaymentId() => Utf8.fromUtf8(paymentId);
+}
diff --git a/cw_monero/lib/structs/ut8_box.dart b/cw_monero/lib/structs/ut8_box.dart
new file mode 100644
index 000000000..a6f41bc75
--- /dev/null
+++ b/cw_monero/lib/structs/ut8_box.dart
@@ -0,0 +1,8 @@
+import 'dart:ffi';
+import 'package:ffi/ffi.dart';
+
+class Utf8Box extends Struct {
+ Pointer value;
+
+ String getValue() => Utf8.fromUtf8(value);
+}
diff --git a/cw_monero/lib/subaddress_list.dart b/cw_monero/lib/subaddress_list.dart
new file mode 100644
index 000000000..ba93af453
--- /dev/null
+++ b/cw_monero/lib/subaddress_list.dart
@@ -0,0 +1,72 @@
+import 'dart:ffi';
+import 'package:ffi/ffi.dart';
+import 'package:flutter/foundation.dart';
+import 'package:cw_monero/signatures.dart';
+import 'package:cw_monero/types.dart';
+import 'package:cw_monero/monero_api.dart';
+import 'package:cw_monero/structs/subaddress_row.dart';
+
+final subaddressSizeNative = moneroApi
+ .lookup>('subaddrress_size')
+ .asFunction();
+
+final subaddressRefreshNative = moneroApi
+ .lookup>('subaddress_refresh')
+ .asFunction();
+
+final subaddrressGetAllNative = moneroApi
+ .lookup>('subaddrress_get_all')
+ .asFunction();
+
+final subaddrressAddNewNative = moneroApi
+ .lookup>('subaddress_add_row')
+ .asFunction();
+
+final subaddrressSetLabelNative = moneroApi
+ .lookup>('subaddress_set_label')
+ .asFunction();
+
+refreshSubaddresses({int accountIndex}) =>
+ subaddressRefreshNative(accountIndex);
+
+List getAllSubaddresses() {
+ refreshSubaddresses(accountIndex: 0);
+ final size = subaddressSizeNative();
+ final subaddressAddressesPointer = subaddrressGetAllNative();
+ final subaddressAddresses = subaddressAddressesPointer.asTypedList(size);
+
+ return subaddressAddresses
+ .map((addr) => Pointer.fromAddress(addr).ref)
+ .toList();
+}
+
+addSubaddressSync({int accountIndex, String label}) {
+ final labelPointer = Utf8.toUtf8(label);
+ subaddrressAddNewNative(accountIndex, labelPointer);
+ free(labelPointer);
+}
+
+setLabelForSubaddressSync({int accountIndex, int addressIndex, String label}) {
+ final labelPointer = Utf8.toUtf8(label);
+ subaddrressSetLabelNative(accountIndex, addressIndex, labelPointer);
+ free(labelPointer);
+}
+
+_addSubaddress(Map args) =>
+ addSubaddressSync(accountIndex: args['accountIndex'], label: args['label']);
+
+_setLabelForSubaddress(Map args) => setLabelForSubaddressSync(
+ accountIndex: args['accountIndex'],
+ addressIndex: args['addressIndex'],
+ label: args['label']);
+
+Future addSubaddress({int accountIndex, String label}) async =>
+ compute(_addSubaddress, {'accountIndex': accountIndex, 'label': label});
+
+Future setLabelForSubaddress(
+ {int accountIndex, int addressIndex, String label}) =>
+ compute(_setLabelForSubaddress, {
+ 'accountIndex': accountIndex,
+ 'addressIndex': addressIndex,
+ 'label': label
+ });
\ No newline at end of file
diff --git a/cw_monero/lib/transaction_history.dart b/cw_monero/lib/transaction_history.dart
new file mode 100644
index 000000000..1b3ce9126
--- /dev/null
+++ b/cw_monero/lib/transaction_history.dart
@@ -0,0 +1,122 @@
+import 'dart:ffi';
+import 'package:cw_monero/structs/ut8_box.dart';
+import 'package:ffi/ffi.dart';
+import 'package:flutter/foundation.dart';
+import 'package:cw_monero/signatures.dart';
+import 'package:cw_monero/types.dart';
+import 'package:cw_monero/monero_api.dart';
+import 'package:cw_monero/structs/transaction_info_row.dart';
+import 'package:cw_monero/structs/pending_transaction.dart';
+import 'package:cw_monero/exceptions/creation_transaction_exception.dart';
+
+final transactionsRefreshNative = moneroApi
+ .lookup>('transactions_refresh')
+ .asFunction();
+
+final transactionsCountNative = moneroApi
+ .lookup>('transactions_count')
+ .asFunction();
+
+final transactionsGetAllNative = moneroApi
+ .lookup>('transactions_get_all')
+ .asFunction();
+
+final transactionCreateNative = moneroApi
+ .lookup>('transaction_create')
+ .asFunction();
+
+final transactionCommitNative = moneroApi
+ .lookup>('transaction_commit')
+ .asFunction();
+
+refreshTransactions() => transactionsRefreshNative();
+
+int countOfTransactions() => transactionsCountNative();
+
+List getAllTransations() {
+ final size = transactionsCountNative();
+ final transactionsPointer = transactionsGetAllNative();
+ final transactionsAddresses = transactionsPointer.asTypedList(size);
+
+ return transactionsAddresses
+ .map((addr) => Pointer.fromAddress(addr).ref)
+ .toList();
+}
+
+PendingTransactionDescription createTransactionSync(
+ {String address,
+ String paymentId,
+ String amount,
+ int priorityRaw,
+ int accountIndex = 0}) {
+ final addressPointer = Utf8.toUtf8(address);
+ final paymentIdPointer = Utf8.toUtf8(paymentId);
+ final amountPointer = amount != null ? Utf8.toUtf8(amount) : nullptr;
+ final errorMessagePointer = allocate();
+ final pendingTransactionRawPointer = allocate();
+ final created = transactionCreateNative(
+ addressPointer,
+ paymentIdPointer,
+ amountPointer,
+ priorityRaw,
+ accountIndex,
+ errorMessagePointer,
+ pendingTransactionRawPointer) !=
+ 0;
+
+ free(addressPointer);
+ free(paymentIdPointer);
+
+ if (amountPointer != nullptr) {
+ free(amountPointer);
+ }
+
+ if (!created) {
+ final message = errorMessagePointer.ref.getValue();
+ free(errorMessagePointer);
+ throw CreationTransactionException(message: message);
+ }
+
+ return PendingTransactionDescription(
+ amount: pendingTransactionRawPointer.ref.amount,
+ fee: pendingTransactionRawPointer.ref.fee,
+ hash: pendingTransactionRawPointer.ref.getHash(),
+ pointerAddress: pendingTransactionRawPointer.address);
+}
+
+commitTransactionFromPointerAddress({int address}) => commitTransaction(
+ transactionPointer: Pointer.fromAddress(address));
+
+commitTransaction({Pointer transactionPointer}) {
+ final errorMessagePointer = allocate();
+ final isCommited =
+ transactionCommitNative(transactionPointer, errorMessagePointer) != 0;
+
+ if (!isCommited) {
+ final message = errorMessagePointer.ref.getValue();
+ free(errorMessagePointer);
+ throw CreationTransactionException(message: message);
+ }
+}
+
+PendingTransactionDescription _createTransactionSync(Map args) =>
+ createTransactionSync(
+ address: args['address'],
+ paymentId: args['paymentId'],
+ amount: args['amount'],
+ priorityRaw: args['priorityRaw'],
+ accountIndex: args['accountIndex']);
+
+Future createTransaction(
+ {String address,
+ String paymentId,
+ String amount,
+ int priorityRaw,
+ int accountIndex = 0}) =>
+ compute(_createTransactionSync, {
+ 'address': address,
+ 'paymentId': paymentId,
+ 'amount': amount,
+ 'priorityRaw': priorityRaw,
+ 'accountIndex': accountIndex
+ });
diff --git a/cw_monero/lib/types.dart b/cw_monero/lib/types.dart
new file mode 100644
index 000000000..e2602ce91
--- /dev/null
+++ b/cw_monero/lib/types.dart
@@ -0,0 +1,106 @@
+import 'dart:ffi';
+import 'package:cw_monero/structs/pending_transaction.dart';
+import 'package:cw_monero/structs/ut8_box.dart';
+import 'package:ffi/ffi.dart';
+
+typedef CreateWallet = int Function(
+ Pointer, Pointer, Pointer, int, Pointer);
+
+typedef RestoreWalletFromSeed = int Function(
+ Pointer, Pointer, Pointer, int, int, Pointer);
+
+typedef RestoreWalletFromKeys = int Function(Pointer, Pointer,
+ Pointer, Pointer, Pointer, Pointer, int, int, Pointer);
+
+typedef IsWalletExist = int Function(Pointer);
+
+typedef LoadWallet = void Function(Pointer, Pointer, int);
+
+typedef GetFilename = Pointer Function();
+
+typedef GetSeed = Pointer Function();
+
+typedef GetAddress = Pointer Function(int, int);
+
+typedef GetFullBalance = int Function(int);
+
+typedef GetUnlockedBalance = int Function(int);
+
+typedef GetCurrentHeight = int Function();
+
+typedef GetNodeHeight = int Function();
+
+typedef IsConnected = int Function();
+
+typedef SetupNode = int Function(
+ Pointer, Pointer, Pointer, int, int, Pointer);
+
+typedef StartRefresh = void Function();
+
+typedef ConnectToNode = int Function();
+
+typedef SetRefreshFromBlockHeight = void Function(int);
+
+typedef SetRecoveringFromSeed = void Function(int);
+
+typedef Store = void Function(Pointer);
+
+typedef SetListener = void Function();
+
+typedef GetSyncingHeight = int Function();
+
+typedef IsNeededToRefresh = int Function();
+
+typedef IsNewTransactionExist = int Function();
+
+typedef SubaddressSize = int Function();
+
+typedef SubaddressRefresh = void Function(int);
+
+typedef SubaddressGetAll = Pointer Function();
+
+typedef SubaddressAddNew = void Function(int accountIndex, Pointer label);
+
+typedef SubaddressSetLabel = void Function(
+ int accountIndex, int addressIndex, Pointer label);
+
+typedef AccountSize = int Function();
+
+typedef AccountRefresh = void Function();
+
+typedef AccountGetAll = Pointer Function();
+
+typedef AccountAddNew = void Function(Pointer label);
+
+typedef AccountSetLabel = void Function(int accountIndex, Pointer label);
+
+typedef TransactionsRefresh = void Function();
+
+typedef TransactionsCount = int Function();
+
+typedef TransactionsGetAll = Pointer Function();
+
+typedef TransactionCreate = int Function(
+ Pointer address,
+ Pointer paymentId,
+ Pointer amount,
+ int priorityRaw,
+ int subaddrAccount,
+ Pointer error,
+ Pointer pendingTransaction);
+
+typedef TransactionCommit = int Function(Pointer, Pointer);
+
+typedef SecretViewKey = Pointer Function();
+
+typedef PublicViewKey = Pointer Function();
+
+typedef SecretSpendKey = Pointer Function();
+
+typedef PublicSpendKey = Pointer Function();
+
+typedef CloseCurrentWallet = void Function();
+
+typedef OnStartup = void Function();
+
+typedef RescanBlockchainAsync = void Function();
\ No newline at end of file
diff --git a/cw_monero/lib/wallet.dart b/cw_monero/lib/wallet.dart
new file mode 100644
index 000000000..560d6a79c
--- /dev/null
+++ b/cw_monero/lib/wallet.dart
@@ -0,0 +1,283 @@
+import 'dart:async';
+import 'dart:ffi';
+import 'package:ffi/ffi.dart';
+import 'package:cw_monero/convert_utf8_to_string.dart';
+import 'package:cw_monero/signatures.dart';
+import 'package:cw_monero/types.dart';
+import 'package:cw_monero/monero_api.dart';
+import 'package:cw_monero/exceptions/setup_wallet_exception.dart';
+import 'package:flutter/foundation.dart';
+import 'package:flutter/services.dart';
+
+int _boolToInt(bool value) => value ? 1 : 0;
+
+final moneroAPIChannel = const MethodChannel('cw_monero');
+
+final getFileNameNative = moneroApi
+ .lookup>('get_filename')
+ .asFunction();
+
+final getSeedNative =
+ moneroApi.lookup>('seed').asFunction();
+
+final getAddressNative = moneroApi
+ .lookup>('get_address')
+ .asFunction();
+
+final getFullBalanceNative = moneroApi
+ .lookup>('get_full_balance')
+ .asFunction();
+
+final getUnlockedBalanceNative = moneroApi
+ .lookup>('get_unlocked_balance')
+ .asFunction();
+
+final getCurrentHeightNative = moneroApi
+ .lookup>('get_current_height')
+ .asFunction();
+
+final getNodeHeightNative = moneroApi
+ .lookup>('get_node_height')
+ .asFunction();
+
+final isConnectedNative = moneroApi
+ .lookup>('is_connected')
+ .asFunction();
+
+final setupNodeNative = moneroApi
+ .lookup>('setup_node')
+ .asFunction();
+
+final startRefreshNative = moneroApi
+ .lookup>('start_refresh')
+ .asFunction();
+
+final connecToNodeNative = moneroApi
+ .lookup>('connect_to_node')
+ .asFunction();
+
+final setRefreshFromBlockHeightNative = moneroApi
+ .lookup>(
+ 'set_refresh_from_block_height')
+ .asFunction();
+
+final setRecoveringFromSeedNative = moneroApi
+ .lookup>(
+ 'set_recovering_from_seed')
+ .asFunction();
+
+final storeNative =
+ moneroApi.lookup>('store').asFunction();
+
+final setListenerNative = moneroApi
+ .lookup>('set_listener')
+ .asFunction();
+
+final getSyncingHeightNative = moneroApi
+ .lookup>('get_syncing_height')
+ .asFunction();
+
+final isNeededToRefreshNative = moneroApi
+ .lookup>('is_needed_to_refresh')
+ .asFunction();
+
+final isNewTransactionExistNative = moneroApi
+ .lookup>(
+ 'is_new_transaction_exist')
+ .asFunction();
+
+final getSecretViewKeyNative = moneroApi
+ .lookup>('secret_view_key')
+ .asFunction();
+
+final getPublicViewKeyNative = moneroApi
+ .lookup>('public_view_key')
+ .asFunction();
+
+final getSecretSpendKeyNative = moneroApi
+ .lookup>('secret_spend_key')
+ .asFunction();
+
+final getPublicSpendKeyNative = moneroApi
+ .lookup>('public_spend_key')
+ .asFunction();
+
+final closeCurrentWalletNative = moneroApi
+ .lookup>('close_current_wallet')
+ .asFunction();
+
+final onStartupNative = moneroApi
+ .lookup>('on_startup')
+ .asFunction();
+
+final rescanBlockchainAsyncNative = moneroApi
+ .lookup>('rescan_blockchain')
+ .asFunction();
+
+int getSyncingHeight() => getSyncingHeightNative();
+
+bool isNeededToRefresh() => isNeededToRefreshNative() != 0;
+
+bool isNewTransactionExist() => isNewTransactionExistNative() != 0;
+
+String getFilename() => convertUTF8ToString(pointer: getFileNameNative());
+
+String getSeed() => convertUTF8ToString(pointer: getSeedNative());
+
+String getAddress({int accountIndex = 0, int addressIndex = 0}) =>
+ convertUTF8ToString(pointer: getAddressNative(accountIndex, addressIndex));
+
+int getFullBalance({int accountIndex = 0}) =>
+ getFullBalanceNative(accountIndex);
+
+int getUnlockedBalance({int accountIndex = 0}) =>
+ getUnlockedBalanceNative(accountIndex);
+
+int getCurrentHeight() => getCurrentHeightNative();
+
+int getNodeHeightSync() => getNodeHeightNative();
+
+bool isConnectedSync() => isConnectedNative() != 0;
+
+bool setupNodeSync(
+ {String address,
+ String login,
+ String password,
+ bool useSSL = false,
+ bool isLightWallet = false}) {
+ final addressPointer = Utf8.toUtf8(address);
+ Pointer loginPointer;
+ Pointer passwordPointer;
+
+ if (login != null) {
+ loginPointer = Utf8.toUtf8(login);
+ }
+
+ if (password != null) {
+ passwordPointer = Utf8.toUtf8(password);
+ }
+
+ final errorMessagePointer = allocate();
+ final isSetupNode = setupNodeNative(
+ addressPointer,
+ loginPointer,
+ passwordPointer,
+ _boolToInt(useSSL),
+ _boolToInt(isLightWallet),
+ errorMessagePointer) !=
+ 0;
+
+ free(addressPointer);
+ free(loginPointer);
+ free(passwordPointer);
+
+ if (!isSetupNode) {
+ throw SetupWalletException(
+ message: convertUTF8ToString(pointer: errorMessagePointer));
+ }
+
+ return isSetupNode;
+}
+
+startRefreshSync() => startRefreshNative();
+
+Future connectToNode() async => connecToNodeNative() != 0;
+
+setRefreshFromBlockHeight({int height}) =>
+ setRefreshFromBlockHeightNative(height);
+
+setRecoveringFromSeed({bool isRecovery}) =>
+ setRecoveringFromSeedNative(_boolToInt(isRecovery));
+
+storeSync() {
+ final pathPointer = Utf8.toUtf8('');
+ storeNative(pathPointer);
+ free(pathPointer);
+}
+
+closeCurrentWallet() => closeCurrentWalletNative();
+
+String getSecretViewKey() =>
+ convertUTF8ToString(pointer: getSecretViewKeyNative());
+
+String getPublicViewKey() =>
+ convertUTF8ToString(pointer: getPublicViewKeyNative());
+
+String getSecretSpendKey() =>
+ convertUTF8ToString(pointer: getSecretSpendKeyNative());
+
+String getPublicSpendKey() =>
+ convertUTF8ToString(pointer: getPublicSpendKeyNative());
+
+Timer _updateSyncInfoTimer;
+
+int _lastKnownBlockHeight = 0;
+
+setListeners(Future Function(int) onNewBlock, Future Function() onNeedToRefresh,
+ Future Function() onNewTransaction) {
+ if (_updateSyncInfoTimer != null) {
+ _updateSyncInfoTimer.cancel();
+ }
+
+ _updateSyncInfoTimer = Timer.periodic(Duration(milliseconds: 200), (_) async {
+ final syncHeight = getSyncingHeight();
+ final needToRefresh = isNeededToRefresh();
+ final newTransactionExist = isNewTransactionExist();
+
+ if (_lastKnownBlockHeight != syncHeight && syncHeight != null) {
+ _lastKnownBlockHeight = syncHeight;
+ await onNewBlock(syncHeight);
+ }
+
+ if (newTransactionExist && onNewTransaction != null) {
+ await onNewTransaction();
+ }
+
+ if (needToRefresh && onNeedToRefresh != null) {
+ await onNeedToRefresh();
+ }
+ });
+ setListenerNative();
+}
+
+closeListeners() {
+ if (_updateSyncInfoTimer != null) {
+ _updateSyncInfoTimer.cancel();
+ }
+}
+
+onStartup() => onStartupNative();
+
+_storeSync(_) => storeSync();
+bool _setupNodeSync(Map args) => setupNodeSync(
+ address: args['address'],
+ login: args['login'] ?? '',
+ password: args['password'] ?? '',
+ useSSL: args['useSSL'],
+ isLightWallet: args['isLightWallet']);
+bool _isConnected(_) => isConnectedSync();
+int _getNodeHeight(_) => getNodeHeightSync();
+
+startRefresh() => startRefreshSync();
+
+Future setupNode(
+ {String address,
+ String login,
+ String password,
+ bool useSSL = false,
+ bool isLightWallet = false}) =>
+ compute(_setupNodeSync, {
+ 'address': address,
+ 'login': login,
+ 'password': password,
+ 'useSSL': useSSL,
+ 'isLightWallet': isLightWallet
+ });
+
+Future store() => compute(_storeSync, 0);
+
+Future isConnected() => compute(_isConnected, 0);
+
+Future getNodeHeight() => compute(_getNodeHeight, 0);
+
+rescanBlockchainAsync() => rescanBlockchainAsyncNative();
\ No newline at end of file
diff --git a/cw_monero/lib/wallet_manager.dart b/cw_monero/lib/wallet_manager.dart
new file mode 100644
index 000000000..4c6e2ef54
--- /dev/null
+++ b/cw_monero/lib/wallet_manager.dart
@@ -0,0 +1,218 @@
+import 'dart:ffi';
+import 'package:ffi/ffi.dart';
+import 'package:flutter/foundation.dart';
+import 'package:cw_monero/convert_utf8_to_string.dart';
+import 'package:cw_monero/signatures.dart';
+import 'package:cw_monero/types.dart';
+import 'package:cw_monero/monero_api.dart';
+import 'package:cw_monero/exceptions/wallet_creation_exception.dart';
+import 'package:cw_monero/exceptions/wallet_restore_from_keys_exception.dart';
+import 'package:cw_monero/exceptions/wallet_restore_from_seed_exception.dart';
+
+final createWalletNative = moneroApi
+ .lookup>('create_wallet')
+ .asFunction();
+
+final restoreWalletFromSeedNative = moneroApi
+ .lookup>(
+ 'restore_wallet_from_seed')
+ .asFunction();
+
+final restoreWalletFromKeysNative = moneroApi
+ .lookup>(
+ 'restore_wallet_from_keys')
+ .asFunction();
+
+final isWalletExistNative = moneroApi
+ .lookup>('is_wallet_exist')
+ .asFunction();
+
+final loadWalletNative = moneroApi
+ .lookup>('load_wallet')
+ .asFunction();
+
+createWalletSync(
+ {String path,
+ String password,
+ String language = 'English',
+ int nettype = 0}) {
+ final pathPointer = Utf8.toUtf8(path);
+ final passwordPointer = Utf8.toUtf8(password);
+ final languagePointer = Utf8.toUtf8(language);
+ final errorMessagePointer = allocate();
+ final isWalletCreated = createWalletNative(pathPointer, passwordPointer,
+ languagePointer, nettype, errorMessagePointer) !=
+ 0;
+
+ free(pathPointer);
+ free(passwordPointer);
+ free(languagePointer);
+
+ if (!isWalletCreated) {
+ throw WalletCreationException(
+ message: convertUTF8ToString(pointer: errorMessagePointer));
+ }
+}
+
+bool isWalletExistSync({String path}) {
+ final pathPointer = Utf8.toUtf8(path);
+ final isExist = isWalletExistNative(pathPointer) != 0;
+
+ free(pathPointer);
+
+ return isExist;
+}
+
+restoreWalletFromSeedSync(
+ {String path,
+ String password,
+ String seed,
+ int nettype = 0,
+ int restoreHeight = 0}) {
+ final pathPointer = Utf8.toUtf8(path);
+ final passwordPointer = Utf8.toUtf8(password);
+ final seedPointer = Utf8.toUtf8(seed);
+ final errorMessagePointer = allocate();
+ final isWalletRestored = restoreWalletFromSeedNative(
+ pathPointer,
+ passwordPointer,
+ seedPointer,
+ nettype,
+ restoreHeight,
+ errorMessagePointer) !=
+ 0;
+
+ free(pathPointer);
+ free(passwordPointer);
+ free(seedPointer);
+
+ if (!isWalletRestored) {
+ throw WalletRestoreFromSeedException(
+ message: convertUTF8ToString(pointer: errorMessagePointer));
+ }
+}
+
+restoreWalletFromKeysSync(
+ {String path,
+ String password,
+ String language = 'English',
+ String address,
+ String viewKey,
+ String spendKey,
+ int nettype = 0,
+ int restoreHeight = 0}) {
+ final pathPointer = Utf8.toUtf8(path);
+ final passwordPointer = Utf8.toUtf8(password);
+ final languagePointer = Utf8.toUtf8(language);
+ final addressPointer = Utf8.toUtf8(address);
+ final viewKeyPointer = Utf8.toUtf8(viewKey);
+ final spendKeyPointer = Utf8.toUtf8(spendKey);
+ final errorMessagePointer = allocate();
+ final isWalletRestored = restoreWalletFromKeysNative(
+ pathPointer,
+ passwordPointer,
+ languagePointer,
+ addressPointer,
+ viewKeyPointer,
+ spendKeyPointer,
+ nettype,
+ restoreHeight,
+ errorMessagePointer) !=
+ 0;
+
+ free(pathPointer);
+ free(passwordPointer);
+ free(languagePointer);
+ free(addressPointer);
+ free(viewKeyPointer);
+ free(spendKeyPointer);
+
+ if (!isWalletRestored) {
+ throw WalletRestoreFromKeysException(
+ message: convertUTF8ToString(pointer: errorMessagePointer));
+ }
+}
+
+loadWallet({String path, String password, int nettype = 0}) {
+ final pathPointer = Utf8.toUtf8(path);
+ final passwordPointer = Utf8.toUtf8(password);
+
+ loadWalletNative(pathPointer, passwordPointer, nettype);
+ free(pathPointer);
+ free(passwordPointer);
+}
+
+_createWallet(args) =>
+ createWalletSync(path: args['path'], password: args['password']);
+
+_restoreFromSeed(args) => restoreWalletFromSeedSync(
+ path: args['path'],
+ password: args['password'],
+ seed: args['seed'],
+ restoreHeight: args['restoreHeight']);
+
+_restoreFromKeys(args) => restoreWalletFromKeysSync(
+ path: args['path'],
+ password: args['password'],
+ restoreHeight: args['restoreHeight'],
+ address: args['address'],
+ viewKey: args['viewKey'],
+ spendKey: args['spendKey']);
+
+_openWallet(Map args) async =>
+ loadWallet(path: args['path'], password: args['password']);
+
+bool _isWalletExist(String path) => isWalletExistSync(path: path);
+
+openWallet({String path, String password, int nettype = 0}) async =>
+ loadWallet(path: path, password: password);
+
+Future openWalletAsync(Map args) async => compute(_openWallet, args);
+
+Future createWallet(
+ {String path,
+ String password,
+ String language = 'English',
+ int nettype = 0}) async =>
+ compute(_createWallet, {
+ 'path': path,
+ 'password': password,
+ 'language': language,
+ 'nettype': nettype
+ });
+
+Future restoreFromSeed(
+ {String path,
+ String password,
+ String seed,
+ int nettype = 0,
+ int restoreHeight = 0}) async =>
+ compute(_restoreFromSeed, {
+ 'path': path,
+ 'password': password,
+ 'seed': seed,
+ 'nettype': nettype,
+ 'restoreHeight': restoreHeight
+ });
+
+Future restoreFromKeys(
+ {String path,
+ String password,
+ String language = 'English',
+ String address,
+ String viewKey,
+ String spendKey,
+ int nettype = 0,
+ int restoreHeight = 0}) async =>
+ compute(_restoreFromKeys, {
+ 'path': path,
+ 'password': password,
+ 'language': language,
+ 'address': address,
+ 'viewKey': viewKey,
+ 'spendKey': spendKey,
+ 'nettype': nettype,
+ 'restoreHeight': restoreHeight
+ });
+
+Future isWalletExist({String path}) => compute(_isWalletExist, path);
\ No newline at end of file
diff --git a/cw_monero/pubspec.lock b/cw_monero/pubspec.lock
new file mode 100644
index 000000000..f462e288d
--- /dev/null
+++ b/cw_monero/pubspec.lock
@@ -0,0 +1,210 @@
+# Generated by pub
+# See https://dart.dev/tools/pub/glossary#lockfile
+packages:
+ archive:
+ dependency: transitive
+ description:
+ name: archive
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.0.11"
+ args:
+ dependency: transitive
+ description:
+ name: args
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.5.2"
+ async:
+ dependency: transitive
+ description:
+ name: async
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.4.0"
+ boolean_selector:
+ dependency: transitive
+ description:
+ name: boolean_selector
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.0.5"
+ charcode:
+ dependency: transitive
+ description:
+ name: charcode
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.1.2"
+ collection:
+ dependency: transitive
+ description:
+ name: collection
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.14.11"
+ convert:
+ dependency: transitive
+ description:
+ name: convert
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.1.1"
+ crypto:
+ dependency: transitive
+ description:
+ name: crypto
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.1.3"
+ ffi:
+ dependency: "direct main"
+ description:
+ name: ffi
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "0.1.3"
+ flutter:
+ dependency: "direct main"
+ description: flutter
+ source: sdk
+ version: "0.0.0"
+ flutter_test:
+ dependency: "direct dev"
+ description: flutter
+ source: sdk
+ version: "0.0.0"
+ image:
+ dependency: transitive
+ description:
+ name: image
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.1.4"
+ matcher:
+ dependency: transitive
+ description:
+ name: matcher
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "0.12.6"
+ meta:
+ dependency: transitive
+ description:
+ name: meta
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.1.8"
+ path:
+ dependency: transitive
+ description:
+ name: path
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.6.4"
+ path_provider:
+ dependency: "direct main"
+ description:
+ name: path_provider
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.4.0"
+ pedantic:
+ dependency: transitive
+ description:
+ name: pedantic
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.8.0+1"
+ petitparser:
+ dependency: transitive
+ description:
+ name: petitparser
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.4.0"
+ platform:
+ dependency: transitive
+ description:
+ name: platform
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.2.1"
+ quiver:
+ dependency: transitive
+ description:
+ name: quiver
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.0.5"
+ sky_engine:
+ dependency: transitive
+ description: flutter
+ source: sdk
+ version: "0.0.99"
+ source_span:
+ dependency: transitive
+ description:
+ name: source_span
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.5.5"
+ stack_trace:
+ dependency: transitive
+ description:
+ name: stack_trace
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.9.3"
+ stream_channel:
+ dependency: transitive
+ description:
+ name: stream_channel
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.0.0"
+ string_scanner:
+ dependency: transitive
+ description:
+ name: string_scanner
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.0.5"
+ term_glyph:
+ dependency: transitive
+ description:
+ name: term_glyph
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.1.0"
+ test_api:
+ dependency: transitive
+ description:
+ name: test_api
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "0.2.11"
+ typed_data:
+ dependency: transitive
+ description:
+ name: typed_data
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.1.6"
+ vector_math:
+ dependency: transitive
+ description:
+ name: vector_math
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.0.8"
+ xml:
+ dependency: transitive
+ description:
+ name: xml
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "3.5.0"
+sdks:
+ dart: ">=2.6.0 <3.0.0"
+ flutter: ">=0.1.4 <2.0.0"
diff --git a/cw_monero/pubspec.yaml b/cw_monero/pubspec.yaml
new file mode 100644
index 000000000..79229759c
--- /dev/null
+++ b/cw_monero/pubspec.yaml
@@ -0,0 +1,62 @@
+name: cw_monero
+description: A new flutter plugin project.
+version: 0.0.1
+author:
+homepage:
+
+environment:
+ sdk: ">=2.6.0 <3.0.0"
+
+dependencies:
+ flutter:
+ sdk: flutter
+ ffi: ^0.1.3
+ path_provider: ^1.4.0
+
+dev_dependencies:
+ flutter_test:
+ sdk: flutter
+
+# For information on the generic Dart part of this file, see the
+# following page: https://dart.dev/tools/pub/pubspec
+
+# The following section is specific to Flutter.
+flutter:
+ # This section identifies this Flutter project as a plugin project.
+ # The androidPackage and pluginClass identifiers should not ordinarily
+ # be modified. They are used by the tooling to maintain consistency when
+ # adding or updating assets for this project.
+ plugin:
+ androidPackage: com.cakewallet.monero
+ pluginClass: CwMoneroPlugin
+
+ # To add assets to your plugin package, add an assets section, like this:
+ # assets:
+ # - images/a_dot_burr.jpeg
+ # - images/a_dot_ham.jpeg
+ #
+ # For details regarding assets in packages, see
+ # https://flutter.dev/assets-and-images/#from-packages
+ #
+ # An image asset can refer to one or more resolution-specific "variants", see
+ # https://flutter.dev/assets-and-images/#resolution-aware.
+
+ # To add custom fonts to your plugin package, add a fonts section here,
+ # in this "flutter" section. Each entry in this list should have a
+ # "family" key with the font family name, and a "fonts" key with a
+ # list giving the asset and other descriptors for the font. For
+ # example:
+ # fonts:
+ # - family: Schyler
+ # fonts:
+ # - asset: fonts/Schyler-Regular.ttf
+ # - asset: fonts/Schyler-Italic.ttf
+ # style: italic
+ # - family: Trajan Pro
+ # fonts:
+ # - asset: fonts/TrajanPro.ttf
+ # - asset: fonts/TrajanPro_Bold.ttf
+ # weight: 700
+ #
+ # For details regarding fonts in packages, see
+ # https://flutter.dev/custom-fonts/#from-packages
diff --git a/ios/.gitignore b/ios/.gitignore
new file mode 100644
index 000000000..e96ef602b
--- /dev/null
+++ b/ios/.gitignore
@@ -0,0 +1,32 @@
+*.mode1v3
+*.mode2v3
+*.moved-aside
+*.pbxuser
+*.perspectivev3
+**/*sync/
+.sconsign.dblite
+.tags*
+**/.vagrant/
+**/DerivedData/
+Icon?
+**/Pods/
+**/.symlinks/
+profile
+xcuserdata
+**/.generated/
+Flutter/App.framework
+Flutter/Flutter.framework
+Flutter/Flutter.podspec
+Flutter/Generated.xcconfig
+Flutter/app.flx
+Flutter/app.zip
+Flutter/flutter_assets/
+Flutter/flutter_export_environment.sh
+ServiceDefinitions.json
+Runner/GeneratedPluginRegistrant.*
+
+# Exceptions to above rules.
+!default.mode1v3
+!default.mode2v3
+!default.pbxuser
+!default.perspectivev3
diff --git a/ios/Flutter/AppFrameworkInfo.plist b/ios/Flutter/AppFrameworkInfo.plist
new file mode 100644
index 000000000..6b4c0f78a
--- /dev/null
+++ b/ios/Flutter/AppFrameworkInfo.plist
@@ -0,0 +1,26 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ $(DEVELOPMENT_LANGUAGE)
+ CFBundleExecutable
+ App
+ CFBundleIdentifier
+ io.flutter.flutter.app
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ App
+ CFBundlePackageType
+ FMWK
+ CFBundleShortVersionString
+ 1.0
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ 1.0
+ MinimumOSVersion
+ 8.0
+
+
diff --git a/ios/Flutter/Debug.xcconfig b/ios/Flutter/Debug.xcconfig
new file mode 100644
index 000000000..e8efba114
--- /dev/null
+++ b/ios/Flutter/Debug.xcconfig
@@ -0,0 +1,2 @@
+#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
+#include "Generated.xcconfig"
diff --git a/ios/Flutter/Release.xcconfig b/ios/Flutter/Release.xcconfig
new file mode 100644
index 000000000..399e9340e
--- /dev/null
+++ b/ios/Flutter/Release.xcconfig
@@ -0,0 +1,2 @@
+#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
+#include "Generated.xcconfig"
diff --git a/ios/Podfile b/ios/Podfile
new file mode 100644
index 000000000..78d39756e
--- /dev/null
+++ b/ios/Podfile
@@ -0,0 +1,74 @@
+# Uncomment this line to define a global platform for your project
+# platform :ios, '9.0'
+
+# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
+ENV['COCOAPODS_DISABLE_STATS'] = 'true'
+
+project 'Runner', {
+ 'Debug' => :debug,
+ 'Profile' => :release,
+ 'Release' => :release,
+}
+
+def parse_KV_file(file, separator='=')
+ file_abs_path = File.expand_path(file)
+ if !File.exists? file_abs_path
+ return [];
+ end
+ pods_ary = []
+ skip_line_start_symbols = ["#", "/"]
+ File.foreach(file_abs_path) { |line|
+ next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ }
+ plugin = line.split(pattern=separator)
+ if plugin.length == 2
+ podname = plugin[0].strip()
+ path = plugin[1].strip()
+ podpath = File.expand_path("#{path}", file_abs_path)
+ pods_ary.push({:name => podname, :path => podpath});
+ else
+ puts "Invalid plugin specification: #{line}"
+ end
+ }
+ return pods_ary
+end
+
+target 'Runner' do
+ # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock
+ # referring to absolute paths on developers' machines.
+ use_frameworks!
+ system('rm -rf .symlinks')
+ system('mkdir -p .symlinks/plugins')
+
+ # Flutter Pods
+ generated_xcode_build_settings = parse_KV_file('./Flutter/Generated.xcconfig')
+ if generated_xcode_build_settings.empty?
+ puts "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first."
+ end
+ generated_xcode_build_settings.map { |p|
+ if p[:name] == 'FLUTTER_FRAMEWORK_DIR'
+ symlink = File.join('.symlinks', 'flutter')
+ File.symlink(File.dirname(p[:path]), symlink)
+ pod 'Flutter', :path => File.join(symlink, File.basename(p[:path]))
+ end
+ }
+
+ # Plugin Pods
+ plugin_pods = parse_KV_file('../.flutter-plugins')
+ plugin_pods.map { |p|
+ symlink = File.join('.symlinks', 'plugins', p[:name])
+ File.symlink(p[:path], symlink)
+ pod p[:name], :path => File.join(symlink, 'ios')
+ }
+end
+
+# Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system.
+install! 'cocoapods', :disable_input_output_paths => true
+
+post_install do |installer|
+ installer.pods_project.targets.each do |target|
+ target.build_configurations.each do |config|
+ config.build_settings['SWIFT_VERSION'] = '4.0' # required by simple_permission
+ config.build_settings['ENABLE_BITCODE'] = 'NO'
+ end
+ end
+end
diff --git a/ios/Podfile.lock b/ios/Podfile.lock
new file mode 100644
index 000000000..e7f54fa8f
--- /dev/null
+++ b/ios/Podfile.lock
@@ -0,0 +1,89 @@
+PODS:
+ - barcode_scan (0.0.1):
+ - Flutter
+ - MTBBarcodeScanner
+ - cw_monero (0.0.2):
+ - cw_monero/Boost (= 0.0.2)
+ - cw_monero/Monero (= 0.0.2)
+ - cw_monero/OpenSSL (= 0.0.2)
+ - cw_monero/Sodium (= 0.0.2)
+ - Flutter
+ - cw_monero/Boost (0.0.2):
+ - Flutter
+ - cw_monero/Monero (0.0.2):
+ - Flutter
+ - cw_monero/OpenSSL (0.0.2):
+ - Flutter
+ - cw_monero/Sodium (0.0.2):
+ - Flutter
+ - esys_flutter_share (0.0.1):
+ - Flutter
+ - Flutter (1.0.0)
+ - flutter_secure_storage (3.3.1):
+ - Flutter
+ - MTBBarcodeScanner (5.0.11)
+ - path_provider (0.0.1):
+ - Flutter
+ - share (0.5.2):
+ - Flutter
+ - shared_preferences (0.0.1):
+ - Flutter
+ - url_launcher (0.0.1):
+ - Flutter
+ - url_launcher_web (0.0.1):
+ - Flutter
+
+DEPENDENCIES:
+ - barcode_scan (from `.symlinks/plugins/barcode_scan/ios`)
+ - cw_monero (from `.symlinks/plugins/cw_monero/ios`)
+ - esys_flutter_share (from `.symlinks/plugins/esys_flutter_share/ios`)
+ - Flutter (from `.symlinks/flutter/ios-release`)
+ - flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`)
+ - path_provider (from `.symlinks/plugins/path_provider/ios`)
+ - share (from `.symlinks/plugins/share/ios`)
+ - shared_preferences (from `.symlinks/plugins/shared_preferences/ios`)
+ - url_launcher (from `.symlinks/plugins/url_launcher/ios`)
+ - url_launcher_web (from `.symlinks/plugins/url_launcher_web/ios`)
+
+SPEC REPOS:
+ trunk:
+ - MTBBarcodeScanner
+
+EXTERNAL SOURCES:
+ barcode_scan:
+ :path: ".symlinks/plugins/barcode_scan/ios"
+ cw_monero:
+ :path: ".symlinks/plugins/cw_monero/ios"
+ esys_flutter_share:
+ :path: ".symlinks/plugins/esys_flutter_share/ios"
+ Flutter:
+ :path: ".symlinks/flutter/ios-release"
+ flutter_secure_storage:
+ :path: ".symlinks/plugins/flutter_secure_storage/ios"
+ path_provider:
+ :path: ".symlinks/plugins/path_provider/ios"
+ share:
+ :path: ".symlinks/plugins/share/ios"
+ shared_preferences:
+ :path: ".symlinks/plugins/shared_preferences/ios"
+ url_launcher:
+ :path: ".symlinks/plugins/url_launcher/ios"
+ url_launcher_web:
+ :path: ".symlinks/plugins/url_launcher_web/ios"
+
+SPEC CHECKSUMS:
+ barcode_scan: 33f586d02270046fc6559135038b34b5754eaa4f
+ cw_monero: ca40a57b99f7753ed93d3b50af671a637277eb89
+ esys_flutter_share: 403498dab005b36ce1f8d7aff377e81f0621b0b4
+ Flutter: 0e3d915762c693b495b44d77113d4970485de6ec
+ flutter_secure_storage: 7953c38a04c3fdbb00571bcd87d8e3b5ceb9daec
+ MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb
+ path_provider: fb74bd0465e96b594bb3b5088ee4a4e7bb1f2a9d
+ share: bae0a282aab4483288913fc4dc0b935d4b491f2e
+ shared_preferences: 430726339841afefe5142b9c1f50cb6bd7793e01
+ url_launcher: a1c0cc845906122c4784c542523d8cacbded5626
+ url_launcher_web: e5527357f037c87560776e36436bf2b0288b965c
+
+PODFILE CHECKSUM: f1916a43bb28badbd408be80e8e4b8652a74e93e
+
+COCOAPODS: 1.8.4
diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj
new file mode 100644
index 000000000..ef5c8ce46
--- /dev/null
+++ b/ios/Runner.xcodeproj/project.pbxproj
@@ -0,0 +1,602 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 02AA3DBD66A19A0A1732294D /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00B973AD352B2957AC387EA9 /* Pods_Runner.framework */; };
+ 0C0DB1F8237DB1AE00BD32F9 /* A.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C0DB1F7237DB1AE00BD32F9 /* A.swift */; };
+ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
+ 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
+ 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; };
+ 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+ 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; };
+ 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+ 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; };
+ 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; };
+ 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; };
+ 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
+ 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
+ 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+ 9705A1C41CF9048500538489 /* Embed Frameworks */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "";
+ dstSubfolderSpec = 10;
+ files = (
+ 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */,
+ 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */,
+ );
+ name = "Embed Frameworks";
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+ 00B973AD352B2957AC387EA9 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ 0C0DB1F6237DB1AD00BD32F9 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; };
+ 0C0DB1F7237DB1AE00BD32F9 /* A.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = A.swift; sourceTree = ""; };
+ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; };
+ 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; };
+ 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; };
+ 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; };
+ 4B157CEA62824A43D7DD4C38 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; };
+ 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; };
+ 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
+ 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
+ 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; };
+ 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "