mirror of
https://github.com/Such-Software/hash-wallet.git
synced 2026-10-22 06:28:39 +02:00
BTC
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
import 'dart:io';
|
||||
import 'package:cake_wallet/src/domain/common/wallet_type.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
|
||||
Future<String> pathForWalletDir({@required String name, @required WalletType type}) async {
|
||||
final root = await getApplicationDocumentsDirectory();
|
||||
final prefix = walletTypeToString(type).toLowerCase();
|
||||
final walletsDir = Directory('${root.path}/wallets');
|
||||
final walletDire = Directory('${walletsDir.path}/$prefix/$name');
|
||||
|
||||
if (!walletDire.existsSync()) {
|
||||
walletDire.createSync(recursive: true);
|
||||
}
|
||||
|
||||
return walletDire.path;
|
||||
}
|
||||
|
||||
Future<String> pathForWallet({@required String name, @required WalletType type}) async =>
|
||||
await pathForWalletDir(name: name, type: type)
|
||||
.then((path) => path + '/$name');
|
||||
@@ -4,7 +4,5 @@ import 'package:cake_wallet/src/domain/common/transaction_info.dart';
|
||||
abstract class TransactionHistory {
|
||||
Observable<List<TransactionInfo>> transactions;
|
||||
Future<List<TransactionInfo>> getAll();
|
||||
Future<int> count();
|
||||
Future refresh();
|
||||
Future update();
|
||||
}
|
||||
|
||||
@@ -1,49 +1,11 @@
|
||||
import 'package:cake_wallet/src/domain/monero/monero_amount_format.dart';
|
||||
import 'package:cw_monero/structs/transaction_info_row.dart';
|
||||
import 'package:cake_wallet/src/domain/common/parseBoolFromString.dart';
|
||||
import 'package:cake_wallet/src/domain/common/transaction_direction.dart';
|
||||
import 'package:cake_wallet/src/domain/common/format_amount.dart';
|
||||
|
||||
class TransactionInfo {
|
||||
TransactionInfo(this.id, this.height, this.direction, this.date,
|
||||
this.isPending, this.amount, this.accountIndex);
|
||||
|
||||
TransactionInfo.fromMap(Map map)
|
||||
: id = (map['hash'] ?? '') as String,
|
||||
height = (map['height'] ?? 0) as int,
|
||||
direction =
|
||||
parseTransactionDirectionFromNumber(map['direction'] as String) ??
|
||||
TransactionDirection.incoming,
|
||||
date = DateTime.fromMillisecondsSinceEpoch(
|
||||
(int.parse(map['timestamp'] as String) ?? 0) * 1000),
|
||||
isPending = parseBoolFromString(map['isPending'] as String),
|
||||
amount = map['amount'] as int,
|
||||
accountIndex = int.parse(map['accountIndex'] as String);
|
||||
|
||||
TransactionInfo.fromRow(TransactionInfoRow row)
|
||||
: id = row.getHash(),
|
||||
height = row.blockHeight,
|
||||
direction = parseTransactionDirectionFromInt(row.direction) ??
|
||||
TransactionDirection.incoming,
|
||||
date = DateTime.fromMillisecondsSinceEpoch(row.getDatetime() * 1000),
|
||||
isPending = row.isPending != 0,
|
||||
amount = row.getAmount(),
|
||||
accountIndex = row.subaddrAccount;
|
||||
|
||||
final String id;
|
||||
final int height;
|
||||
final TransactionDirection direction;
|
||||
final DateTime date;
|
||||
final int accountIndex;
|
||||
final bool isPending;
|
||||
final int amount;
|
||||
String recipientAddress;
|
||||
|
||||
String _fiatAmount;
|
||||
|
||||
String amountFormatted() => '${formatAmount(moneroAmountToString(amount: amount))} XMR';
|
||||
|
||||
String fiatAmount() => _fiatAmount ?? '';
|
||||
|
||||
void changeFiatAmount(String amount) => _fiatAmount = formatAmount(amount);
|
||||
}
|
||||
abstract class TransactionInfo extends Object {
|
||||
int amount;
|
||||
TransactionDirection direction;
|
||||
bool isPending;
|
||||
DateTime date;
|
||||
int height;
|
||||
String amountFormatted();
|
||||
String fiatAmount();
|
||||
}
|
||||
@@ -2,13 +2,18 @@ import 'package:hive/hive.dart';
|
||||
|
||||
part 'wallet_type.g.dart';
|
||||
|
||||
const walletTypes = [WalletType.monero, WalletType.bitcoin];
|
||||
|
||||
@HiveType()
|
||||
enum WalletType {
|
||||
@HiveField(0)
|
||||
monero,
|
||||
|
||||
@HiveField(1)
|
||||
none
|
||||
none,
|
||||
|
||||
@HiveField(2)
|
||||
bitcoin
|
||||
}
|
||||
|
||||
int serializeToInt(WalletType type) {
|
||||
@@ -33,7 +38,9 @@ String walletTypeToString(WalletType type) {
|
||||
switch (type) {
|
||||
case WalletType.monero:
|
||||
return 'Monero';
|
||||
case WalletType.bitcoin:
|
||||
return 'Bitcoin';
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'dart:core';
|
||||
import 'package:cake_wallet/src/domain/monero/monero_transaction_info.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:rxdart/rxdart.dart';
|
||||
import 'package:cw_monero/transaction_history.dart'
|
||||
@@ -6,10 +7,11 @@ import 'package:cw_monero/transaction_history.dart'
|
||||
import 'package:cake_wallet/src/domain/common/transaction_history.dart';
|
||||
import 'package:cake_wallet/src/domain/common/transaction_info.dart';
|
||||
|
||||
List<TransactionInfo> _getAllTransactions(dynamic _) => monero_transaction_history
|
||||
.getAllTransations()
|
||||
.map((row) => TransactionInfo.fromRow(row))
|
||||
.toList();
|
||||
List<TransactionInfo> _getAllTransactions(dynamic _) =>
|
||||
monero_transaction_history
|
||||
.getAllTransations()
|
||||
.map((row) => MoneroTransactionInfo.fromRow(row))
|
||||
.toList();
|
||||
|
||||
class MoneroTransactionHistory extends TransactionHistory {
|
||||
MoneroTransactionHistory()
|
||||
@@ -31,7 +33,6 @@ class MoneroTransactionHistory extends TransactionHistory {
|
||||
|
||||
try {
|
||||
_isUpdating = true;
|
||||
await refresh();
|
||||
_transactions.value = await getAll(force: true);
|
||||
_isUpdating = false;
|
||||
|
||||
@@ -46,13 +47,11 @@ class MoneroTransactionHistory extends TransactionHistory {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<TransactionInfo>> getAll({bool force = false}) async =>
|
||||
_getAllTransactions(null);
|
||||
Future<List<TransactionInfo>> getAll({bool force = false}) async {
|
||||
await refresh();
|
||||
return _getAllTransactions(null);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<int> count() async => monero_transaction_history.countOfTransactions();
|
||||
|
||||
@override
|
||||
Future refresh() async {
|
||||
if (_isRefreshing) {
|
||||
return;
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
import 'package:cake_wallet/src/domain/common/transaction_info.dart';
|
||||
import 'package:cake_wallet/src/domain/monero/monero_amount_format.dart';
|
||||
import 'package:cw_monero/structs/transaction_info_row.dart';
|
||||
import 'package:cake_wallet/src/domain/common/parseBoolFromString.dart';
|
||||
import 'package:cake_wallet/src/domain/common/transaction_direction.dart';
|
||||
import 'package:cake_wallet/src/domain/common/format_amount.dart';
|
||||
|
||||
class MoneroTransactionInfo extends TransactionInfo {
|
||||
MoneroTransactionInfo(this.id, this.height, this.direction, this.date,
|
||||
this.isPending, this.amount, this.accountIndex);
|
||||
|
||||
MoneroTransactionInfo.fromMap(Map map)
|
||||
: id = (map['hash'] ?? '') as String,
|
||||
height = (map['height'] ?? 0) as int,
|
||||
direction =
|
||||
parseTransactionDirectionFromNumber(map['direction'] as String) ??
|
||||
TransactionDirection.incoming,
|
||||
date = DateTime.fromMillisecondsSinceEpoch(
|
||||
(int.parse(map['timestamp'] as String) ?? 0) * 1000),
|
||||
isPending = parseBoolFromString(map['isPending'] as String),
|
||||
amount = map['amount'] as int,
|
||||
accountIndex = int.parse(map['accountIndex'] as String);
|
||||
|
||||
MoneroTransactionInfo.fromRow(TransactionInfoRow row)
|
||||
: id = row.getHash(),
|
||||
height = row.blockHeight,
|
||||
direction = parseTransactionDirectionFromInt(row.direction) ??
|
||||
TransactionDirection.incoming,
|
||||
date = DateTime.fromMillisecondsSinceEpoch(row.getDatetime() * 1000),
|
||||
isPending = row.isPending != 0,
|
||||
amount = row.getAmount(),
|
||||
accountIndex = row.subaddrAccount;
|
||||
|
||||
final String id;
|
||||
final int height;
|
||||
final TransactionDirection direction;
|
||||
final DateTime date;
|
||||
final int accountIndex;
|
||||
final bool isPending;
|
||||
final int amount;
|
||||
String recipientAddress;
|
||||
|
||||
String _fiatAmount;
|
||||
|
||||
String amountFormatted() => '${formatAmount(moneroAmountToString(amount: amount))} XMR';
|
||||
|
||||
String fiatAmount() => _fiatAmount ?? '';
|
||||
|
||||
void changeFiatAmount(String amount) => _fiatAmount = formatAmount(amount);
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
import 'package:cake_wallet/src/domain/common/pathForWallet.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
@@ -11,17 +12,7 @@ import 'package:cake_wallet/src/domain/common/wallet.dart';
|
||||
import 'package:cake_wallet/src/domain/monero/monero_wallet.dart';
|
||||
import 'package:cake_wallet/src/domain/common/wallet_description.dart';
|
||||
|
||||
Future<String> pathForWallet({String name}) async {
|
||||
final directory = await getApplicationDocumentsDirectory();
|
||||
final pathDir = directory.path + '/$name';
|
||||
final dir = Directory(pathDir);
|
||||
|
||||
if (!await dir.exists()) {
|
||||
await dir.create();
|
||||
}
|
||||
|
||||
return pathDir + '/$name';
|
||||
}
|
||||
|
||||
class MoneroWalletsManager extends WalletsManager {
|
||||
MoneroWalletsManager({@required this.walletInfoSource});
|
||||
@@ -34,7 +25,7 @@ class MoneroWalletsManager extends WalletsManager {
|
||||
Future<Wallet> create(String name, String password, String language) async {
|
||||
try {
|
||||
const isRecovery = false;
|
||||
final path = await pathForWallet(name: name);
|
||||
final path = await pathForWallet(name: name, type: WalletType.monero);
|
||||
|
||||
await monero_wallet_manager.createWallet(path: path, password: password, language: language);
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import 'dart:async';
|
||||
import 'package:cake_wallet/bitcoin/bitcoin_wallet.manager.dart';
|
||||
import 'package:cake_wallet/bitcoin/key.dart';
|
||||
import 'package:cake_wallet/src/domain/common/wallet_info.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
@@ -29,13 +31,15 @@ class WalletListService {
|
||||
this.walletInfoSource,
|
||||
this.walletsManager,
|
||||
@required this.walletService,
|
||||
@required this.sharedPreferences});
|
||||
@required this.sharedPreferences})
|
||||
: _type = WalletType.monero;
|
||||
|
||||
final FlutterSecureStorage secureStorage;
|
||||
final WalletService walletService;
|
||||
final Box<WalletInfo> walletInfoSource;
|
||||
final SharedPreferences sharedPreferences;
|
||||
WalletsManager walletsManager;
|
||||
WalletType _type;
|
||||
|
||||
Future<List<WalletDescription>> getAll() async => walletInfoSource.values
|
||||
.map((info) => WalletDescription(name: info.name, type: info.type))
|
||||
@@ -50,7 +54,7 @@ class WalletListService {
|
||||
await walletService.close();
|
||||
}
|
||||
|
||||
final password = Uuid().v4();
|
||||
final password = _generatePassword();
|
||||
await saveWalletPassword(password: password, walletName: name);
|
||||
|
||||
final wallet = await walletsManager.create(name, password, language);
|
||||
@@ -67,7 +71,7 @@ class WalletListService {
|
||||
await walletService.close();
|
||||
}
|
||||
|
||||
final password = Uuid().v4();
|
||||
final password = _generatePassword();
|
||||
await saveWalletPassword(password: password, walletName: name);
|
||||
|
||||
final wallet = await walletsManager.restoreFromSeed(
|
||||
@@ -76,8 +80,8 @@ class WalletListService {
|
||||
await onWalletChange(wallet);
|
||||
}
|
||||
|
||||
Future restoreFromKeys(String name, String language, int restoreHeight, String address,
|
||||
String viewKey, String spendKey) async {
|
||||
Future restoreFromKeys(String name, String language, int restoreHeight,
|
||||
String address, String viewKey, String spendKey) async {
|
||||
if (await walletsManager.isWalletExit(name)) {
|
||||
throw WalletIsExistException(name);
|
||||
}
|
||||
@@ -86,7 +90,7 @@ class WalletListService {
|
||||
await walletService.close();
|
||||
}
|
||||
|
||||
final password = Uuid().v4();
|
||||
final password = _generatePassword();
|
||||
await saveWalletPassword(password: password, walletName: name);
|
||||
|
||||
final wallet = await walletsManager.restoreFromKeys(
|
||||
@@ -107,11 +111,16 @@ class WalletListService {
|
||||
}
|
||||
|
||||
Future changeWalletManger({WalletType walletType}) async {
|
||||
_type = walletType;
|
||||
|
||||
switch (walletType) {
|
||||
case WalletType.monero:
|
||||
walletsManager =
|
||||
MoneroWalletsManager(walletInfoSource: walletInfoSource);
|
||||
break;
|
||||
case WalletType.bitcoin:
|
||||
walletsManager = BitcoinWalletManager();
|
||||
break;
|
||||
case WalletType.none:
|
||||
walletsManager = null;
|
||||
break;
|
||||
@@ -121,6 +130,7 @@ class WalletListService {
|
||||
Future onWalletChange(Wallet wallet) async {
|
||||
walletService.currentWallet = wallet;
|
||||
final walletName = await wallet.getName();
|
||||
print('walletName $walletName ');
|
||||
await sharedPreferences.setString('current_wallet_name', walletName);
|
||||
}
|
||||
|
||||
@@ -142,4 +152,13 @@ class WalletListService {
|
||||
|
||||
await secureStorage.write(key: key, value: encodedPassword);
|
||||
}
|
||||
|
||||
String _generatePassword() {
|
||||
switch (_type) {
|
||||
case WalletType.bitcoin:
|
||||
return generateKey();
|
||||
default:
|
||||
return Uuid().v4();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ class WalletService extends Wallet {
|
||||
WalletDescription description;
|
||||
|
||||
@override
|
||||
WalletType getType() => WalletType.monero;
|
||||
WalletType getType() => _currentWallet.getType();
|
||||
|
||||
@override
|
||||
Future<String> getFilename() => _currentWallet.getFilename();
|
||||
|
||||
@@ -33,7 +33,7 @@ class ReceivePage extends BasePage {
|
||||
splashColor: Colors.transparent,
|
||||
padding: EdgeInsets.all(0),
|
||||
onPressed: () => Share.text(
|
||||
'Share address', walletStore.subaddress.address, 'text/plain'),
|
||||
'Share address', walletStore.getAddress, 'text/plain'),
|
||||
child: Icon(
|
||||
Icons.share,
|
||||
size: 30.0,
|
||||
@@ -65,7 +65,11 @@ class ReceiveBodyState extends State<ReceiveBody> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final walletStore = Provider.of<WalletStore>(context);
|
||||
final subaddressListStore = Provider.of<SubaddressListStore>(context);
|
||||
SubaddressListStore subaddressListStore;
|
||||
|
||||
try {
|
||||
subaddressListStore = Provider.of<SubaddressListStore>(context);
|
||||
} catch (_) {}
|
||||
|
||||
final currentColor = Theme.of(context).selectedRowColor;
|
||||
final notCurrentColor = Theme.of(context).scaffoldBackgroundColor;
|
||||
@@ -101,7 +105,7 @@ class ReceiveBodyState extends State<ReceiveBody> {
|
||||
padding: EdgeInsets.all(5),
|
||||
color: Colors.white,
|
||||
child: QrImage(
|
||||
data: walletStore.subaddress.address +
|
||||
data: walletStore.getAddress +
|
||||
walletStore.amountValue,
|
||||
backgroundColor: Colors.transparent,
|
||||
),
|
||||
@@ -122,8 +126,8 @@ class ReceiveBodyState extends State<ReceiveBody> {
|
||||
child: Center(
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
Clipboard.setData(ClipboardData(
|
||||
text: walletStore.subaddress.address));
|
||||
Clipboard.setData(
|
||||
ClipboardData(text: walletStore.getAddress));
|
||||
Scaffold.of(context).showSnackBar(SnackBar(
|
||||
content: Text(
|
||||
S.of(context).copied_to_clipboard,
|
||||
@@ -133,7 +137,7 @@ class ReceiveBodyState extends State<ReceiveBody> {
|
||||
));
|
||||
},
|
||||
child: Text(
|
||||
walletStore.subaddress.address,
|
||||
walletStore.getAddress,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 14.0,
|
||||
@@ -187,78 +191,17 @@ class ReceiveBodyState extends State<ReceiveBody> {
|
||||
],
|
||||
),
|
||||
),
|
||||
Row(
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: Container(
|
||||
color: Theme.of(context).accentTextTheme.headline.color,
|
||||
child: Column(
|
||||
subaddressListStore != null
|
||||
? Row(
|
||||
children: <Widget>[
|
||||
ListTile(
|
||||
title: Text(
|
||||
S.of(context).subaddresses,
|
||||
style: TextStyle(
|
||||
fontSize: 16.0,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.headline
|
||||
.color),
|
||||
),
|
||||
trailing: Container(
|
||||
width: 28.0,
|
||||
height: 28.0,
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).selectedRowColor,
|
||||
shape: BoxShape.circle),
|
||||
child: InkWell(
|
||||
onTap: () => Navigator.of(context)
|
||||
.pushNamed(Routes.newSubaddress),
|
||||
borderRadius: BorderRadius.all(Radius.circular(14.0)),
|
||||
child: Icon(
|
||||
Icons.add,
|
||||
color: Palette.violet,
|
||||
size: 22.0,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Divider(
|
||||
color: Theme.of(context).dividerTheme.color,
|
||||
height: 1.0,
|
||||
)
|
||||
],
|
||||
),
|
||||
))
|
||||
],
|
||||
),
|
||||
Observer(builder: (_) {
|
||||
return ListView.separated(
|
||||
shrinkWrap: true,
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
itemCount: subaddressListStore.subaddresses.length,
|
||||
separatorBuilder: (context, i) {
|
||||
return Divider(
|
||||
color: Theme.of(context).dividerTheme.color,
|
||||
height: 1.0,
|
||||
);
|
||||
},
|
||||
itemBuilder: (context, i) {
|
||||
return Observer(builder: (_) {
|
||||
final subaddress = subaddressListStore.subaddresses[i];
|
||||
final isCurrent =
|
||||
walletStore.subaddress.address == subaddress.address;
|
||||
final label = subaddress.label.isNotEmpty
|
||||
? subaddress.label
|
||||
: subaddress.address;
|
||||
|
||||
return InkWell(
|
||||
onTap: () => walletStore.setSubaddress(subaddress),
|
||||
child: Container(
|
||||
color: isCurrent ? currentColor : notCurrentColor,
|
||||
child: Column(children: <Widget>[
|
||||
Expanded(
|
||||
child: Container(
|
||||
color: Theme.of(context).accentTextTheme.headline.color,
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
ListTile(
|
||||
title: Text(
|
||||
label,
|
||||
S.of(context).subaddresses,
|
||||
style: TextStyle(
|
||||
fontSize: 16.0,
|
||||
color: Theme.of(context)
|
||||
@@ -266,13 +209,79 @@ class ReceiveBodyState extends State<ReceiveBody> {
|
||||
.headline
|
||||
.color),
|
||||
),
|
||||
trailing: Container(
|
||||
width: 28.0,
|
||||
height: 28.0,
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).selectedRowColor,
|
||||
shape: BoxShape.circle),
|
||||
child: InkWell(
|
||||
onTap: () => Navigator.of(context)
|
||||
.pushNamed(Routes.newSubaddress),
|
||||
borderRadius:
|
||||
BorderRadius.all(Radius.circular(14.0)),
|
||||
child: Icon(
|
||||
Icons.add,
|
||||
color: Palette.violet,
|
||||
size: 22.0,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Divider(
|
||||
color: Theme.of(context).dividerTheme.color,
|
||||
height: 1.0,
|
||||
)
|
||||
]),
|
||||
],
|
||||
),
|
||||
);
|
||||
});
|
||||
});
|
||||
})
|
||||
))
|
||||
],
|
||||
)
|
||||
: Container(),
|
||||
subaddressListStore != null
|
||||
? Observer(builder: (_) {
|
||||
return ListView.separated(
|
||||
shrinkWrap: true,
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
itemCount: subaddressListStore.subaddresses.length,
|
||||
separatorBuilder: (context, i) {
|
||||
return Divider(
|
||||
color: Theme.of(context).dividerTheme.color,
|
||||
height: 1.0,
|
||||
);
|
||||
},
|
||||
itemBuilder: (context, i) {
|
||||
return Observer(builder: (_) {
|
||||
final subaddress = subaddressListStore.subaddresses[i];
|
||||
final isCurrent =
|
||||
walletStore.getAddress == subaddress.address;
|
||||
final label = subaddress.label.isNotEmpty
|
||||
? subaddress.label
|
||||
: subaddress.address;
|
||||
|
||||
return InkWell(
|
||||
onTap: () => walletStore.setSubaddress(subaddress),
|
||||
child: Container(
|
||||
color: isCurrent ? currentColor : notCurrentColor,
|
||||
child: Column(children: <Widget>[
|
||||
ListTile(
|
||||
title: Text(
|
||||
label,
|
||||
style: TextStyle(
|
||||
fontSize: 16.0,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.headline
|
||||
.color),
|
||||
),
|
||||
)
|
||||
]),
|
||||
),
|
||||
);
|
||||
});
|
||||
});
|
||||
})
|
||||
: Container()
|
||||
],
|
||||
)));
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:cake_wallet/src/domain/common/wallet_type.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cake_wallet/palette.dart';
|
||||
import 'package:cake_wallet/routes.dart';
|
||||
@@ -9,7 +10,10 @@ import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
|
||||
class RestoreOptionsPage extends BasePage {
|
||||
RestoreOptionsPage({@required this.type});
|
||||
|
||||
static const _aspectRatioImage = 2.086;
|
||||
final WalletType type;
|
||||
|
||||
@override
|
||||
String get title => S.current.restore_restore_wallet;
|
||||
|
||||
@@ -6,12 +6,16 @@ import 'package:cake_wallet/src/screens/restore/widgets/restore_button.dart';
|
||||
import 'package:cake_wallet/src/screens/restore/widgets/image_widget.dart';
|
||||
import 'package:cake_wallet/src/screens/restore/widgets/base_restore_widget.dart';
|
||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
import 'package:cake_wallet/src/domain/common/wallet_type.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/src/stores/seed_language/seed_language_store.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class RestoreWalletOptionsPage extends BasePage {
|
||||
RestoreWalletOptionsPage({@required this.type});
|
||||
|
||||
static const _aspectRatioImage = 2.086;
|
||||
final WalletType type;
|
||||
|
||||
@override
|
||||
String get title => S.current.restore_seed_keys_restore;
|
||||
@@ -31,7 +35,7 @@ class RestoreWalletOptionsPage extends BasePage {
|
||||
firstRestoreButton: RestoreButton(
|
||||
onPressed: () {
|
||||
seedLanguageStore.setCurrentRoute(Routes.restoreWalletFromSeed);
|
||||
Navigator.pushNamed(context, Routes.seedLanguage);
|
||||
Navigator.pushNamed(context, Routes.seedLanguage, arguments: type);
|
||||
},
|
||||
imageWidget: ImageWidget(
|
||||
image: _imageSeed,
|
||||
@@ -46,7 +50,7 @@ class RestoreWalletOptionsPage extends BasePage {
|
||||
secondRestoreButton: RestoreButton(
|
||||
onPressed: () {
|
||||
seedLanguageStore.setCurrentRoute(Routes.restoreWalletFromKeys);
|
||||
Navigator.pushNamed(context, Routes.seedLanguage);
|
||||
Navigator.pushNamed(context, Routes.seedLanguage, arguments: type);
|
||||
},
|
||||
imageWidget: ImageWidget(
|
||||
image: _imageKeys,
|
||||
|
||||
@@ -25,11 +25,19 @@ class ShowKeysPage extends BasePage {
|
||||
builder: (_) {
|
||||
final keysMap = {
|
||||
S.of(context).view_key_public: walletKeysStore.publicViewKey,
|
||||
S.of(context).view_key_private: walletKeysStore.privateViewKey,
|
||||
S.of(context).spend_key_public: walletKeysStore.publicSpendKey,
|
||||
S.of(context).spend_key_private: walletKeysStore.privateSpendKey
|
||||
};
|
||||
|
||||
if (walletKeysStore.privateViewKey.isNotEmpty) {
|
||||
keysMap[S.of(context).view_key_private] =
|
||||
walletKeysStore.privateViewKey;
|
||||
}
|
||||
|
||||
if (walletKeysStore.publicSpendKey.isNotEmpty) {
|
||||
keysMap[S.of(context).spend_key_public] =
|
||||
walletKeysStore.publicSpendKey;
|
||||
}
|
||||
|
||||
return ListView.separated(
|
||||
separatorBuilder: (_, __) => Container(
|
||||
padding: EdgeInsets.only(left: 30.0, right: 20.0),
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:cake_wallet/src/domain/monero/monero_transaction_info.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
@@ -46,31 +47,33 @@ class TransactionDetailsFormState extends State<TransactionDetailsForm> {
|
||||
@override
|
||||
void initState() {
|
||||
final _dateFormat = widget.settingsStore.getCurrentDateFormat(
|
||||
formatUSA: "yyyy.MM.dd, HH:mm",
|
||||
formatDefault: "dd.MM.yyyy, HH:mm");
|
||||
final items = [
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_transaction_id,
|
||||
value: widget.transactionInfo.id),
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_date,
|
||||
value: _dateFormat.format(widget.transactionInfo.date)),
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_height,
|
||||
value: '${widget.transactionInfo.height}'),
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_amount,
|
||||
value: widget.transactionInfo.amountFormatted())
|
||||
];
|
||||
formatUSA: "yyyy.MM.dd, HH:mm", formatDefault: "dd.MM.yyyy, HH:mm");
|
||||
final tx = widget.transactionInfo;
|
||||
|
||||
if (widget.settingsStore.shouldSaveRecipientAddress &&
|
||||
widget.transactionInfo.recipientAddress != null) {
|
||||
items.add(StandartListItem(
|
||||
title: S.current.transaction_details_recipient_address,
|
||||
value: widget.transactionInfo.recipientAddress));
|
||||
if (tx is MoneroTransactionInfo) {
|
||||
final items = [
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_transaction_id, value: tx.id),
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_date,
|
||||
value: _dateFormat.format(tx.date)),
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_height, value: '${tx.height}'),
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_amount,
|
||||
value: tx.amountFormatted())
|
||||
];
|
||||
|
||||
if (widget.settingsStore.shouldSaveRecipientAddress &&
|
||||
tx.recipientAddress != null) {
|
||||
items.add(StandartListItem(
|
||||
title: S.current.transaction_details_recipient_address,
|
||||
value: tx.recipientAddress));
|
||||
}
|
||||
|
||||
_items.addAll(items);
|
||||
}
|
||||
|
||||
_items.addAll(items);
|
||||
super.initState();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'package:cake_wallet/src/domain/common/wallet_type.dart';
|
||||
import 'package:cake_wallet/src/widgets/picker.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cake_wallet/palette.dart';
|
||||
import 'package:cake_wallet/routes.dart';
|
||||
@@ -5,14 +7,38 @@ import 'package:cake_wallet/src/widgets/primary_button.dart';
|
||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
|
||||
WalletType _selectedType;
|
||||
|
||||
class WelcomePage extends BasePage {
|
||||
static const _aspectRatioImage = 1.26;
|
||||
static const _baseWidth = 411.43;
|
||||
final _image = Image.asset('assets/images/welcomeImg.png');
|
||||
final _cakeLogo = Image.asset('assets/images/cake_logo.png');
|
||||
final Map<String, WalletType> _picker =
|
||||
walletTypes.fold(Map<String, WalletType>(), (acc, item) {
|
||||
acc[walletTypeToString(item)] = item;
|
||||
return acc;
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) => _selectedType == null
|
||||
? showDialog<void>(
|
||||
builder: (_) => Picker(
|
||||
items: walletTypes
|
||||
.map((item) => walletTypeToString(item))
|
||||
.toList(),
|
||||
selectedAtIndex: -1,
|
||||
title: 'Select wallet type',
|
||||
pickerHeight: 510,
|
||||
onItemSelected: (String item) {
|
||||
print('before $_selectedType');
|
||||
_selectedType = _picker[item];
|
||||
print('after $_selectedType');
|
||||
}),
|
||||
context: context)
|
||||
: null);
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: Theme.of(context).backgroundColor,
|
||||
resizeToAvoidBottomPadding: false,
|
||||
@@ -72,7 +98,8 @@ class WelcomePage extends BasePage {
|
||||
child: Column(children: <Widget>[
|
||||
PrimaryButton(
|
||||
onPressed: () {
|
||||
Navigator.pushNamed(context, Routes.newWalletFromWelcome);
|
||||
Navigator.pushNamed(context, Routes.newWalletFromWelcome,
|
||||
arguments: _selectedType);
|
||||
},
|
||||
text: S.of(context).create_new,
|
||||
color:
|
||||
@@ -82,7 +109,8 @@ class WelcomePage extends BasePage {
|
||||
SizedBox(height: 10),
|
||||
PrimaryButton(
|
||||
onPressed: () {
|
||||
Navigator.pushNamed(context, Routes.restoreOptions);
|
||||
Navigator.pushNamed(context, Routes.restoreOptions,
|
||||
arguments: _selectedType);
|
||||
},
|
||||
color: Theme.of(context).accentTextTheme.caption.backgroundColor,
|
||||
borderColor:
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'dart:async';
|
||||
import 'package:cake_wallet/src/domain/exchange/trade.dart';
|
||||
import 'package:cake_wallet/src/domain/monero/monero_transaction_info.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
@@ -98,10 +99,14 @@ abstract class ActionListBase with Store {
|
||||
final price = _priceStore.prices[symbol];
|
||||
|
||||
_transactions.forEach((item) {
|
||||
final amount = calculateFiatAmountRaw(
|
||||
cryptoAmount: moneroAmountToDouble(amount: item.transaction.amount),
|
||||
price: price);
|
||||
item.transaction.changeFiatAmount(amount);
|
||||
final tx = item.transaction;
|
||||
|
||||
if (tx is MoneroTransactionInfo) {
|
||||
final amount = calculateFiatAmountRaw(
|
||||
cryptoAmount: moneroAmountToDouble(amount: tx.amount),
|
||||
price: price);
|
||||
tx.changeFiatAmount(amount);
|
||||
}
|
||||
});
|
||||
|
||||
return _transactions;
|
||||
@@ -171,7 +176,6 @@ abstract class ActionListBase with Store {
|
||||
tradesSource.values.map((trade) => TradeListItem(trade: trade)).toList();
|
||||
|
||||
Future _updateTransactionsList() async {
|
||||
await _history.refresh();
|
||||
final _transactions = await _history.getAll();
|
||||
await _setTransactions(_transactions);
|
||||
}
|
||||
@@ -203,22 +207,29 @@ abstract class ActionListBase with Store {
|
||||
Future _setTransactions(List<TransactionInfo> transactions) async {
|
||||
final wallet = _walletService.currentWallet;
|
||||
List<TransactionInfo> sortedTransactions = transactions.map((transaction) {
|
||||
if (transactionDescriptions.values.isNotEmpty) {
|
||||
final description = transactionDescriptions.values.firstWhere(
|
||||
(desc) => desc.id == transaction.id,
|
||||
orElse: () => null);
|
||||
if (transaction is MoneroTransactionInfo) {
|
||||
if (transactionDescriptions.values.isNotEmpty) {
|
||||
final description = transactionDescriptions.values.firstWhere(
|
||||
(desc) => desc.id == transaction.id,
|
||||
orElse: () => null);
|
||||
|
||||
if (description != null && description.recipientAddress != null) {
|
||||
transaction.recipientAddress = description.recipientAddress;
|
||||
if (description != null && description.recipientAddress != null) {
|
||||
transaction.recipientAddress = description.recipientAddress;
|
||||
}
|
||||
}
|
||||
|
||||
return transaction;
|
||||
}
|
||||
|
||||
return transaction;
|
||||
}).toList();
|
||||
|
||||
if (wallet is MoneroWallet) {
|
||||
sortedTransactions =
|
||||
transactions.where((tx) => tx.accountIndex == _account.id).toList();
|
||||
sortedTransactions = transactions
|
||||
.where((tx) => tx is MoneroTransactionInfo
|
||||
? tx.accountIndex == _account.id
|
||||
: false)
|
||||
.toList();
|
||||
}
|
||||
|
||||
this._transactions = sortedTransactions
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'dart:async';
|
||||
import 'package:cake_wallet/bitcoin/bitcoin_balance.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:cake_wallet/src/domain/common/wallet.dart';
|
||||
@@ -87,17 +88,30 @@ abstract class BalanceStoreBase with Store {
|
||||
}
|
||||
|
||||
Future _onBalanceChange(Balance balance) async {
|
||||
final _balance = balance as MoneroBalance;
|
||||
|
||||
if (this.fullBalance != _balance.fullBalance) {
|
||||
this.fullBalance = _balance.fullBalance;
|
||||
if (balance is MoneroBalance) {
|
||||
await _onMoneroBalanceChange(balance);
|
||||
}
|
||||
|
||||
if (this.unlockedBalance != _balance.unlockedBalance) {
|
||||
this.unlockedBalance = _balance.unlockedBalance;
|
||||
if (balance is BitcoinBalance) {
|
||||
await _onBitcoinBalanceChange(balance);
|
||||
}
|
||||
}
|
||||
|
||||
Future _onMoneroBalanceChange(MoneroBalance balance) async {
|
||||
if (this.fullBalance != balance.fullBalance) {
|
||||
this.fullBalance = balance.fullBalance;
|
||||
}
|
||||
|
||||
if (this.unlockedBalance != balance.unlockedBalance) {
|
||||
this.unlockedBalance = balance.unlockedBalance;
|
||||
}
|
||||
}
|
||||
|
||||
Future _onBitcoinBalanceChange(BitcoinBalance balance) async {
|
||||
fullBalance = balance.totalFormatted;
|
||||
unlockedBalance = balance.totalFormatted;
|
||||
}
|
||||
|
||||
Future _onWalletChanged(Wallet wallet) async {
|
||||
if (_onBalanceChangeSubscription != null) {
|
||||
await _onBalanceChangeSubscription.cancel();
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:cake_wallet/src/domain/common/wallet_type.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:cake_wallet/src/domain/services/wallet_service.dart';
|
||||
@@ -15,10 +16,17 @@ abstract class WalletKeysStoreBase with Store {
|
||||
|
||||
if (walletService.currentWallet != null) {
|
||||
walletService.getKeys().then((keys) {
|
||||
publicViewKey = keys['publicViewKey'];
|
||||
privateViewKey = keys['privateViewKey'];
|
||||
publicSpendKey = keys['publicSpendKey'];
|
||||
privateSpendKey = keys['privateSpendKey'];
|
||||
if (walletService.getType() == WalletType.monero) {
|
||||
publicViewKey = keys['publicViewKey'];
|
||||
privateViewKey = keys['privateViewKey'];
|
||||
publicSpendKey = keys['publicSpendKey'];
|
||||
privateSpendKey = keys['privateSpendKey'];
|
||||
}
|
||||
|
||||
if (walletService.getType() == WalletType.bitcoin) {
|
||||
publicViewKey = keys['publicKey'];
|
||||
privateSpendKey = keys['privateKey'];
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'dart:async';
|
||||
import 'package:cake_wallet/src/domain/common/node.dart';
|
||||
import 'package:cake_wallet/src/domain/common/wallet_type.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:cake_wallet/src/domain/common/wallet.dart';
|
||||
import 'package:cake_wallet/src/domain/monero/account.dart';
|
||||
@@ -119,6 +120,7 @@ abstract class WalletStoreBase with Store {
|
||||
return;
|
||||
}
|
||||
|
||||
address = await wallet.getAddress();
|
||||
wallet.onNameChange.listen((name) => this.name = name);
|
||||
wallet.onAddressChange.listen((address) => this.address = address);
|
||||
|
||||
@@ -160,4 +162,9 @@ abstract class WalletStoreBase with Store {
|
||||
}
|
||||
|
||||
Future<bool> isConnected() async => await _walletService.isConnected();
|
||||
|
||||
WalletType getType() => _walletService.getType();
|
||||
|
||||
String get getAddress =>
|
||||
getType() == WalletType.monero ? subaddress.address : address;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user