# Conflicts: # android/app/build.gradle # android/build.gradle # ios/Podfile # ios/Podfile.lock # res/values/strings_de.arb # res/values/strings_en.arb # res/values/strings_es.arb # res/values/strings_hi.arb # res/values/strings_hr.arb # res/values/strings_it.arb # res/values/strings_ja.arb # res/values/strings_ko.arb # res/values/strings_nl.arb # res/values/strings_pl.arb # res/values/strings_pt.arb # res/values/strings_ru.arb # res/values/strings_uk.arb # res/values/strings_zh.arbwownero
commit
37f326e21f
@ -0,0 +1,21 @@
|
||||
package com.cakewallet.cake_wallet;
|
||||
|
||||
import io.flutter.app.FlutterApplication;
|
||||
import io.flutter.plugin.common.PluginRegistry;
|
||||
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback;
|
||||
import io.flutter.plugins.GeneratedPluginRegistrant;
|
||||
import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService;
|
||||
import io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin;
|
||||
|
||||
public class Application extends FlutterApplication implements PluginRegistrantCallback {
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
FlutterFirebaseMessagingService.setPluginRegistrant(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerWith(PluginRegistry registry) {
|
||||
FirebaseMessagingPlugin.registerWith(registry.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin"));
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 981 B |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 507 B |
After Width: | Height: | Size: 1.3 KiB |
@ -1,5 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict/>
|
||||
<dict>
|
||||
<key>aps-environment</key>
|
||||
<string>development</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
@ -1,5 +1,5 @@
|
||||
class BitcoinMnemonicIsIncorrectException implements Exception {
|
||||
@override
|
||||
String toString() =>
|
||||
'Bitcoin mnemonic has incorrect format. Mnemonic should contain 24 words separated by space.';
|
||||
'Bitcoin mnemonic has incorrect format. Mnemonic should contain 12 or 24 words separated by space.';
|
||||
}
|
||||
|
@ -0,0 +1,12 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
class BuyAmount {
|
||||
BuyAmount({
|
||||
@required this.sourceAmount,
|
||||
@required this.destAmount,
|
||||
this.minAmount = 0});
|
||||
|
||||
final double sourceAmount;
|
||||
final double destAmount;
|
||||
final int minAmount;
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:cake_wallet/buy/buy_provider_description.dart';
|
||||
|
||||
class BuyException implements Exception {
|
||||
BuyException({@required this.description, @required this.text});
|
||||
|
||||
final BuyProviderDescription description;
|
||||
final String text;
|
||||
|
||||
@override
|
||||
String toString() => '${description.title}: $text';
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
import 'package:cake_wallet/buy/buy_amount.dart';
|
||||
import 'package:cake_wallet/buy/buy_provider_description.dart';
|
||||
import 'package:cake_wallet/buy/order.dart';
|
||||
import 'package:cake_wallet/core/wallet_base.dart';
|
||||
import 'package:cake_wallet/entities/wallet_type.dart';
|
||||
|
||||
abstract class BuyProvider {
|
||||
BuyProvider({this.wallet, this.isTestEnvironment});
|
||||
|
||||
final WalletBase wallet;
|
||||
final bool isTestEnvironment;
|
||||
|
||||
String get title;
|
||||
BuyProviderDescription get description;
|
||||
String get trackUrl;
|
||||
|
||||
WalletType get walletType => wallet.type;
|
||||
String get walletAddress => wallet.address;
|
||||
String get walletId => wallet.id;
|
||||
|
||||
@override
|
||||
String toString() => title;
|
||||
|
||||
Future<String> requestUrl(String amount, String sourceCurrency);
|
||||
Future<Order> findOrderById(String id);
|
||||
Future<BuyAmount> calculateAmount(String amount, String sourceCurrency);
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
import 'package:cake_wallet/entities/enumerable_item.dart';
|
||||
|
||||
class BuyProviderDescription extends EnumerableItem<int>
|
||||
with Serializable<int> {
|
||||
const BuyProviderDescription({String title, int raw})
|
||||
: super(title: title, raw: raw);
|
||||
|
||||
static const wyre = BuyProviderDescription(title: 'Wyre', raw: 0);
|
||||
static const moonPay = BuyProviderDescription(title: 'MoonPay', raw: 1);
|
||||
|
||||
static BuyProviderDescription deserialize({int raw}) {
|
||||
switch (raw) {
|
||||
case 0:
|
||||
return wyre;
|
||||
case 1:
|
||||
return moonPay;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cake_wallet/buy/buy_provider_description.dart';
|
||||
|
||||
Image getBuyProviderIcon(BuyProviderDescription providerDescription,
|
||||
{bool isWhiteIconColor = false}) {
|
||||
|
||||
final _wyreIcon =
|
||||
Image.asset('assets/images/wyre-icon.png', width: 36, height: 36);
|
||||
final _moonPayWhiteIcon =
|
||||
Image.asset('assets/images/moonpay-icon.png', color: Colors.white,
|
||||
width: 36, height: 34);
|
||||
final _moonPayBlackIcon =
|
||||
Image.asset('assets/images/moonpay-icon.png', color: Colors.black,
|
||||
width: 36, height: 34);
|
||||
|
||||
if (providerDescription != null) {
|
||||
switch (providerDescription) {
|
||||
case BuyProviderDescription.wyre:
|
||||
return _wyreIcon;
|
||||
case BuyProviderDescription.moonPay:
|
||||
return isWhiteIconColor ? _moonPayWhiteIcon : _moonPayBlackIcon;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,144 @@
|
||||
import 'dart:convert';
|
||||
import 'package:crypto/crypto.dart';
|
||||
import 'package:cake_wallet/buy/buy_exception.dart';
|
||||
import 'package:http/http.dart';
|
||||
import 'package:cake_wallet/buy/buy_amount.dart';
|
||||
import 'package:cake_wallet/buy/buy_provider.dart';
|
||||
import 'package:cake_wallet/buy/buy_provider_description.dart';
|
||||
import 'package:cake_wallet/buy/order.dart';
|
||||
import 'package:cake_wallet/core/wallet_base.dart';
|
||||
import 'package:cake_wallet/entities/wallet_type.dart';
|
||||
import 'package:cake_wallet/exchange/trade_state.dart';
|
||||
import 'package:cake_wallet/.secrets.g.dart' as secrets;
|
||||
|
||||
class MoonPayBuyProvider extends BuyProvider {
|
||||
MoonPayBuyProvider({WalletBase wallet, bool isTestEnvironment = false})
|
||||
: super(wallet: wallet, isTestEnvironment: isTestEnvironment) {
|
||||
baseUrl = isTestEnvironment ? _baseTestUrl : _baseProductUrl;
|
||||
}
|
||||
|
||||
static const _baseTestUrl = 'https://buy-staging.moonpay.com';
|
||||
static const _baseProductUrl = 'https://buy.moonpay.com';
|
||||
static const _apiUrl = 'https://api.moonpay.com';
|
||||
static const _currenciesSuffix = '/v3/currencies';
|
||||
static const _quoteSuffix = '/buy_quote';
|
||||
static const _transactionsSuffix = '/v1/transactions';
|
||||
static const _ipAddressSuffix = '/v4/ip_address';
|
||||
static const _apiKey = secrets.moonPayApiKey;
|
||||
static const _secretKey = secrets.moonPaySecretKey;
|
||||
|
||||
@override
|
||||
String get title => 'MoonPay';
|
||||
|
||||
@override
|
||||
BuyProviderDescription get description => BuyProviderDescription.moonPay;
|
||||
|
||||
String get currencyCode =>
|
||||
walletTypeToCryptoCurrency(walletType).title.toLowerCase();
|
||||
|
||||
@override
|
||||
String get trackUrl => baseUrl + '/transaction_receipt?transactionId=';
|
||||
|
||||
String baseUrl;
|
||||
|
||||
@override
|
||||
Future<String> requestUrl(String amount, String sourceCurrency) async {
|
||||
final enabledPaymentMethods =
|
||||
'credit_debit_card%2Capple_pay%2Cgoogle_pay%2Csamsung_pay'
|
||||
'%2Csepa_bank_transfer%2Cgbp_bank_transfer%2Cgbp_open_banking_payment';
|
||||
|
||||
final suffix = '?apiKey=' + _apiKey + '¤cyCode=' +
|
||||
currencyCode + '&enabledPaymentMethods=' + enabledPaymentMethods +
|
||||
'&walletAddress=' + walletAddress +
|
||||
'&baseCurrencyCode=' + sourceCurrency.toLowerCase() +
|
||||
'&baseCurrencyAmount=' + amount + '&lockAmount=true' +
|
||||
'&showAllCurrencies=false' + '&showWalletAddressForm=false';
|
||||
|
||||
final originalUrl = baseUrl + suffix;
|
||||
|
||||
final messageBytes = utf8.encode(suffix);
|
||||
final key = utf8.encode(_secretKey);
|
||||
final hmac = Hmac(sha256, key);
|
||||
final digest = hmac.convert(messageBytes);
|
||||
final signature = base64.encode(digest.bytes);
|
||||
final urlWithSignature = originalUrl +
|
||||
'&signature=${Uri.encodeComponent(signature)}';
|
||||
|
||||
return isTestEnvironment ? originalUrl : urlWithSignature;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<BuyAmount> calculateAmount(String amount, String sourceCurrency) async {
|
||||
final url = _apiUrl + _currenciesSuffix + '/$currencyCode' +
|
||||
_quoteSuffix + '/?apiKey=' + _apiKey +
|
||||
'&baseCurrencyAmount=' + amount +
|
||||
'&baseCurrencyCode=' + sourceCurrency.toLowerCase();
|
||||
|
||||
final response = await get(url);
|
||||
|
||||
if (response.statusCode != 200) {
|
||||
throw BuyException(
|
||||
description: description,
|
||||
text: 'Quote is not found!');
|
||||
}
|
||||
|
||||
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
|
||||
final sourceAmount = responseJSON['totalAmount'] as double;
|
||||
final destAmount = responseJSON['quoteCurrencyAmount'] as double;
|
||||
final minSourceAmount = responseJSON['baseCurrency']['minAmount'] as int;
|
||||
|
||||
return BuyAmount(
|
||||
sourceAmount: sourceAmount,
|
||||
destAmount: destAmount,
|
||||
minAmount: minSourceAmount);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Order> findOrderById(String id) async {
|
||||
final url = _apiUrl + _transactionsSuffix + '/$id' +
|
||||
'?apiKey=' + _apiKey;
|
||||
|
||||
final response = await get(url);
|
||||
|
||||
if (response.statusCode != 200) {
|
||||
throw BuyException(
|
||||
description: description,
|
||||
text: 'Transaction $id is not found!');
|
||||
}
|
||||
|
||||
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
|
||||
final status = responseJSON['status'] as String;
|
||||
final state = TradeState.deserialize(raw: status);
|
||||
final createdAtRaw = responseJSON['createdAt'] as String;
|
||||
final createdAt = DateTime.parse(createdAtRaw).toLocal();
|
||||
final amount = responseJSON['quoteCurrencyAmount'] as double;
|
||||
|
||||
return Order(
|
||||
id: id,
|
||||
provider: description,
|
||||
transferId: id,
|
||||
state: state,
|
||||
createdAt: createdAt,
|
||||
amount: amount.toString(),
|
||||
receiveAddress: walletAddress,
|
||||
walletId: walletId
|
||||
);
|
||||
}
|
||||
|
||||
static Future<bool> onEnabled() async {
|
||||
final url = _apiUrl + _ipAddressSuffix + '?apiKey=' + _apiKey;
|
||||
var isBuyEnable = false;
|
||||
|
||||
final response = await get(url);
|
||||
|
||||
try {
|
||||
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
|
||||
isBuyEnable = responseJSON['isBuyAllowed'] as bool;
|
||||
} catch (e) {
|
||||
isBuyEnable = false;
|
||||
print(e.toString());
|
||||
}
|
||||
|
||||
return isBuyEnable;
|
||||
}
|
||||
}
|
@ -0,0 +1,163 @@
|
||||
import 'dart:convert';
|
||||
import 'package:cake_wallet/buy/buy_exception.dart';
|
||||
import 'package:http/http.dart';
|
||||
import 'package:cake_wallet/buy/buy_amount.dart';
|
||||
import 'package:cake_wallet/buy/buy_provider.dart';
|
||||
import 'package:cake_wallet/buy/buy_provider_description.dart';
|
||||
import 'package:cake_wallet/buy/order.dart';
|
||||
import 'package:cake_wallet/core/wallet_base.dart';
|
||||
import 'package:cake_wallet/entities/wallet_type.dart';
|
||||
import 'package:cake_wallet/exchange/trade_state.dart';
|
||||
import 'package:cake_wallet/.secrets.g.dart' as secrets;
|
||||
|
||||
class WyreBuyProvider extends BuyProvider {
|
||||
WyreBuyProvider({WalletBase wallet, bool isTestEnvironment = false})
|
||||
: super(wallet: wallet, isTestEnvironment: isTestEnvironment) {
|
||||
baseApiUrl = isTestEnvironment
|
||||
? _baseTestApiUrl
|
||||
: _baseProductApiUrl;
|
||||
}
|
||||
|
||||
static const _baseTestApiUrl = 'https://api.testwyre.com';
|
||||
static const _baseProductApiUrl = 'https://api.sendwyre.com';
|
||||
static const _trackTestUrl = 'https://dash.testwyre.com/track/';
|
||||
static const _trackProductUrl = 'https://dash.sendwyre.com/track/';
|
||||
static const _ordersSuffix = '/v3/orders';
|
||||
static const _reserveSuffix = '/reserve';
|
||||
static const _quoteSuffix = '/quote/partner';
|
||||
static const _timeStampSuffix = '?timestamp=';
|
||||
static const _transferSuffix = '/v2/transfer/';
|
||||
static const _trackSuffix = '/track';
|
||||
static const _countryCode = 'US';
|
||||
static const _secretKey = secrets.wyreSecretKey;
|
||||
static const _accountId = secrets.wyreAccountId;
|
||||
|
||||
@override
|
||||
String get title => 'Wyre';
|
||||
|
||||
@override
|
||||
BuyProviderDescription get description => BuyProviderDescription.wyre;
|
||||
|
||||
@override
|
||||
String get trackUrl => isTestEnvironment
|
||||
? _trackTestUrl
|
||||
: _trackProductUrl;
|
||||
|
||||
String baseApiUrl;
|
||||
|
||||
@override
|
||||
Future<String> requestUrl(String amount, String sourceCurrency) async {
|
||||
final timestamp = DateTime.now().millisecondsSinceEpoch.toString();
|
||||
final url = baseApiUrl + _ordersSuffix + _reserveSuffix +
|
||||
_timeStampSuffix + timestamp;
|
||||
final body = {
|
||||
'amount': amount,
|
||||
'sourceCurrency': sourceCurrency,
|
||||
'destCurrency': walletTypeToCryptoCurrency(walletType).title,
|
||||
'dest': walletTypeToString(walletType).toLowerCase() + ':' + walletAddress,
|
||||
'referrerAccountId': _accountId,
|
||||
'lockFields': ['amount', 'sourceCurrency', '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 BuyException(
|
||||
description: description,
|
||||
text: 'Url $url is not found!');
|
||||
}
|
||||
|
||||
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
|
||||
final urlFromResponse = responseJSON['url'] as String;
|
||||
return urlFromResponse;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<BuyAmount> calculateAmount(String amount, String sourceCurrency) async {
|
||||
final quoteUrl = _baseProductApiUrl + _ordersSuffix + _quoteSuffix;
|
||||
final body = {
|
||||
'amount': amount,
|
||||
'sourceCurrency': sourceCurrency,
|
||||
'destCurrency': walletTypeToCryptoCurrency(walletType).title,
|
||||
'dest': walletTypeToString(walletType).toLowerCase() + ':' + walletAddress,
|
||||
'accountId': _accountId,
|
||||
'country': _countryCode
|
||||
};
|
||||
|
||||
final response = await post(quoteUrl,
|
||||
headers: {
|
||||
'Authorization': 'Bearer $_secretKey',
|
||||
'Content-Type': 'application/json',
|
||||
'cache-control': 'no-cache'
|
||||
},
|
||||
body: json.encode(body));
|
||||
|
||||
if (response.statusCode != 200) {
|
||||
throw BuyException(
|
||||
description: description,
|
||||
text: 'Quote is not found!');
|
||||
}
|
||||
|
||||
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
|
||||
final sourceAmount = responseJSON['sourceAmount'] as double;
|
||||
final destAmount = responseJSON['destAmount'] as double;
|
||||
|
||||
return BuyAmount(sourceAmount: sourceAmount, destAmount: destAmount);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Order> findOrderById(String id) async {
|
||||
final orderUrl = baseApiUrl + _ordersSuffix + '/$id';
|
||||
final orderResponse = await get(orderUrl);
|
||||
|
||||
if (orderResponse.statusCode != 200) {
|
||||
throw BuyException(
|
||||
description: description,
|
||||
text: '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 BuyException(
|
||||
description: description,
|
||||
text: '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,
|
||||
provider: description,
|
||||
transferId: transferId,
|
||||
from: from,
|
||||
to: to,
|
||||
state: state,
|
||||
createdAt: createdAt,
|
||||
amount: amount.toString(),
|
||||
receiveAddress: walletAddress,
|
||||
walletId: walletId
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
import 'dart:io';
|
||||
import 'package:cake_wallet/main.dart';
|
||||
import 'package:cake_wallet/utils/show_bar.dart';
|
||||
import 'package:firebase_messaging/firebase_messaging.dart';
|
||||
|
||||
class PushNotificationsService {
|
||||
PushNotificationsService._();
|
||||
|
||||
factory PushNotificationsService() => _instance;
|
||||
|
||||
static final PushNotificationsService _instance = PushNotificationsService._();
|
||||
static Future<dynamic> _onBackgroundMessage(Map<String, dynamic> message) async {}
|
||||
static Future<void> _showNotification(Map<String, dynamic> message) async {
|
||||
Map<dynamic, dynamic> alert = <dynamic, dynamic>{};
|
||||
String msg = '';
|
||||
String title = '';
|
||||
|
||||
if (Platform.isIOS) {
|
||||
alert = message['aps']['alert'] as Map<dynamic, dynamic> ?? <dynamic, dynamic>{};
|
||||
msg = alert['body'] as String ?? '';
|
||||
title = alert['title'] as String ?? '';
|
||||
}
|
||||
|
||||
if (Platform.isAndroid) {
|
||||
msg = message['notification']['body'] as String ?? '';
|
||||
title = message['notification']['title'] as String ?? '';
|
||||
}
|
||||
|
||||
await showBar<void>(navigatorKey.currentContext, msg, titleText: title, duration: null);
|
||||
}
|
||||
|
||||
final _firebaseMessaging = FirebaseMessaging();
|
||||
bool _initialized = false;
|
||||
|
||||
Future<void> init() async {
|
||||
if (_initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
_firebaseMessaging.requestNotificationPermissions();
|
||||
_firebaseMessaging.configure(
|
||||
onMessage: (message) async => _showNotification(message),
|
||||
onLaunch: (message) async => _showNotification(message),
|
||||
onResume: (message) async => _showNotification(message),
|
||||
onBackgroundMessage: _onBackgroundMessage);
|
||||
|
||||
_initialized = true;
|
||||
}
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
class WyreException implements Exception {
|
||||
WyreException(this.description);
|
||||
|
||||
String description;
|
||||
|
||||
@override
|
||||
String toString() => description;
|
||||
}
|
@ -1,113 +0,0 @@
|
||||
import 'dart:convert';
|
||||
import 'package:cake_wallet/entities/wyre_exception.dart';
|
||||
import 'package:cake_wallet/exchange/trade_state.dart';
|
||||
import 'package:cake_wallet/store/app_store.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.appStore, this.isTestEnvironment = false}) {
|
||||
baseApiUrl = isTestEnvironment ? _baseTestApiUrl : _baseProductApiUrl;
|
||||
trackUrl = isTestEnvironment ? _trackTestUrl : _trackProductUrl;
|
||||
}
|
||||
|
||||
static const _baseTestApiUrl = 'https://api.testwyre.com';
|
||||
static const _baseProductApiUrl = 'https://api.sendwyre.com';
|
||||
static const _trackTestUrl = 'https://dash.testwyre.com/track/';
|
||||
static const _trackProductUrl = '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 AppStore appStore;
|
||||
|
||||
WalletType get walletType => appStore.wallet.type;
|
||||
String get walletAddress => appStore.wallet.address;
|
||||
String get walletId => appStore.wallet.id;
|
||||
|
||||
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(),
|
||||
receiveAddress: walletAddress,
|
||||
walletId: walletId);
|
||||
}
|
||||
}
|
@ -0,0 +1,287 @@
|
||||
import 'dart:ui';
|
||||
import 'package:cake_wallet/buy/buy_amount.dart';
|
||||
import 'package:cake_wallet/buy/buy_provider.dart';
|
||||
import 'package:cake_wallet/buy/moonpay/moonpay_buy_provider.dart';
|
||||
import 'package:cake_wallet/entities/wallet_type.dart';
|
||||
import 'package:cake_wallet/src/screens/buy/widgets/buy_list_item.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
|
||||
import 'package:cake_wallet/src/widgets/keyboard_done_button.dart';
|
||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||
import 'package:cake_wallet/view_model/buy/buy_view_model.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
import 'package:keyboard_actions/keyboard_actions.dart';
|
||||
import 'package:cake_wallet/routes.dart';
|
||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
import 'package:cake_wallet/src/widgets/primary_button.dart';
|
||||
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
|
||||
import 'package:cake_wallet/src/widgets/trail_button.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
class PreOrderPage extends BasePage {
|
||||
PreOrderPage({@required this.buyViewModel})
|
||||
: _amountFocus = FocusNode(),
|
||||
_amountController = TextEditingController() {
|
||||
|
||||
_amountController.addListener(() {
|
||||
final amount = _amountController.text;
|
||||
|
||||
if (amount != buyViewModel.buyAmountViewModel.amount) {
|
||||
buyViewModel.buyAmountViewModel.amount = amount;
|
||||
buyViewModel.selectedProvider = null;
|
||||
}
|
||||
});
|
||||
|
||||
reaction((_) => buyViewModel.buyAmountViewModel.amount, (String amount) {
|
||||
if (_amountController.text != amount) {
|
||||
_amountController.text = amount;
|
||||
}
|
||||
if (amount.isEmpty) {
|
||||
buyViewModel.selectedProvider = null;
|
||||
buyViewModel.isShowProviderButtons = false;
|
||||
} else {
|
||||
buyViewModel.isShowProviderButtons = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static const _amountPattern = '^([0-9]+([.\,][0-9]{0,2})?|[.\,][0-9]{1,2})\$';
|
||||
|
||||
final BuyViewModel buyViewModel;
|
||||
final FocusNode _amountFocus;
|
||||
final TextEditingController _amountController;
|
||||
|
||||
@override
|
||||
String get title => S.current.buy + ' ' + walletTypeToString(buyViewModel.wallet.type);
|
||||
|
||||
@override
|
||||
Color get titleColor => Colors.white;
|
||||
|
||||
@override
|
||||
bool get resizeToAvoidBottomInset => false;
|
||||
|
||||
@override
|
||||
bool get extendBodyBehindAppBar => true;
|
||||
|
||||
@override
|
||||
AppBarStyle get appBarStyle => AppBarStyle.transparent;
|
||||
|
||||
@override
|
||||
Widget trailing(context) => TrailButton(
|
||||
caption: S.of(context).clear,
|
||||
onPressed: () => buyViewModel.reset());
|
||||
|
||||
@override
|
||||
Widget body(BuildContext context) {
|
||||
return KeyboardActions(
|
||||
config: KeyboardActionsConfig(
|
||||
keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
|
||||
keyboardBarColor: Theme.of(context).accentTextTheme.body2
|
||||
.backgroundColor,
|
||||
nextFocus: false,
|
||||
actions: [
|
||||
KeyboardActionsItem(
|
||||
focusNode: _amountFocus,
|
||||
toolbarButtons: [(_) => KeyboardDoneButton()],
|
||||
),
|
||||
]),
|
||||
child: Container(
|
||||
height: 0,
|
||||
color: Theme.of(context).backgroundColor,
|
||||
child: ScrollableWithBottomSection(
|
||||
contentPadding: EdgeInsets.only(bottom: 24),
|
||||
content: Observer(builder: (_) => Column(
|
||||
children: [
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.only(
|
||||
bottomLeft: Radius.circular(24),
|
||||
bottomRight: Radius.circular(24)),
|
||||
gradient: LinearGradient(colors: [
|
||||
Theme.of(context).primaryTextTheme.subhead.color,
|
||||
Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.subhead
|
||||
.decorationColor,
|
||||
], begin: Alignment.topLeft, end: Alignment.bottomRight),
|
||||
),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(top: 100, bottom: 65),
|
||||
child: Center(
|
||||
child: Container(
|
||||
width: 210,
|
||||
child: BaseTextFormField(
|
||||
focusNode: _amountFocus,
|
||||
controller: _amountController,
|
||||
keyboardType:
|
||||
TextInputType.numberWithOptions(
|
||||
signed: false, decimal: true),
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter
|
||||
.allow(RegExp(_amountPattern))
|
||||
],
|
||||
prefixIcon: Padding(
|
||||
padding: EdgeInsets.only(top: 2),
|
||||
child:
|
||||
Text(buyViewModel.fiatCurrency.title + ': ',
|
||||
style: TextStyle(
|
||||
fontSize: 36,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.white,
|
||||
)),
|
||||
),
|
||||
hintText: '0.00',
|
||||
borderColor: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.body2
|
||||
.decorationColor,
|
||||
borderWidth: 0.5,
|
||||
textStyle: TextStyle(
|
||||
fontSize: 36,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.white),
|
||||
placeholderTextStyle: TextStyle(
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.headline
|
||||
.decorationColor,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 36),
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
if (buyViewModel.isShowProviderButtons) Padding(
|
||||
padding: EdgeInsets.only(top: 38, bottom: 18),
|
||||
child: Text(
|
||||
S.of(context).buy_with + ':',
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).primaryTextTheme.title.color,
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold
|
||||
),
|
||||
)
|
||||
),
|
||||
if (buyViewModel.isShowProviderButtons)
|
||||
...buyViewModel.items.map(
|
||||
(item) => Observer(builder: (_) =>
|
||||
FutureBuilder<BuyAmount>(
|
||||
future: item.buyAmount,
|
||||
builder: (context, AsyncSnapshot<BuyAmount> snapshot) {
|
||||
double sourceAmount;
|
||||
double destAmount;
|
||||
int minAmount;
|
||||
|
||||
if (snapshot.hasData) {
|
||||
sourceAmount = snapshot.data.sourceAmount;
|
||||
destAmount = snapshot.data.destAmount;
|
||||
minAmount = snapshot.data.minAmount;
|
||||
} else {
|
||||
sourceAmount = 0.0;
|
||||
destAmount = 0.0;
|
||||
minAmount = 0;
|
||||
}
|
||||
|
||||
return Padding(
|
||||
padding:
|
||||
EdgeInsets.only(left: 15, top: 20, right: 15),
|
||||
child: Observer(builder: (_) {
|
||||
return BuyListItem(
|
||||
selectedProvider:
|
||||
buyViewModel.selectedProvider,
|
||||
provider: item.provider,
|
||||
sourceAmount: sourceAmount,
|
||||
sourceCurrency: buyViewModel.fiatCurrency,
|
||||
destAmount: destAmount,
|
||||
destCurrency: buyViewModel.cryptoCurrency,
|
||||
onTap: ((buyViewModel.doubleAmount != 0.0)
|
||||
&& (snapshot.hasData)) ? () =>
|
||||
onSelectBuyProvider(
|
||||
context: context,
|
||||
provider: item.provider,
|
||||
sourceAmount: sourceAmount,
|
||||
minAmount: minAmount
|
||||
) : null
|
||||
);
|
||||
})
|
||||
);
|
||||
}
|
||||
))
|
||||
)
|
||||
],
|
||||
)),
|
||||
bottomSectionPadding:
|
||||
EdgeInsets.only(left: 24, right: 24, bottom: 24),
|
||||
bottomSection: Observer(builder: (_) {
|
||||
return LoadingPrimaryButton(
|
||||
onPressed: () => onPresentProvider(context: context),
|
||||
text: buyViewModel.selectedProvider == null
|
||||
? S.of(context).buy
|
||||
: S.of(context).buy_with +
|
||||
' ${buyViewModel.selectedProvider
|
||||
.description.title}',
|
||||
color: Theme.of(context).accentTextTheme.body2.color,
|
||||
textColor: Colors.white,
|
||||
isLoading: buyViewModel.isRunning,
|
||||
isDisabled: (buyViewModel.selectedProvider == null) ||
|
||||
buyViewModel.isDisabled
|
||||
);
|
||||
})
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
void onSelectBuyProvider({BuildContext context, BuyProvider provider,
|
||||
double sourceAmount, int minAmount}) {
|
||||
|
||||
if ((provider is MoonPayBuyProvider)&&
|
||||
(buyViewModel.buyAmountViewModel.doubleAmount < minAmount)) {
|
||||
showPopUp<void>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertWithOneAction(
|
||||
alertTitle: 'MoonPay',
|
||||
alertContent: S.of(context).moonpay_alert_text(
|
||||
minAmount.toString(),
|
||||
buyViewModel.fiatCurrency.toString()),
|
||||
buttonText: S.of(context).ok,
|
||||
buttonAction: () => Navigator.of(context).pop());
|
||||
});
|
||||
return;
|
||||
}
|
||||
buyViewModel.selectedProvider = provider;
|
||||
sourceAmount > 0
|
||||
? buyViewModel.isDisabled = false
|
||||
: buyViewModel.isDisabled = true;
|
||||
}
|
||||
|
||||
Future<void> onPresentProvider({BuildContext context}) async {
|
||||
if (buyViewModel.isRunning) {
|
||||
return;
|
||||
}
|
||||
|
||||
buyViewModel.isRunning = true;
|
||||
final url = await buyViewModel.fetchUrl();
|
||||
|
||||
if (url.isNotEmpty) {
|
||||
if (buyViewModel.selectedProvider is MoonPayBuyProvider) {
|
||||
if (await canLaunch(url)) await launch(url);
|
||||
} else {
|
||||
await Navigator.of(context)
|
||||
.pushNamed(Routes.buyWebView,
|
||||
arguments: [url, buyViewModel]);
|
||||
}
|
||||
}
|
||||
|
||||
buyViewModel.reset();
|
||||
buyViewModel.isRunning = false;
|
||||
}
|
||||
}
|
@ -0,0 +1,116 @@
|
||||
import 'package:cake_wallet/buy/buy_provider.dart';
|
||||
import 'package:cake_wallet/buy/get_buy_provider_icon.dart';
|
||||
import 'package:cake_wallet/entities/crypto_currency.dart';
|
||||
import 'package:cake_wallet/entities/fiat_currency.dart';
|
||||
import 'package:cake_wallet/palette.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class BuyListItem extends StatelessWidget {
|
||||
BuyListItem({
|
||||
@required this.selectedProvider,
|
||||
@required this.provider,
|
||||
@required this.sourceAmount,
|
||||
@required this.sourceCurrency,
|
||||
@required this.destAmount,
|
||||
@required this.destCurrency,
|
||||
@required this.onTap
|
||||
});
|
||||
|
||||
final BuyProvider selectedProvider;
|
||||
final BuyProvider provider;
|
||||
final double sourceAmount;
|
||||
final FiatCurrency sourceCurrency;
|
||||
final double destAmount;
|
||||
final CryptoCurrency destCurrency;
|
||||
final void Function() onTap;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final isSelected = selectedProvider?.description == provider.description;
|
||||
|
||||
final providerIcon = getBuyProviderIcon(provider.description,
|
||||
isWhiteIconColor: isSelected);
|
||||
|
||||
final backgroundColor = isSelected
|
||||
? Palette.greyBlueCraiola
|
||||
: Palette.shadowWhite;
|
||||
|
||||
final primaryTextColor = isSelected
|
||||
? Colors.white
|
||||
: Palette.darkGray;
|
||||
|
||||
final secondaryTextColor = isSelected
|
||||
? Colors.white
|
||||
: Palette.darkBlueCraiola;
|
||||
|
||||
return GestureDetector(
|
||||
onTap: () => onTap?.call(),
|
||||
child: Container(
|
||||
height: 102,
|
||||
padding: EdgeInsets.only(
|
||||
left: 20,
|
||||
//top: 33,
|
||||
right: 20
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.all(Radius.circular(25)),
|
||||
color: backgroundColor
|
||||
),
|
||||
child: Stack(
|
||||
children: [
|
||||
Positioned(
|
||||
top: 33,
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
if (providerIcon != null) Padding(
|
||||
padding: EdgeInsets.only(right: 10),
|
||||
child: providerIcon
|
||||
),
|
||||
Text(
|
||||
provider.description.title,
|
||||
style: TextStyle(
|
||||
color: secondaryTextColor,
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
Text(
|
||||
'${destAmount?.toString()} ${destCurrency.title}',
|
||||
style: TextStyle(
|
||||
color: secondaryTextColor,
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
),
|
||||
Positioned(
|
||||
top: 65,
|
||||
right: 0,
|
||||
child: Text(
|
||||
'${sourceAmount?.toString()} ${sourceCurrency.title}',
|
||||
style: TextStyle(
|
||||
color: primaryTextColor,
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:cake_wallet/entities/fiat_currency.dart';
|
||||
|
||||
part 'buy_amount_view_model.g.dart';
|
||||
|
||||
class BuyAmountViewModel = BuyAmountViewModelBase with _$BuyAmountViewModel;
|
||||
|
||||
abstract class BuyAmountViewModelBase with Store {
|
||||
BuyAmountViewModelBase() : amount = '';
|
||||
|
||||
@observable
|
||||
String amount;
|
||||
|
||||
FiatCurrency get fiatCurrency => FiatCurrency.usd;
|
||||
|
||||
@computed
|
||||
double get doubleAmount {
|
||||
double _amount;
|
||||
|
||||
try {
|
||||
_amount = double.parse(amount.replaceAll(',', '.')) ?? 0.0;
|
||||
} catch (e) {
|
||||
_amount = 0.0;
|
||||
}
|
||||
|
||||
return _amount;
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
import 'package:cake_wallet/buy/buy_amount.dart';
|
||||
import 'package:cake_wallet/buy/buy_provider.dart';
|
||||
import 'package:cake_wallet/entities/fiat_currency.dart';
|
||||
import 'package:cake_wallet/view_model/buy/buy_amount_view_model.dart';
|
||||
|
||||
class BuyItem {
|
||||
BuyItem({this.provider, this.buyAmountViewModel});
|
||||
|
||||
final BuyProvider provider;
|
||||
final BuyAmountViewModel buyAmountViewModel;
|
||||
|
||||
double get amount => buyAmountViewModel.doubleAmount;
|
||||
|
||||
FiatCurrency get fiatCurrency => buyAmountViewModel.fiatCurrency;
|
||||
|
||||
Future<BuyAmount> get buyAmount async {
|
||||
BuyAmount _buyAmount;
|
||||
|
||||
try {
|
||||
_buyAmount = await provider
|
||||
.calculateAmount(amount?.toString(), fiatCurrency.title);
|
||||
} catch (e) {
|
||||
_buyAmount = BuyAmount(sourceAmount: 0.0, destAmount: 0.0);
|
||||
print(e.toString());
|
||||
}
|
||||
|
||||
return _buyAmount;
|
||||
}
|
||||
}
|
@ -0,0 +1,114 @@
|
||||
import 'package:cake_wallet/buy/buy_provider.dart';
|
||||
import 'package:cake_wallet/buy/moonpay/moonpay_buy_provider.dart';
|
||||
import 'package:cake_wallet/buy/wyre/wyre_buy_provider.dart';
|
||||
import 'package:cake_wallet/entities/crypto_currency.dart';
|
||||
import 'package:cake_wallet/entities/fiat_currency.dart';
|
||||
import 'package:cake_wallet/entities/wallet_type.dart';
|
||||
import 'package:cake_wallet/store/settings_store.dart';
|
||||
import 'package:cake_wallet/view_model/buy/buy_item.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:cake_wallet/buy/order.dart';
|
||||
import 'package:cake_wallet/store/dashboard/orders_store.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:cake_wallet/core/wallet_base.dart';
|
||||
import 'buy_amount_view_model.dart';
|
||||
|
||||
part 'buy_view_model.g.dart';
|
||||
|
||||
class BuyViewModel = BuyViewModelBase with _$BuyViewModel;
|
||||
|
||||
abstract class BuyViewModelBase with Store {
|
||||
BuyViewModelBase(this.ordersSource, this.ordersStore, this.settingsStore,
|
||||
this.buyAmountViewModel, {@required this.wallet}) {
|
||||
|
||||
_fetchBuyItems();
|
||||
|
||||
isRunning = false;
|
||||
isDisabled = true;
|
||||
isShowProviderButtons = false;
|
||||
}
|
||||
|
||||
final Box<Order> ordersSource;
|
||||
final OrdersStore ordersStore;
|
||||
final SettingsStore settingsStore;
|
||||
final BuyAmountViewModel buyAmountViewModel;
|
||||
final WalletBase wallet;
|
||||
|
||||
@observable
|
||||
BuyProvider selectedProvider;
|
||||
|
||||
@observable
|
||||
List<BuyItem> items;
|
||||
|
||||
@observable
|
||||
bool isRunning;
|
||||
|
||||
@observable
|
||||
bool isDisabled;
|
||||
|
||||
@observable
|
||||
bool isShowProviderButtons;
|
||||
|
||||
WalletType get type => wallet.type;
|
||||
|
||||
double get doubleAmount => buyAmountViewModel.doubleAmount;
|
||||
|
||||
FiatCurrency get fiatCurrency => buyAmountViewModel.fiatCurrency;
|
||||
|
||||
CryptoCurrency get cryptoCurrency => walletTypeToCryptoCurrency(type);
|
||||
|
||||
Future <String> fetchUrl() async {
|
||||
String _url = '';
|
||||
|
||||
try {
|
||||
_url = await selectedProvider
|
||||
?.requestUrl(doubleAmount?.toString(), fiatCurrency.title);
|
||||
} catch (e) {
|
||||
print(e.toString());
|
||||
}
|
||||
|
||||
return _url;
|
||||
}
|
||||
|
||||
Future<void> saveOrder(String orderId) async {
|
||||
try {
|
||||
final order = await selectedProvider?.findOrderById(orderId);
|
||||
order.from = fiatCurrency.title;
|
||||
order.to = cryptoCurrency.title;
|
||||
await ordersSource.add(order);
|
||||
ordersStore.setOrder(order);
|
||||
} catch (e) {
|
||||
print(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
void reset() {
|
||||
buyAmountViewModel.amount = '';
|
||||
selectedProvider = null;
|
||||
}
|
||||
|
||||
Future<void> _fetchBuyItems() async {
|
||||
final List<BuyProvider> _providerList = [];
|
||||
|
||||
if (wallet.type == WalletType.bitcoin) {
|
||||
_providerList.add(WyreBuyProvider(wallet: wallet));
|
||||
}
|
||||
|
||||
var isMoonPayEnabled = false;
|
||||
try {
|
||||
isMoonPayEnabled = await MoonPayBuyProvider.onEnabled();
|
||||
} catch (e) {
|
||||
isMoonPayEnabled = false;
|
||||
print(e.toString());
|
||||
}
|
||||
|
||||
if (isMoonPayEnabled) {
|
||||
_providerList.add(MoonPayBuyProvider(wallet: wallet));
|
||||
}
|
||||
|
||||
items = _providerList.map((provider) =>
|
||||
BuyItem(provider: provider, buyAmountViewModel: buyAmountViewModel))
|
||||
.toList();
|
||||
}
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
import 'package:cake_wallet/entities/wyre_service.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:cake_wallet/entities/order.dart';
|
||||
import 'package:cake_wallet/store/dashboard/orders_store.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
|
||||
part 'wyre_view_model.g.dart';
|
||||
|
||||
class WyreViewModel = WyreViewModelBase with _$WyreViewModel;
|
||||
|
||||
abstract class WyreViewModelBase with Store {
|
||||
WyreViewModelBase(this.ordersSource, this.ordersStore,
|
||||
{@required this.wyreService});
|
||||
|
||||
Future<String> get wyreUrl => wyreService.getWyreUrl();
|
||||
|
||||
String get trackUrl => wyreService.trackUrl;
|
||||
|
||||
final Box<Order> ordersSource;
|
||||
final OrdersStore ordersStore;
|
||||
|
||||
final WyreService wyreService;
|
||||
|
||||
Future<void> saveOrder(String orderId) async {
|
||||
try {
|
||||
final order = await wyreService.findOrderById(orderId);
|
||||
await ordersSource.add(order);
|
||||
ordersStore.setOrder(order);
|
||||
} catch (e) {
|
||||
print(e.toString());
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in new issue