-## Open Source Monero and Bitcoin Wallet
+
+
+
+
+
+
+
+[

](https://apps.apple.com/us/app/cake-wallet/id1334702542?platform=iphone)
+[

](https://play.google.com/store/apps/details?id=com.cakewallet.cake_wallet)
+[

](https://fdroid.cakelabs.com)
+[

](https://apps.apple.com/us/app/cake-wallet/id1334702542?platform=mac)
+[

](https://github.com/cake-tech/cake_wallet/releases)
+
+
+
+# Cake Wallet
+
+[Cake Wallet](https://cakewallet.com) is an open-source, non-custodial, and private multi-currency crypto wallet for Android, iOS, macOS, and Linux.
+
+Cake Wallet includes support for several cryptocurrencies, including:
+* Monero (XMR)
+* Bitcoin (BTC)
+* Ethereum (ETH)
+* Litecoin (LTC)
+* Bitcoin Cash (BCH)
+* Polygon (POL)
+* Solana (SOL)
+* Tron (TRX)
+* Nano (XNO)
+* Zano (ZANO)
+* Decred (DCR)
+* Wownero (WOW)
+
+## Features
+
+### App-Wide Features
+
+* Completely noncustodial. *Your keys, your coins.*
+* Built-in exchange for dozens of pairs
+* Easily pay cryptocurrency invoices with fixed rate exchanges
+* Buy cryptocurrency (BTC/LTC/XMR/ETH) with credit/debit/bank
+* Sell cryptocurrency by bank transfer
+* Scan QR codes for easy cryptocurrency transfers
+* Create several wallets
+* Select your own custom nodes/servers
+* Address book
+* Backup to an external location or iCloud
+* Send to OpenAlias, Unstoppable Domains, Yats, and FIO Crypto Handles
+* Set desired network fee level
+* Store local transaction notes
+* Extremely simple user experience
+* Convenient exchange and sending templates for recurring payments
+* Create donation links and invoices in the receive screen
+* Robust privacy settings (eg: Tor-only connections)
+* Robust security settings (eg: Cake 2FA)
+
+### Monero Specific Features
+
+* The Monero view key is retained on the device for maximum privacy
+* Full support for Monero subaddresses and accounts
+* Specify restore height for faster syncing
+* Specify multiple recipients for batch sending
+* Optionally set Monero nodes as trusted for faster syncing
+* Specify a proxy for Monero nodes, compatible with Tor and i2p
+
+### Bitcoin Specific Features
+
+* Bitcoin coin control (specify specific outputs to spend)
+* Automatically generate new addresses
+* Specify multiple recipients for batch sending
+
+### Ethereum Specific Features
+
+* Store ETH and all ERc-20 tokens
+* Add custom tokens by contract address
+* Enable or disable Etherscan for transaction history
+
+### Litecoin Specific Features
+
+* Litecoin coin control (specify specific outputs to spend)
+* Automatically generate new addresses
+* Specify multiple recipients for batch sending
+
+# Monero.com by Cake Wallet for Android and iOS
+
+## Open Source Monero-Only Wallet
+
+*Exchanging to/from other assets is also supported.*
+
+## Links
+
+* Website: https://monero.com
+* App Store (iOS): https://apps.apple.com/app/id1601990386
+* Google Play: https://play.google.com/store/apps/details?id=com.monero.app
+* F-Droid: https://fdroid.cakelabs.com
+* APK: https://github.com/cake-tech/cake_wallet/releases
+
+### APK Verification
+
+APK releases on GitHub, Accrescent, and F-Droid use the same key. They can easily be verified using [apksigner](https://developer.android.com/tools/apksigner#options-verify) or [AppVerifier](https://github.com/soupslurpr/AppVerifier).
+
+See below for Cake Wallet's SHA-256 signing certificate hash:
+
+```
+com.cakewallet.cake_wallet
+C5:40:53:AB:0F:10:D9:54:17:62:A3:DA:76:65:AE:3D:BA:5E:7C:74:3A:B4:F1:08:A5:34:9D:62:AC:10:6E:F5
+```
+
+# Support
+
+We have 24/7 free support. Please contact support@cakewallet.com
+
+We have excellent user guides, which are also open-source and open for contributions: https://guides.cakewallet.com
+
+# Build Instructions
More instructions to follow
-For instructions on how to build for Android: please view file `howto-build-android.md`
\ No newline at end of file
+For instructions on how to build for Android: please view file `howto-build-android.md`
+
+# Contributing
+
+## Improving translations
+
+Edit the applicable `strings_XX.arb` file in `res/values/` and open a pull request with the changes.
+
+## Current list of language files:
+
+- English
+- Spanish
+- French
+- German
+- Italian
+- Portuguese
+- Dutch
+- Polish
+- Croatian
+- Russian
+- Ukrainian
+- Hindi
+- Japanese
+- Chinese
+- Korean
+- Thai
+- Arabic
+- Turkish
+- Burmese
+- Urdu
+- Bulgarian
+- Czech
+- Indonesian
+- Hausa
+- Yoruba
+
+## Add a new language
+
+1. Create a new `strings_XX.arb` file in `res/values/`, replacing XX with the language's [ISO 639-1 code](https://en.wikipedia.org/wiki/ISO_639-1).
+
+2. Edit the strings in this file, replacing XXX below with the translation for each string.
+
+`"welcome": "Welcome to",` -> `"welcome": "XXX",`
+
+3. For strings where there is a variable, denoted by a $ symbol and braces, such as ${status}, the string in braces should not be translated. For example, when editing line 106:
+
+"time" : "${minutes}m ${seconds}s"
+
+The only parts to be translated, if needed, are the values m and s after the variables.
+
+4. Add the language to `lib/entities/language_service.dart` under both `supportedLocales` and `localeCountryCode`. Use the name of the language in the local language and in English in parentheses after for `supportedLocales`. Use the [ISO 3166-1 alpha-3 code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-3) for `localeCountryCode`. You must choose one country, so choose the country with the most native speakers of this language or is otherwise best associated with this language.
+
+5. Add a relevant flag to `assets/images/flags/XXXX.png`, replacing XXXX with the 3 letters localeCountryCode. The image must be 42x26 pixels with 3 pixels of transparent margin on all 4 sides. You can resize the flag with [paint.net](https://www.getpaint.net/) to 36x20 pixels, expand the canvas to 42x26 pixels with the flag anchored in the middle, and then manually delete the 3 pixels on each side to make it transparent. Or you can use another program like Photoshop.
+
+6. Add the new language code to `tool/utils/translation/translation_constants.dart`
+
+## Add a new fiat currency
+
+1. Check with [Cake Wallet support](https://guides.cakewallet.com) to see if the desired new fiat currency is available through our fiat API. Not all fiat currencies are.
+
+2. If the currency is associated strongly with a specific issuing country, map the [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) currency code with the applicable [ISO 3166-1 alpha-3 code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-3) in `lib/entities/fiat_currency.dart`. If the currency is used in a whole region or organization, then map with a reasonable interpretation of this (eg: eur countryCode for EUR symbol).
+
+3. Add the raw mapping underneath in `lib/entities/fiat_currency.dart` following the same format as the others.
+
+4. Add a flag of the issuing country or organization to `assets/images/flags/XXXX.png`, replacing XXXX with the ISO 3166-1 alpha-3 code used above (eg: `usa.png`, `eur.png`). Do not add this if the flag with the same name already exists. The image must be 42x26 pixels with a 3 pixels of transparent margin on all 4 sides.
+
+---
+
+Copyright (C) 2018-2023 Cake Labs LLC
diff --git a/analysis_options.yaml b/analysis_options.yaml
index 52f1e3224..bd35233ba 100644
--- a/analysis_options.yaml
+++ b/analysis_options.yaml
@@ -1,55 +1,88 @@
+include: package:lints/recommended.yaml
+
+
analyzer:
- strong-mode:
- implicit-casts: false
- implicit-dynamic: false
- exclude:
- - "build/**"
- - "lib/generated/*.dart"
- - "**.g.dart"
+ exclude: [
+ build/**,
+ lib/**.g.dart,
+ cw_core/lib/**.g.dart,
+ cw_haven/lib/**.g.dart,
+ cw_monero/lib/**.g.dart,
+ lib/generated/*.dart,
+ cw_monero/ios/External/**,
+ cw_shared_external/**,
+ shared_external/**,
+ lib/bitcoin/cw_bitcoin.dart,
+ lib/bitcoin_cash/cw_bitcoin_cash.dart,
+ lib/ethereum/cw_ethereum.dart,
+ lib/haven/cw_haven.dart,
+ lib/monero/cw_monero.dart,
+ lib/nano/cw_nano.dart,
+ lib/polygon/cw_polygon.dart,
+ lib/solana/cw_solana.dart,
+ lib/tron/cw_tron.dart,
+ lib/wownero/cw_wownero.dart,
+ lib/zano/cw_zano.dart,
+ ]
+ language:
+ strict-casts: true
+ strict-raw-types: true
linter:
rules:
- - always_declare_return_types
- - annotate_overrides
- - 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
+ - always_declare_return_types
- prefer_final_fields
- - prefer_final_locals
- - prefer_is_not_empty
- - slash_for_doc_comments
- - sort_constructors_first
- - sort_unnamed_constructors_first
- - test_types_in_equals
- - throw_in_finally
- - type_init_formals
- - unawaited_futures
- - unnecessary_getters_setters
- - unrelated_type_equality_checks
- - valid_regexps
\ No newline at end of file
+
+
+# analyzer:
+# strong-mode:
+# implicit-casts: false
+# implicit-dynamic: false
+# exclude: [build/**, lib/generated/*.dart, lib/**.g.dart, cw_monero/ios/External/**, cw_shared_external/**, shared_external/**]
+
+# linter:
+# rules:
+# - always_declare_return_types
+# - annotate_overrides
+# - 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
+# - 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
+# - slash_for_doc_comments
+# - sort_constructors_first
+# - sort_unnamed_constructors_first
+# - test_types_in_equals
+# - throw_in_finally
+# - type_init_formals
+# - unawaited_futures
+# - unnecessary_getters_setters
+# - unrelated_type_equality_checks
+# - valid_regexps
diff --git a/android/.settings/org.eclipse.buildship.core.prefs b/android/.settings/org.eclipse.buildship.core.prefs
index e8895216f..9d2efc8e7 100644
--- a/android/.settings/org.eclipse.buildship.core.prefs
+++ b/android/.settings/org.eclipse.buildship.core.prefs
@@ -1,2 +1,2 @@
connection.project.dir=
-eclipse.preferences.version=1
+eclipse.preferences.version=1
\ No newline at end of file
diff --git a/android/app/build.gradle b/android/app/build.gradle
index 0c6a46dc4..4a8045bb3 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -1,3 +1,9 @@
+plugins {
+ id "com.android.application"
+ id "kotlin-android"
+ id "dev.flutter.flutter-gradle-plugin"
+}
+
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
@@ -6,11 +12,6 @@ if (localPropertiesFile.exists()) {
}
}
-def flutterRoot = localProperties.getProperty('flutter.sdk')
-if (flutterRoot == null) {
- throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
-}
-
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
@@ -21,30 +22,44 @@ 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))
}
+def appProperties = new Properties()
+def appPropertiesFile = rootProject.file('app.properties')
+if (appPropertiesFile.exists()) {
+ appProperties.load(new FileInputStream(appPropertiesFile))
+}
+
android {
- compileSdkVersion 29
+ compileSdkVersion 35
+ buildToolsVersion "35.0.0"
lintOptions {
disable 'InvalidPackage'
}
+ compileOptions {
+ coreLibraryDesugaringEnabled true
+
+ sourceCompatibility JavaVersion.VERSION_17
+ targetCompatibility JavaVersion.VERSION_17
+ }
+
+
+ namespace "com.cakewallet.cake_wallet"
+
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 29
+ applicationId appProperties['id']
+ minSdkVersion 24
+ targetSdkVersion 34
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ manifestPlaceholders = [APP_NAME: appProperties['name']]
externalNativeBuild {
cmake {
@@ -66,13 +81,14 @@ android {
buildTypes {
release {
signingConfig signingConfigs.release
-
- minifyEnabled true
- useProguard true
-
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
+ debug {
+ signingConfig signingConfigs.release
+ }
}
+
+ ndkVersion "27.0.12077973"
}
flutter {
@@ -81,6 +97,12 @@ flutter {
dependencies {
testImplementation 'junit:junit:4.12'
- androidTestImplementation 'androidx.test:runner:1.1.1'
- androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
+ androidTestImplementation 'androidx.test:runner:1.3.0'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
+ coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.1.5'
+}
+configurations {
+ implementation.exclude module:'proto-google-common-protos'
+ implementation.exclude module:'protolite-well-known-types'
+ implementation.exclude module:'protobuf-javalite'
}
diff --git a/android/app/proguard-rules.pro b/android/app/proguard-rules.pro
index d24d7f10a..a733bae9e 100644
--- a/android/app/proguard-rules.pro
+++ b/android/app/proguard-rules.pro
@@ -5,4 +5,98 @@
-keep class io.flutter.view.** { *; }
-keep class io.flutter.** { *; }
-keep class io.flutter.plugins.** { *; }
--dontwarn io.flutter.embedding.**
\ No newline at end of file
+-dontwarn io.flutter.embedding.**
+-dontwarn com.google.android.play.core.splitcompat.SplitCompatApplication
+
+# start reown
+-dontwarn com.github.luben.zstd.BufferPool
+-dontwarn com.github.luben.zstd.ZstdInputStream
+-dontwarn com.github.luben.zstd.ZstdOutputStream
+-dontwarn com.google.api.client.http.GenericUrl
+-dontwarn com.google.api.client.http.HttpHeaders
+-dontwarn com.google.api.client.http.HttpRequest
+-dontwarn com.google.api.client.http.HttpRequestFactory
+-dontwarn com.google.api.client.http.HttpResponse
+-dontwarn com.google.api.client.http.HttpTransport
+-dontwarn com.google.api.client.http.javanet.NetHttpTransport$Builder
+-dontwarn com.google.api.client.http.javanet.NetHttpTransport
+-dontwarn java.awt.Color
+-dontwarn java.awt.Dimension
+-dontwarn java.awt.Graphics2D
+-dontwarn java.awt.Graphics
+-dontwarn java.awt.Image
+-dontwarn java.awt.Point
+-dontwarn java.awt.Polygon
+-dontwarn java.awt.Shape
+-dontwarn java.awt.color.ColorSpace
+-dontwarn java.awt.geom.AffineTransform
+-dontwarn java.awt.image.BufferedImage
+-dontwarn java.awt.image.ColorModel
+-dontwarn java.awt.image.ComponentColorModel
+-dontwarn java.awt.image.ComponentSampleModel
+-dontwarn java.awt.image.DataBuffer
+-dontwarn java.awt.image.DataBufferByte
+-dontwarn java.awt.image.DataBufferInt
+-dontwarn java.awt.image.DataBufferUShort
+-dontwarn java.awt.image.ImageObserver
+-dontwarn java.awt.image.MultiPixelPackedSampleModel
+-dontwarn java.awt.image.Raster
+-dontwarn java.awt.image.RenderedImage
+-dontwarn java.awt.image.SampleModel
+-dontwarn java.awt.image.SinglePixelPackedSampleModel
+-dontwarn java.awt.image.WritableRaster
+-dontwarn java.beans.BeanInfo
+-dontwarn java.beans.FeatureDescriptor
+-dontwarn java.beans.IntrospectionException
+-dontwarn java.beans.Introspector
+-dontwarn java.beans.PropertyDescriptor
+-dontwarn java.lang.reflect.InaccessibleObjectException
+-dontwarn javax.imageio.IIOImage
+-dontwarn javax.imageio.ImageIO
+-dontwarn javax.imageio.ImageWriteParam
+-dontwarn javax.imageio.ImageWriter
+-dontwarn javax.imageio.metadata.IIOMetadata
+-dontwarn javax.imageio.stream.ImageOutputStream
+-dontwarn javax.swing.JComponent
+-dontwarn javax.swing.JFileChooser
+-dontwarn javax.swing.JFrame
+-dontwarn javax.swing.JPanel
+-dontwarn javax.swing.ProgressMonitor
+-dontwarn javax.swing.SwingUtilities
+-dontwarn org.brotli.dec.BrotliInputStream
+-dontwarn org.joda.time.Instant
+-dontwarn org.objectweb.asm.AnnotationVisitor
+-dontwarn org.objectweb.asm.Attribute
+-dontwarn org.objectweb.asm.ClassReader
+-dontwarn org.objectweb.asm.ClassVisitor
+-dontwarn org.objectweb.asm.FieldVisitor
+-dontwarn org.objectweb.asm.Label
+-dontwarn org.objectweb.asm.MethodVisitor
+-dontwarn org.objectweb.asm.Type
+-dontwarn org.tukaani.xz.ARMOptions
+-dontwarn org.tukaani.xz.ARMThumbOptions
+-dontwarn org.tukaani.xz.DeltaOptions
+-dontwarn org.tukaani.xz.FilterOptions
+-dontwarn org.tukaani.xz.FinishableOutputStream
+-dontwarn org.tukaani.xz.FinishableWrapperOutputStream
+-dontwarn org.tukaani.xz.IA64Options
+-dontwarn org.tukaani.xz.LZMA2InputStream
+-dontwarn org.tukaani.xz.LZMA2Options
+-dontwarn org.tukaani.xz.LZMAInputStream
+-dontwarn org.tukaani.xz.LZMAOutputStream
+-dontwarn org.tukaani.xz.MemoryLimitException
+-dontwarn org.tukaani.xz.PowerPCOptions
+-dontwarn org.tukaani.xz.SPARCOptions
+-dontwarn org.tukaani.xz.SingleXZInputStream
+-dontwarn org.tukaani.xz.UnsupportedOptionsException
+-dontwarn org.tukaani.xz.X86Options
+-dontwarn org.tukaani.xz.XZ
+-dontwarn org.tukaani.xz.XZInputStream
+-dontwarn org.tukaani.xz.XZOutputStream
+-dontwarn us.hebi.matlab.mat.ejml.Mat5Ejml
+-dontwarn us.hebi.matlab.mat.format.Mat5
+-dontwarn us.hebi.matlab.mat.format.Mat5File
+-dontwarn us.hebi.matlab.mat.types.Array
+-dontwarn us.hebi.matlab.mat.types.MatFile$Entry
+-dontwarn us.hebi.matlab.mat.types.MatFile
+# end reown
\ No newline at end of file
diff --git a/android/app/src/debug/AndroidManifest.xml b/android/app/src/debug/AndroidManifest.xml
index dc767a55d..f880684a6 100644
--- a/android/app/src/debug/AndroidManifest.xml
+++ b/android/app/src/debug/AndroidManifest.xml
@@ -1,5 +1,4 @@
-