diff --git a/android/.project b/android/.project
new file mode 100644
index 000000000..17c95d4b1
--- /dev/null
+++ b/android/.project
@@ -0,0 +1,17 @@
+
+
+ android
+ Project android_ created by Buildship.
+
+
+
+
+ org.eclipse.buildship.core.gradleprojectbuilder
+
+
+
+
+
+ org.eclipse.buildship.core.gradleprojectnature
+
+
diff --git a/android/.settings/org.eclipse.buildship.core.prefs b/android/.settings/org.eclipse.buildship.core.prefs
new file mode 100644
index 000000000..e8895216f
--- /dev/null
+++ b/android/.settings/org.eclipse.buildship.core.prefs
@@ -0,0 +1,2 @@
+connection.project.dir=
+eclipse.preferences.version=1
diff --git a/android/app/.classpath b/android/app/.classpath
new file mode 100644
index 000000000..4a04201ca
--- /dev/null
+++ b/android/app/.classpath
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/android/app/.project b/android/app/.project
new file mode 100644
index 000000000..ac485d7c3
--- /dev/null
+++ b/android/app/.project
@@ -0,0 +1,23 @@
+
+
+ app
+ Project app created by Buildship.
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.buildship.core.gradleprojectbuilder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+ org.eclipse.buildship.core.gradleprojectnature
+
+
diff --git a/android/app/.settings/org.eclipse.buildship.core.prefs b/android/app/.settings/org.eclipse.buildship.core.prefs
new file mode 100644
index 000000000..b1886adb4
--- /dev/null
+++ b/android/app/.settings/org.eclipse.buildship.core.prefs
@@ -0,0 +1,2 @@
+connection.project.dir=..
+eclipse.preferences.version=1
diff --git a/cw_monero/android/.classpath b/cw_monero/android/.classpath
new file mode 100644
index 000000000..4a04201ca
--- /dev/null
+++ b/cw_monero/android/.classpath
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/cw_monero/android/.project b/cw_monero/android/.project
new file mode 100644
index 000000000..e0799208f
--- /dev/null
+++ b/cw_monero/android/.project
@@ -0,0 +1,23 @@
+
+
+ cw_monero
+ Project android created by Buildship.
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.buildship.core.gradleprojectbuilder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+ org.eclipse.buildship.core.gradleprojectnature
+
+
diff --git a/cw_monero/android/.settings/org.eclipse.buildship.core.prefs b/cw_monero/android/.settings/org.eclipse.buildship.core.prefs
new file mode 100644
index 000000000..a88c4d484
--- /dev/null
+++ b/cw_monero/android/.settings/org.eclipse.buildship.core.prefs
@@ -0,0 +1,13 @@
+arguments=
+auto.sync=false
+build.scans.enabled=false
+connection.gradle.distribution=GRADLE_DISTRIBUTION(VERSION(6.0-20191016123526+0000))
+connection.project.dir=../../android
+eclipse.preferences.version=1
+gradle.user.home=
+java.home=
+jvm.arguments=
+offline.mode=false
+override.workspace.settings=true
+show.console.view=true
+show.executions.view=true
diff --git a/cw_monero/ios/cw_monero.podspec b/cw_monero/ios/cw_monero.podspec
index 1fd4a89c2..78416a9e7 100644
--- a/cw_monero/ios/cw_monero.podspec
+++ b/cw_monero/ios/cw_monero.podspec
@@ -48,4 +48,9 @@ A new flutter plugin project.
sodium.libraries = 'sodium'
sodium.xcconfig = { 'HEADER_SEARCH_PATHS' => "${PODS_ROOT}/#{s.name}/External/ios/libs/sodium/include/**" }
end
+
+ s.subspec 'lmdb' do |lmdb|
+ lmdb.vendored_libraries = 'External/ios/libs/lmdb/liblmdb.a'
+ lmdb.libraries = 'lmdb'
+ end
end
\ No newline at end of file
diff --git a/ios/Podfile.lock b/ios/Podfile.lock
index e7f54fa8f..32b99bcb9 100644
--- a/ios/Podfile.lock
+++ b/ios/Podfile.lock
@@ -4,24 +4,33 @@ PODS:
- MTBBarcodeScanner
- cw_monero (0.0.2):
- cw_monero/Boost (= 0.0.2)
+ - cw_monero/lmdb (= 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/lmdb (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
+ - devicelocale (0.0.1):
+ - Flutter
- esys_flutter_share (0.0.1):
- Flutter
- Flutter (1.0.0)
- flutter_secure_storage (3.3.1):
- Flutter
+ - local_auth (0.0.1):
+ - Flutter
- MTBBarcodeScanner (5.0.11)
+ - package_info (0.0.1):
+ - Flutter
- path_provider (0.0.1):
- Flutter
- share (0.5.2):
@@ -36,9 +45,12 @@ PODS:
DEPENDENCIES:
- barcode_scan (from `.symlinks/plugins/barcode_scan/ios`)
- cw_monero (from `.symlinks/plugins/cw_monero/ios`)
+ - devicelocale (from `.symlinks/plugins/devicelocale/ios`)
- esys_flutter_share (from `.symlinks/plugins/esys_flutter_share/ios`)
- - Flutter (from `.symlinks/flutter/ios-release`)
+ - Flutter (from `.symlinks/flutter/ios`)
- flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`)
+ - local_auth (from `.symlinks/plugins/local_auth/ios`)
+ - package_info (from `.symlinks/plugins/package_info/ios`)
- path_provider (from `.symlinks/plugins/path_provider/ios`)
- share (from `.symlinks/plugins/share/ios`)
- shared_preferences (from `.symlinks/plugins/shared_preferences/ios`)
@@ -54,12 +66,18 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/barcode_scan/ios"
cw_monero:
:path: ".symlinks/plugins/cw_monero/ios"
+ devicelocale:
+ :path: ".symlinks/plugins/devicelocale/ios"
esys_flutter_share:
:path: ".symlinks/plugins/esys_flutter_share/ios"
Flutter:
- :path: ".symlinks/flutter/ios-release"
+ :path: ".symlinks/flutter/ios"
flutter_secure_storage:
:path: ".symlinks/plugins/flutter_secure_storage/ios"
+ local_auth:
+ :path: ".symlinks/plugins/local_auth/ios"
+ package_info:
+ :path: ".symlinks/plugins/package_info/ios"
path_provider:
:path: ".symlinks/plugins/path_provider/ios"
share:
@@ -73,11 +91,14 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
barcode_scan: 33f586d02270046fc6559135038b34b5754eaa4f
- cw_monero: ca40a57b99f7753ed93d3b50af671a637277eb89
+ cw_monero: 2e1f79929880cc2293b5bc1b25e28152e4d84649
+ devicelocale: feebbe5e7a30adb8c4f83185de1b50ff19b44f00
esys_flutter_share: 403498dab005b36ce1f8d7aff377e81f0621b0b4
Flutter: 0e3d915762c693b495b44d77113d4970485de6ec
flutter_secure_storage: 7953c38a04c3fdbb00571bcd87d8e3b5ceb9daec
+ local_auth: 2571c49920ae469f46d5557435fad8fa473a5e88
MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb
+ package_info: 48b108e75b8802c2d5e126f208ef540561c98aef
path_provider: fb74bd0465e96b594bb3b5088ee4a4e7bb1f2a9d
share: bae0a282aab4483288913fc4dc0b935d4b491f2e
shared_preferences: 430726339841afefe5142b9c1f50cb6bd7793e01
@@ -86,4 +107,4 @@ SPEC CHECKSUMS:
PODFILE CHECKSUM: f1916a43bb28badbd408be80e8e4b8652a74e93e
-COCOAPODS: 1.8.4
+COCOAPODS: 1.9.1
diff --git a/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
new file mode 100644
index 000000000..f9b0d7c5e
--- /dev/null
+++ b/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
@@ -0,0 +1,8 @@
+
+
+
+
+ PreviewsEnabled
+
+
+
diff --git a/lib/bitcoin/api.dart b/lib/bitcoin/api.dart
new file mode 100644
index 000000000..829637f0a
--- /dev/null
+++ b/lib/bitcoin/api.dart
@@ -0,0 +1,21 @@
+import 'dart:convert';
+import 'package:http/http.dart';
+
+const blockchainInfoBaseURI = 'https://blockchain.info';
+const multiAddressURI = '$blockchainInfoBaseURI/multiaddr';
+
+Future> fetchAllAddresses({String xpub}) async {
+ final uri = '$multiAddressURI?active=$xpub';
+ final response = await get(uri);
+ final responseJSON = json.decode(response.body) as Map;
+
+ print(responseJSON);
+
+ return (responseJSON['addresses'] as List).map((dynamic row) {
+ if (row is Map) {
+ return row['address'] as String;
+ }
+
+ return '';
+ }).toList();
+}
diff --git a/lib/bitcoin/bitcoin_amount_format.dart b/lib/bitcoin/bitcoin_amount_format.dart
new file mode 100644
index 000000000..a1ff8cecf
--- /dev/null
+++ b/lib/bitcoin/bitcoin_amount_format.dart
@@ -0,0 +1,13 @@
+import 'package:intl/intl.dart';
+import 'package:cake_wallet/src/domain/common/crypto_amount_format.dart';
+
+const bitcoinAmountLength = 8;
+const bitcoinAmountDivider = 100000000;
+final bitcoinAmountFormat = NumberFormat()
+ ..maximumFractionDigits = bitcoinAmountLength
+ ..minimumFractionDigits = 1;
+
+String bitcoinAmountToString({int amount}) =>
+ bitcoinAmountFormat.format(cryptoAmountToDouble(amount: amount, divider: bitcoinAmountDivider));
+
+double bitcoinAmountToDouble({int amount}) => cryptoAmountToDouble(amount: amount, divider: bitcoinAmountDivider);
diff --git a/lib/bitcoin/bitcoin_balance.dart b/lib/bitcoin/bitcoin_balance.dart
new file mode 100644
index 000000000..8f9d06fa0
--- /dev/null
+++ b/lib/bitcoin/bitcoin_balance.dart
@@ -0,0 +1,14 @@
+import 'package:flutter/foundation.dart';
+import 'package:cake_wallet/bitcoin/bitcoin_amount_format.dart';
+import 'package:cake_wallet/src/domain/common/balance.dart';
+
+class BitcoinBalance extends Balance {
+ BitcoinBalance({@required this.confirmed, @required this.unconfirmed});
+
+ final int confirmed;
+ final int unconfirmed;
+ int get total => confirmed + unconfirmed;
+ String get confirmedFormatted => bitcoinAmountToString(amount: confirmed);
+ String get unconfirmedFormatted => bitcoinAmountToString(amount: unconfirmed);
+ String get totalFormatted => bitcoinAmountToString(amount: total);
+}
diff --git a/lib/bitcoin/bitcoin_transaction_history.dart b/lib/bitcoin/bitcoin_transaction_history.dart
new file mode 100644
index 000000000..cbea45ef6
--- /dev/null
+++ b/lib/bitcoin/bitcoin_transaction_history.dart
@@ -0,0 +1,145 @@
+import 'dart:convert';
+import 'package:cake_wallet/bitcoin/bitcoin_wallet.dart';
+import 'package:flutter/foundation.dart';
+import 'package:rxdart/rxdart.dart';
+import 'package:cake_wallet/bitcoin/bitcoin_transaction_info.dart';
+import 'package:cake_wallet/bitcoin/electrum.dart';
+import 'package:cake_wallet/src/domain/common/transaction_history.dart';
+import 'package:cake_wallet/src/domain/common/transaction_info.dart';
+import 'package:cake_wallet/bitcoin/file.dart';
+
+class BitcoinTransactionHistory extends TransactionHistory {
+ BitcoinTransactionHistory(
+ {@required this.eclient,
+ @required this.path,
+ @required String password,
+ @required this.wallet})
+ : _transactions = BehaviorSubject>.seeded([]),
+ _password = password,
+ _height = 0;
+
+ final BitcoinWallet wallet;
+ final ElectrumClient eclient;
+ final String path;
+ final String _password;
+ int _height;
+
+ @override
+ Observable> get transactions => _transactions.stream;
+ List get transactionsAll => _transactions.value;
+ final BehaviorSubject> _transactions;
+ bool _isUpdating = false;
+
+ Future init() async {
+ final info = await _read();
+ _height = (info['height'] as int) ?? _height;
+ _transactions.value = info['transactions'] as List;
+ }
+
+ @override
+ Future> getAll() async => _transactions.value;
+
+ @override
+ Future update() async {
+ if (_isUpdating) {
+ return;
+ }
+
+ try {
+ _isUpdating = true;
+ final newTransasctions = await fetchTransactions();
+ _transactions.value = _transactions.value + newTransasctions;
+ _updateHeight();
+ await save();
+ _isUpdating = false;
+ } catch (e) {
+ _isUpdating = false;
+ rethrow;
+ }
+ }
+
+ Future