dev
dart 171 lines 6.86 KB
Raw
1 import 'dart:convert';
2 import 'package:cake_wallet/buy/buy_exception.dart';
3 import 'package:cake_wallet/order/order_source_description.dart';
4 import 'package:cake_wallet/buy/pairs_utils.dart';
5 import 'package:cake_wallet/entities/fiat_currency.dart';
6 import 'package:cw_core/crypto_currency.dart';
7 import 'package:cw_core/currency_for_wallet_type.dart';
8 import 'package:cw_core/utils/proxy_wrapper.dart';
9 import 'package:cake_wallet/buy/buy_amount.dart';
10 import 'package:cake_wallet/buy/buy_provider.dart';
11 import 'package:cake_wallet/buy/buy_provider_description.dart';
12 import 'package:cake_wallet/order/order.dart';
13 import 'package:cw_core/wallet_base.dart';
14 import 'package:cw_core/wallet_type.dart';
15 import 'package:cake_wallet/exchange/trade_state.dart';
16 import 'package:cake_wallet/.secrets.g.dart' as secrets;
17
18 class WyreBuyProvider extends BuyProvider {
19 WyreBuyProvider({required WalletBase wallet, bool isTestEnvironment = false})
20 : baseApiUrl = isTestEnvironment ? _baseTestApiUrl : _baseProductApiUrl,
21 super(
22 wallet: wallet,
23 isTestEnvironment: isTestEnvironment,
24 hardwareWalletVM: null,
25 supportedCryptoList: supportedCryptoToFiatPairs(
26 notSupportedCrypto: _notSupportedCrypto, notSupportedFiat: _notSupportedFiat),
27 supportedFiatList: supportedFiatToCryptoPairs(
28 notSupportedFiat: _notSupportedFiat, notSupportedCrypto: _notSupportedCrypto));
29
30 static const _baseTestApiUrl = 'https://api.testwyre.com';
31 static const _baseProductApiUrl = 'https://api.sendwyre.com';
32 static const _trackTestUrl = 'https://dash.testwyre.com/track/';
33 static const _trackProductUrl = 'https://dash.sendwyre.com/track/';
34 static const _ordersSuffix = '/v3/orders';
35 static const _reserveSuffix = '/reserve';
36 static const _quoteSuffix = '/quote/partner';
37 static const _timeStampSuffix = '?timestamp=';
38 static const _transferSuffix = '/v2/transfer/';
39 static const _trackSuffix = '/track';
40 static const _countryCode = 'US';
41 static const _secretKey = secrets.wyreSecretKey;
42 static const _accountId = secrets.wyreAccountId;
43
44 static const List<CryptoCurrency> _notSupportedCrypto = [];
45 static const List<FiatCurrency> _notSupportedFiat = [];
46
47 @override
48 String get title => 'Wyre';
49
50 @override
51 String get providerDescription => '';
52
53 @override
54 String get lightIcon => 'assets/images/robinhood_light.png';
55
56 @override
57 String get darkIcon => 'assets/images/robinhood_dark.png';
58
59 @override
60 bool get isAggregator => false;
61
62 String get trackUrl => isTestEnvironment ? _trackTestUrl : _trackProductUrl;
63
64 String baseApiUrl;
65
66 Future<String> requestUrl(String amount, String sourceCurrency) async {
67 final timestamp = DateTime.now().millisecondsSinceEpoch.toString();
68 final url = baseApiUrl + _ordersSuffix + _reserveSuffix + _timeStampSuffix + timestamp;
69 final uri = Uri.parse(url);
70 final body = {
71 'amount': amount,
72 'sourceCurrency': sourceCurrency,
73 'destCurrency': walletTypeToCryptoCurrency(wallet.type, chainId: wallet.chainId).title,
74 'dest': walletTypeToString(wallet.type).toLowerCase() + ':' + wallet.walletAddresses.address,
75 'referrerAccountId': _accountId,
76 'lockFields': ['amount', 'sourceCurrency', 'destCurrency', 'dest']
77 };
78 final response = await ProxyWrapper().post(
79 clearnetUri: uri,
80 headers: {
81 'Authorization': 'Bearer $_secretKey',
82 'Content-Type': 'application/json',
83 'cache-control': 'no-cache'
84 },
85 body: json.encode(body),
86 );
87
88 if (response.statusCode != 200) {
89 throw BuyException(title: providerDescription, content: 'Url $url is not found!');
90 }
91
92 final responseJSON = json.decode(response.body) as Map<String, dynamic>;
93 final urlFromResponse = responseJSON['url'] as String;
94 return urlFromResponse;
95 }
96
97 Future<BuyAmount> calculateAmount(String amount, String sourceCurrency) async {
98 final quoteUrl = _baseProductApiUrl + _ordersSuffix + _quoteSuffix;
99 final body = {
100 'amount': amount,
101 'sourceCurrency': sourceCurrency,
102 'destCurrency': walletTypeToCryptoCurrency(wallet.type, chainId: wallet.chainId).title,
103 'dest': walletTypeToString(wallet.type).toLowerCase() + ':' + wallet.walletAddresses.address,
104 'accountId': _accountId,
105 'country': _countryCode
106 };
107 final uri = Uri.parse(quoteUrl);
108 final response = await ProxyWrapper().post(
109 clearnetUri: uri,
110 headers: {
111 'Authorization': 'Bearer $_secretKey',
112 'Content-Type': 'application/json',
113 'cache-control': 'no-cache'
114 },
115 body: json.encode(body),
116 );
117
118 if (response.statusCode != 200) {
119 throw BuyException(title: providerDescription, content: 'Quote is not found!');
120 }
121
122 final responseJSON = json.decode(response.body) as Map<String, dynamic>;
123 final sourceAmount = responseJSON['sourceAmount'] as double;
124 final destAmount = responseJSON['destAmount'] as double;
125 final achAmount = responseJSON['sourceAmountWithoutFees'] as double;
126
127 return BuyAmount(
128 sourceAmount: sourceAmount, destAmount: destAmount, achSourceAmount: achAmount);
129 }
130
131 Future<Order> findOrderById(String id) async {
132 final orderUrl = baseApiUrl + _ordersSuffix + '/$id';
133 final orderUri = Uri.parse(orderUrl);
134 final orderResponse = await ProxyWrapper().get(clearnetUri: orderUri);
135 if (orderResponse.statusCode != 200) {
136 throw BuyException(title: providerDescription, content: 'Order $id is not found!');
137 }
138
139 final orderResponseJSON = json.decode(orderResponse.body) as Map<String, dynamic>;
140 final transferId = orderResponseJSON['transferId'] as String;
141 final from = orderResponseJSON['sourceCurrency'] as String;
142 final to = orderResponseJSON['destCurrency'] as String;
143 final status = orderResponseJSON['status'] as String;
144 final state = TradeState.deserialize(raw: status.toLowerCase());
145 final createdAtRaw = orderResponseJSON['createdAt'] as int;
146 final createdAt = DateTime.fromMillisecondsSinceEpoch(createdAtRaw).toLocal();
147
148 final transferUrl = baseApiUrl + _transferSuffix + transferId + _trackSuffix;
149 final transferUri = Uri.parse(transferUrl);
150 final transferResponse = await ProxyWrapper().get(clearnetUri: transferUri);
151 if (transferResponse.statusCode != 200) {
152 throw BuyException(title: providerDescription, content: 'Transfer $transferId is not found!');
153 }
154
155 final transferResponseJSON = json.decode(transferResponse.body) as Map<String, dynamic>;
156 final amount = transferResponseJSON['destAmount'] as double;
157
158 return Order(
159 id: id,
160 source: OrderSourceDescription.buy,
161 buyProvider: BuyProviderDescription.wyre,
162 transferId: transferId,
163 from: from,
164 to: to,
165 state: state,
166 createdAt: createdAt,
167 amount: amount.toString(),
168 receiveAddress: wallet.walletAddresses.address,
169 walletId: wallet.id);
170 }
171 }