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,8 +95,10 @@ 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) {
cardColor = getColorStr(Colors.white); if (settingsStore!.currentTheme.title == S.current.high_contrast_theme) {
cardColor = getColorStr(Colors.white);
}
} }
final networkName = final networkName =
@ -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,31 +1,60 @@
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)
class Order extends HiveObject { class Order extends HiveObject {
Order( Order(
{required this.id, {required this.id,
required this.transferId, required this.transferId,
required this.createdAt, required this.createdAt,
required this.amount, required this.amount,
required this.receiveAddress, required this.receiveAddress,
required this.walletId, required this.walletId,
BuyProviderDescription? provider, ProviderType? provider,
TradeState? state, OnRamperPartner? onramperPartner,
this.from, TradeState? state,
this.to}) { this.from,
if (provider != null) { this.to}) {
providerRaw = provider.raw; if (provider != null) {
} providerRaw = ProvidersHelper.serialize(provider);
if (state != null) {
stateRaw = state.raw;
}
} }
if (onramperPartner != null) {
onramperPartnerRaw = onramperPartner.index;
}
if (state != null) {
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';
@ -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>(),
getIt.get<SettingsStore>(),
getIt.get<BuyAmountViewModel>(),
wallet: getIt.get<AppStore>().wallet!));
return BuyViewModel(_ordersSource, getIt.get<OrdersStore>(), getIt.get<SettingsStore>(),
getIt.get<BuyAmountViewModel>(),
wallet: 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,
isDisabled = true, orderId = '',
isShowProviderButtons = false, isDisabled = true,
items = <BuyItem>[] { isShowProviderButtons = false,
_fetchBuyItems(); items = <BuyItem>[] {}
}
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);
}
}
return null;
} }
Future<void> _fetchBuyItems() async { void processProviderUrl({required String urlStr}) async {
final List<BuyProvider> _providerList = []; if (selectedProviderType == null) return;
if (wallet.type == WalletType.bitcoin) { final orderId = extractInfoFromUrl(urlStr, selectedProviderType!);
_providerList.add(WyreBuyProvider(wallet: wallet)); final onRamperPartner = determineOnRamperPartner(urlStr); // Determine the partner
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
} }
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();
} }
}
OnRamperPartner? determineOnRamperPartner(String url) {
if (url.contains('guardarian')) {
return OnRamperPartner.guardarian;
} else if (url.contains('paybis')) {
return OnRamperPartner.paybis;
}
// Add more partners as needed
return null;
}
final Map<ProviderType, ProviderUrlConfig> providerUrlConfigs = {
ProviderType.onramper: ProviderUrlConfig(
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';
@ -21,17 +20,11 @@ abstract class OrderDetailsViewModelBase with Store {
OrderDetailsViewModelBase({required WalletBase wallet, required Order orderForDetails}) OrderDetailsViewModelBase({required WalletBase wallet, required Order orderForDetails})
: 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) {}
} }
) )