mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-01-25 12:06:05 +00:00
Merge branch 'CAKE-279-integrate-wyre' of github.com:cake-tech/cake_wallet into CAKE-279-integrate-wyre
This commit is contained in:
commit
4c788eb2aa
7 changed files with 160 additions and 117 deletions
14
lib/di.dart
14
lib/di.dart
|
@ -496,9 +496,6 @@ Future setup(
|
||||||
getIt.registerFactoryParam<TradeDetailsViewModel, Trade, void>((trade, _) =>
|
getIt.registerFactoryParam<TradeDetailsViewModel, Trade, void>((trade, _) =>
|
||||||
TradeDetailsViewModel(tradeForDetails: trade, trades: _tradesSource));
|
TradeDetailsViewModel(tradeForDetails: trade, trades: _tradesSource));
|
||||||
|
|
||||||
getIt.registerFactoryParam<OrderDetailsViewModel, Order, void>(
|
|
||||||
(order, _) => OrderDetailsViewModel(orderForDetails: order));
|
|
||||||
|
|
||||||
getIt.registerFactory(() => BackupService(
|
getIt.registerFactory(() => BackupService(
|
||||||
getIt.get<FlutterSecureStorage>(),
|
getIt.get<FlutterSecureStorage>(),
|
||||||
_walletInfoSource,
|
_walletInfoSource,
|
||||||
|
@ -528,9 +525,6 @@ Future setup(
|
||||||
getIt.registerFactoryParam<TradeDetailsPage, Trade, void>((Trade trade, _) =>
|
getIt.registerFactoryParam<TradeDetailsPage, Trade, void>((Trade trade, _) =>
|
||||||
TradeDetailsPage(getIt.get<TradeDetailsViewModel>(param1: trade)));
|
TradeDetailsPage(getIt.get<TradeDetailsViewModel>(param1: trade)));
|
||||||
|
|
||||||
getIt.registerFactoryParam<OrderDetailsPage, Order, void>((Order order, _) =>
|
|
||||||
OrderDetailsPage(getIt.get<OrderDetailsViewModel>(param1: order)));
|
|
||||||
|
|
||||||
getIt.registerFactory(() {
|
getIt.registerFactory(() {
|
||||||
final wallet = getIt.get<AppStore>().wallet;
|
final wallet = getIt.get<AppStore>().wallet;
|
||||||
return WyreViewModel(ordersSource, getIt.get<OrdersStore>(),
|
return WyreViewModel(ordersSource, getIt.get<OrdersStore>(),
|
||||||
|
@ -541,6 +535,14 @@ Future setup(
|
||||||
WyrePage(getIt.get<WyreViewModel>(),
|
WyrePage(getIt.get<WyreViewModel>(),
|
||||||
ordersStore: getIt.get<OrdersStore>(), url: url));
|
ordersStore: getIt.get<OrdersStore>(), url: url));
|
||||||
|
|
||||||
|
getIt.registerFactoryParam<OrderDetailsViewModel, Order, void>(
|
||||||
|
(order, _) => OrderDetailsViewModel(
|
||||||
|
wyreViewModel: getIt.get<WyreViewModel>(),
|
||||||
|
orderForDetails: order));
|
||||||
|
|
||||||
|
getIt.registerFactoryParam<OrderDetailsPage, Order, void>((Order order, _) =>
|
||||||
|
OrderDetailsPage(getIt.get<OrderDetailsViewModel>(param1: order)));
|
||||||
|
|
||||||
getIt.registerFactory(() => SupportViewModel());
|
getIt.registerFactory(() => SupportViewModel());
|
||||||
|
|
||||||
getIt.registerFactory(() => SupportPage(getIt.get<SupportViewModel>()));
|
getIt.registerFactory(() => SupportPage(getIt.get<SupportViewModel>()));
|
||||||
|
|
|
@ -1,40 +0,0 @@
|
||||||
import 'dart:convert';
|
|
||||||
import 'package:cake_wallet/entities/order.dart';
|
|
||||||
import 'package:cake_wallet/exchange/trade_state.dart';
|
|
||||||
import 'package:http/http.dart';
|
|
||||||
|
|
||||||
Future<Order> findOrderById(String id) async {
|
|
||||||
final orderUrl = 'https://api.sendwyre.com/v3/orders/' + id;
|
|
||||||
|
|
||||||
final orderResponse = await get(orderUrl);
|
|
||||||
|
|
||||||
final orderResponseJSON =
|
|
||||||
json.decode(orderResponse.body) as Map<String, dynamic>;
|
|
||||||
final transferId = orderResponseJSON['transferId'] as String;
|
|
||||||
final from = orderResponseJSON['sourceCurrency'] as String;
|
|
||||||
final to = orderResponseJSON['destCurrency'] as String;
|
|
||||||
final status = orderResponseJSON['status'] as String;
|
|
||||||
final state = TradeState.deserialize(raw: status.toLowerCase());
|
|
||||||
final createdAtRaw = orderResponseJSON['createdAt'] as int;
|
|
||||||
final createdAt =
|
|
||||||
DateTime.fromMillisecondsSinceEpoch(createdAtRaw).toLocal();
|
|
||||||
|
|
||||||
final transferUrl =
|
|
||||||
'https://api.sendwyre.com/v2/transfer/' + transferId + '/track';
|
|
||||||
|
|
||||||
final transferResponse = await get(transferUrl);
|
|
||||||
|
|
||||||
final transferResponseJSON =
|
|
||||||
json.decode(transferResponse.body) as Map<String, dynamic>;
|
|
||||||
final amount = transferResponseJSON['destAmount'] as double;
|
|
||||||
|
|
||||||
return Order(
|
|
||||||
id: id,
|
|
||||||
transferId: transferId,
|
|
||||||
from: from,
|
|
||||||
to: to,
|
|
||||||
state: state,
|
|
||||||
createdAt: createdAt,
|
|
||||||
amount: amount.toString()
|
|
||||||
);
|
|
||||||
}
|
|
115
lib/entities/wyre_service.dart
Normal file
115
lib/entities/wyre_service.dart
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'package:cake_wallet/exchange/trade_state.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:http/http.dart';
|
||||||
|
import 'package:cake_wallet/.secrets.g.dart' as secrets;
|
||||||
|
import 'package:cake_wallet/entities/order.dart';
|
||||||
|
import 'package:cake_wallet/entities/wallet_type.dart';
|
||||||
|
|
||||||
|
class WyreService {
|
||||||
|
WyreService({
|
||||||
|
@required this.walletType,
|
||||||
|
@required this.walletAddress,
|
||||||
|
this.isTestEnvironment = false}) {
|
||||||
|
baseApiUrl = isTestEnvironment
|
||||||
|
? 'https://api.testwyre.com'
|
||||||
|
: 'https://api.sendwyre.com';
|
||||||
|
trackUrl = isTestEnvironment
|
||||||
|
? 'https://dash.testwyre.com/track/'
|
||||||
|
: 'https://dash.sendwyre.com/track/';
|
||||||
|
}
|
||||||
|
|
||||||
|
static const _ordersSuffix = '/v3/orders';
|
||||||
|
static const _reserveSuffix = '/reserve';
|
||||||
|
static const _timeStampSuffix = '?timestamp=';
|
||||||
|
static const _transferSuffix = '/v2/transfer/';
|
||||||
|
static const _trackSuffix = '/track';
|
||||||
|
|
||||||
|
final bool isTestEnvironment;
|
||||||
|
final WalletType walletType;
|
||||||
|
final String walletAddress;
|
||||||
|
|
||||||
|
String baseApiUrl;
|
||||||
|
String trackUrl;
|
||||||
|
|
||||||
|
Future<String> getWyreUrl() async {
|
||||||
|
final timestamp = DateTime.now().millisecondsSinceEpoch.toString();
|
||||||
|
final url = baseApiUrl + _ordersSuffix + _reserveSuffix +
|
||||||
|
_timeStampSuffix + timestamp;
|
||||||
|
final secretKey = secrets.wyreSecretKey;
|
||||||
|
final accountId = secrets.wyreAccountId;
|
||||||
|
final body = {
|
||||||
|
'destCurrency': walletTypeToCryptoCurrency(walletType).title,
|
||||||
|
'dest': walletTypeToString(walletType).toLowerCase() + ':' + walletAddress,
|
||||||
|
'referrerAccountId': accountId,
|
||||||
|
'lockFields': ['destCurrency', 'dest']
|
||||||
|
};
|
||||||
|
|
||||||
|
final response = await post(url,
|
||||||
|
headers: {
|
||||||
|
'Authorization': 'Bearer $secretKey',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'cache-control': 'no-cache'
|
||||||
|
},
|
||||||
|
body: json.encode(body));
|
||||||
|
|
||||||
|
if (response.statusCode != 200) {
|
||||||
|
throw WyreException('Url $url is not found!');
|
||||||
|
}
|
||||||
|
|
||||||
|
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
|
||||||
|
final urlFromResponse = responseJSON['url'] as String;
|
||||||
|
return urlFromResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Order> findOrderById(String id) async {
|
||||||
|
final orderUrl = baseApiUrl + _ordersSuffix + id;
|
||||||
|
final orderResponse = await get(orderUrl);
|
||||||
|
|
||||||
|
if (orderResponse.statusCode != 200) {
|
||||||
|
throw WyreException('Order $id is not found!');
|
||||||
|
}
|
||||||
|
|
||||||
|
final orderResponseJSON =
|
||||||
|
json.decode(orderResponse.body) as Map<String, dynamic>;
|
||||||
|
final transferId = orderResponseJSON['transferId'] as String;
|
||||||
|
final from = orderResponseJSON['sourceCurrency'] as String;
|
||||||
|
final to = orderResponseJSON['destCurrency'] as String;
|
||||||
|
final status = orderResponseJSON['status'] as String;
|
||||||
|
final state = TradeState.deserialize(raw: status.toLowerCase());
|
||||||
|
final createdAtRaw = orderResponseJSON['createdAt'] as int;
|
||||||
|
final createdAt =
|
||||||
|
DateTime.fromMillisecondsSinceEpoch(createdAtRaw).toLocal();
|
||||||
|
|
||||||
|
final transferUrl =
|
||||||
|
baseApiUrl + _transferSuffix + transferId + _trackSuffix;
|
||||||
|
final transferResponse = await get(transferUrl);
|
||||||
|
|
||||||
|
if (transferResponse.statusCode != 200) {
|
||||||
|
throw WyreException('Transfer $transferId is not found!');
|
||||||
|
}
|
||||||
|
|
||||||
|
final transferResponseJSON =
|
||||||
|
json.decode(transferResponse.body) as Map<String, dynamic>;
|
||||||
|
final amount = transferResponseJSON['destAmount'] as double;
|
||||||
|
|
||||||
|
return Order(
|
||||||
|
id: id,
|
||||||
|
transferId: transferId,
|
||||||
|
from: from,
|
||||||
|
to: to,
|
||||||
|
state: state,
|
||||||
|
createdAt: createdAt,
|
||||||
|
amount: amount.toString()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class WyreException implements Exception {
|
||||||
|
WyreException(this.description);
|
||||||
|
|
||||||
|
String description;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => description;
|
||||||
|
}
|
|
@ -146,11 +146,10 @@ class DashboardPage extends BasePage {
|
||||||
: () async {
|
: () async {
|
||||||
try {
|
try {
|
||||||
walletViewModel.isRunningWebView = true;
|
walletViewModel.isRunningWebView = true;
|
||||||
final url = await walletViewModel.wyreViewModel.getWyreUrl();
|
final url =
|
||||||
if (url.isNotEmpty) {
|
await walletViewModel.wyreViewModel.wyreUrl;
|
||||||
await Navigator.of(context)
|
await Navigator.of(context)
|
||||||
.pushNamed(Routes.wyre, arguments: url);
|
.pushNamed(Routes.wyre, arguments: url);
|
||||||
}
|
|
||||||
walletViewModel.isRunningWebView = false;
|
walletViewModel.isRunningWebView = false;
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
print(e.toString());
|
print(e.toString());
|
||||||
|
|
|
@ -4,7 +4,6 @@ import 'dart:io';
|
||||||
import 'package:cake_wallet/bitcoin/bitcoin_transaction_info.dart';
|
import 'package:cake_wallet/bitcoin/bitcoin_transaction_info.dart';
|
||||||
import 'package:cake_wallet/bitcoin/bitcoin_wallet.dart';
|
import 'package:cake_wallet/bitcoin/bitcoin_wallet.dart';
|
||||||
import 'package:cake_wallet/entities/balance.dart';
|
import 'package:cake_wallet/entities/balance.dart';
|
||||||
import 'package:cake_wallet/entities/find_order_by_id.dart';
|
|
||||||
import 'package:cake_wallet/entities/order.dart';
|
import 'package:cake_wallet/entities/order.dart';
|
||||||
import 'package:cake_wallet/entities/transaction_history.dart';
|
import 'package:cake_wallet/entities/transaction_history.dart';
|
||||||
import 'package:cake_wallet/exchange/trade_state.dart';
|
import 'package:cake_wallet/exchange/trade_state.dart';
|
||||||
|
@ -147,27 +146,8 @@ abstract class DashboardViewModelBase with Store {
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
dataChannel.setMessageHandler((ByteData message) async {
|
|
||||||
final type = ByteData.view(message.buffer, 0, 4).getInt32(0);
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case _dataExists:
|
|
||||||
print('Wyre: Data exists');
|
|
||||||
break;
|
|
||||||
case _dataNotExists:
|
|
||||||
print('Wyre: Data not exists');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ByteData(0);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const dataChannel = BasicMessageChannel('data_change', BinaryCodec());
|
|
||||||
static const _dataExists = 1;
|
|
||||||
static const _dataNotExists = 0;
|
|
||||||
|
|
||||||
@observable
|
@observable
|
||||||
WalletType type;
|
WalletType type;
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:cake_wallet/entities/find_order_by_id.dart';
|
|
||||||
import 'package:cake_wallet/entities/order.dart';
|
import 'package:cake_wallet/entities/order.dart';
|
||||||
import 'package:cake_wallet/utils/date_formatter.dart';
|
import 'package:cake_wallet/utils/date_formatter.dart';
|
||||||
|
import 'package:cake_wallet/view_model/wyre_view_model.dart';
|
||||||
import 'package:mobx/mobx.dart';
|
import 'package:mobx/mobx.dart';
|
||||||
import 'package:cake_wallet/generated/i18n.dart';
|
import 'package:cake_wallet/generated/i18n.dart';
|
||||||
import 'package:cake_wallet/src/screens/transaction_details/standart_list_item.dart';
|
import 'package:cake_wallet/src/screens/transaction_details/standart_list_item.dart';
|
||||||
|
@ -14,7 +14,7 @@ class OrderDetailsViewModel = OrderDetailsViewModelBase
|
||||||
with _$OrderDetailsViewModel;
|
with _$OrderDetailsViewModel;
|
||||||
|
|
||||||
abstract class OrderDetailsViewModelBase with Store {
|
abstract class OrderDetailsViewModelBase with Store {
|
||||||
OrderDetailsViewModelBase({Order orderForDetails}) {
|
OrderDetailsViewModelBase({this.wyreViewModel, Order orderForDetails}) {
|
||||||
order = orderForDetails;
|
order = orderForDetails;
|
||||||
|
|
||||||
items = ObservableList<StandartListItem>();
|
items = ObservableList<StandartListItem>();
|
||||||
|
@ -32,12 +32,15 @@ abstract class OrderDetailsViewModelBase with Store {
|
||||||
@observable
|
@observable
|
||||||
ObservableList<StandartListItem> items;
|
ObservableList<StandartListItem> items;
|
||||||
|
|
||||||
|
WyreViewModel wyreViewModel;
|
||||||
|
|
||||||
Timer _timer;
|
Timer _timer;
|
||||||
|
|
||||||
@action
|
@action
|
||||||
Future<void> _updateOrder() async {
|
Future<void> _updateOrder() async {
|
||||||
try {
|
try {
|
||||||
final updatedOrder = await findOrderById(order.id);
|
final updatedOrder =
|
||||||
|
await wyreViewModel.wyreService.findOrderById(order.id);
|
||||||
|
|
||||||
updatedOrder.receiveAddress = order.receiveAddress;
|
updatedOrder.receiveAddress = order.receiveAddress;
|
||||||
updatedOrder.walletId = order.walletId;
|
updatedOrder.walletId = order.walletId;
|
||||||
|
@ -52,7 +55,7 @@ abstract class OrderDetailsViewModelBase with Store {
|
||||||
void _updateItems() {
|
void _updateItems() {
|
||||||
final dateFormat = DateFormatter.withCurrentLocal();
|
final dateFormat = DateFormatter.withCurrentLocal();
|
||||||
final buildURL =
|
final buildURL =
|
||||||
'https://dash.sendwyre.com/track/${order.transferId}';
|
wyreViewModel.trackUrl + '${order.transferId}';
|
||||||
|
|
||||||
items?.clear();
|
items?.clear();
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,23 @@
|
||||||
import 'dart:convert';
|
import 'package:cake_wallet/entities/wyre_service.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'package:http/http.dart';
|
|
||||||
import 'package:cake_wallet/.secrets.g.dart' as secrets;
|
|
||||||
import 'package:cake_wallet/entities/find_order_by_id.dart';
|
|
||||||
import 'package:cake_wallet/entities/order.dart';
|
import 'package:cake_wallet/entities/order.dart';
|
||||||
import 'package:cake_wallet/entities/wallet_type.dart';
|
import 'package:cake_wallet/entities/wallet_type.dart';
|
||||||
import 'package:cake_wallet/store/dashboard/orders_store.dart';
|
import 'package:cake_wallet/store/dashboard/orders_store.dart';
|
||||||
|
import 'package:mobx/mobx.dart';
|
||||||
|
|
||||||
class WyreViewModel {
|
part 'wyre_view_model.g.dart';
|
||||||
WyreViewModel(this.ordersSource, this.ordersStore,
|
|
||||||
{@required this.walletId, @required this.address, @required this.type});
|
class WyreViewModel = WyreViewModelBase with _$WyreViewModel;
|
||||||
|
|
||||||
|
abstract class WyreViewModelBase with Store {
|
||||||
|
WyreViewModelBase(this.ordersSource, this.ordersStore,
|
||||||
|
{@required this.walletId, @required this.address, @required this.type})
|
||||||
|
: wyreService = WyreService(walletType: type, walletAddress: address);
|
||||||
|
|
||||||
|
Future<String> get wyreUrl => wyreService.getWyreUrl();
|
||||||
|
|
||||||
|
String get trackUrl => wyreService.trackUrl;
|
||||||
|
|
||||||
final Box<Order> ordersSource;
|
final Box<Order> ordersSource;
|
||||||
final OrdersStore ordersStore;
|
final OrdersStore ordersStore;
|
||||||
|
@ -19,42 +26,19 @@ class WyreViewModel {
|
||||||
final WalletType type;
|
final WalletType type;
|
||||||
final String address;
|
final String address;
|
||||||
|
|
||||||
|
WyreService wyreService;
|
||||||
|
|
||||||
Future<void> saveOrder(String orderId) async {
|
Future<void> saveOrder(String orderId) async {
|
||||||
final order = await findOrderById(orderId);
|
try {
|
||||||
order.receiveAddress = address;
|
final order = await wyreService.findOrderById(orderId);
|
||||||
order.walletId = walletId;
|
order.receiveAddress = address;
|
||||||
await ordersSource.add(order);
|
order.walletId = walletId;
|
||||||
ordersStore.setOrder(order);
|
await ordersSource.add(order);
|
||||||
}
|
ordersStore.setOrder(order);
|
||||||
|
} catch (e) {
|
||||||
Future<String> getWyreUrl() async {
|
print(e.toString());
|
||||||
final timestamp = DateTime.now().millisecondsSinceEpoch.toString();
|
|
||||||
final url = 'https://api.sendwyre.com/v3/orders/reserve' +
|
|
||||||
'?timestamp=' +
|
|
||||||
timestamp;
|
|
||||||
final secretKey = secrets.wyreSecretKey;
|
|
||||||
final accountId = secrets.wyreAccountId;
|
|
||||||
final body = {
|
|
||||||
'destCurrency': walletTypeToCryptoCurrency(type).title,
|
|
||||||
'dest': walletTypeToString(type).toLowerCase() + ':' + address,
|
|
||||||
'referrerAccountId': accountId,
|
|
||||||
'lockFields': ['destCurrency', 'dest']
|
|
||||||
};
|
|
||||||
|
|
||||||
final response = await post(url,
|
|
||||||
headers: {
|
|
||||||
'Authorization': 'Bearer $secretKey',
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'cache-control': 'no-cache'
|
|
||||||
},
|
|
||||||
body: json.encode(body));
|
|
||||||
|
|
||||||
if (response.statusCode == 200) {
|
|
||||||
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
|
|
||||||
final urlFromResponse = responseJSON['url'] as String;
|
|
||||||
return urlFromResponse;
|
|
||||||
} else {
|
|
||||||
return '';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue