cake_wallet/lib/anonpay/anonpay_api.dart
Rafael Saes 2bce18d240
Linux flutter upgrade (#1054)
* V4.8.1 v1.5.1 (#1038)

* Revert "Cw 397 chatwoot live support (#1011)"

This reverts commit af9b5ff10c.

* Add Version 4.8.1 configs

* Update macos build version [skip ci]

* Re add chatwoot (#1044)

* Revert "Revert "Cw 397 chatwoot live support (#1011)""

This reverts commit ecdc7baa2e.

* Re-add chatwoot
Change chatwoot base url

* Cw 396 additional themes (#962)

* fix: SectionStandardList using BuildContext as param

* refactor: deprecated backgroundColor -> colorScheme.background

* refactor: themeBase and current themes

* refactor: accentTextTheme.titleLarge.color -> dialogTheme.backgroundColor

* refactor: gradient background

* refactor: text themes using the same color as primaryColor

* refactor: accentTextTheme.bodySmall.color -> cardColor

* refactor: text themes using same dialogBackgroundColor

* refactor: scrollbarTheme

* refactor: create SyncIndicatorTheme

* refactor: SectionDivider

* refactor: base_page improvements and simplify

* refactor: collapsible_standart_list improvements

* refactor: accentTextTheme.bodyLarge.backgroundColor -> KeyboardTheme.keyboardBarColor

* refactor: create PinCodeTheme for accentTextTheme.bodyMedium

* refactor: create SupportPageTheme for accentTextTheme.displayLarge.backgroundColor and fix cases that use it

* refactor: accentTextTheme.displayLarge.color -> disabledColor

* refactor: create ExchangePageTheme

* refactor: create DashboardPageTheme and use textColor

* refactor: create NewWalletTheme for accentTextTheme.displayMedium

* refactor: create BalancePageTheme for accentTextTheme.displaySmall.backgroundColor

* refactor: create AddressTheme for accentTextTheme.displaySmall.color

* refactor: create IndicatorDotTheme

* refactor: create CakeMenuTheme

* refactor: create FilterTheme

* refactor: create WalletListTheme

* refactor: accentTextTheme.bodySmall.decorationColor -> InfoTheme.textColor

* refactor: accentTextTheme.titleLarge.backgroundColor -> PickerTheme.dividerColor

* refactor: primaryTextTheme.bodyLarge.backgroundColor -> AlertTheme.leftButtonTextColor

* refactor: primaryTextTheme.displayLarge.backgroundColor -> OrderTheme.iconColor

* refactor: create SendPageTheme

* fix: missing migrated styles

* refactor: primaryTextTheme.labelSmall.decorationColor -> PlaceholderTheme.color

* refactor: create TransactionTradeTheme

* refactor: create CakeTextTheme

* refactor: create AccountListTheme

* refactor: create ReceivePageTheme

* refactor: create QRCodeTheme

* refactor: move remaining items to CakeTextTheme and some missing fixes

* feat(display_settings): add new theme selector

* feat: additional themes

* fix: conflict error

* fix(lag): move colorScheme initialization to constructor

* feat: add backdropColor to alert and picker backdrop filters

* fix: merge fixes

* fix: send template page missing new colors

* fix: anonpay pages title and icon colors

* fix: merge fixes

* fix: unspent coins page

* fix: also fix exchange template

* fix: missing checkbox

* fix: fixes for high contrast theme

* Merge branch 'main' into CW-396-additional-themes

* fix: merge fixes

* fix: .gitignore and rm added files

* Fix review comments

---------

Co-authored-by: OmarHatem <omarh.ismail1@gmail.com>

* Flutter update (#1048)

* Update Flutter
Update packages

* Fix localization issues
Fix UI issues
Update old packages
Update workflow
Update how to build guide

* Additional UI fixes for merged conflicts

* Fix Ethereum network for anonpay invoice (#1051)

* build: migrate from wakelock to wakelock_plus

- plus is compatible with package_info_plus ^4.0.0
- plus has implemented Linux support

* fix: theme & support view model merge fixes

---------

Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>
2023-08-24 02:30:21 +03:00

213 lines
6.6 KiB
Dart

import 'dart:convert';
import 'package:cake_wallet/anonpay/anonpay_donation_link_info.dart';
import 'package:cake_wallet/anonpay/anonpay_invoice_info.dart';
import 'package:cake_wallet/anonpay/anonpay_request.dart';
import 'package:cake_wallet/anonpay/anonpay_status_response.dart';
import 'package:cake_wallet/core/fiat_conversion_service.dart';
import 'package:cake_wallet/entities/fiat_currency.dart';
import 'package:cake_wallet/exchange/limits.dart';
import 'package:cw_core/wallet_base.dart';
import 'package:http/http.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cake_wallet/.secrets.g.dart' as secrets;
class AnonPayApi {
const AnonPayApi({
this.useTorOnly = false,
required this.wallet,
});
final bool useTorOnly;
final WalletBase wallet;
static const anonpayRef = secrets.anonPayReferralCode;
static const onionApiAuthority = 'trocadorfyhlu27aefre5u7zri66gudtzdyelymftvr4yjwcxhfaqsid.onion';
static const clearNetAuthority = 'trocador.app';
static const markup = secrets.trocadorExchangeMarkup;
static const anonPayPath = '/anonpay';
static const anonPayStatus = '/anonpay/status';
static const coinPath = 'api/coin';
static const apiKey = secrets.trocadorApiKey;
Future<AnonpayStatusResponse> paymentStatus(String id) async {
final authority = await _getAuthority();
final response = await get(Uri.https(authority, "$anonPayStatus/$id"));
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final status = responseJSON['Status'] as String;
final fiatAmount = responseJSON['Fiat_Amount'] as double?;
final fiatEquiv = responseJSON['Fiat_Equiv'] as String?;
final amountTo = responseJSON['AmountTo'] as double?;
final coinTo = responseJSON['CoinTo'] as String;
final address = responseJSON['Address'] as String;
return AnonpayStatusResponse(
status: status,
fiatAmount: fiatAmount,
amountTo: amountTo,
coinTo: coinTo,
address: address,
fiatEquiv: fiatEquiv,
);
}
Future<AnonpayInvoiceInfo> createInvoice(AnonPayRequest request) async {
final description = Uri.encodeComponent(request.description);
final body = <String, dynamic>{
'ticker_to': request.cryptoCurrency.title.toLowerCase(),
'network_to': _networkFor(request.cryptoCurrency),
'address': request.address,
'name': request.name,
'description': description,
'email': request.email,
'ref': anonpayRef,
'markup': markup,
'direct': 'False',
};
if (request.amount != null) {
body['amount'] = request.amount;
}
if (request.fiatEquivalent != null) {
body['fiat_equiv'] = request.fiatEquivalent;
}
final authority = await _getAuthority();
final response = await get(Uri.https(authority, anonPayPath, body));
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final id = responseJSON['ID'] as String;
final url = responseJSON['url'] as String;
final urlOnion = responseJSON['url_onion'] as String;
final statusUrl = responseJSON['status_url'] as String;
final statusUrlOnion = responseJSON['status_url_onion'] as String;
final statusInfo = await paymentStatus(id);
return AnonpayInvoiceInfo(
invoiceId: id,
clearnetUrl: url,
onionUrl: urlOnion,
status: statusInfo.status,
fiatAmount: statusInfo.fiatAmount,
fiatEquiv: statusInfo.fiatEquiv,
amountTo: statusInfo.amountTo,
coinTo: statusInfo.coinTo,
address: statusInfo.address,
clearnetStatusUrl: statusUrl,
onionStatusUrl: statusUrlOnion,
walletId: wallet.id,
createdAt: DateTime.now(),
provider: 'Trocador AnonPay invoice',
);
}
Future<AnonpayDonationLinkInfo> generateDonationLink(AnonPayRequest request) async {
final body = <String, dynamic>{
'ticker_to': request.cryptoCurrency.title.toLowerCase(),
'network_to': _networkFor(request.cryptoCurrency),
'address': request.address,
'ref': anonpayRef,
'direct': 'True',
};
if (request.name.isNotEmpty) {
body['name'] = request.name;
}
if (request.description.isNotEmpty) {
body['description'] = request.description;
}
if (request.email.isNotEmpty) {
body['email'] = request.email;
}
final clearnetUrl = Uri.https(clearNetAuthority, anonPayPath, body);
final onionUrl = Uri.https(onionApiAuthority, anonPayPath, body);
return AnonpayDonationLinkInfo(
clearnetUrl: clearnetUrl.toString(),
onionUrl: onionUrl.toString(),
address: request.address,
);
}
Future<Limits> fetchLimits({
FiatCurrency? fiatCurrency,
required CryptoCurrency cryptoCurrency,
}) async {
double fiatRate = 0.0;
if (fiatCurrency != null) {
fiatRate = await FiatConversionService.fetchPrice(
crypto: cryptoCurrency,
fiat: fiatCurrency,
torOnly: useTorOnly,
);
}
final params = <String, String>{
'api_key': apiKey,
'ticker': cryptoCurrency.title.toLowerCase(),
'name': cryptoCurrency.name,
};
final String apiAuthority = await _getAuthority();
final uri = Uri.https(apiAuthority, coinPath, params);
final response = await get(uri);
if (response.statusCode != 200) {
throw Exception('Unexpected http status: ${response.statusCode}');
}
final responseJSON = json.decode(response.body) as List<dynamic>;
if (responseJSON.isEmpty) {
throw Exception('No data');
}
final coinJson = responseJSON.first as Map<String, dynamic>;
final minimum = coinJson['minimum'] as double;
final maximum = coinJson['maximum'] as double;
if (fiatCurrency != null) {
return Limits(
min: double.tryParse((minimum * fiatRate).toStringAsFixed(2)),
max: double.tryParse((maximum * fiatRate).toStringAsFixed(2)),
);
}
return Limits(
min: minimum,
max: maximum,
);
}
String _networkFor(CryptoCurrency currency) {
switch (currency) {
case CryptoCurrency.usdt:
return CryptoCurrency.btc.title.toLowerCase();
case CryptoCurrency.eth:
return 'ERC20';
default:
return currency.tag != null ? _normalizeTag(currency.tag!) : 'Mainnet';
}
}
String _normalizeTag(String tag) {
switch (tag) {
case 'ETH':
return 'ERC20';
default:
return tag.toLowerCase();
}
}
Future<String> _getAuthority() async {
try {
if (useTorOnly) {
return onionApiAuthority;
}
final uri = Uri.https(onionApiAuthority, '/anonpay');
await get(uri);
return onionApiAuthority;
} catch (e) {
return clearNetAuthority;
}
}
}