diff --git a/lib/api/response/cashier_withdrawal_cancel_response_extended.dart b/lib/api/response/cashier_withdrawal_cancel_response_extended.dart new file mode 100644 index 0000000000..3650793677 --- /dev/null +++ b/lib/api/response/cashier_withdrawal_cancel_response_extended.dart @@ -0,0 +1,36 @@ +// ignore_for_file: prefer_single_quotes, unnecessary_import, unused_import + +import 'package:deriv_dependency_injector/dependency_injector.dart'; +import 'package:equatable/equatable.dart'; +import 'package:flutter_deriv_api/api/exceptions/base_api_exception.dart'; +import 'package:flutter_deriv_api/api/models/base_exception_model.dart'; +import 'package:flutter_deriv_api/api/response/cashier_withdrawal_cancel_response_result.dart'; +import 'package:flutter_deriv_api/basic_api/generated/cashier_withdrawal_cancel_receive.dart'; +import 'package:flutter_deriv_api/basic_api/generated/cashier_withdrawal_cancel_send.dart'; + +import 'package:flutter_deriv_api/helpers/helpers.dart'; +import 'package:flutter_deriv_api/services/connection/api_manager/base_api.dart'; + +/// The extended version of the [CashierWithdrawalCancelResponseExtended] class to implement +/// the API call methods. +class CashierWithdrawalCancelResponseExtended + extends CashierWithdrawalCancelResponseModel { + static final BaseAPI _api = Injector()(); + + /// Fetches the cashier payments. + static Future cancelCasWithdrawl({ + required CashierWithdrawalCancelRequest request, + }) async { + final CashierWithdrawalCancelReceive response = + await _api.call(request: request); + + checkException( + response: response, + exceptionCreator: ({BaseExceptionModel? baseExceptionModel}) => + BaseAPIException(baseExceptionModel: baseExceptionModel), + ); + + return CashierWithdrawalCancelResponse.fromJson( + response.cashierWithdrawalCancel); + } +} diff --git a/lib/api/response/get_account_status_response_result.dart b/lib/api/response/get_account_status_response_result.dart index e0ce801aa7..d6b31c9dbc 100644 --- a/lib/api/response/get_account_status_response_result.dart +++ b/lib/api/response/get_account_status_response_result.dart @@ -330,6 +330,7 @@ abstract class GetAccountStatusModel { /// - `mt5_additional_kyc_required`: client tax information, place of birth and account opening reason is missing. /// - `poi_expiring_soon`: the POI documents of the client will get expired soon, allow them to reupload POI documents. /// - `poa_expiring_soon`: the POA documents of the client will get outdated soon, allow them to reupload POA documents. + /// - `tin_manually_approved`: the client's tax_identification_number has been manually approved as client is not applicable for tax_identification_number final List status; /// Client risk classification: `low`, `standard`, `high`. @@ -825,6 +826,7 @@ abstract class DocumentModel { this.authenticatedWithIdv, this.expiryDate, this.status, + this.verifiedJurisdiction, }); /// This represents the current status of idv authentication for each mt5 jurisdiction. @@ -835,6 +837,9 @@ abstract class DocumentModel { /// This represents the current status of the proof of address document submitted for authentication. final DocumentStatusEnum? status; + + /// This represents the current status of authentication for each mt5 jurisdiction. + final VerifiedJurisdiction? verifiedJurisdiction; } /// Document class. @@ -844,6 +849,7 @@ class Document extends DocumentModel { super.authenticatedWithIdv, super.expiryDate, super.status, + super.verifiedJurisdiction, }); /// Creates an instance from JSON. @@ -855,6 +861,9 @@ class Document extends DocumentModel { status: json['status'] == null ? null : documentStatusEnumMapper[json['status']], + verifiedJurisdiction: json['verified_jurisdiction'] == null + ? null + : VerifiedJurisdiction.fromJson(json['verified_jurisdiction']), ); /// Converts an instance to JSON. @@ -869,6 +878,9 @@ class Document extends DocumentModel { .firstWhere((MapEntry entry) => entry.value == status) .key; + if (verifiedJurisdiction != null) { + resultMap['verified_jurisdiction'] = verifiedJurisdiction!.toJson(); + } return resultMap; } @@ -878,11 +890,13 @@ class Document extends DocumentModel { AuthenticatedWithIdv? authenticatedWithIdv, DateTime? expiryDate, DocumentStatusEnum? status, + VerifiedJurisdiction? verifiedJurisdiction, }) => Document( authenticatedWithIdv: authenticatedWithIdv ?? this.authenticatedWithIdv, expiryDate: expiryDate ?? this.expiryDate, status: status ?? this.status, + verifiedJurisdiction: verifiedJurisdiction ?? this.verifiedJurisdiction, ); } @@ -1018,6 +1032,138 @@ class AuthenticatedWithIdv extends AuthenticatedWithIdvModel { ); } +/// Verified jurisdiction model class. +abstract class VerifiedJurisdictionModel { + /// Initializes Verified jurisdiction model class . + const VerifiedJurisdictionModel({ + this.bvi, + this.dsl, + this.iom, + this.labuan, + this.malta, + this.maltainvest, + this.samoa, + this.samoaVirtual, + this.svg, + this.vanuatu, + this.virtual, + }); + + /// This represents whether the client is allowed or not to create an account under this jurisdiction + final bool? bvi; + + /// This represents whether the client is allowed or not to create an account under this jurisdiction + final bool? dsl; + + /// This represents whether the client is allowed or not to create an account under this jurisdiction + final bool? iom; + + /// This represents whether the client is allowed or not to create an account under this jurisdiction + final bool? labuan; + + /// This represents whether the client is allowed or not to create an account under this jurisdiction + final bool? malta; + + /// This represents whether the client is allowed or not to create an account under this jurisdiction + final bool? maltainvest; + + /// This represents whether the client is allowed or not to create an account under this jurisdiction + final bool? samoa; + + /// This represents whether the client is allowed or not to create an account under this jurisdiction + final bool? samoaVirtual; + + /// This represents whether the client is allowed or not to create an account under this jurisdiction + final bool? svg; + + /// This represents whether the client is allowed or not to create an account under this jurisdiction + final bool? vanuatu; + + /// This represents whether the client is allowed or not to create an account under this jurisdiction + final bool? virtual; +} + +/// Verified jurisdiction class. +class VerifiedJurisdiction extends VerifiedJurisdictionModel { + /// Initializes Verified jurisdiction class. + const VerifiedJurisdiction({ + super.bvi, + super.dsl, + super.iom, + super.labuan, + super.malta, + super.maltainvest, + super.samoa, + super.samoaVirtual, + super.svg, + super.vanuatu, + super.virtual, + }); + + /// Creates an instance from JSON. + factory VerifiedJurisdiction.fromJson(Map json) => + VerifiedJurisdiction( + bvi: getBool(json['bvi']), + dsl: getBool(json['dsl']), + iom: getBool(json['iom']), + labuan: getBool(json['labuan']), + malta: getBool(json['malta']), + maltainvest: getBool(json['maltainvest']), + samoa: getBool(json['samoa']), + samoaVirtual: getBool(json['samoa-virtual']), + svg: getBool(json['svg']), + vanuatu: getBool(json['vanuatu']), + virtual: getBool(json['virtual']), + ); + + /// Converts an instance to JSON. + Map toJson() { + final Map resultMap = {}; + + resultMap['bvi'] = bvi; + resultMap['dsl'] = dsl; + resultMap['iom'] = iom; + resultMap['labuan'] = labuan; + resultMap['malta'] = malta; + resultMap['maltainvest'] = maltainvest; + resultMap['samoa'] = samoa; + resultMap['samoa-virtual'] = samoaVirtual; + resultMap['svg'] = svg; + resultMap['vanuatu'] = vanuatu; + resultMap['virtual'] = virtual; + + return resultMap; + } + + /// Creates a copy of instance with given parameters. + VerifiedJurisdiction copyWith({ + bool? bvi, + bool? dsl, + bool? iom, + bool? labuan, + bool? malta, + bool? maltainvest, + bool? samoa, + bool? samoaVirtual, + bool? svg, + bool? vanuatu, + bool? virtual, + }) => + VerifiedJurisdiction( + bvi: bvi ?? this.bvi, + dsl: dsl ?? this.dsl, + iom: iom ?? this.iom, + labuan: labuan ?? this.labuan, + malta: malta ?? this.malta, + maltainvest: maltainvest ?? this.maltainvest, + samoa: samoa ?? this.samoa, + samoaVirtual: samoaVirtual ?? this.samoaVirtual, + svg: svg ?? this.svg, + vanuatu: vanuatu ?? this.vanuatu, + virtual: virtual ?? this.virtual, + ); +} + /// Identity model class. abstract class IdentityModel { /// Initializes Identity model class . @@ -1157,6 +1303,7 @@ abstract class IdvModel { const IdvModel({ this.expiryDate, this.lastRejected, + this.reportAvailable, this.reportedProperties, this.status, this.submissionsLeft, @@ -1168,6 +1315,9 @@ abstract class IdvModel { /// Show the last IDV reported reasons for the rejected cases final List? lastRejected; + /// Indicate if the verification report was returned by the provider + final bool? reportAvailable; + /// Shows the latest document properties detected and reported by IDVS final Map? reportedProperties; @@ -1184,6 +1334,7 @@ class Idv extends IdvModel { const Idv({ super.expiryDate, super.lastRejected, + super.reportAvailable, super.reportedProperties, super.status, super.submissionsLeft, @@ -1199,6 +1350,7 @@ class Idv extends IdvModel { (dynamic item) => item, ), ), + reportAvailable: getBool(json['report_available']), reportedProperties: json['reported_properties'], status: json['status'] == null ? null : idvStatusEnumMapper[json['status']], @@ -1217,6 +1369,7 @@ class Idv extends IdvModel { ) .toList(); } + resultMap['report_available'] = reportAvailable; resultMap['reported_properties'] = reportedProperties; resultMap['status'] = idvStatusEnumMapper.entries .firstWhere( @@ -1231,6 +1384,7 @@ class Idv extends IdvModel { Idv copyWith({ DateTime? expiryDate, List? lastRejected, + bool? reportAvailable, Map? reportedProperties, IdvStatusEnum? status, int? submissionsLeft, @@ -1238,6 +1392,7 @@ class Idv extends IdvModel { Idv( expiryDate: expiryDate ?? this.expiryDate, lastRejected: lastRejected ?? this.lastRejected, + reportAvailable: reportAvailable ?? this.reportAvailable, reportedProperties: reportedProperties ?? this.reportedProperties, status: status ?? this.status, submissionsLeft: submissionsLeft ?? this.submissionsLeft, diff --git a/lib/api/response/proposal_open_contract_response_result.dart b/lib/api/response/proposal_open_contract_response_result.dart index 99e37ca790..b54825f943 100644 --- a/lib/api/response/proposal_open_contract_response_result.dart +++ b/lib/api/response/proposal_open_contract_response_result.dart @@ -1,7 +1,5 @@ // ignore_for_file: prefer_single_quotes, unnecessary_import, unused_import - import 'package:equatable/equatable.dart'; - import 'package:flutter_deriv_api/api/exceptions/exceptions.dart'; import 'package:flutter_deriv_api/api/models/base_exception_model.dart'; import 'package:flutter_deriv_api/api/models/enums.dart'; @@ -163,14 +161,21 @@ class ProposalOpenContractResponse extends ProposalOpenContractResponseModel { /// Default be 0 for 'sell at market'. /// Throws a [BaseAPIException] if API response contains an error static Future sell( - {required int contractId, double price = 0}) => - SellResponse.sellContract(SellRequest(sell: contractId, price: price)); + {required int contractId, double price = 0, String? loginId}) => + SellResponse.sellContract(SellRequest( + sell: contractId, + price: price, + loginid: loginId, + )); /// Cancels this contract /// /// Throws a [BaseAPIException] if API response contains an error - static Future cancel(int contractId) => - CancelResponse.cancelContract(CancelRequest(cancel: contractId)); + static Future cancel(int contractId, {String? loginId}) => + CancelResponse.cancelContract(CancelRequest( + cancel: contractId, + loginid: loginId, + )); /// Creates a copy of instance with given parameters. ProposalOpenContractResponse copyWith({ diff --git a/lib/api/response/topup_virtual_response_result.dart b/lib/api/response/topup_virtual_response_result.dart index 42393cfec2..156329069d 100644 --- a/lib/api/response/topup_virtual_response_result.dart +++ b/lib/api/response/topup_virtual_response_result.dart @@ -1,5 +1,6 @@ // ignore_for_file: prefer_single_quotes, unnecessary_import, unused_import +import 'package:build/build.dart'; import 'package:equatable/equatable.dart'; import 'package:flutter_deriv_api/api/exceptions/exceptions.dart'; @@ -55,11 +56,13 @@ class TopupVirtualResponse extends TopupVirtualResponseModel { /// /// For parameters information refer to [TopupVirtualRequest]. /// Throws a [BaseAPIException] if API response contains an error - static Future topUp([ + static Future topUp({ TopupVirtualRequest? request, - ]) async { + String? loginId, + }) async { final TopupVirtualReceive response = await _api.call( - request: request ?? const TopupVirtualRequest(), + request: request?.copyWith(loginid: loginId) ?? + TopupVirtualRequest(loginid: loginId), ); checkException( diff --git a/lib/basic_api/generated/methods/topup_virtual_receive_methods.json b/lib/basic_api/generated/methods/topup_virtual_receive_methods.json index be41a59d85..7f44e71a7c 100644 --- a/lib/basic_api/generated/methods/topup_virtual_receive_methods.json +++ b/lib/basic_api/generated/methods/topup_virtual_receive_methods.json @@ -1,4 +1,4 @@ { - "methods": "static final BaseAPI _api = Injector()();\n\n /// Topes up the virtual-money's account balance becomes when it becomes low.\n ///\n /// For parameters information refer to [TopupVirtualRequest].\n /// Throws a [BaseAPIException] if API response contains an error\n static Future topUp([\n TopupVirtualRequest? request,\n ]) async {\n final TopupVirtualReceive response = await _api.call(\n request: request ?? const TopupVirtualRequest(),\n );\n\n checkException(\n response: response,\n exceptionCreator: ({BaseExceptionModel? baseExceptionModel}) =>\n BaseAPIException(baseExceptionModel: baseExceptionModel),\n );\n\n return TopupVirtualResponse.fromJson(response.topupVirtual);\n }", + "methods": "static final BaseAPI _api = Injector()();\n\n /// Topes up the virtual-money's account balance becomes when it becomes low.\n ///\n /// For parameters information refer to [TopupVirtualRequest].\n /// Throws a [BaseAPIException] if API response contains an error\n static Future topUp({\n TopupVirtualRequest? request,\n String? loginId, \n}) async {\n final TopupVirtualReceive response = await _api.call(\n request: request?.copyWith(loginid: loginId) ?? TopupVirtualRequest(loginid: loginId),\n );\n\n checkException(\n response: response,\n exceptionCreator: ({BaseExceptionModel? baseExceptionModel}) =>\n BaseAPIException(baseExceptionModel: baseExceptionModel),\n );\n\n return TopupVirtualResponse.fromJson(response.topupVirtual);\n }", "imports": "import 'package:flutter_deriv_api/api/exceptions/exceptions.dart';\nimport 'package:flutter_deriv_api/api/models/base_exception_model.dart';\nimport 'package:flutter_deriv_api/basic_api/generated/topup_virtual_receive.dart';\nimport 'package:flutter_deriv_api/basic_api/generated/topup_virtual_send.dart';\nimport 'package:flutter_deriv_api/helpers/helpers.dart';\nimport 'package:flutter_deriv_api/services/connection/api_manager/base_api.dart';\nimport 'package:deriv_dependency_injector/dependency_injector.dart';\n" } diff --git a/lib/services/connection/call_manager/call_history.dart b/lib/services/connection/call_manager/call_history.dart index 164afdb9e5..370f7c3da3 100644 --- a/lib/services/connection/call_manager/call_history.dart +++ b/lib/services/connection/call_manager/call_history.dart @@ -1,7 +1,17 @@ +import 'dart:async'; + import 'package:flutter_deriv_api/services/connection/call_manager/call_history_entry.dart'; +import 'package:flutter_deriv_api/services/interfaces/call_history_provider.dart'; /// Provides storage for messages sent/received via the web socket connection -class CallHistory { +class CallHistory implements CallHistoryProvider { + /// It initializes [CallHistory] instance. + CallHistory() { + _callHistoryBroadcaster = StreamController.broadcast(); + } + + late final StreamController _callHistoryBroadcaster; + /// Messages that were sent to the remote endpoint final List outgoing = []; @@ -29,7 +39,15 @@ class CallHistory { incoming.add( CallHistoryEntry(timeStamp: timestamp, method: method, message: message), ); - + if (!method.contains('ping')) { + _callHistoryBroadcaster.add( + NetworkPayload( + method: method, + body: message, + direction: NetworkDirections.received, + timeStamp: timestamp), + ); + } _trimHistory(incoming); } @@ -42,6 +60,15 @@ class CallHistory { outgoing.add( CallHistoryEntry(timeStamp: timestamp, method: method, message: message), ); + if (!method.contains('ping')) { + _callHistoryBroadcaster.add( + NetworkPayload( + method: method, + body: message, + direction: NetworkDirections.sent, + timeStamp: timestamp), + ); + } _trimHistory(outgoing); } @@ -52,4 +79,7 @@ class CallHistory { callHistory.removeRange(0, callHistory.length - limit); } } + + @override + Stream get stream => _callHistoryBroadcaster.stream; } diff --git a/lib/services/interfaces/call_history_provider.dart b/lib/services/interfaces/call_history_provider.dart new file mode 100644 index 0000000000..3c7065c33f --- /dev/null +++ b/lib/services/interfaces/call_history_provider.dart @@ -0,0 +1,37 @@ +/// This interface provides stream of network payload that is going out(SENT) +/// and coming in(RECEIVED) to the application. +abstract class CallHistoryProvider { + /// Stream of network payload that is going out(SENT) and coming in(RECEIVED) + Stream get stream; +} + +/// Network payload that is going out and coming in from the web socket. +class NetworkPayload { + /// Initializes [NetworkPayload] instance. + NetworkPayload({ + required this.method, + required this.body, + required this.direction, + required this.timeStamp, + }); + + /// name of the api. + final String method; + + /// content of the api. + final Object body; + + /// direction of the api i.e SENT or RECEIVED. + final NetworkDirections direction; + + /// time of the api. + final int timeStamp; +} + +enum NetworkDirections { + /// Going out from the web socket. + sent, + + /// Coming in from the web socket. + received +} diff --git a/lib/state/connection/connection_cubit.dart b/lib/state/connection/connection_cubit.dart index 2ccb974b53..3c90cc438a 100644 --- a/lib/state/connection/connection_cubit.dart +++ b/lib/state/connection/connection_cubit.dart @@ -46,7 +46,7 @@ class ConnectionCubit extends Cubit { final String _key = '${UniqueKey()}'; - late final BaseAPI? _api; + late final BaseAPI _api; /// Enables debug mode. /// @@ -86,6 +86,9 @@ class ConnectionCubit extends Cubit { /// Stream subscription for connectivity. StreamSubscription? connectivitySubscription; + /// Getter for [BaseAPI] implementation class. By default, it will be [BinaryAPI]. + BaseAPI get api => _api; + /// Reconnect to Websocket. Future reconnect({ ConnectionInformation? connectionInformation, @@ -109,7 +112,7 @@ class ConnectionCubit extends Cubit { emit(const ConnectionConnectingState()); try { - await _api!.disconnect().timeout(_pingTimeout); + await _api.disconnect().timeout(_pingTimeout); } on Exception catch (e) { dev.log('$runtimeType disconnect exception: $e', error: e); @@ -118,7 +121,7 @@ class ConnectionCubit extends Cubit { return; } - await _api!.connect( + await _api.connect( _connectionInformation, printResponse: enableDebug && printResponse, onOpen: (String key) {