mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2024-12-23 20:19:25 +00:00
Add anypay. Add purschase gift card.
This commit is contained in:
parent
716c0821bb
commit
6c947cdb63
10 changed files with 248 additions and 56 deletions
38
lib/anypay/any_pay_payment.dart
Normal file
38
lib/anypay/any_pay_payment.dart
Normal 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;
|
||||
}
|
30
lib/anypay/any_pay_payment_instruction.dart
Normal file
30
lib/anypay/any_pay_payment_instruction.dart
Normal 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;
|
||||
}
|
10
lib/anypay/any_pay_payment_instruction_output.dart
Normal file
10
lib/anypay/any_pay_payment_instruction_output.dart
Normal 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;
|
||||
}
|
48
lib/anypay/anypay_api.dart
Normal file
48
lib/anypay/anypay_api.dart
Normal 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);
|
||||
}
|
||||
}
|
|
@ -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>(),
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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 {
|
||||
|
||||
}
|
||||
}
|
23
lib/ionia/ionia_order.dart
Normal file
23
lib/ionia/ionia_order.dart
Normal 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;
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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';
|
||||
|
|
Loading…
Reference in a new issue