onramper order

This commit is contained in:
Serhii 2024-02-12 13:21:46 +02:00
parent 39a73b2058
commit 3b71b679bb
21 changed files with 361 additions and 342 deletions

View file

@ -1,6 +1,3 @@
import 'package:flutter/foundation.dart';
import 'package:cake_wallet/buy/buy_provider_description.dart';
class BuyException implements Exception { class BuyException implements Exception {
BuyException({required this.title, required this.content}); BuyException({required this.title, required this.content});

View file

@ -1,5 +1,6 @@
import 'package:cake_wallet/buy/buy_amount.dart'; import 'package:cake_wallet/buy/buy_amount.dart';
import 'package:cake_wallet/buy/order.dart'; import 'package:cake_wallet/buy/order.dart';
import 'package:cake_wallet/entities/provider_types.dart';
import 'package:cw_core/wallet_base.dart'; import 'package:cw_core/wallet_base.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -20,6 +21,10 @@ abstract class BuyProvider {
String get darkIcon; String get darkIcon;
ProviderType get providerType;
String get trackUrl;
@override @override
String toString() => title; String toString() => title;

View file

@ -1,21 +0,0 @@
import 'package:cw_core/enumerable_item.dart';
class BuyProviderDescription extends EnumerableItem<int>
with Serializable<int> {
const BuyProviderDescription({required String title, required 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({required int raw}) {
switch (raw) {
case 0:
return wyre;
case 1:
return moonPay;
default:
throw Exception('Incorrect token $raw for BuyProviderDescription deserialize');
}
}
}

View file

@ -1,6 +1,7 @@
import 'dart:convert'; import 'dart:convert';
import 'package:cake_wallet/buy/buy_provider.dart'; import 'package:cake_wallet/buy/buy_provider.dart';
import 'package:cake_wallet/entities/provider_types.dart';
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart'; import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
@ -23,7 +24,10 @@ class DFXBuyProvider extends BuyProvider {
static const walletName = 'CakeWallet'; static const walletName = 'CakeWallet';
@override @override
String get title => 'DFX Connect'; ProviderType get providerType => ProviderType.dfx;
@override
String get title => providerType.title;
@override @override
String get providerDescription => S.current.dfx_option_description; String get providerDescription => S.current.dfx_option_description;
@ -34,6 +38,9 @@ class DFXBuyProvider extends BuyProvider {
@override @override
String get darkIcon => 'assets/images/dfx_dark.png'; String get darkIcon => 'assets/images/dfx_dark.png';
@override
String get trackUrl => 'https://dash.dfx.swiss/track/';
String get assetOut { String get assetOut {
switch (wallet.type) { switch (wallet.type) {
case WalletType.bitcoin: case WalletType.bitcoin:
@ -186,7 +193,7 @@ class DFXBuyProvider extends BuyProvider {
if (await canLaunchUrl(uri)) { if (await canLaunchUrl(uri)) {
if (DeviceInfo.instance.isMobile) { if (DeviceInfo.instance.isMobile) {
Navigator.of(context).pushNamed(Routes.webViewPage, arguments: [title, uri]); Navigator.of(context).pushNamed(Routes.webViewPage, arguments: [uri, providerType]);
} else { } else {
await launchUrl(uri, mode: LaunchMode.externalApplication); await launchUrl(uri, mode: LaunchMode.externalApplication);
} }

View file

@ -1,25 +0,0 @@
import 'package:flutter/material.dart';
import 'package:cake_wallet/buy/buy_provider_description.dart';
Image? getBuyProviderIcon(BuyProviderDescription providerDescription,
{Color iconColor = Colors.black}) {
final _wyreIcon =
Image.asset('assets/images/wyre-icon.png', width: 36, height: 36);
final _moonPayIcon =
Image.asset('assets/images/moonpay-icon.png', color: iconColor,
width: 36, height: 34);
if (providerDescription != null) {
switch (providerDescription) {
case BuyProviderDescription.wyre:
return _wyreIcon;
case BuyProviderDescription.moonPay:
return _moonPayIcon;
default:
return null;
}
} else {
return null;
}
}

View file

@ -1,4 +1,5 @@
import 'dart:convert'; import 'dart:convert';
import 'package:cake_wallet/entities/provider_types.dart';
import 'package:cake_wallet/palette.dart'; import 'package:cake_wallet/palette.dart';
import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart'; import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
@ -12,7 +13,6 @@ import 'package:flutter/material.dart';
import 'package:http/http.dart'; import 'package:http/http.dart';
import 'package:cake_wallet/buy/buy_amount.dart'; import 'package:cake_wallet/buy/buy_amount.dart';
import 'package:cake_wallet/buy/buy_provider.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/buy/order.dart';
import 'package:cw_core/wallet_base.dart'; import 'package:cw_core/wallet_base.dart';
import 'package:cw_core/wallet_type.dart'; import 'package:cw_core/wallet_type.dart';
@ -36,11 +36,14 @@ class MoonPaySellProvider extends BuyProvider {
static const _baseProductUrl = 'sell.moonpay.com'; static const _baseProductUrl = 'sell.moonpay.com';
@override @override
String get providerDescription => ProviderType get providerType => ProviderType.moonpaySell;
'MoonPay offers a fast and simple way to buy and sell cryptocurrencies';
@override @override
String get title => 'MoonPay'; String get title => providerType.title;
@override
String get providerDescription =>
'MoonPay offers a fast and simple way to buy and sell cryptocurrencies';
@override @override
String get lightIcon => 'assets/images/moonpay_light.png'; String get lightIcon => 'assets/images/moonpay_light.png';
@ -48,6 +51,9 @@ class MoonPaySellProvider extends BuyProvider {
@override @override
String get darkIcon => 'assets/images/moonpay_dark.png'; String get darkIcon => 'assets/images/moonpay_dark.png';
@override
String get trackUrl => '';
static String themeToMoonPayTheme(ThemeBase theme) { static String themeToMoonPayTheme(ThemeBase theme) {
switch (theme.type) { switch (theme.type) {
case ThemeType.bright: case ThemeType.bright:
@ -113,7 +119,7 @@ class MoonPaySellProvider extends BuyProvider {
if (await canLaunchUrl(uri)) { if (await canLaunchUrl(uri)) {
if (DeviceInfo.instance.isMobile) { if (DeviceInfo.instance.isMobile) {
Navigator.of(context).pushNamed(Routes.webViewPage, arguments: ['MoonPay', uri]); Navigator.of(context).pushNamed(Routes.webViewPage, arguments: [uri]);
} else { } else {
await launchUrl(uri, mode: LaunchMode.externalApplication); await launchUrl(uri, mode: LaunchMode.externalApplication);
} }
@ -152,7 +158,10 @@ class MoonPayBuyProvider extends BuyProvider {
static const _secretKey = secrets.moonPaySecretKey; static const _secretKey = secrets.moonPaySecretKey;
@override @override
String get title => 'MoonPay'; ProviderType get providerType => ProviderType.moonpaySell;
@override
String get title => providerType.name;
@override @override
String get providerDescription => String get providerDescription =>
@ -247,7 +256,7 @@ class MoonPayBuyProvider extends BuyProvider {
return Order( return Order(
id: id, id: id,
provider: BuyProviderDescription.moonPay, provider: ProviderType.moonpaySell,
transferId: id, transferId: id,
state: state, state: state,
createdAt: createdAt, createdAt: createdAt,

View file

@ -1,5 +1,6 @@
import 'package:cake_wallet/.secrets.g.dart' as secrets; import 'package:cake_wallet/.secrets.g.dart' as secrets;
import 'package:cake_wallet/buy/buy_provider.dart'; import 'package:cake_wallet/buy/buy_provider.dart';
import 'package:cake_wallet/entities/provider_types.dart';
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/store/settings_store.dart'; import 'package:cake_wallet/store/settings_store.dart';
@ -9,18 +10,32 @@ import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/wallet_base.dart'; import 'package:cw_core/wallet_base.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
import 'package:collection/collection.dart';
enum OnRamperPartner {
guardarian,
paybis,
}
class OnRamperBuyProvider extends BuyProvider { class OnRamperBuyProvider extends BuyProvider {
OnRamperBuyProvider(this._settingsStore, OnRamperBuyProvider({this.settingsStore,this.partner,
{required WalletBase wallet, bool isTestEnvironment = false}) required WalletBase wallet, bool isTestEnvironment = false})
: super(wallet: wallet, isTestEnvironment: isTestEnvironment); : super(wallet: wallet, isTestEnvironment: isTestEnvironment);
static const _baseUrl = 'buy.onramper.com'; static const _baseUrl = 'buy.onramper.com';
final SettingsStore _settingsStore; static OnRamperPartner? fromRaw(int? raw) =>
OnRamperPartner.values.firstWhereOrNull((e) => e.index == raw);
final SettingsStore? settingsStore;
OnRamperPartner? partner;
@override @override
String get title => 'Onramper'; ProviderType get providerType => ProviderType.onramper;
@override
String get title => providerType.title;
@override @override
String get providerDescription => S.current.onramper_option_description; String get providerDescription => S.current.onramper_option_description;
@ -31,6 +46,17 @@ class OnRamperBuyProvider extends BuyProvider {
@override @override
String get darkIcon => 'assets/images/onramper_dark.png'; String get darkIcon => 'assets/images/onramper_dark.png';
String get trackUrl {
switch (partner) {
case OnRamperPartner.guardarian:
return "https://payments.guardarian.com/checkout?tid=";
case OnRamperPartner.paybis:
return "https://widget.paybis.com/?requestId=";
default:
return '';
}
}
String get _apiKey => secrets.onramperApiKey; String get _apiKey => secrets.onramperApiKey;
String get _normalizeCryptoCurrency { String get _normalizeCryptoCurrency {
@ -69,9 +95,11 @@ class OnRamperBuyProvider extends BuyProvider {
containerColor = getColorStr(Theme.of(context).colorScheme.background); containerColor = getColorStr(Theme.of(context).colorScheme.background);
cardColor = getColorStr(Theme.of(context).cardColor); cardColor = getColorStr(Theme.of(context).cardColor);
if (_settingsStore.currentTheme.title == S.current.high_contrast_theme) { if (settingsStore != null) {
if (settingsStore!.currentTheme.title == S.current.high_contrast_theme) {
cardColor = getColorStr(Colors.white); cardColor = getColorStr(Colors.white);
} }
}
final networkName = final networkName =
wallet.currency.fullName?.toUpperCase().replaceAll(" ", ""); wallet.currency.fullName?.toUpperCase().replaceAll(" ", "");
@ -96,7 +124,7 @@ class OnRamperBuyProvider extends BuyProvider {
final uri = requestOnramperUrl(context, isBuyAction); final uri = requestOnramperUrl(context, isBuyAction);
if (DeviceInfo.instance.isMobile) { if (DeviceInfo.instance.isMobile) {
Navigator.of(context) Navigator.of(context)
.pushNamed(Routes.webViewPage, arguments: [title, uri]); .pushNamed(Routes.webViewPage, arguments:[uri, providerType]);
} else { } else {
await launchUrl(uri); await launchUrl(uri);
} }

View file

@ -1,9 +1,13 @@
import 'package:cake_wallet/buy/buy_provider_description.dart'; import 'dart:convert';
import 'package:cake_wallet/entities/provider_types.dart';
import 'package:cake_wallet/exchange/trade_state.dart'; import 'package:cake_wallet/exchange/trade_state.dart';
import 'package:cw_core/format_amount.dart'; import 'package:cw_core/format_amount.dart';
import 'package:cw_core/hive_type_ids.dart'; import 'package:cw_core/hive_type_ids.dart';
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';
import 'onramper/onramper_buy_provider.dart';
part 'order.g.dart'; part 'order.g.dart';
@HiveType(typeId: Order.typeId) @HiveType(typeId: Order.typeId)
@ -15,18 +19,43 @@ class Order extends HiveObject {
required this.amount, required this.amount,
required this.receiveAddress, required this.receiveAddress,
required this.walletId, required this.walletId,
BuyProviderDescription? provider, ProviderType? provider,
OnRamperPartner? onramperPartner,
TradeState? state, TradeState? state,
this.from, this.from,
this.to}) { this.to}) {
if (provider != null) { if (provider != null) {
providerRaw = provider.raw; providerRaw = ProvidersHelper.serialize(provider);
}
if (onramperPartner != null) {
onramperPartnerRaw = onramperPartner.index;
} }
if (state != null) { if (state != null) {
stateRaw = state.raw; stateRaw = state.raw;
} }
} }
factory Order.fromJSON(String jsonSource) {
final decoded = json.decode(jsonSource) as Map<String, dynamic>;
final providerRaw = decoded['providerRaw'] as int?;
final onramperPartnerRaw = decoded['onramperPartnerRaw'] as int?;
return Order(
id: decoded['id'] as String,
transferId: decoded['transferId'] as String? ?? '',
createdAt: DateTime.parse(decoded['createdAt'] as String),
amount: decoded['amount'] as String? ?? '',
receiveAddress: decoded['receiveAddress'] as String? ?? '',
walletId: decoded['walletId'] as String? ?? '',
provider: providerRaw != null ? ProvidersHelper.deserialize(raw: providerRaw) : null,
onramperPartner:
onramperPartnerRaw != null ? OnRamperBuyProvider.fromRaw(onramperPartnerRaw) : null,
state: TradeState.created,
from: decoded['from'] as String?,
to: decoded['to'] as String?,
);
}
static const typeId = ORDER_TYPE_ID; static const typeId = ORDER_TYPE_ID;
static const boxName = 'Orders'; static const boxName = 'Orders';
static const boxKey = 'ordersBoxKey'; static const boxKey = 'ordersBoxKey';
@ -44,9 +73,7 @@ class Order extends HiveObject {
String? to; String? to;
@HiveField(4, defaultValue: '') @HiveField(4, defaultValue: '')
late String stateRaw; String? stateRaw;
TradeState get state => TradeState.deserialize(raw: stateRaw);
@HiveField(5) @HiveField(5)
DateTime createdAt; DateTime createdAt;
@ -60,11 +87,19 @@ class Order extends HiveObject {
@HiveField(8, defaultValue: '') @HiveField(8, defaultValue: '')
String walletId; String walletId;
@HiveField(9, defaultValue: 0) @HiveField(9)
late int providerRaw; int? providerRaw;
BuyProviderDescription get provider => @HiveField(10)
BuyProviderDescription.deserialize(raw: providerRaw); int? onramperPartnerRaw;
TradeState? get state => stateRaw != null ? TradeState.deserialize(raw: stateRaw!) : null;
ProviderType? get provider =>
providerRaw != null ? ProvidersHelper.deserialize(raw: providerRaw!) : null;
OnRamperPartner? get onramperPartner =>
onramperPartnerRaw != null ? OnRamperBuyProvider.fromRaw(onramperPartnerRaw!) : null;
String amountFormatted() => formatAmount(amount); String amountFormatted() => formatAmount(amount);
} }

View file

@ -2,6 +2,7 @@ import 'dart:convert';
import 'package:cake_wallet/.secrets.g.dart' as secrets; import 'package:cake_wallet/.secrets.g.dart' as secrets;
import 'package:cake_wallet/buy/buy_provider.dart'; import 'package:cake_wallet/buy/buy_provider.dart';
import 'package:cake_wallet/entities/provider_types.dart';
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart'; import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:cake_wallet/utils/show_pop_up.dart';
@ -19,7 +20,10 @@ class RobinhoodBuyProvider extends BuyProvider {
static const _cIdBaseUrl = 'exchange-helper.cakewallet.com'; static const _cIdBaseUrl = 'exchange-helper.cakewallet.com';
@override @override
String get title => 'Robinhood Connect'; ProviderType get providerType => ProviderType.robinhood;
@override
String get title => providerType.title;
@override @override
String get providerDescription => S.current.robinhood_option_description; String get providerDescription => S.current.robinhood_option_description;
@ -30,6 +34,9 @@ class RobinhoodBuyProvider extends BuyProvider {
@override @override
String get darkIcon => 'assets/images/robinhood_dark.png'; String get darkIcon => 'assets/images/robinhood_dark.png';
@override
String get trackUrl => '';
String get _applicationId => secrets.robinhoodApplicationId; String get _applicationId => secrets.robinhoodApplicationId;
String get _apiSecret => secrets.robinhoodCIdApiSecret; String get _apiSecret => secrets.robinhoodCIdApiSecret;

View file

@ -1,10 +1,10 @@
import 'dart:convert'; import 'dart:convert';
import 'package:cake_wallet/buy/buy_exception.dart'; import 'package:cake_wallet/buy/buy_exception.dart';
import 'package:cake_wallet/entities/provider_types.dart';
import 'package:flutter/src/widgets/framework.dart'; import 'package:flutter/src/widgets/framework.dart';
import 'package:http/http.dart'; import 'package:http/http.dart';
import 'package:cake_wallet/buy/buy_amount.dart'; import 'package:cake_wallet/buy/buy_amount.dart';
import 'package:cake_wallet/buy/buy_provider.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/buy/order.dart';
import 'package:cw_core/wallet_base.dart'; import 'package:cw_core/wallet_base.dart';
import 'package:cw_core/wallet_type.dart'; import 'package:cw_core/wallet_type.dart';
@ -30,17 +30,21 @@ class WyreBuyProvider extends BuyProvider {
static const _secretKey = secrets.wyreSecretKey; static const _secretKey = secrets.wyreSecretKey;
static const _accountId = secrets.wyreAccountId; static const _accountId = secrets.wyreAccountId;
@override @override
String get title => 'Wyre'; ProviderType get providerType => ProviderType.wyre;
@override
String get title => providerType.title;
@override @override
String get providerDescription => ''; String get providerDescription => '';
@override @override
String get lightIcon => 'assets/images/robinhood_light.png'; String get lightIcon => 'assets/images/wyre-icon.png';
@override @override
String get darkIcon => 'assets/images/robinhood_dark.png'; String get darkIcon => 'assets/images/wyre-icon.png';
String get trackUrl => isTestEnvironment ? _trackTestUrl : _trackProductUrl; String get trackUrl => isTestEnvironment ? _trackTestUrl : _trackProductUrl;
@ -138,7 +142,7 @@ class WyreBuyProvider extends BuyProvider {
return Order( return Order(
id: id, id: id,
provider: BuyProviderDescription.wyre, provider: ProviderType.wyre,
transferId: transferId, transferId: transferId,
from: from, from: from,
to: to, to: to,

View file

@ -120,7 +120,6 @@ import 'package:cake_wallet/exchange/trade.dart';
import 'package:cake_wallet/reactions/on_authentication_state_change.dart'; import 'package:cake_wallet/reactions/on_authentication_state_change.dart';
import 'package:cake_wallet/src/screens/backup/backup_page.dart'; import 'package:cake_wallet/src/screens/backup/backup_page.dart';
import 'package:cake_wallet/src/screens/backup/edit_backup_password_page.dart'; import 'package:cake_wallet/src/screens/backup/edit_backup_password_page.dart';
import 'package:cake_wallet/src/screens/buy/buy_webview_page.dart';
import 'package:cake_wallet/src/screens/contact/contact_list_page.dart'; import 'package:cake_wallet/src/screens/contact/contact_list_page.dart';
import 'package:cake_wallet/src/screens/contact/contact_page.dart'; import 'package:cake_wallet/src/screens/contact/contact_page.dart';
import 'package:cake_wallet/src/screens/exchange_trade/exchange_confirm_page.dart'; import 'package:cake_wallet/src/screens/exchange_trade/exchange_confirm_page.dart';
@ -231,6 +230,7 @@ import 'package:cake_wallet/entities/qr_view_data.dart';
import 'buy/dfx/dfx_buy_provider.dart'; import 'buy/dfx/dfx_buy_provider.dart';
import 'core/totp_request_details.dart'; import 'core/totp_request_details.dart';
import 'entities/provider_types.dart';
import 'src/screens/settings/desktop_settings/desktop_settings_page.dart'; import 'src/screens/settings/desktop_settings/desktop_settings_page.dart';
final getIt = GetIt.instance; final getIt = GetIt.instance;
@ -808,11 +808,16 @@ Future<void> setup({
settingsStore: getIt.get<AppStore>().settingsStore, wallet: getIt.get<AppStore>().wallet!)); settingsStore: getIt.get<AppStore>().settingsStore, wallet: getIt.get<AppStore>().wallet!));
getIt.registerFactory<OnRamperBuyProvider>(() => OnRamperBuyProvider( getIt.registerFactory<OnRamperBuyProvider>(() => OnRamperBuyProvider(
getIt.get<AppStore>().settingsStore, settingsStore: getIt.get<AppStore>().settingsStore,
wallet: getIt.get<AppStore>().wallet!, wallet: getIt.get<AppStore>().wallet!,
)); ));
getIt.registerFactoryParam<WebViewPage, String, Uri>((title, uri) => WebViewPage(title, uri)); getIt.registerFactoryParam<WebViewPage,List<dynamic>, void>((args, _) {
final uri = args.first as Uri;
final type = args.length > 1 ? args[1] as ProviderType? : null;
return WebViewPage(uri, type, buyViewModel: getIt.get<BuyViewModel>());
});
getIt.registerFactory<PayfuraBuyProvider>(() => PayfuraBuyProvider( getIt.registerFactory<PayfuraBuyProvider>(() => PayfuraBuyProvider(
settingsStore: getIt.get<AppStore>().settingsStore, settingsStore: getIt.get<AppStore>().settingsStore,
@ -954,21 +959,14 @@ Future<void> setup({
getIt.registerFactoryParam<BuySellOptionsPage, bool, void>( getIt.registerFactoryParam<BuySellOptionsPage, bool, void>(
(isBuyOption, _) => BuySellOptionsPage(getIt.get<DashboardViewModel>(), isBuyOption)); (isBuyOption, _) => BuySellOptionsPage(getIt.get<DashboardViewModel>(), isBuyOption));
getIt.registerFactory(() { getIt.registerFactory(() => BuyViewModel(
final wallet = getIt.get<AppStore>().wallet; _ordersSource,
getIt.get<OrdersStore>(),
return BuyViewModel(_ordersSource, getIt.get<OrdersStore>(), getIt.get<SettingsStore>(), getIt.get<SettingsStore>(),
getIt.get<BuyAmountViewModel>(), getIt.get<BuyAmountViewModel>(),
wallet: wallet!); wallet: getIt.get<AppStore>().wallet!));
});
getIt.registerFactoryParam<BuyWebViewPage, List<dynamic>, void>((List<dynamic> args, _) {
final url = args.first as String;
final buyViewModel = args[1] as BuyViewModel;
return BuyWebViewPage(
buyViewModel: buyViewModel, ordersStore: getIt.get<OrdersStore>(), url: url);
});
getIt.registerFactoryParam<OrderDetailsViewModel, Order, void>((order, _) { getIt.registerFactoryParam<OrderDetailsViewModel, Order, void>((order, _) {
final wallet = getIt.get<AppStore>().wallet; final wallet = getIt.get<AppStore>().wallet;

View file

@ -3,6 +3,7 @@ import 'package:cake_wallet/buy/dfx/dfx_buy_provider.dart';
import 'package:cake_wallet/buy/moonpay/moonpay_provider.dart'; import 'package:cake_wallet/buy/moonpay/moonpay_provider.dart';
import 'package:cake_wallet/buy/onramper/onramper_buy_provider.dart'; import 'package:cake_wallet/buy/onramper/onramper_buy_provider.dart';
import 'package:cake_wallet/buy/robinhood/robinhood_buy_provider.dart'; import 'package:cake_wallet/buy/robinhood/robinhood_buy_provider.dart';
import 'package:cake_wallet/buy/wyre/wyre_buy_provider.dart';
import 'package:cake_wallet/di.dart'; import 'package:cake_wallet/di.dart';
import 'package:cw_core/wallet_type.dart'; import 'package:cw_core/wallet_type.dart';
@ -12,6 +13,7 @@ enum ProviderType {
dfx, dfx,
onramper, onramper,
moonpaySell, moonpaySell,
wyre,
} }
extension ProviderTypeName on ProviderType { extension ProviderTypeName on ProviderType {
@ -27,6 +29,8 @@ extension ProviderTypeName on ProviderType {
return 'Onramper'; return 'Onramper';
case ProviderType.moonpaySell: case ProviderType.moonpaySell:
return 'MoonPay'; return 'MoonPay';
case ProviderType.wyre:
return 'Wyre';
} }
} }
@ -42,6 +46,8 @@ extension ProviderTypeName on ProviderType {
return 'onramper_provider'; return 'onramper_provider';
case ProviderType.moonpaySell: case ProviderType.moonpaySell:
return 'moonpay_provider'; return 'moonpay_provider';
case ProviderType.wyre:
return 'wyre_provider';
} }
} }
} }
@ -105,10 +111,50 @@ class ProvidersHelper {
return getIt.get<DFXBuyProvider>(); return getIt.get<DFXBuyProvider>();
case ProviderType.onramper: case ProviderType.onramper:
return getIt.get<OnRamperBuyProvider>(); return getIt.get<OnRamperBuyProvider>();
case ProviderType.askEachTime:
return null;
case ProviderType.moonpaySell: case ProviderType.moonpaySell:
return getIt.get<MoonPaySellProvider>(); return getIt.get<MoonPaySellProvider>();
case ProviderType.wyre:
return getIt.get<WyreBuyProvider>();
case ProviderType.askEachTime:
return null;
}
}
static int serialize(ProviderType type) {
switch (type) {
case ProviderType.askEachTime:
return 0;
case ProviderType.robinhood:
return 1;
case ProviderType.dfx:
return 2;
case ProviderType.onramper:
return 3;
case ProviderType.moonpaySell:
return 4;
case ProviderType.wyre:
return 5;
default:
throw Exception('Incorrect token $type for ProviderType serialize');
}
}
static ProviderType deserialize({required int raw}) {
switch (raw) {
case 0:
return ProviderType.askEachTime;
case 1:
return ProviderType.robinhood;
case 2:
return ProviderType.dfx;
case 3:
return ProviderType.onramper;
case 4:
return ProviderType.moonpaySell;
case 5:
return ProviderType.wyre;
default:
throw Exception('Incorrect token $raw for ProviderType deserialize');
} }
} }
} }

View file

@ -10,7 +10,6 @@ import 'package:cake_wallet/src/screens/anonpay_details/anonpay_details_page.dar
import 'package:cake_wallet/src/screens/backup/backup_page.dart'; import 'package:cake_wallet/src/screens/backup/backup_page.dart';
import 'package:cake_wallet/src/screens/backup/edit_backup_password_page.dart'; import 'package:cake_wallet/src/screens/backup/edit_backup_password_page.dart';
import 'package:cake_wallet/src/screens/buy/buy_options_page.dart'; import 'package:cake_wallet/src/screens/buy/buy_options_page.dart';
import 'package:cake_wallet/src/screens/buy/buy_webview_page.dart';
import 'package:cake_wallet/src/screens/buy/webview_page.dart'; import 'package:cake_wallet/src/screens/buy/webview_page.dart';
import 'package:cake_wallet/src/screens/dashboard/edit_token_page.dart'; import 'package:cake_wallet/src/screens/dashboard/edit_token_page.dart';
import 'package:cake_wallet/src/screens/dashboard/home_settings_page.dart'; import 'package:cake_wallet/src/screens/dashboard/home_settings_page.dart';
@ -396,12 +395,6 @@ Route<dynamic> createRoute(RouteSettings settings) {
return MaterialPageRoute<void>( return MaterialPageRoute<void>(
builder: (_) => getIt.get<BuySellOptionsPage>(param1: args)); builder: (_) => getIt.get<BuySellOptionsPage>(param1: args));
case Routes.buyWebView:
final args = settings.arguments as List;
return MaterialPageRoute<void>(
fullscreenDialog: true, builder: (_) => getIt.get<BuyWebViewPage>(param1: args));
case Routes.exchange: case Routes.exchange:
return CupertinoPageRoute<void>( return CupertinoPageRoute<void>(
fullscreenDialog: true, builder: (_) => getIt.get<ExchangePage>()); fullscreenDialog: true, builder: (_) => getIt.get<ExchangePage>());
@ -526,10 +519,8 @@ Route<dynamic> createRoute(RouteSettings settings) {
case Routes.webViewPage: case Routes.webViewPage:
final args = settings.arguments as List; final args = settings.arguments as List;
final title = args.first as String;
final url = args[1] as Uri;
return CupertinoPageRoute<void>( return CupertinoPageRoute<void>(
builder: (_) => getIt.get<WebViewPage>(param1: title, param2: url)); builder: (_) => getIt.get<WebViewPage>(param1: args));
case Routes.advancedPrivacySettings: case Routes.advancedPrivacySettings:
final type = settings.arguments as WalletType; final type = settings.arguments as WalletType;

View file

@ -42,7 +42,7 @@ class BuySellOptionsPage extends BasePage {
padding: EdgeInsets.only(top: 24), padding: EdgeInsets.only(top: 24),
child: OptionTile( child: OptionTile(
image: icon, image: icon,
title: provider.toString(), title: provider.title,
description: provider.providerDescription, description: provider.providerDescription,
onPressed: () => provider.launchProvider(context, isBuyAction), onPressed: () => provider.launchProvider(context, isBuyAction),
), ),

View file

@ -1,110 +0,0 @@
import 'dart:async';
import 'package:cake_wallet/buy/moonpay/moonpay_provider.dart';
import 'package:cake_wallet/buy/wyre/wyre_buy_provider.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/store/dashboard/orders_store.dart';
import 'package:cake_wallet/view_model/buy/buy_view_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
class BuyWebViewPage extends BasePage {
BuyWebViewPage({required this.buyViewModel, required this.ordersStore, required this.url});
final OrdersStore ordersStore;
final String url;
final BuyViewModel buyViewModel;
@override
String get title => S.current.buy;
@override
Color get backgroundDarkColor => Colors.white;
@override
Widget body(BuildContext context) =>
BuyWebViewPageBody(buyViewModel, ordersStore: ordersStore, url: url);
}
class BuyWebViewPageBody extends StatefulWidget {
BuyWebViewPageBody(this.buyViewModel, {required this.ordersStore, this.url});
final OrdersStore ordersStore;
final String? url;
final BuyViewModel buyViewModel;
@override
BuyWebViewPageBodyState createState() => BuyWebViewPageBodyState();
}
class BuyWebViewPageBodyState extends State<BuyWebViewPageBody> {
BuyWebViewPageBodyState()
: _webViewkey = GlobalKey(),
_isSaving = false,
orderId = '';
String orderId;
InAppWebViewController? _webViewController;
GlobalKey _webViewkey;
Timer? _timer;
bool _isSaving;
@override
void initState() {
super.initState();
_webViewkey = GlobalKey();
_isSaving = false;
widget.ordersStore.orderId = '';
if (widget.buyViewModel.selectedProvider is WyreBuyProvider) {
_saveOrder(keyword: 'completed', splitSymbol: '/');
}
if (widget.buyViewModel.selectedProvider is MoonPayBuyProvider) {
_saveOrder(keyword: 'transactionId', splitSymbol: '=');
}
}
@override
Widget build(BuildContext context) {
return InAppWebView(
key: _webViewkey,
initialSettings: InAppWebViewSettings(
transparentBackground: true,
),
initialUrlRequest: URLRequest(url: WebUri(widget.url ?? '')),
onWebViewCreated: (InAppWebViewController controller) =>
setState(() => _webViewController = controller));
}
void _saveOrder({required String keyword, required String splitSymbol}) {
_timer?.cancel();
_timer = Timer.periodic(Duration(seconds: 1), (timer) async {
try {
if (_webViewController == null || _isSaving) {
return;
}
final url = (await _webViewController!.getUrl())?.toString();
if (url == null) {
throw Exception('_saveOrder: Url is null');
}
if (url.contains(keyword)) {
final urlParts = url.split(splitSymbol);
orderId = urlParts.last;
widget.ordersStore.orderId = orderId;
if (orderId.isNotEmpty) {
_isSaving = true;
await widget.buyViewModel.saveOrder(orderId);
timer.cancel();
}
}
} catch (e) {
_isSaving = false;
print(e);
}
});
}
}

View file

@ -1,31 +1,39 @@
import 'dart:async';
import 'package:cake_wallet/entities/provider_types.dart';
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/screens/base_page.dart'; import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart'; import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/buy/buy_view_model.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart'; import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:permission_handler/permission_handler.dart'; import 'package:permission_handler/permission_handler.dart';
class WebViewPage extends BasePage { class WebViewPage extends BasePage {
WebViewPage(this._title, this._url); WebViewPage(this._url, this._providerType, {required this.buyViewModel}) {
buyViewModel.selectedProviderType = _providerType;
}
final String _title;
final Uri _url; final Uri _url;
final ProviderType? _providerType;
final BuyViewModel buyViewModel;
@override @override
String get title => _title; String get title => _providerType?.title ?? '';
@override @override
Widget body(BuildContext context) { Widget body(BuildContext context) {
return WebViewPageBody(_title, _url); return WebViewPageBody(title, _url, buyViewModel);
} }
} }
class WebViewPageBody extends StatefulWidget { class WebViewPageBody extends StatefulWidget {
WebViewPageBody(this.title, this.uri); WebViewPageBody(this.title, this.uri, this.buyViewModel);
final String title; final String title;
final Uri uri; final Uri uri;
final BuyViewModel buyViewModel;
@override @override
WebViewPageBodyState createState() => WebViewPageBodyState(); WebViewPageBodyState createState() => WebViewPageBodyState();
@ -41,6 +49,12 @@ class WebViewPageBodyState extends State<WebViewPageBody> {
transparentBackground: true, transparentBackground: true,
), ),
initialUrlRequest: URLRequest(url: WebUri.uri(widget.uri)), initialUrlRequest: URLRequest(url: WebUri.uri(widget.uri)),
onWebViewCreated: (InAppWebViewController controller) =>
setState(() => controller),
onLoadStart: (controller, url) async {
if (widget.buyViewModel.selectedProviderType == null) return;
widget.buyViewModel.processProviderUrl(urlStr: url.toString());
},
onPermissionRequest: (controller, request) async { onPermissionRequest: (controller, request) async {
bool permissionGranted = await Permission.camera.status == PermissionStatus.granted; bool permissionGranted = await Permission.camera.status == PermissionStatus.granted;
if (!permissionGranted) { if (!permissionGranted) {
@ -70,9 +84,8 @@ class WebViewPageBodyState extends State<WebViewPageBody> {
return PermissionResponse( return PermissionResponse(
resources: request.resources, resources: request.resources,
action: permissionGranted action:
? PermissionResponseAction.GRANT permissionGranted ? PermissionResponseAction.GRANT : PermissionResponseAction.DENY,
: PermissionResponseAction.DENY,
); );
}, },
); );

View file

@ -1,5 +1,4 @@
import 'package:cake_wallet/buy/buy_provider.dart'; import 'package:cake_wallet/buy/buy_provider.dart';
import 'package:cake_wallet/buy/get_buy_provider_icon.dart';
import 'package:cw_core/crypto_currency.dart'; import 'package:cw_core/crypto_currency.dart';
import 'package:cake_wallet/entities/fiat_currency.dart'; import 'package:cake_wallet/entities/fiat_currency.dart';
import 'package:cake_wallet/palette.dart'; import 'package:cake_wallet/palette.dart';

View file

@ -1,3 +1,4 @@
import 'package:cake_wallet/entities/provider_types.dart';
import 'package:cake_wallet/src/screens/dashboard/widgets/anonpay_transaction_row.dart'; import 'package:cake_wallet/src/screens/dashboard/widgets/anonpay_transaction_row.dart';
import 'package:cake_wallet/src/screens/dashboard/widgets/order_row.dart'; import 'package:cake_wallet/src/screens/dashboard/widgets/order_row.dart';
import 'package:cake_wallet/themes/extensions/placeholder_theme.dart'; import 'package:cake_wallet/themes/extensions/placeholder_theme.dart';
@ -47,7 +48,6 @@ class TransactionsPage extends StatelessWidget {
padding: const EdgeInsets.fromLTRB(24, 0, 24, 8), padding: const EdgeInsets.fromLTRB(24, 0, 24, 8),
child: DashBoardRoundedCardWidget( child: DashBoardRoundedCardWidget(
onTap: () => Navigator.of(context).pushNamed(Routes.webViewPage, arguments: [ onTap: () => Navigator.of(context).pushNamed(Routes.webViewPage, arguments: [
'',
Uri.parse( Uri.parse(
'https://guides.cakewallet.com/docs/FAQ/why_are_my_funds_not_appearing/') 'https://guides.cakewallet.com/docs/FAQ/why_are_my_funds_not_appearing/')
]), ]),
@ -127,12 +127,13 @@ class TransactionsPage extends StatelessWidget {
if (item is OrderListItem) { if (item is OrderListItem) {
final order = item.order; final order = item.order;
if (order.provider == null) return null;
return Observer( return Observer(
builder: (_) => OrderRow( builder: (_) => OrderRow(
onTap: () => Navigator.of(context) onTap: () => Navigator.of(context)
.pushNamed(Routes.orderDetails, arguments: order), .pushNamed(Routes.orderDetails, arguments: order),
provider: order.provider, provider: ProvidersHelper.getProviderByType(order.provider!)!,
from: order.from!, from: order.from!,
to: order.to!, to: order.to!,
createdAtFormattedDate: createdAtFormattedDate:

View file

@ -1,7 +1,6 @@
import 'package:cake_wallet/buy/buy_provider_description.dart'; import 'package:cake_wallet/buy/buy_provider.dart';
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart'; import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/buy/get_buy_provider_icon.dart'; import 'package:cake_wallet/themes/extensions/option_tile_theme.dart';
import 'package:cake_wallet/themes/extensions/order_theme.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart'; import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
@ -14,7 +13,7 @@ class OrderRow extends StatelessWidget {
this.onTap, this.onTap,
this.formattedAmount}); this.formattedAmount});
final VoidCallback? onTap; final VoidCallback? onTap;
final BuyProviderDescription provider; final BuyProvider provider;
final String from; final String from;
final String to; final String to;
final String createdAtFormattedDate; final String createdAtFormattedDate;
@ -22,10 +21,8 @@ class OrderRow extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final iconColor = final isLightMode = Theme.of(context).extension<OptionTileTheme>()?.useDarkImage ?? false;
Theme.of(context).extension<OrderTheme>()!.iconColor;
final providerIcon = getBuyProviderIcon(provider, iconColor: iconColor);
return InkWell( return InkWell(
onTap: onTap, onTap: onTap,
@ -36,10 +33,12 @@ class OrderRow extends StatelessWidget {
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
if (providerIcon != null) Padding( Container(
padding: EdgeInsets.only(right: 12), height: 36,
child: providerIcon, width: 36,
child: Image.asset(isLightMode ? provider.lightIcon : provider.darkIcon),
), ),
SizedBox(width: 12),
Expanded( Expanded(
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,

View file

@ -1,16 +1,19 @@
import 'package:cake_wallet/buy/buy_provider.dart'; import 'dart:async';
import 'package:cake_wallet/buy/moonpay/moonpay_provider.dart'; import 'dart:convert';
import 'package:cake_wallet/buy/wyre/wyre_buy_provider.dart';
import 'package:cw_core/crypto_currency.dart'; import 'package:cake_wallet/buy/onramper/onramper_buy_provider.dart';
import 'package:cake_wallet/buy/order.dart';
import 'package:cake_wallet/entities/fiat_currency.dart'; import 'package:cake_wallet/entities/fiat_currency.dart';
import 'package:cw_core/wallet_type.dart'; import 'package:cake_wallet/entities/provider_types.dart';
import 'package:cake_wallet/store/dashboard/orders_store.dart';
import 'package:cake_wallet/store/settings_store.dart'; import 'package:cake_wallet/store/settings_store.dart';
import 'package:cake_wallet/view_model/buy/buy_item.dart'; import 'package:cake_wallet/view_model/buy/buy_item.dart';
import 'package:hive/hive.dart'; import 'package:cw_core/crypto_currency.dart';
import 'package:cake_wallet/buy/order.dart';
import 'package:cake_wallet/store/dashboard/orders_store.dart';
import 'package:mobx/mobx.dart';
import 'package:cw_core/wallet_base.dart'; import 'package:cw_core/wallet_base.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:hive/hive.dart';
import 'package:mobx/mobx.dart';
import 'buy_amount_view_model.dart'; import 'buy_amount_view_model.dart';
part 'buy_view_model.g.dart'; part 'buy_view_model.g.dart';
@ -18,14 +21,13 @@ part 'buy_view_model.g.dart';
class BuyViewModel = BuyViewModelBase with _$BuyViewModel; class BuyViewModel = BuyViewModelBase with _$BuyViewModel;
abstract class BuyViewModelBase with Store { abstract class BuyViewModelBase with Store {
BuyViewModelBase(this.ordersSource, this.ordersStore, this.settingsStore, BuyViewModelBase(this.ordersSource, this.ordersStore, this.settingsStore, this.buyAmountViewModel,
this.buyAmountViewModel, {required this.wallet}) {required this.wallet})
: isRunning = false, : isRunning = false,
orderId = '',
isDisabled = true, isDisabled = true,
isShowProviderButtons = false, isShowProviderButtons = false,
items = <BuyItem>[] { items = <BuyItem>[] {}
_fetchBuyItems();
}
final Box<Order> ordersSource; final Box<Order> ordersSource;
final OrdersStore ordersStore; final OrdersStore ordersStore;
@ -33,8 +35,9 @@ abstract class BuyViewModelBase with Store {
final BuyAmountViewModel buyAmountViewModel; final BuyAmountViewModel buyAmountViewModel;
final WalletBase wallet; final WalletBase wallet;
@observable String orderId;
BuyProvider? selectedProvider;
ProviderType? selectedProviderType;
@observable @observable
List<BuyItem> items; List<BuyItem> items;
@ -57,23 +60,24 @@ abstract class BuyViewModelBase with Store {
CryptoCurrency get cryptoCurrency => walletTypeToCryptoCurrency(type); CryptoCurrency get cryptoCurrency => walletTypeToCryptoCurrency(type);
Future <String> fetchUrl() async { Future<void> saveOrder(String orderId, {int? onRamperPartnerRaw}) async {
String _url = '';
try { try {
_url = await selectedProvider!.requestUrl(doubleAmount.toString(), fiatCurrency.title); final String jsonSource = json.encode({
} catch (e) { 'id': orderId,
print(e.toString()); 'transferId': orderId,
} 'createdAt': DateTime.now().toIso8601String(),
'amount': doubleAmount.toString(),
'receiveAddress': 'address123',
'walletId': wallet.id,
'providerRaw': ProvidersHelper.serialize(selectedProviderType ?? ProviderType.askEachTime),
'onramperPartnerRaw': onRamperPartnerRaw,
'stateRaw': 'created',
'from': fiatCurrency.title,
'to': cryptoCurrency.title,
}).toString();
return _url; final order = Order.fromJSON(jsonSource);
}
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); await ordersSource.add(order);
ordersStore.setOrder(order); ordersStore.setOrder(order);
} catch (e) { } catch (e) {
@ -81,32 +85,80 @@ abstract class BuyViewModelBase with Store {
} }
} }
void reset() { String? extractInfoFromUrl(String url, ProviderType providerType) {
buyAmountViewModel.amount = ''; final config = providerUrlConfigs[providerType];
selectedProvider = null; if (config == null) return null;
for (var entry in config.parameterKeywords.entries) {
final keyword = entry.value;
final paramIndex = url.indexOf('$keyword=');
if (paramIndex != -1) {
final start = paramIndex + keyword.length + 1;
int end = config.splitSymbol != null ? url.indexOf(config.splitSymbol!, start) : url.length;
end = end == -1 ? url.length : end;
return url.substring(start, end);
}
} }
Future<void> _fetchBuyItems() async { return null;
final List<BuyProvider> _providerList = [];
if (wallet.type == WalletType.bitcoin) {
_providerList.add(WyreBuyProvider(wallet: wallet));
} }
var isMoonPayEnabled = false; void processProviderUrl({required String urlStr}) async {
try { if (selectedProviderType == null) return;
isMoonPayEnabled = await MoonPayBuyProvider.onEnabled();
} catch (e) { final orderId = extractInfoFromUrl(urlStr, selectedProviderType!);
isMoonPayEnabled = false; final onRamperPartner = determineOnRamperPartner(urlStr); // Determine the partner
print(e.toString()); final onRamperPartnerRaw = onRamperPartner != null ? onRamperPartner.index : null; // Serialize the partner for storage
if (orderId != null && orderId.isNotEmpty && orderId != this.orderId) {
this.orderId = orderId;
await saveOrder(orderId, onRamperPartnerRaw: onRamperPartnerRaw); // Pass the partner information
}
} }
if (isMoonPayEnabled) { OnRamperPartner? determineOnRamperPartner(String url) {
_providerList.add(MoonPayBuyProvider(wallet: wallet)); if (url.contains('guardarian')) {
return OnRamperPartner.guardarian;
} else if (url.contains('paybis')) {
return OnRamperPartner.paybis;
}
// Add more partners as needed
return null;
} }
items = _providerList.map((provider) => final Map<ProviderType, ProviderUrlConfig> providerUrlConfigs = {
BuyItem(provider: provider, buyAmountViewModel: buyAmountViewModel)) ProviderType.onramper: ProviderUrlConfig(
.toList(); name: ProviderType.onramper.title,
parameterKeywords: {
'guardarian': 'tid',
'paybis': 'requestId',
},
splitSymbol: '&',
),
ProviderType.dfx: ProviderUrlConfig(
name: ProviderType.dfx.title,
parameterKeywords: {
'transaction': 'id', // Adjust based on actual URL scheme.
},
),
ProviderType.robinhood: ProviderUrlConfig(
name: ProviderType.robinhood.title,
parameterKeywords: {
'order': 'ref', // Adjust based on actual URL scheme.
},
),
// Add more providers as necessary, using their titles.
};
} }
class ProviderUrlConfig {
final String name;
final Map<String, String> parameterKeywords;
final String? splitSymbol;
ProviderUrlConfig({required this.name, required this.parameterKeywords, this.splitSymbol});
} }

View file

@ -1,7 +1,8 @@
import 'dart:async'; import 'dart:async';
import 'package:cake_wallet/buy/buy_provider.dart'; import 'package:cake_wallet/buy/buy_provider.dart';
import 'package:cake_wallet/buy/buy_provider_description.dart'; import 'package:cake_wallet/buy/onramper/onramper_buy_provider.dart';
import 'package:cake_wallet/buy/order.dart'; import 'package:cake_wallet/buy/order.dart';
import 'package:cake_wallet/entities/provider_types.dart';
import 'package:cake_wallet/utils/date_formatter.dart'; import 'package:cake_wallet/utils/date_formatter.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';
@ -9,8 +10,6 @@ import 'package:cake_wallet/src/screens/transaction_details/standart_list_item.d
import 'package:cake_wallet/src/screens/trade_details/track_trade_list_item.dart'; import 'package:cake_wallet/src/screens/trade_details/track_trade_list_item.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
import 'package:cw_core/wallet_base.dart'; import 'package:cw_core/wallet_base.dart';
import 'package:cake_wallet/buy/moonpay/moonpay_provider.dart';
import 'package:cake_wallet/buy/wyre/wyre_buy_provider.dart';
part 'order_details_view_model.g.dart'; part 'order_details_view_model.g.dart';
@ -22,16 +21,10 @@ abstract class OrderDetailsViewModelBase with Store {
: items = ObservableList<StandartListItem>(), : items = ObservableList<StandartListItem>(),
order = orderForDetails { order = orderForDetails {
if (order.provider != null) { if (order.provider != null) {
switch (order.provider) { order.provider == ProviderType.onramper
case BuyProviderDescription.wyre: ? _provider = OnRamperBuyProvider(wallet: wallet, partner: order.onramperPartner)
_provider = WyreBuyProvider(wallet: wallet); : _provider = ProvidersHelper.getProviderByType(order.provider!);
break;
case BuyProviderDescription.moonPay:
_provider = MoonPayBuyProvider(wallet: wallet);
break;
} }
}
_updateItems(); _updateItems();
_updateOrder(); _updateOrder();
timer = Timer.periodic(Duration(seconds: 20), (_) async => _updateOrder()); timer = Timer.periodic(Duration(seconds: 20), (_) async => _updateOrder());
@ -50,20 +43,16 @@ abstract class OrderDetailsViewModelBase with Store {
@action @action
Future<void> _updateOrder() async { Future<void> _updateOrder() async {
try { try {
if (_provider != null && (_provider is MoonPayBuyProvider || _provider is WyreBuyProvider)) { final updatedOrder = await _provider!.findOrderById(order.transferId);
final updatedOrder = _provider is MoonPayBuyProvider
? await (_provider as MoonPayBuyProvider).findOrderById(order.id)
: await (_provider as WyreBuyProvider).findOrderById(order.id);
updatedOrder.from = order.from; updatedOrder.from = order.from;
updatedOrder.to = order.to; updatedOrder.to = order.to;
updatedOrder.receiveAddress = order.receiveAddress; updatedOrder.receiveAddress = order.receiveAddress;
updatedOrder.walletId = order.walletId; updatedOrder.walletId = order.walletId;
if (order.provider != null) { updatedOrder.providerRaw = order.provider != null
updatedOrder.providerRaw = order.provider.raw; ? ProvidersHelper.serialize(order.provider!) : null;
}
order = updatedOrder; order = updatedOrder;
_updateItems(); _updateItems();
}
} catch (e) { } catch (e) {
print(e.toString()); print(e.toString());
} }
@ -86,24 +75,19 @@ abstract class OrderDetailsViewModelBase with Store {
items.add( items.add(
StandartListItem( StandartListItem(
title: 'Buy provider', title: 'Buy provider',
value: order.provider.title) value: order.provider?.title ?? '')
); );
if (_provider != null && (_provider is MoonPayBuyProvider || _provider is WyreBuyProvider)) { if(_provider != null) {
if(_provider!.trackUrl.isNotEmpty && order.transferId.isNotEmpty) {
final trackUrl = _provider is MoonPayBuyProvider final buildURL = _provider!.trackUrl + '${order.transferId}';
? (_provider as MoonPayBuyProvider).trackUrl
: (_provider as WyreBuyProvider).trackUrl;
if (trackUrl.isNotEmpty ?? false) {
final buildURL = trackUrl + '${order.transferId}';
items.add( items.add(
TrackTradeListItem( TrackTradeListItem(
title: 'Track', title: 'Track',
value: buildURL, value: buildURL,
onTap: () { onTap: () {
try { try {
launch(buildURL); launchUrl(Uri.parse(buildURL));
} catch (e) {} } catch (e) {}
} }
) )