Add anypay. Add purschase gift card.

This commit is contained in:
M 2022-06-20 20:27:28 +01:00
parent 716c0821bb
commit 6c947cdb63
10 changed files with 248 additions and 56 deletions

View file

@ -0,0 +1,38 @@
import 'package:flutter/foundation.dart';
import 'package:cake_wallet/anypay/any_pay_payment_instruction.dart';
class AnyPayPayment {
AnyPayPayment({
@required this.time,
@required this.expires,
@required this.memo,
@required this.paymentUrl,
@required this.paymentId,
@required this.chain,
@required this.network,
@required this.instructions});
factory AnyPayPayment.fromMap(Map<String, dynamic> obj) {
final instructions = (obj['instructions'] as List<dynamic>)
.map((dynamic instruction) => AnyPayPaymentInstruction.fromMap(instruction as Map<String, dynamic>))
.toList();
return AnyPayPayment(
time: DateTime.parse(obj['time'] as String),
expires: DateTime.parse(obj['expires'] as String),
memo: obj['memo'] as String,
paymentUrl: obj['paymentUrl'] as String,
paymentId: obj['paymentId'] as String,
chain: obj['chain'] as String,
network: obj['network'] as String,
instructions: instructions);
}
final DateTime time;
final DateTime expires;
final String memo;
final String paymentUrl;
final String paymentId;
final String chain;
final String network;
final List<AnyPayPaymentInstruction> instructions;
}

View file

@ -0,0 +1,30 @@
import 'package:flutter/foundation.dart';
import 'package:cake_wallet/anypay/any_pay_payment_instruction_output.dart';
class AnyPayPaymentInstruction {
AnyPayPaymentInstruction({
@required this.type,
@required this.requiredFeeRate,
@required this.txKey,
@required this.txHash,
@required this.outputs});
factory AnyPayPaymentInstruction.fromMap(Map<String, dynamic> obj) {
final outputs = (obj['outputs'] as List<dynamic>)
.map((dynamic out) =>
AnyPayPaymentInstructionOutput.fromMap(out as Map<String, dynamic>))
.toList();
return AnyPayPaymentInstruction(
type: obj['type'] as String,
requiredFeeRate: obj['requiredFeeRate'] as int,
txKey: obj['tx_key'] as bool,
txHash: obj['tx_hash'] as bool,
outputs: outputs);
}
final String type;
final int requiredFeeRate;
final bool txKey;
final bool txHash;
final List<AnyPayPaymentInstructionOutput> outputs;
}

View file

@ -0,0 +1,10 @@
class AnyPayPaymentInstructionOutput {
const AnyPayPaymentInstructionOutput(this.address, this.amount);
factory AnyPayPaymentInstructionOutput.fromMap(Map<String, dynamic> obj) {
return AnyPayPaymentInstructionOutput(obj['address'] as String, obj['amount'] as int);
}
final String address;
final int amount;
}

View file

@ -0,0 +1,48 @@
import 'dart:convert';
import 'package:http/http.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cake_wallet/anypay/any_pay_payment.dart';
class AnyPayApi {
static const contentTypePaymentRequest = 'application/payment-request';
static const xPayproVersion = '2';
static String chainByScheme(String scheme) {
switch (scheme.toLowerCase()) {
case 'monero':
return CryptoCurrency.xmr.title;
default:
return '';
}
}
static CryptoCurrency currencyByScheme(String scheme) {
switch (scheme.toLowerCase()) {
case 'monero':
return CryptoCurrency.xmr;
default:
return null;
}
}
Future<AnyPayPayment> pay(String uri) async {
final fragments = uri.split(':?r=');
final scheme = fragments.first;
final url = fragments[1];
final headers = <String, String>{
'Content-Type': contentTypePaymentRequest,
'X-Paypro-Version': xPayproVersion,
'Accept': '*/*',};
final body = <String, dynamic>{
'chain': chainByScheme(scheme),
'currency': currencyByScheme(scheme).title};
final response = await post(url, headers: headers, body: utf8.encode(json.encode(body)));
if (response.statusCode != 200) {
return null;
}
final decodedBody = json.decode(response.body) as Map<String, dynamic>;
return AnyPayPayment.fromMap(decodedBody);
}
}

