mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2024-12-22 03:29:36 +00:00
Cw 682 integrate stealth ex exchange provider (#1575)
* add stealthEx provider * minor fix * Update pr_test_build.yml * Update dashboard_view_model.dart * update api key * add api key * add secret to linux [skip ci] * fix network param issue * additional fee percent [skip ci] * fix for poly network * add StealthEx tracking link. * minor fix * update name [skip ci] --------- Co-authored-by: OmarHatem <omarh.ismail1@gmail.com>
This commit is contained in:
parent
580bd01345
commit
f279a222df
12 changed files with 362 additions and 21 deletions
2
.github/workflows/pr_test_build_android.yml
vendored
2
.github/workflows/pr_test_build_android.yml
vendored
|
@ -168,6 +168,8 @@ jobs:
|
|||
echo "const nanoNowNodesApiKey = '${{ secrets.NANO_NOW_NODES_API_KEY }}';" >> cw_nano/lib/.secrets.g.dart
|
||||
echo "const tronGridApiKey = '${{ secrets.TRON_GRID_API_KEY }}';" >> cw_tron/lib/.secrets.g.dart
|
||||
echo "const tronNowNodesApiKey = '${{ secrets.TRON_NOW_NODES_API_KEY }}';" >> cw_tron/lib/.secrets.g.dart
|
||||
echo "const stealthExBearerToken = '${{ secrets.STEALTH_EX_BEARER_TOKEN }}';" >> lib/.secrets.g.dart
|
||||
echo "const stealthExAdditionalFeePercent = '${{ secrets.STEALTH_EX_ADDITIONAL_FEE_PERCENT }}';" >> lib/.secrets.g.dart
|
||||
|
||||
- name: Rename app
|
||||
run: |
|
||||
|
|
2
.github/workflows/pr_test_build_linux.yml
vendored
2
.github/workflows/pr_test_build_linux.yml
vendored
|
@ -154,6 +154,8 @@ jobs:
|
|||
echo "const nanoNowNodesApiKey = '${{ secrets.NANO_NOW_NODES_API_KEY }}';" >> cw_nano/lib/.secrets.g.dart
|
||||
echo "const tronGridApiKey = '${{ secrets.TRON_GRID_API_KEY }}';" >> cw_tron/lib/.secrets.g.dart
|
||||
echo "const tronNowNodesApiKey = '${{ secrets.TRON_NOW_NODES_API_KEY }}';" >> cw_tron/lib/.secrets.g.dart
|
||||
echo "const stealthExBearerToken = '${{ secrets.STEALTH_EX_BEARER_TOKEN }}';" >> lib/.secrets.g.dart
|
||||
echo "const stealthExAdditionalFeePercent = '${{ secrets.STEALTH_EX_ADDITIONAL_FEE_PERCENT }}';" >> lib/.secrets.g.dart
|
||||
|
||||
- name: Rename app
|
||||
run: |
|
||||
|
|
BIN
assets/images/stealthex.png
Normal file
BIN
assets/images/stealthex.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.4 KiB |
|
@ -27,6 +27,8 @@ class ExchangeProviderDescription extends EnumerableItem<int> with Serializable<
|
|||
ExchangeProviderDescription(title: 'ThorChain', raw: 8, image: 'assets/images/thorchain.png');
|
||||
static const quantex =
|
||||
ExchangeProviderDescription(title: 'Quantex', raw: 9, image: 'assets/images/quantex.png');
|
||||
static const stealthEx =
|
||||
ExchangeProviderDescription(title: 'StealthEx', raw: 10, image: 'assets/images/stealthex.png');
|
||||
|
||||
static ExchangeProviderDescription deserialize({required int raw}) {
|
||||
switch (raw) {
|
||||
|
@ -50,6 +52,8 @@ class ExchangeProviderDescription extends EnumerableItem<int> with Serializable<
|
|||
return thorChain;
|
||||
case 9:
|
||||
return quantex;
|
||||
case 10:
|
||||
return stealthEx;
|
||||
default:
|
||||
throw Exception('Unexpected token: $raw for ExchangeProviderDescription deserialize');
|
||||
}
|
||||
|
|
299
lib/exchange/provider/stealth_ex_exchange_provider.dart
Normal file
299
lib/exchange/provider/stealth_ex_exchange_provider.dart
Normal file
|
@ -0,0 +1,299 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:cake_wallet/.secrets.g.dart' as secrets;
|
||||
import 'package:cake_wallet/exchange/provider/exchange_provider.dart';
|
||||
import 'package:cake_wallet/exchange/exchange_provider_description.dart';
|
||||
import 'package:cake_wallet/exchange/limits.dart';
|
||||
import 'package:cake_wallet/exchange/trade.dart';
|
||||
import 'package:cake_wallet/exchange/trade_not_created_exception.dart';
|
||||
import 'package:cake_wallet/exchange/trade_request.dart';
|
||||
import 'package:cake_wallet/exchange/trade_state.dart';
|
||||
import 'package:cake_wallet/exchange/utils/currency_pairs_utils.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
class StealthExExchangeProvider extends ExchangeProvider {
|
||||
StealthExExchangeProvider() : super(pairList: supportedPairs(_notSupported));
|
||||
|
||||
static const List<CryptoCurrency> _notSupported = [];
|
||||
|
||||
static final apiKey = secrets.stealthExBearerToken;
|
||||
static final _additionalFeePercent = double.tryParse(secrets.stealthExAdditionalFeePercent);
|
||||
static const _baseUrl = 'https://api.stealthex.io';
|
||||
static const _rangePath = '/v4/rates/range';
|
||||
static const _amountPath = '/v4/rates/estimated-amount';
|
||||
static const _exchangesPath = '/v4/exchanges';
|
||||
|
||||
@override
|
||||
String get title => 'StealthEX';
|
||||
|
||||
@override
|
||||
bool get isAvailable => true;
|
||||
|
||||
@override
|
||||
bool get isEnabled => true;
|
||||
|
||||
@override
|
||||
bool get supportsFixedRate => true;
|
||||
|
||||
@override
|
||||
ExchangeProviderDescription get description => ExchangeProviderDescription.stealthEx;
|
||||
|
||||
@override
|
||||
Future<bool> checkIsAvailable() async => true;
|
||||
|
||||
@override
|
||||
Future<Limits> fetchLimits(
|
||||
{required CryptoCurrency from,
|
||||
required CryptoCurrency to,
|
||||
required bool isFixedRateMode}) async {
|
||||
final curFrom = isFixedRateMode ? to : from;
|
||||
final curTo = isFixedRateMode ? from : to;
|
||||
|
||||
final headers = {'Authorization': apiKey, 'Content-Type': 'application/json'};
|
||||
final body = {
|
||||
'route': {
|
||||
'from': {'symbol': _getName(curFrom), 'network': _getNetwork(curFrom)},
|
||||
'to': {'symbol': _getName(curTo), 'network': _getNetwork(curTo)}
|
||||
},
|
||||
'estimation': isFixedRateMode ? 'reversed' : 'direct',
|
||||
'rate': isFixedRateMode ? 'fixed' : 'floating',
|
||||
'additional_fee_percent': _additionalFeePercent,
|
||||
};
|
||||
|
||||
try {
|
||||
final response = await http.post(Uri.parse(_baseUrl + _rangePath),
|
||||
headers: headers, body: json.encode(body));
|
||||
if (response.statusCode != 200) {
|
||||
throw Exception('StealthEx fetch limits failed: ${response.body}');
|
||||
}
|
||||
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
|
||||
final min = responseJSON['min_amount'] as double?;
|
||||
final max = responseJSON['max_amount'] as double?;
|
||||
return Limits(min: min, max: max);
|
||||
} catch (e) {
|
||||
log(e.toString());
|
||||
throw Exception('StealthEx failed to fetch limits');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<double> fetchRate(
|
||||
{required CryptoCurrency from,
|
||||
required CryptoCurrency to,
|
||||
required double amount,
|
||||
required bool isFixedRateMode,
|
||||
required bool isReceiveAmount}) async {
|
||||
final response = await getEstimatedExchangeAmount(
|
||||
from: from, to: to, amount: amount, isFixedRateMode: isFixedRateMode);
|
||||
final estimatedAmount = response['estimated_amount'] as double? ?? 0.0;
|
||||
return estimatedAmount > 0.0
|
||||
? isFixedRateMode
|
||||
? amount / estimatedAmount
|
||||
: estimatedAmount / amount
|
||||
: 0.0;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Trade> createTrade(
|
||||
{required TradeRequest request,
|
||||
required bool isFixedRateMode,
|
||||
required bool isSendAll}) async {
|
||||
String? rateId;
|
||||
String? validUntil;
|
||||
|
||||
try {
|
||||
if (isFixedRateMode) {
|
||||
final response = await getEstimatedExchangeAmount(
|
||||
from: request.fromCurrency,
|
||||
to: request.toCurrency,
|
||||
amount: double.parse(request.toAmount),
|
||||
isFixedRateMode: isFixedRateMode);
|
||||
rateId = response['rate_id'] as String?;
|
||||
validUntil = response['valid_until'] as String?;
|
||||
if (rateId == null) throw TradeNotCreatedException(description);
|
||||
}
|
||||
|
||||
final headers = {'Authorization': apiKey, 'Content-Type': 'application/json'};
|
||||
final body = {
|
||||
'route': {
|
||||
'from': {
|
||||
'symbol': _getName(request.fromCurrency),
|
||||
'network': _getNetwork(request.fromCurrency)
|
||||
},
|
||||
'to': {'symbol': _getName(request.toCurrency), 'network': _getNetwork(request.toCurrency)}
|
||||
},
|
||||
'estimation': isFixedRateMode ? 'reversed' : 'direct',
|
||||
'rate': isFixedRateMode ? 'fixed' : 'floating',
|
||||
if (isFixedRateMode) 'rate_id': rateId,
|
||||
'amount':
|
||||
isFixedRateMode ? double.parse(request.toAmount) : double.parse(request.fromAmount),
|
||||
'address': request.toAddress,
|
||||
'refund_address': request.refundAddress,
|
||||
'additional_fee_percent': _additionalFeePercent,
|
||||
};
|
||||
|
||||
final response = await http.post(Uri.parse(_baseUrl + _exchangesPath),
|
||||
headers: headers, body: json.encode(body));
|
||||
|
||||
if (response.statusCode != 201) {
|
||||
throw Exception('StealthEx create trade failed: ${response.body}');
|
||||
}
|
||||
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
|
||||
final deposit = responseJSON['deposit'] as Map<String, dynamic>;
|
||||
final withdrawal = responseJSON['withdrawal'] as Map<String, dynamic>;
|
||||
|
||||
final id = responseJSON['id'] as String;
|
||||
final from = deposit['symbol'] as String;
|
||||
final to = withdrawal['symbol'] as String;
|
||||
final payoutAddress = withdrawal['address'] as String;
|
||||
final depositAddress = deposit['address'] as String;
|
||||
final refundAddress = responseJSON['refund_address'] as String;
|
||||
final depositAmount = toDouble(deposit['amount']);
|
||||
final receiveAmount = toDouble(withdrawal['amount']);
|
||||
final status = responseJSON['status'] as String;
|
||||
final createdAtString = responseJSON['created_at'] as String;
|
||||
|
||||
final createdAt = DateTime.parse(createdAtString);
|
||||
final expiredAt = validUntil != null
|
||||
? DateTime.parse(validUntil)
|
||||
: DateTime.now().add(Duration(minutes: 5));
|
||||
|
||||
|
||||
CryptoCurrency fromCurrency;
|
||||
if (request.fromCurrency.tag != null && request.fromCurrency.title.toLowerCase() == from) {
|
||||
fromCurrency = request.fromCurrency;
|
||||
} else {
|
||||
fromCurrency = CryptoCurrency.fromString(from);
|
||||
}
|
||||
|
||||
CryptoCurrency toCurrency;
|
||||
if (request.toCurrency.tag != null && request.toCurrency.title.toLowerCase() == to) {
|
||||
toCurrency = request.toCurrency;
|
||||
} else {
|
||||
toCurrency = CryptoCurrency.fromString(to);
|
||||
}
|
||||
|
||||
return Trade(
|
||||
id: id,
|
||||
from: fromCurrency,
|
||||
to: toCurrency,
|
||||
provider: description,
|
||||
inputAddress: depositAddress,
|
||||
payoutAddress: payoutAddress,
|
||||
refundAddress: refundAddress,
|
||||
amount: depositAmount.toString(),
|
||||
receiveAmount: receiveAmount.toString(),
|
||||
state: TradeState.deserialize(raw: status),
|
||||
createdAt: createdAt,
|
||||
expiredAt: expiredAt,
|
||||
);
|
||||
} catch (e) {
|
||||
log(e.toString());
|
||||
throw TradeNotCreatedException(description);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Trade> findTradeById({required String id}) async {
|
||||
final headers = {'Authorization': apiKey, 'Content-Type': 'application/json'};
|
||||
|
||||
final uri = Uri.parse('$_baseUrl$_exchangesPath/$id');
|
||||
final response = await http.get(uri, headers: headers);
|
||||
|
||||
if (response.statusCode != 200) {
|
||||
throw Exception('StealthEx fetch trade failed: ${response.body}');
|
||||
}
|
||||
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
|
||||
final deposit = responseJSON['deposit'] as Map<String, dynamic>;
|
||||
final withdrawal = responseJSON['withdrawal'] as Map<String, dynamic>;
|
||||
|
||||
final respId = responseJSON['id'] as String;
|
||||
final from = deposit['symbol'] as String;
|
||||
final to = withdrawal['symbol'] as String;
|
||||
final payoutAddress = withdrawal['address'] as String;
|
||||
final depositAddress = deposit['address'] as String;
|
||||
final refundAddress = responseJSON['refund_address'] as String;
|
||||
final depositAmount = toDouble(deposit['amount']);
|
||||
final receiveAmount = toDouble(withdrawal['amount']);
|
||||
final status = responseJSON['status'] as String;
|
||||
final createdAtString = responseJSON['created_at'] as String;
|
||||
final createdAt = DateTime.parse(createdAtString);
|
||||
|
||||
return Trade(
|
||||
id: respId,
|
||||
from: CryptoCurrency.fromString(from),
|
||||
to: CryptoCurrency.fromString(to),
|
||||
provider: description,
|
||||
inputAddress: depositAddress,
|
||||
payoutAddress: payoutAddress,
|
||||
refundAddress: refundAddress,
|
||||
amount: depositAmount.toString(),
|
||||
receiveAmount: receiveAmount.toString(),
|
||||
state: TradeState.deserialize(raw: status),
|
||||
createdAt: createdAt,
|
||||
isRefund: status == 'refunded',
|
||||
);
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> getEstimatedExchangeAmount(
|
||||
{required CryptoCurrency from,
|
||||
required CryptoCurrency to,
|
||||
required double amount,
|
||||
required bool isFixedRateMode}) async {
|
||||
final headers = {'Authorization': apiKey, 'Content-Type': 'application/json'};
|
||||
|
||||
final body = {
|
||||
'route': {
|
||||
'from': {'symbol': _getName(from), 'network': _getNetwork(from)},
|
||||
'to': {'symbol': _getName(to), 'network': _getNetwork(to)}
|
||||
},
|
||||
'estimation': isFixedRateMode ? 'reversed' : 'direct',
|
||||
'rate': isFixedRateMode ? 'fixed' : 'floating',
|
||||
'amount': amount,
|
||||
'additional_fee_percent': _additionalFeePercent,
|
||||
};
|
||||
|
||||
try {
|
||||
final response = await http.post(Uri.parse(_baseUrl + _amountPath),
|
||||
headers: headers, body: json.encode(body));
|
||||
if (response.statusCode != 200) return {};
|
||||
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
|
||||
final rate = responseJSON['rate'] as Map<String, dynamic>?;
|
||||
return {
|
||||
'estimated_amount': responseJSON['estimated_amount'] as double?,
|
||||
if (rate != null) 'valid_until': rate['valid_until'] as String?,
|
||||
if (rate != null) 'rate_id': rate['id'] as String?
|
||||
};
|
||||
} catch (e) {
|
||||
log(e.toString());
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
double toDouble(dynamic value) {
|
||||
if (value is int) {
|
||||
return value.toDouble();
|
||||
} else if (value is double) {
|
||||
return value;
|
||||
} else {
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
String _getName(CryptoCurrency currency) {
|
||||
if (currency == CryptoCurrency.usdcEPoly) return 'usdce';
|
||||
return currency.title.toLowerCase();
|
||||
}
|
||||
|
||||
String _getNetwork(CryptoCurrency currency) {
|
||||
if (currency.tag == null) return 'mainnet';
|
||||
|
||||
if (currency == CryptoCurrency.maticpoly) return 'mainnet';
|
||||
|
||||
if (currency.tag == 'POLY') return 'matic';
|
||||
|
||||
return currency.tag!.toLowerCase();
|
||||
}
|
||||
}
|
|
@ -40,7 +40,6 @@ class TradeState extends EnumerableItem<String> with Serializable<String> {
|
|||
static const exchanging = TradeState(raw: 'exchanging', title: 'Exchanging');
|
||||
static const sending = TradeState(raw: 'sending', title: 'Sending');
|
||||
static const success = TradeState(raw: 'success', title: 'Success');
|
||||
|
||||
static TradeState deserialize({required String raw}) {
|
||||
|
||||
switch (raw) {
|
||||
|
@ -119,6 +118,7 @@ class TradeState extends EnumerableItem<String> with Serializable<String> {
|
|||
case 'refunded':
|
||||
return refunded;
|
||||
case 'confirmation':
|
||||
case 'verifying':
|
||||
return confirmation;
|
||||
case 'confirmed':
|
||||
return confirmed;
|
||||
|
|
|
@ -16,7 +16,8 @@ abstract class TradeFilterStoreBase with Store {
|
|||
displaySimpleSwap = true,
|
||||
displayTrocador = true,
|
||||
displayExolix = true,
|
||||
displayThorChain = true;
|
||||
displayThorChain = true,
|
||||
displayStealthEx = true;
|
||||
|
||||
@observable
|
||||
bool displayXMRTO;
|
||||
|
@ -42,6 +43,9 @@ abstract class TradeFilterStoreBase with Store {
|
|||
@observable
|
||||
bool displayThorChain;
|
||||
|
||||
@observable
|
||||
bool displayStealthEx;
|
||||
|
||||
@computed
|
||||
bool get displayAllTrades =>
|
||||
displayChangeNow &&
|
||||
|
@ -49,7 +53,8 @@ abstract class TradeFilterStoreBase with Store {
|
|||
displaySimpleSwap &&
|
||||
displayTrocador &&
|
||||
displayExolix &&
|
||||
displayThorChain;
|
||||
displayThorChain &&
|
||||
displayStealthEx;
|
||||
|
||||
@action
|
||||
void toggleDisplayExchange(ExchangeProviderDescription provider) {
|
||||
|
@ -78,6 +83,9 @@ abstract class TradeFilterStoreBase with Store {
|
|||
case ExchangeProviderDescription.thorChain:
|
||||
displayThorChain = !displayThorChain;
|
||||
break;
|
||||
case ExchangeProviderDescription.stealthEx:
|
||||
displayStealthEx = !displayStealthEx;
|
||||
break;
|
||||
case ExchangeProviderDescription.all:
|
||||
if (displayAllTrades) {
|
||||
displayChangeNow = false;
|
||||
|
@ -88,6 +96,7 @@ abstract class TradeFilterStoreBase with Store {
|
|||
displayTrocador = false;
|
||||
displayExolix = false;
|
||||
displayThorChain = false;
|
||||
displayStealthEx = false;
|
||||
} else {
|
||||
displayChangeNow = true;
|
||||
displaySideShift = true;
|
||||
|
@ -97,6 +106,7 @@ abstract class TradeFilterStoreBase with Store {
|
|||
displayTrocador = true;
|
||||
displayExolix = true;
|
||||
displayThorChain = true;
|
||||
displayStealthEx = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -112,13 +122,19 @@ abstract class TradeFilterStoreBase with Store {
|
|||
? _trades
|
||||
.where((item) =>
|
||||
(displayXMRTO && item.trade.provider == ExchangeProviderDescription.xmrto) ||
|
||||
(displaySideShift && item.trade.provider == ExchangeProviderDescription.sideShift) ||
|
||||
(displayChangeNow && item.trade.provider == ExchangeProviderDescription.changeNow) ||
|
||||
(displayMorphToken && item.trade.provider == ExchangeProviderDescription.morphToken) ||
|
||||
(displaySimpleSwap && item.trade.provider == ExchangeProviderDescription.simpleSwap) ||
|
||||
(displaySideShift &&
|
||||
item.trade.provider == ExchangeProviderDescription.sideShift) ||
|
||||
(displayChangeNow &&
|
||||
item.trade.provider == ExchangeProviderDescription.changeNow) ||
|
||||
(displayMorphToken &&
|
||||
item.trade.provider == ExchangeProviderDescription.morphToken) ||
|
||||
(displaySimpleSwap &&
|
||||
item.trade.provider == ExchangeProviderDescription.simpleSwap) ||
|
||||
(displayTrocador && item.trade.provider == ExchangeProviderDescription.trocador) ||
|
||||
(displayExolix && item.trade.provider == ExchangeProviderDescription.exolix) ||
|
||||
(displayThorChain && item.trade.provider == ExchangeProviderDescription.thorChain))
|
||||
(displayThorChain &&
|
||||
item.trade.provider == ExchangeProviderDescription.thorChain) ||
|
||||
(displayStealthEx && item.trade.provider == ExchangeProviderDescription.stealthEx))
|
||||
.toList()
|
||||
: _trades;
|
||||
}
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:cake_wallet/.secrets.g.dart' as secrets;
|
||||
import 'package:cake_wallet/bitcoin/bitcoin.dart';
|
||||
import 'package:cake_wallet/buy/buy_provider.dart';
|
||||
import 'package:cake_wallet/core/key_service.dart';
|
||||
import 'package:cake_wallet/entities/auto_generate_subaddress_status.dart';
|
||||
import 'package:cake_wallet/entities/balance_display_mode.dart';
|
||||
import 'package:cake_wallet/entities/exchange_api_mode.dart';
|
||||
import 'package:cake_wallet/entities/preferences_key.dart';
|
||||
import 'package:cake_wallet/entities/provider_types.dart';
|
||||
import 'package:cake_wallet/entities/exchange_api_mode.dart';
|
||||
import 'package:cake_wallet/entities/service_status.dart';
|
||||
import 'package:cake_wallet/exchange/exchange_provider_description.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
|
@ -45,11 +47,9 @@ import 'package:cw_core/wallet_info.dart';
|
|||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:eth_sig_util/util/utils.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:cake_wallet/bitcoin/bitcoin.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:cake_wallet/.secrets.g.dart' as secrets;
|
||||
|
||||
part 'dashboard_view_model.g.dart';
|
||||
|
||||
|
@ -129,6 +129,11 @@ abstract class DashboardViewModelBase with Store {
|
|||
caption: ExchangeProviderDescription.thorChain.title,
|
||||
onChanged: () =>
|
||||
tradeFilterStore.toggleDisplayExchange(ExchangeProviderDescription.thorChain)),
|
||||
FilterItem(
|
||||
value: () => tradeFilterStore.displayStealthEx,
|
||||
caption: ExchangeProviderDescription.stealthEx.title,
|
||||
onChanged: () =>
|
||||
tradeFilterStore.toggleDisplayExchange(ExchangeProviderDescription.stealthEx)),
|
||||
]
|
||||
},
|
||||
subname = '',
|
||||
|
|
|
@ -7,6 +7,7 @@ import 'package:cake_wallet/exchange/provider/exolix_exchange_provider.dart';
|
|||
import 'package:cake_wallet/exchange/provider/quantex_exchange_provider.dart';
|
||||
import 'package:cake_wallet/exchange/provider/sideshift_exchange_provider.dart';
|
||||
import 'package:cake_wallet/exchange/provider/simpleswap_exchange_provider.dart';
|
||||
import 'package:cake_wallet/exchange/provider/stealth_ex_exchange_provider.dart';
|
||||
import 'package:cake_wallet/exchange/provider/thorchain_exchange.provider.dart';
|
||||
import 'package:cake_wallet/exchange/provider/trocador_exchange_provider.dart';
|
||||
import 'package:cake_wallet/exchange/trade.dart';
|
||||
|
@ -52,6 +53,8 @@ abstract class ExchangeTradeViewModelBase with Store {
|
|||
case ExchangeProviderDescription.quantex:
|
||||
_provider = QuantexExchangeProvider();
|
||||
break;
|
||||
case ExchangeProviderDescription.stealthEx:
|
||||
_provider = StealthExExchangeProvider();
|
||||
case ExchangeProviderDescription.thorChain:
|
||||
_provider = ThorChainExchangeProvider(tradesStore: trades);
|
||||
break;
|
||||
|
|
|
@ -4,6 +4,7 @@ import 'dart:convert';
|
|||
|
||||
import 'package:bitcoin_base/bitcoin_base.dart';
|
||||
import 'package:cake_wallet/core/create_trade_result.dart';
|
||||
import 'package:cake_wallet/exchange/provider/stealth_ex_exchange_provider.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cw_core/sync_status.dart';
|
||||
import 'package:cw_core/transaction_priority.dart';
|
||||
|
@ -160,15 +161,16 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
|
|||
final SharedPreferences sharedPreferences;
|
||||
|
||||
List<ExchangeProvider> get _allProviders => [
|
||||
ChangeNowExchangeProvider(settingsStore: _settingsStore),
|
||||
SideShiftExchangeProvider(),
|
||||
SimpleSwapExchangeProvider(),
|
||||
ThorChainExchangeProvider(tradesStore: trades),
|
||||
if (FeatureFlag.isExolixEnabled) ExolixExchangeProvider(),
|
||||
QuantexExchangeProvider(),
|
||||
TrocadorExchangeProvider(
|
||||
useTorOnly: _useTorOnly, providerStates: _settingsStore.trocadorProviderStates),
|
||||
];
|
||||
ChangeNowExchangeProvider(settingsStore: _settingsStore),
|
||||
SideShiftExchangeProvider(),
|
||||
SimpleSwapExchangeProvider(),
|
||||
ThorChainExchangeProvider(tradesStore: trades),
|
||||
if (FeatureFlag.isExolixEnabled) ExolixExchangeProvider(),
|
||||
QuantexExchangeProvider(),
|
||||
StealthExExchangeProvider(),
|
||||
TrocadorExchangeProvider(
|
||||
useTorOnly: _useTorOnly, providerStates: _settingsStore.trocadorProviderStates),
|
||||
];
|
||||
|
||||
@observable
|
||||
ExchangeProvider? provider;
|
||||
|
|
|
@ -7,6 +7,7 @@ import 'package:cake_wallet/exchange/provider/exolix_exchange_provider.dart';
|
|||
import 'package:cake_wallet/exchange/provider/quantex_exchange_provider.dart';
|
||||
import 'package:cake_wallet/exchange/provider/sideshift_exchange_provider.dart';
|
||||
import 'package:cake_wallet/exchange/provider/simpleswap_exchange_provider.dart';
|
||||
import 'package:cake_wallet/exchange/provider/stealth_ex_exchange_provider.dart';
|
||||
import 'package:cake_wallet/exchange/provider/thorchain_exchange.provider.dart';
|
||||
import 'package:cake_wallet/exchange/provider/trocador_exchange_provider.dart';
|
||||
import 'package:cake_wallet/exchange/trade.dart';
|
||||
|
@ -60,6 +61,9 @@ abstract class TradeDetailsViewModelBase with Store {
|
|||
case ExchangeProviderDescription.quantex:
|
||||
_provider = QuantexExchangeProvider();
|
||||
break;
|
||||
case ExchangeProviderDescription.stealthEx:
|
||||
_provider = StealthExExchangeProvider();
|
||||
break;
|
||||
}
|
||||
|
||||
_updateItems();
|
||||
|
@ -86,6 +90,8 @@ abstract class TradeDetailsViewModelBase with Store {
|
|||
return 'https://track.ninerealms.com/${trade.id}';
|
||||
case ExchangeProviderDescription.quantex:
|
||||
return 'https://myquantex.com/send/${trade.id}';
|
||||
case ExchangeProviderDescription.stealthEx:
|
||||
return 'https://stealthex.io/exchange/?id=${trade.id}';
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -43,6 +43,8 @@ class SecretKey {
|
|||
SecretKey('cakePayApiKey', () => ''),
|
||||
SecretKey('CSRFToken', () => ''),
|
||||
SecretKey('authorization', () => ''),
|
||||
SecretKey('stealthExBearerToken', () => ''),
|
||||
SecretKey('stealthExAdditionalFeePercent', () => ''),
|
||||
];
|
||||
|
||||
static final evmChainsSecrets = [
|
||||
|
|
Loading…
Reference in a new issue