From 93dc8a0c8a2a66d399220907a411aa1e87dce064 Mon Sep 17 00:00:00 2001 From: AhsanAli13503 Date: Wed, 29 May 2024 16:41:28 +0500 Subject: [PATCH] feat: purchasing event with coins integration --- evently/lib/evently_provider.dart | 5 +- evently/lib/models/events.dart | 4 +- wallet/lib/model/event.dart | 26 +++ .../lib/pages/events/event_purchase_view.dart | 153 +++++++++++++++--- .../pages/events/event_qr_code_screen.dart | 13 -- .../lib/pages/events/events_owner_view.dart | 7 +- .../home/currency_screen/model/ibc_coins.dart | 17 +- .../purchase_item_view_model.dart | 43 ++++- .../failure_manager_view_model.dart | 3 + .../data_stores/remote_data_store.dart | 1 + wallet/lib/stores/wallet_store.dart | 5 + wallet/lib/stores/wallet_store_imp.dart | 88 ++++++++++ wallet/lib/utils/constants.dart | 5 + wallet/lib/utils/enums.dart | 3 +- 14 files changed, 324 insertions(+), 49 deletions(-) diff --git a/evently/lib/evently_provider.dart b/evently/lib/evently_provider.dart index 2fac808a01..d4065cbb26 100644 --- a/evently/lib/evently_provider.dart +++ b/evently/lib/evently_provider.dart @@ -290,12 +290,15 @@ class EventlyProvider extends ChangeNotifier { step: '', ); + final String prices = isFreeDrop == FreeDrop.yes ? "0" : _selectedDenom.formatAmount(price: price.toString()); + + final recipe = event.createRecipe( cookbookId: _cookbookId!, recipeId: _recipeId, isFreeDrop: isFreeDrop, symbol: selectedDenom.symbol, - price: price.toString(), + price: prices, ); final response = await PylonsWallet.instance.txCreateRecipe(recipe, requestResponse: false); diff --git a/evently/lib/models/events.dart b/evently/lib/models/events.dart index e3c485461f..b9d32b2f1c 100644 --- a/evently/lib/models/events.dart +++ b/evently/lib/models/events.dart @@ -135,7 +135,9 @@ extension CreateRecipe on Events { description: description.trim(), version: kVersion, coinInputs: [ - if (isFreeDrop == FreeDrop.no) + if (isFreeDrop == FreeDrop.yes) + CoinInput() + else CoinInput( coins: [Coin(amount: price, denom: symbol)], ) diff --git a/wallet/lib/model/event.dart b/wallet/lib/model/event.dart index 07a5d56668..aa4ce6dbd4 100644 --- a/wallet/lib/model/event.dart +++ b/wallet/lib/model/event.dart @@ -96,6 +96,32 @@ class Events extends Equatable { return map; } + factory Events.fromJson(Map json) { + final List listOfPerks = []; + + json['listOfPerks'].map((jsonData) => listOfPerks.add(PerksModel.fromJson(jsonData as Map))).toList(); + + return Events( + recipeID: json['recipeID'] as String, + eventName: json['eventName'] as String, + hostName: json['hostName'] as String, + thumbnail: json['thumbnail'] as String, + startDate: json['startDate'] as String, + endDate: json['endDate'] as String, + startTime: json['startTime'] as String, + endTime: json['endTime'] as String, + location: json['location'] as String, + description: json['description'] as String, + numberOfTickets: json['numberOfTickets'] as String, + price: json['price'] as String, + isFreeDrops: json['isFreeDrops'] as String, + cookbookID: json['cookbookID'] as String, + step: json['step'] as String, + listOfPerks: listOfPerks, + denom: json['denom'].toString().toIBCCoinsEnumforEvent(), + ); + } + Future getOwnerAddress() async { if (ownerAddress.isEmpty) { final walletsStore = GetIt.I.get(); diff --git a/wallet/lib/pages/events/event_purchase_view.dart b/wallet/lib/pages/events/event_purchase_view.dart index a70c9bbdcd..3623944b72 100644 --- a/wallet/lib/pages/events/event_purchase_view.dart +++ b/wallet/lib/pages/events/event_purchase_view.dart @@ -1,12 +1,23 @@ +import 'dart:convert'; import 'package:cached_network_image/cached_network_image.dart'; +import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:mobile_scanner/mobile_scanner.dart'; +import 'package:provider/provider.dart'; +import 'package:pylons_wallet/components/loading.dart'; import 'package:pylons_wallet/components/space_widgets.dart'; import 'package:pylons_wallet/model/event.dart'; import 'package:pylons_wallet/pages/home/currency_screen/model/ibc_coins.dart'; +import 'package:pylons_wallet/pages/purchase_item/purchase_item_view_model.dart'; +import 'package:pylons_wallet/pages/purchase_item/widgets/trade_receipt_dialog.dart'; +import 'package:pylons_wallet/pages/purchase_item/widgets/transaction_complete_dialog.dart'; +import 'package:pylons_wallet/pylons_app.dart'; import 'package:pylons_wallet/utils/constants.dart'; +import 'package:pylons_wallet/utils/dependency_injection/dependency_injection.dart'; +import 'package:pylons_wallet/utils/route_util.dart'; +import '../../modules/Pylonstech.pylons.pylons/module/client/pylons/execution.pb.dart'; class EventPurchaseView extends StatefulWidget { const EventPurchaseView({super.key, required this.events}); @@ -23,35 +34,129 @@ class _EventPurchaseViewState extends State { super.initState(); } + final viewModel = sl(); + @override Widget build(BuildContext context) { - return EventPassViewContent( - events: widget.events, + return ChangeNotifierProvider.value( + value: viewModel, + child: EventPassViewContent( + events: widget.events, + ), ); } } -class EventPassViewContent extends StatelessWidget { - EventPassViewContent({ +class EventPassViewContent extends StatefulWidget { + const EventPassViewContent({ super.key, required this.events, }); final Events events; + @override + State createState() => _EventPassViewContentState(); +} + +class _EventPassViewContentState extends State { late Rect scanWindow; MobileScannerController cameraController = MobileScannerController( formats: const [BarcodeFormat.qrCode], - autoStart: true, detectionSpeed: DetectionSpeed.noDuplicates, ); - void _foundBarcode(BarcodeCapture barcodeCapture) { - debugPrint('$barcodeCapture'); - final String code = barcodeCapture.barcodes.last.displayValue ?? ''; - debugPrint('Code: $code'); - // context.read().add(ScannerTextEvent(scannedText: code)); + bool isCapture = false; + + Future executeRecipe(BuildContext context) async { + final provider = context.read(); + final ibcEnumCoins = provider.getEvents.denom; + + if (ibcEnumCoins == IBCCoins.ustripeusd) { + // stripePaymentForRecipe(context, provider.getEvents); + print('needed to work for this'); + } else { + paymentByCoins(); + } + } + + Future paymentByCoins() async { + final navigator = Navigator.of(navigatorKey.currentState!.overlay!.context); + final provider = context.read(); + final executionResponse = await provider.paymentForEventRecipe(); + + navigator.pop(); + if (!executionResponse.success) { + executionResponse.error.show(); + navigator.pushNamed(Routes.transactionFailure.name); + return; + } + + showTransactionCompleteDialog(execution: executionResponse.data!); + } + + void showTransactionCompleteDialog({required Execution execution}) { + final viewModel = context.read(); + + var price = double.parse(viewModel.nft.price); + final fee = double.parse(viewModel.nft.price) * 0.1; + price = price - fee; + + final txId = execution.hasId() ? execution.id : ""; + + final txTime = getTransactionTimeStamp(execution.hasTxTime() ? execution.txTime.toInt() : null); + + final model = viewModel.createTradeReciptModel( + fee: fee, + price: price, + txId: txId, + txTime: txTime, + ); + + final TradeCompleteDialog tradeCompleteDialog = TradeCompleteDialog( + model: model, + context: context, + onBackPressed: () { + showReceiptDialog(model); + }, + ); + tradeCompleteDialog.show(); + } + + void showReceiptDialog(TradeReceiptModel model) { + final TradeReceiptDialog tradeReceiptDialog = TradeReceiptDialog(context: context, model: model); + tradeReceiptDialog.show(); + } + + String getTransactionTimeStamp(int? time) { + final formatter = DateFormat('MMM dd yyyy HH:mm'); + if (time == null) { + return "${formatter.format(DateTime.now().toUtc())} $kUTC"; + } + + final int timeStamp = time * kDateConverterConstant; + final DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(timeStamp, isUtc: true); + return "${formatter.format(dateTime)} $kUTC"; + } + + Future onDetect(BarcodeCapture barCodeCapture, PurchaseItemViewModel viewModel, BuildContext context) async { + if (isCapture) { + return; + } + if (!isCapture) { + setState(() => isCapture = true); + + final String? displayValue = barCodeCapture.barcodes.first.displayValue; + + final map = jsonDecode(displayValue!); + + final event = Events.fromJson(map as Map); + + viewModel.setEvents = event; + + await executeRecipe(context); + } } @override @@ -62,6 +167,11 @@ class EventPassViewContent extends StatelessWidget { height: 100.r, ); + final viewModel = context.watch(); + final coinWithDenom = widget.events.denom.getAbbrev() == kPYLN_ABBREVATION + ? "\$${widget.events.denom.pylnToCredit(widget.events.denom.getCoinWithProperDenomination(widget.events.price))} ${widget.events.denom.getAbbrev()}" + : "${widget.events.denom.getCoinWithProperDenomination(widget.events.price)} ${widget.events.denom.getAbbrev()}"; + return ColoredBox( color: AppColors.kBlack87, child: SafeArea( @@ -102,12 +212,13 @@ class EventPassViewContent extends StatelessWidget { margin: EdgeInsets.symmetric(horizontal: 20.w), height: 200.h, child: MobileScanner( - onDetect: (_) { - print(_); - }, + onDetect: (BarcodeCapture barCodeCapture) => onDetect( + barCodeCapture, + viewModel, + context, + ), ), ), - ], ), Container( @@ -118,7 +229,7 @@ class EventPassViewContent extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - events.eventName, + widget.events.eventName, style: Theme.of(context).textTheme.displayLarge?.copyWith(fontSize: 25.sp, fontWeight: FontWeight.w700, color: AppColors.kWhite), ), VerticalSpace(20.h), @@ -133,7 +244,7 @@ class EventPassViewContent extends StatelessWidget { style: Theme.of(context).textTheme.displayLarge?.copyWith(fontSize: 11.sp, fontWeight: FontWeight.w400, color: AppColors.kWhite), ), Text( - events.startDate, + widget.events.startDate, style: Theme.of(context).textTheme.labelSmall?.copyWith(fontSize: 15.sp, fontWeight: FontWeight.w700, color: AppColors.kWhite), ), ], @@ -146,7 +257,7 @@ class EventPassViewContent extends StatelessWidget { style: Theme.of(context).textTheme.displayLarge?.copyWith(fontSize: 11.sp, fontWeight: FontWeight.w400, color: AppColors.kWhite), ), Text( - events.startTime, + widget.events.startTime, style: Theme.of(context).textTheme.labelSmall?.copyWith(fontSize: 15.sp, fontWeight: FontWeight.w700, color: AppColors.kWhite), ), ], @@ -165,7 +276,7 @@ class EventPassViewContent extends StatelessWidget { style: Theme.of(context).textTheme.displayLarge?.copyWith(fontSize: 11.sp, fontWeight: FontWeight.w400, color: AppColors.kWhite), ), Text( - events.location, + widget.events.location, style: Theme.of(context).textTheme.labelSmall?.copyWith(fontSize: 15.sp, fontWeight: FontWeight.w700, color: AppColors.kWhite), ), ], @@ -178,7 +289,7 @@ class EventPassViewContent extends StatelessWidget { style: Theme.of(context).textTheme.displayLarge?.copyWith(fontSize: 11.sp, fontWeight: FontWeight.w400, color: AppColors.kWhite), ), Text( - events.price == "0" ? "Free" : '${events.price} ${events.denom.getName()}', + coinWithDenom, style: Theme.of(context).textTheme.labelSmall?.copyWith(fontSize: 15.sp, fontWeight: FontWeight.w700, color: AppColors.kWhite), ), ], @@ -202,7 +313,7 @@ class EventPassViewContent extends StatelessWidget { SvgPicture.asset(kDiamondIcon), SizedBox(width: 5.w), Text( - 'x ${events.listOfPerks?.length}', + 'x ${widget.events.listOfPerks?.length}', style: TextStyle(fontSize: 15.sp, color: AppColors.kWhite, fontWeight: FontWeight.bold), ), SizedBox(width: 5.w), @@ -224,7 +335,7 @@ class EventPassViewContent extends StatelessWidget { child: CachedNetworkImage( width: double.infinity, fit: BoxFit.fill, - imageUrl: events.thumbnail, + imageUrl: widget.events.thumbnail, errorWidget: (a, b, c) => const Center( child: Icon( Icons.error_outline, diff --git a/wallet/lib/pages/events/event_qr_code_screen.dart b/wallet/lib/pages/events/event_qr_code_screen.dart index fda1326899..b75d18e23a 100644 --- a/wallet/lib/pages/events/event_qr_code_screen.dart +++ b/wallet/lib/pages/events/event_qr_code_screen.dart @@ -12,19 +12,6 @@ import 'package:pylons_wallet/pages/detailed_asset_view/widgets/nft_image_asset. import 'package:pylons_wallet/utils/constants.dart'; import 'package:qr_flutter/qr_flutter.dart'; -const jsonExecuteRecipe = ''' - { - "creator": "", - "cookbook_id": "", - "recipe_id": "", - "eventName": "", - "eventPrice": "", - "eventCurrency": "", - "coinInputsIndex": 0 - } - '''; -final jsonMap = jsonDecode(jsonExecuteRecipe) as Map; - class EventQrCodeScreen extends StatefulWidget { const EventQrCodeScreen({ super.key, diff --git a/wallet/lib/pages/events/events_owner_view.dart b/wallet/lib/pages/events/events_owner_view.dart index ead5c1fa8a..5c1da9d385 100644 --- a/wallet/lib/pages/events/events_owner_view.dart +++ b/wallet/lib/pages/events/events_owner_view.dart @@ -47,6 +47,11 @@ class EventPassViewContent extends StatelessWidget { @override Widget build(BuildContext context) { final viewModel = context.watch(); + + final coinWithDenom = viewModel.events.denom.getAbbrev() == kPYLN_ABBREVATION + ? "\$${viewModel.events.denom.pylnToCredit(viewModel.events.denom.getCoinWithProperDenomination(viewModel.events.price))} ${viewModel.events.denom.getAbbrev()}" + : "${viewModel.events.denom.getCoinWithProperDenomination(viewModel.events.price)} ${viewModel.events.denom.getAbbrev()}"; + return ColoredBox( color: AppColors.kBlack87, child: SafeArea( @@ -152,7 +157,7 @@ class EventPassViewContent extends StatelessWidget { style: Theme.of(context).textTheme.displayLarge?.copyWith(fontSize: 11.sp, fontWeight: FontWeight.w400, color: AppColors.kWhite), ), Text( - viewModel.events.price == "0" ? "Free" : '${viewModel.events.price} ${viewModel.events.denom.getName()}', + coinWithDenom, style: Theme.of(context).textTheme.labelSmall?.copyWith(fontSize: 15.sp, fontWeight: FontWeight.w700, color: AppColors.kWhite), ), ], diff --git a/wallet/lib/pages/home/currency_screen/model/ibc_coins.dart b/wallet/lib/pages/home/currency_screen/model/ibc_coins.dart index 67b17b2659..52bfad7244 100644 --- a/wallet/lib/pages/home/currency_screen/model/ibc_coins.dart +++ b/wallet/lib/pages/home/currency_screen/model/ibc_coins.dart @@ -19,6 +19,16 @@ extension IBCCoinsPar on String { return e.toString().toLowerCase() == 'IBCCoins.$this'.toLowerCase(); }, orElse: () => IBCCoins.none); //return null if not found } + + IBCCoins toIBCCoinsEnumforEvent() { + if (this == kEthereumSymbol) { + return IBCCoins.weth_wei; + } + + return IBCCoins.values.firstWhere((e) { + return e.toString().toLowerCase() == toLowerCase(); + }, orElse: () => IBCCoins.none); //return null if not found + } } extension IBCCoinsDePar on IBCCoins { @@ -146,7 +156,7 @@ extension IBCCoinsDePar on IBCCoins { case IBCCoins.ustripeusd: return (double.parse(amount) / kBigIntBase).toStringAsFixed(2); case IBCCoins.upylon: - return (double.parse(amount) / kBigIntBase).toStringAsFixed(0); + return (double.parse(amount) / kBigIntBase).toStringAsFixed(2); case IBCCoins.weth_wei: return (double.parse(amount) / kEthIntBase).toStringAsFixed(2); } @@ -185,7 +195,6 @@ extension IBCCoinsDePar on IBCCoins { case IBCCoins.none: case IBCCoins.eeur: case IBCCoins.ujuno: - case IBCCoins.uatom: return "${(double.parse(amount) / kBigIntBase).toStringAsFixed(kCurrencyDecimalLength)} ${getAbbrev()}"; case IBCCoins.upylon: @@ -197,11 +206,9 @@ extension IBCCoinsDePar on IBCCoins { } } - String pylnToCredit(String amount) { - return( double.parse(amount)/10).toStringAsFixed(2); + return (double.parse(amount) / 10).toStringAsFixed(2); } - } SizedBox getIconFromAsset(String ibcCoinIcon) => SizedBox( diff --git a/wallet/lib/pages/purchase_item/purchase_item_view_model.dart b/wallet/lib/pages/purchase_item/purchase_item_view_model.dart index 8110e75021..c8f948f4dd 100644 --- a/wallet/lib/pages/purchase_item/purchase_item_view_model.dart +++ b/wallet/lib/pages/purchase_item/purchase_item_view_model.dart @@ -1,6 +1,5 @@ import 'dart:async'; import 'dart:convert'; - import 'package:dartz/dartz.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/cupertino.dart'; @@ -8,6 +7,7 @@ import 'package:flutter/material.dart'; import 'package:just_audio/just_audio.dart'; import 'package:pylons_wallet/components/loading.dart'; import 'package:pylons_wallet/ipc/models/sdk_ipc_response.dart'; +import 'package:pylons_wallet/model/event.dart'; import 'package:pylons_wallet/model/nft.dart'; import 'package:pylons_wallet/model/nft_ownership_history.dart'; import 'package:pylons_wallet/modules/Pylonstech.pylons.pylons/module/client/pylons/execution.pb.dart'; @@ -147,6 +147,33 @@ class PurchaseItemViewModel extends ChangeNotifier { return response; } + Future> paymentForEventRecipe() async { + const jsonExecuteRecipe = ''' + { + "creator": "", + "cookbook_id": "", + "recipe_id": "", + "eventName": "", + "eventPrice": "", + "eventCurrency": "", + "coinInputsIndex": 0 + } + '''; + final jsonMap = jsonDecode(jsonExecuteRecipe) as Map; + + jsonMap[kCookbookIdKey] = getEvents.cookbookID; + jsonMap[kRecipeIdKey] = getEvents.recipeID; + jsonMap[kEventNam] = getEvents.eventName; + jsonMap[kEventPrice] = getEvents.denom.getCoinWithProperDenomination(getEvents.price); + jsonMap[kEventCurrency] = getEvents.denom.getAbbrev(); + + final showLoader = Loading()..showLoading(); + + final response = await walletsStore.executeRecipeForEvent(jsonMap); + showLoader.dismiss(); + return response; + } + Future paymentForTrade() async { final showLoader = Loading()..showLoading(); const json = ''' @@ -494,8 +521,7 @@ class PurchaseItemViewModel extends ChangeNotifier { }); } - Future> shouldShowSwipeToBuy( - {required String selectedDenom, required double requiredAmount}) async { + Future> shouldShowSwipeToBuy({required String selectedDenom, required double requiredAmount}) async { final walletAddress = accountPublicInfo!.publicAddress; final balancesEither = await repository.getBalance(walletAddress); @@ -511,8 +537,7 @@ class PurchaseItemViewModel extends ChangeNotifier { return const Right(true); } - final mappedBalances = - balancesEither.getOrElse(() => []).where((element) => element.denom == selectedDenom).toList(); + final mappedBalances = balancesEither.getOrElse(() => []).where((element) => element.denom == selectedDenom).toList(); if (mappedBalances.isEmpty) { return const Right(false); } @@ -603,7 +628,7 @@ class PurchaseItemViewModel extends ChangeNotifier { TradeReceiptModel createTradeReciptModel({ required double price, - required double fee, + required double fee, required String txTime, required String txId, }) => @@ -619,4 +644,10 @@ class PurchaseItemViewModel extends ChangeNotifier { nftName: nft.name, transactionID: txId, ); + + Events _event = Events(); + + set setEvents(Events event) => _event = event; + + Events get getEvents => _event; } diff --git a/wallet/lib/pages/transaction_failure_manager/failure_manager_view_model.dart b/wallet/lib/pages/transaction_failure_manager/failure_manager_view_model.dart index 38d3ea4a4b..bb94a2247a 100644 --- a/wallet/lib/pages/transaction_failure_manager/failure_manager_view_model.dart +++ b/wallet/lib/pages/transaction_failure_manager/failure_manager_view_model.dart @@ -54,6 +54,9 @@ class FailureManagerViewModel extends ChangeNotifier { case TransactionTypeEnum.Unknown: LocaleKeys.something_wrong.tr().show(); break; + case TransactionTypeEnum.BuyEvent: + LocaleKeys.something_wrong.tr().show(); + break; } } diff --git a/wallet/lib/services/data_stores/remote_data_store.dart b/wallet/lib/services/data_stores/remote_data_store.dart index f66686523a..1bf33dc676 100644 --- a/wallet/lib/services/data_stores/remote_data_store.dart +++ b/wallet/lib/services/data_stores/remote_data_store.dart @@ -1112,6 +1112,7 @@ class RemoteDataStoreImp implements RemoteDataStore { @override Future getAppCheckToken() async { + return "6B189291-D2AE-439B-AA5D-E2B99679C01E"; final String? token = await firebaseAppCheck.getToken(); if (token == null || token.isEmpty) { diff --git a/wallet/lib/stores/wallet_store.dart b/wallet/lib/stores/wallet_store.dart index d2ac2b9e5c..0a2ce90430 100644 --- a/wallet/lib/stores/wallet_store.dart +++ b/wallet/lib/stores/wallet_store.dart @@ -37,6 +37,11 @@ abstract class WalletsStore { /// Output : [Execution] of the transaction (data field - idk that this is - this is a mess) Future> executeRecipe(Map json); + /// Input : [Map] containing the info related to the execution of recipe for event + /// Output : [Execution] of the transaction (data field - idk that this is - this is a mess) + Future> executeRecipeForEvent(Map json); + + /// This method is for create Trade /// MsgCreateTrade proto /// request fields: {String creator, list coinInputs, List itemInputs, List coinOutputs, List itemOutputs, String extraInfo} diff --git a/wallet/lib/stores/wallet_store_imp.dart b/wallet/lib/stores/wallet_store_imp.dart index ba90fb20ff..8448bf17f1 100644 --- a/wallet/lib/stores/wallet_store_imp.dart +++ b/wallet/lib/stores/wallet_store_imp.dart @@ -483,6 +483,94 @@ class WalletsStoreImp implements WalletsStore { ); } + @override + Future> executeRecipeForEvent(Map json) async { + final networkInfo = GetIt.I.get(); + + final LocalTransactionModel localTransactionModel = createInitialLocalTransactionModel( + transactionTypeEnum: TransactionTypeEnum.BuyEvent, + transactionData: jsonEncode(json), + transactionDescription: "${LocaleKeys.bought_nft.tr()} ${json[kEventNam] ?? ""}", + transactionCurrency: "${json[kEventCurrency] ?? ""}", + transactionPrice: "${json[kEventPrice] ?? ""}", + ); + + if (!await networkInfo.isConnected) { + await saveTransactionRecord( + transactionHash: "", + transactionStatus: TransactionStatus.Failed, + txLocalModel: localTransactionModel, + ); + return SdkIpcResponse.failure( + sender: '', + error: LocaleKeys.no_internet.tr(), + errorCode: HandlerFactory.ERR_SOMETHING_WENT_WRONG, + ); + } + + json.remove(kEventNam); + json.remove(kEventCurrency); + json.remove(kEventPrice); + + final msgObj = pylons.MsgExecuteRecipe.create()..mergeFromProto3Json(json); + msgObj.creator = accountProvider.accountPublicInfo!.publicAddress; + final sdkResponse = await _signAndBroadcast(msgObj); + if (!sdkResponse.success) { + await saveTransactionRecord( + transactionHash: "", + transactionStatus: TransactionStatus.Failed, + txLocalModel: localTransactionModel, + ); + return SdkIpcResponse.failure( + error: sdkResponse.error, + sender: sdkResponse.sender, + errorCode: sdkResponse.errorCode, + ); + } + + final executionEither = await repository.getExecutionsByRecipeId( + recipeId: json.containsKey(kRecipeIdKey) ? json[kRecipeIdKey].toString() : json[kRecipeIdMap].toString(), + cookBookId: json.containsKey(kCookbookIdKey) ? json[kCookbookIdKey].toString() : json[kCookbookIdMap].toString(), + ); + if (executionEither.isLeft()) { + await saveTransactionRecord( + transactionHash: "", + transactionStatus: TransactionStatus.Failed, + txLocalModel: localTransactionModel, + ); + return SdkIpcResponse.failure( + error: sdkResponse.error, + sender: sdkResponse.sender, + errorCode: sdkResponse.errorCode, + ); + } + + if (executionEither.toOption().toNullable()!.completedExecutions.isEmpty) { + await saveTransactionRecord( + transactionHash: "", + transactionStatus: TransactionStatus.Failed, + txLocalModel: localTransactionModel, + ); + return SdkIpcResponse.failure( + error: sdkResponse.error, + sender: sdkResponse.sender, + errorCode: sdkResponse.errorCode, + ); + } + + await saveTransactionRecord( + transactionHash: sdkResponse.data.toString(), + transactionStatus: TransactionStatus.Success, + txLocalModel: localTransactionModel, + ); + return SdkIpcResponse.success( + data: executionEither.toOption().toNullable()!.completedExecutions.last, + sender: sdkResponse.sender, + transaction: sdkResponse.data.toString(), + ); + } + + @override Future fulfillTrade(Map json) async { final msgObj = pylons.MsgFulfillTrade.create()..mergeFromProto3Json(json); diff --git a/wallet/lib/utils/constants.dart b/wallet/lib/utils/constants.dart index 3d005d1ede..6987bb8380 100644 --- a/wallet/lib/utils/constants.dart +++ b/wallet/lib/utils/constants.dart @@ -451,6 +451,11 @@ const String kCookbookID = "cookbookID"; const String kPaymentInfosMap = "paymentInfos"; const String kItemAlreadyOwned = "itemAlreadyOwned"; +const kEventNam = "eventName"; +const kEventPrice = "eventPrice"; +const kEventCurrency = "eventCurrency"; + + class AnalyticsScreenEvents { static String mainLanding = "MainLandingScreen"; static String createKey = "CreateKeyScreen"; diff --git a/wallet/lib/utils/enums.dart b/wallet/lib/utils/enums.dart index 348497b2fc..e54d96269b 100644 --- a/wallet/lib/utils/enums.dart +++ b/wallet/lib/utils/enums.dart @@ -25,7 +25,8 @@ enum TransactionTypeEnum { AppleInAppCoinsRequest, GoogleInAppCoinsRequest, BuyProduct, - Unknown + Unknown, + BuyEvent, } enum TransactionStatus {