View file

@ -1,7 +1,7 @@
import 'package:cake_wallet/core/yat_service.dart';
import 'package:cake_wallet/entities/parse_address_from_domain.dart';
import 'package:cake_wallet/entities/wake_lock.dart';
import 'package:cake_wallet/ionia/ionia.dart';
import 'package:cake_wallet/ionia/ionia_service.dart';
import 'package:cake_wallet/ionia/ionia_api.dart';
import 'package:cake_wallet/monero/monero.dart';
import 'package:cake_wallet/haven/haven.dart';
@ -129,7 +129,6 @@ import 'package:cake_wallet/entities/template.dart';
import 'package:cake_wallet/exchange/exchange_template.dart';
import 'package:cake_wallet/.secrets.g.dart' as secrets;
import 'package:cake_wallet/src/screens/dashboard/widgets/address_page.dart';
import 'package:cake_wallet/ionia/ionia_merchant_service.dart';
import 'package:cake_wallet/ionia/ionia_token_service.dart';
final getIt = GetIt.instance;
@ -225,8 +224,6 @@ Future setup(
sharedPreferences: getIt.get<SharedPreferences>()));
getIt.registerFactory(() => IoniaTokenService(getIt.get<FlutterSecureStorage>()));
getIt.registerFactory(() => IoniaMerchantService(getIt.get<IoniaTokenService>(), isDevEnv: true));
getIt.registerFactoryParam<WalletNewVM, WalletType, void>((type, _) =>
WalletNewVM(getIt.get<AppStore>(),

View file

@ -1,4 +1,6 @@
import 'dart:convert';
import 'package:cake_wallet/ionia/ionia_merchant.dart';
import 'package:cake_wallet/ionia/ionia_order.dart';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart';
import 'package:cake_wallet/ionia/ionia_user_credentials.dart';
@ -11,6 +13,8 @@ class IoniaApi {
static final verifyEmailUri = Uri.https(baseUri, '/$pathPrefix/VerifyEmail');
static final createCardUri = Uri.https(baseUri, '/$pathPrefix/CreateCard');
static final getCardsUri = Uri.https(baseUri, '/$pathPrefix/GetCards');
static final getMerchantsUrl = Uri.https(baseUri, '/$pathPrefix/GetMerchants');
static final getPurchaseMerchantsUrl = Uri.https(baseUri, '/$pathPrefix/PurchaseGiftCard');
// Create user
@ -122,4 +126,69 @@ class IoniaApi {
return IoniaVirtualCard.fromMap(data);
}
// Get Merchants
Future<List<IoniaMerchant>> getMerchants({
@required String username,
@required String password,
@required String clientId}) async {
final headers = <String, String>{
'clientId': clientId,
'username': username,
'password': password};
final response = await post(getMerchantsUrl, headers: headers);
if (response.statusCode != 200) {
return [];
}
final decodedBody = json.decode(response.body) as Map<String, dynamic>;
final isSuccessful = decodedBody['Successful'] as bool ?? false;
if (!isSuccessful) {
return [];
}
final data = decodedBody['Data'] as List<dynamic>;
return data.map((dynamic e) {
final element = e as Map<String, dynamic>;
return IoniaMerchant.fromJsonMap(element);
}).toList();
}
// Purchase Gift Card
Future<IoniaOrder> purchaseGiftCard({
@required String merchId,
@required double amount,
@required String currency,
@required String username,
@required String password,
@required String clientId}) async {
final headers = <String, String>{
'clientId': clientId,
'username': username,
'password': password,
'Content-Type': 'application/json'};
final body = <String, dynamic>{
'Amount': amount,
'Currency': currency,
'MerchantId': merchId};
final response = await post(getPurchaseMerchantsUrl, headers: headers, body: json.encode(body));
if (response.statusCode != 200) {
return null;
}
final decodedBody = json.decode(response.body) as Map<String, dynamic>;
final isSuccessful = decodedBody['Successful'] as bool ?? false;
if (!isSuccessful) {
return null;
}
final data = decodedBody['Data'] as Map<String, dynamic>;
return IoniaOrder.fromMap(data);
}
}

View file

@ -1,51 +0,0 @@
import 'dart:convert';
import 'package:http/http.dart';
import 'package:flutter/foundation.dart';
import 'package:cake_wallet/ionia/ionia_merchant.dart';
import 'package:cake_wallet/ionia/ionia_token_service.dart';
class IoniaMerchantService {
IoniaMerchantService(this._tokenService, {@required this.isDevEnv});
static String devApiUrl = "https://apidev.dashdirect.org/partner";
final bool isDevEnv;
final TokenService _tokenService;
String get apiUrl => isDevEnv ? devApiUrl : '';
String get getMerchantsUrl => '$apiUrl/GetMerchants';
Future<List<IoniaMerchant>> getMerchants() async {
final token = await _tokenService.getToken();
// FIX ME: remove hardcoded values
final headers = <String, String>{
'Authorization': token.toString(),
'firstName': 'cake',
'lastName': 'cake',
'email': 'cake@test'};
final response = await post(getMerchantsUrl, headers: headers);
if (response.statusCode != 200) {
return [];
}
final decodedBody = json.decode(response.body) as Map<String, dynamic>;
final isSuccessful = decodedBody['Successful'] as bool ?? false;
if (!isSuccessful) {
return [];
}
final data = decodedBody['Data'] as List<dynamic>;
return data.map((dynamic e) {
final element = e as Map<String, dynamic>;
return IoniaMerchant.fromJsonMap(element);
}).toList();
}
Future<void> purchaseGiftCard() async {
}
}

View file

@ -0,0 +1,23 @@
import 'package:flutter/foundation.dart';
class IoniaOrder {
IoniaOrder({@required this.id,
@required this.uri,
@required this.currency,
@required this.amount,
@required this.paymentId});
factory IoniaOrder.fromMap(Map<String, dynamic> obj) {
return IoniaOrder(
id: obj['order_id'] as String,
uri: obj['uri'] as String,
currency: obj['currency'] as String,
amount: obj['amount'] as double,
paymentId: obj['payment_id'] as String);
}
final String id;
final String uri;
final String currency;
final double amount;
final String paymentId;
}

View file

@ -1,4 +1,7 @@
import 'package:cake_wallet/ionia/ionia_merchant.dart';
import 'package:cake_wallet/ionia/ionia_order.dart';
import 'package:cake_wallet/ionia/ionia_virtual_card.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:cake_wallet/.secrets.g.dart' as secrets;
import 'package:cake_wallet/ionia/ionia_api.dart';
@ -59,4 +62,29 @@ class IoniaService {
final password = await secureStorage.read(key: ioniaPasswordStorageKey);
return ioniaApi.getCards(username: username, password: password, clientId: clientId);
}
// Get Merchants
Future<List<IoniaMerchant>> getMerchants() async {
final username = await secureStorage.read(key: ioniaUsernameStorageKey);
final password = await secureStorage.read(key: ioniaPasswordStorageKey);
return ioniaApi.getMerchants(username: username, password: password, clientId: clientId);
}
// Purchase Gift Card
Future<IoniaOrder> purchaseGiftCard({
@required String merchId,
@required double amount,
@required String currency}) async {
final username = await secureStorage.read(key: ioniaUsernameStorageKey);
final password = await secureStorage.read(key: ioniaPasswordStorageKey);
return ioniaApi.purchaseGiftCard(
merchId: merchId,
amount: amount,
currency: currency,
username: username,
password: password,
clientId: clientId);
}
}

View file

@ -1,4 +1,4 @@
import 'package:cake_wallet/ionia/ionia.dart';
import 'package:cake_wallet/ionia/ionia_service.dart';
import 'package:cake_wallet/ionia/ionia_create_state.dart';
import 'package:cake_wallet/ionia/ionia_virtual_card.dart';
import 'package:mobx/mobx.dart';