changenow v2 currencies call to access tokenContract param

This commit is contained in:
julian 2023-02-28 14:27:42 -06:00
parent 1d97be9f73
commit 0c11e859aa
17 changed files with 452 additions and 23 deletions

View file

@ -44,11 +44,16 @@ class Currency {
@Index()
final bool isStackCoin;
@ignore
bool get supportsFixedRate => rateType == SupportedRateType.fixed || rateType == SupportedRateType.both;
final String? tokenContract;
@ignore
bool get supportsEstimatedRate => rateType == SupportedRateType.estimated || rateType == SupportedRateType.both;
bool get supportsFixedRate =>
rateType == SupportedRateType.fixed || rateType == SupportedRateType.both;
@ignore
bool get supportsEstimatedRate =>
rateType == SupportedRateType.estimated ||
rateType == SupportedRateType.both;
Currency({
required this.exchangeName,
@ -61,6 +66,7 @@ class Currency {
required this.rateType,
this.isAvailable,
required this.isStackCoin,
required this.tokenContract,
});
factory Currency.fromJson(
@ -83,6 +89,7 @@ class Currency {
isAvailable: json["isAvailable"] as bool?,
isStackCoin:
json["isStackCoin"] as bool? ?? Currency.checkIsStackCoin(ticker),
tokenContract: json["tokenContract"] as String?,
)..id = json["id"] as int?;
} catch (e) {
rethrow;
@ -102,6 +109,7 @@ class Currency {
"rateType": rateType,
"isAvailable": isAvailable,
"isStackCoin": isStackCoin,
"tokenContract": tokenContract,
};
return map;
@ -119,6 +127,7 @@ class Currency {
SupportedRateType? rateType,
bool? isAvailable,
bool? isStackCoin,
String? tokenContract,
}) {
return Currency(
exchangeName: exchangeName ?? this.exchangeName,
@ -131,6 +140,7 @@ class Currency {
rateType: rateType ?? this.rateType,
isAvailable: isAvailable ?? this.isAvailable,
isStackCoin: isStackCoin ?? this.isStackCoin,
tokenContract: tokenContract ?? this.tokenContract,
)..id = id ?? this.id;
}

View file

@ -67,6 +67,11 @@ const CurrencySchema = CollectionSchema(
id: 9,
name: r'ticker',
type: IsarType.string,
),
r'tokenContract': PropertySchema(
id: 10,
name: r'tokenContract',
type: IsarType.string,
)
},
estimateSize: _currencyEstimateSize,
@ -150,6 +155,12 @@ int _currencyEstimateSize(
bytesCount += 3 + object.name.length * 3;
bytesCount += 3 + object.network.length * 3;
bytesCount += 3 + object.ticker.length * 3;
{
final value = object.tokenContract;
if (value != null) {
bytesCount += 3 + value.length * 3;
}
}
return bytesCount;
}
@ -169,6 +180,7 @@ void _currencySerialize(
writer.writeString(offsets[7], object.network);
writer.writeByte(offsets[8], object.rateType.index);
writer.writeString(offsets[9], object.ticker);
writer.writeString(offsets[10], object.tokenContract);
}
Currency _currencyDeserialize(
@ -190,6 +202,7 @@ Currency _currencyDeserialize(
_CurrencyrateTypeValueEnumMap[reader.readByteOrNull(offsets[8])] ??
SupportedRateType.fixed,
ticker: reader.readString(offsets[9]),
tokenContract: reader.readStringOrNull(offsets[10]),
);
object.id = id;
return object;
@ -223,6 +236,8 @@ P _currencyDeserializeProp<P>(
SupportedRateType.fixed) as P;
case 9:
return (reader.readString(offset)) as P;
case 10:
return (reader.readStringOrNull(offset)) as P;
default:
throw IsarError('Unknown property with id $propertyId');
}
@ -1533,6 +1548,158 @@ extension CurrencyQueryFilter
));
});
}
QueryBuilder<Currency, Currency, QAfterFilterCondition>
tokenContractIsNull() {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(const FilterCondition.isNull(
property: r'tokenContract',
));
});
}
QueryBuilder<Currency, Currency, QAfterFilterCondition>
tokenContractIsNotNull() {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(const FilterCondition.isNotNull(
property: r'tokenContract',
));
});
}
QueryBuilder<Currency, Currency, QAfterFilterCondition> tokenContractEqualTo(
String? value, {
bool caseSensitive = true,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.equalTo(
property: r'tokenContract',
value: value,
caseSensitive: caseSensitive,
));
});
}
QueryBuilder<Currency, Currency, QAfterFilterCondition>
tokenContractGreaterThan(
String? value, {
bool include = false,
bool caseSensitive = true,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.greaterThan(
include: include,
property: r'tokenContract',
value: value,
caseSensitive: caseSensitive,
));
});
}
QueryBuilder<Currency, Currency, QAfterFilterCondition> tokenContractLessThan(
String? value, {
bool include = false,
bool caseSensitive = true,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.lessThan(
include: include,
property: r'tokenContract',
value: value,
caseSensitive: caseSensitive,
));
});
}
QueryBuilder<Currency, Currency, QAfterFilterCondition> tokenContractBetween(
String? lower,
String? upper, {
bool includeLower = true,
bool includeUpper = true,
bool caseSensitive = true,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.between(
property: r'tokenContract',
lower: lower,
includeLower: includeLower,
upper: upper,
includeUpper: includeUpper,
caseSensitive: caseSensitive,
));
});
}
QueryBuilder<Currency, Currency, QAfterFilterCondition>
tokenContractStartsWith(
String value, {
bool caseSensitive = true,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.startsWith(
property: r'tokenContract',
value: value,
caseSensitive: caseSensitive,
));
});
}
QueryBuilder<Currency, Currency, QAfterFilterCondition> tokenContractEndsWith(
String value, {
bool caseSensitive = true,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.endsWith(
property: r'tokenContract',
value: value,
caseSensitive: caseSensitive,
));
});
}
QueryBuilder<Currency, Currency, QAfterFilterCondition> tokenContractContains(
String value,
{bool caseSensitive = true}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.contains(
property: r'tokenContract',
value: value,
caseSensitive: caseSensitive,
));
});
}
QueryBuilder<Currency, Currency, QAfterFilterCondition> tokenContractMatches(
String pattern,
{bool caseSensitive = true}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.matches(
property: r'tokenContract',
wildcard: pattern,
caseSensitive: caseSensitive,
));
});
}
QueryBuilder<Currency, Currency, QAfterFilterCondition>
tokenContractIsEmpty() {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.equalTo(
property: r'tokenContract',
value: '',
));
});
}
QueryBuilder<Currency, Currency, QAfterFilterCondition>
tokenContractIsNotEmpty() {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.greaterThan(
property: r'tokenContract',
value: '',
));
});
}
}
extension CurrencyQueryObject
@ -1661,6 +1828,18 @@ extension CurrencyQuerySortBy on QueryBuilder<Currency, Currency, QSortBy> {
return query.addSortBy(r'ticker', Sort.desc);
});
}
QueryBuilder<Currency, Currency, QAfterSortBy> sortByTokenContract() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'tokenContract', Sort.asc);
});
}
QueryBuilder<Currency, Currency, QAfterSortBy> sortByTokenContractDesc() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'tokenContract', Sort.desc);
});
}
}
extension CurrencyQuerySortThenBy
@ -1796,6 +1975,18 @@ extension CurrencyQuerySortThenBy
return query.addSortBy(r'ticker', Sort.desc);
});
}
QueryBuilder<Currency, Currency, QAfterSortBy> thenByTokenContract() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'tokenContract', Sort.asc);
});
}
QueryBuilder<Currency, Currency, QAfterSortBy> thenByTokenContractDesc() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'tokenContract', Sort.desc);
});
}
}
extension CurrencyQueryWhereDistinct
@ -1865,6 +2056,14 @@ extension CurrencyQueryWhereDistinct
return query.addDistinctBy(r'ticker', caseSensitive: caseSensitive);
});
}
QueryBuilder<Currency, Currency, QDistinct> distinctByTokenContract(
{bool caseSensitive = true}) {
return QueryBuilder.apply(this, (query) {
return query.addDistinctBy(r'tokenContract',
caseSensitive: caseSensitive);
});
}
}
extension CurrencyQueryProperty
@ -1935,4 +2134,10 @@ extension CurrencyQueryProperty
return query.addPropertyName(r'ticker');
});
}
QueryBuilder<Currency, String?, QQueryOperations> tokenContractProperty() {
return QueryBuilder.apply(this, (query) {
return query.addPropertyName(r'tokenContract');
});
}
}

View file

@ -260,6 +260,7 @@ const _AddresstypeEnumValueMap = {
'mimbleWimble': 4,
'unknown': 5,
'nonWallet': 6,
'ethereum': 7,
};
const _AddresstypeValueEnumMap = {
0: AddressType.p2pkh,
@ -269,6 +270,7 @@ const _AddresstypeValueEnumMap = {
4: AddressType.mimbleWimble,
5: AddressType.unknown,
6: AddressType.nonWallet,
7: AddressType.ethereum,
};
Id _addressGetId(Address object) {

View file

@ -330,12 +330,14 @@ const _TransactionsubTypeEnumValueMap = {
'bip47Notification': 1,
'mint': 2,
'join': 3,
'ethToken': 4,
};
const _TransactionsubTypeValueEnumMap = {
0: TransactionSubType.none,
1: TransactionSubType.bip47Notification,
2: TransactionSubType.mint,
3: TransactionSubType.join,
4: TransactionSubType.ethToken,
};
const _TransactiontypeEnumValueMap = {
'outgoing': 0,

View file

@ -5,6 +5,7 @@ import 'package:stackwallet/models/ethereum/eth_token.dart';
import 'package:stackwallet/models/isar/exchange_cache/currency.dart';
import 'package:stackwallet/services/exchange/change_now/change_now_exchange.dart';
import 'package:stackwallet/services/exchange/exchange_data_loading_service.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/widgets/custom_buttons/draggable_switch_button.dart';
import 'package:stackwallet/widgets/rounded_white_container.dart';
@ -30,23 +31,16 @@ class _AddTokenListElementState extends State<AddTokenListElement> {
Widget build(BuildContext context) {
final currency = ExchangeDataLoadingService.instance.isar.currencies
.where()
.tickerExchangeNameEqualToAnyName(
"${widget.data.token.symbol}ERC20",
ChangeNowExchange.exchangeName,
)
.or()
.tickerExchangeNameEqualToAnyName(
widget.data.token.symbol,
ChangeNowExchange.exchangeName,
)
.or()
.tickerExchangeNameEqualToAnyName(
"${widget.data.token.symbol}BSC",
ChangeNowExchange.exchangeName,
)
.exchangeNameEqualTo(ChangeNowExchange.exchangeName)
.filter()
.tokenContractEqualTo(
widget.data.token.contractAddress,
caseSensitive: false,
)
.and()
.imageIsNotEmpty()
.findFirstSync();
return RoundedWhiteContainer(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
@ -59,10 +53,12 @@ class _AddTokenListElementState extends State<AddTokenListElement> {
width: 24,
height: 24,
)
: Container(
: SvgPicture.asset(
widget.data.token.symbol == "BNB"
? Assets.svg.bnbIcon
: Assets.svg.ethereum,
width: 24,
height: 24,
color: Colors.red,
),
const SizedBox(
width: 12,

View file

@ -195,6 +195,89 @@ class ChangeNowAPI {
}
}
Future<ExchangeResponse<List<Currency>>> getCurrenciesV2(
// {
// bool? fixedRate,
// bool? active,
// }
) async {
Map<String, dynamic>? params;
// if (active != null || fixedRate != null) {
// params = {};
// if (fixedRate != null) {
// params.addAll({"fixedRate": fixedRate.toString()});
// }
// if (active != null) {
// params.addAll({"active": active.toString()});
// }
// }
final uri = _buildUriV2("/exchange/currencies", params);
try {
// json array is expected here
final jsonArray = await _makeGetRequest(uri);
try {
final result = await compute(
_parseV2CurrenciesJson,
jsonArray as List<dynamic>,
);
return result;
} catch (e, s) {
Logging.instance.log("getAvailableCurrencies exception: $e\n$s",
level: LogLevel.Error);
return ExchangeResponse(
exception: ExchangeException(
"Error: $jsonArray",
ExchangeExceptionType.serializeResponseError,
),
);
}
} catch (e, s) {
Logging.instance.log("getAvailableCurrencies exception: $e\n$s",
level: LogLevel.Error);
return ExchangeResponse(
exception: ExchangeException(
e.toString(),
ExchangeExceptionType.generic,
),
);
}
}
ExchangeResponse<List<Currency>> _parseV2CurrenciesJson(
List<dynamic> args,
) {
try {
List<Currency> currencies = [];
for (final json in args) {
try {
final map = Map<String, dynamic>.from(json as Map);
currencies.add(
Currency.fromJson(
map,
rateType: (map["supportsFixedRate"] as bool)
? SupportedRateType.both
: SupportedRateType.estimated,
exchangeName: ChangeNowExchange.exchangeName,
),
);
} catch (_) {
return ExchangeResponse(
exception: ExchangeException("Failed to serialize $json",
ExchangeExceptionType.serializeResponseError));
}
}
return ExchangeResponse(value: currencies);
} catch (_) {
rethrow;
}
}
/// This API endpoint returns the array of markets available for the specified currency be default.
/// The availability of a particular pair is determined by the 'isAvailable' field.
///

View file

@ -82,10 +82,11 @@ class ChangeNowExchange extends Exchange {
Future<ExchangeResponse<List<Currency>>> getAllCurrencies(
bool fixedRate,
) async {
return await ChangeNowAPI.instance.getAvailableCurrencies(
fixedRate: fixedRate ? true : null,
active: true,
);
return await ChangeNowAPI.instance.getCurrenciesV2();
// return await ChangeNowAPI.instance.getAvailableCurrencies(
// fixedRate: fixedRate ? true : null,
// active: true,
// );
}
@override

View file

@ -131,6 +131,7 @@ class MajesticBankExchange extends Exchange {
rateType: SupportedRateType.both,
isAvailable: true,
isStackCoin: Currency.checkIsStackCoin(limit.currency),
tokenContract: null,
);
currencies.add(currency);
}

View file

@ -67,6 +67,7 @@ class SimpleSwapExchange extends Exchange {
: SupportedRateType.estimated,
isAvailable: true,
isStackCoin: Currency.checkIsStackCoin(e.symbol),
tokenContract: null,
),
)
.toList();

View file

@ -1988,6 +1988,22 @@ class MockBitcoinWallet extends _i1.Mock implements _i26.BitcoinWallet {
returnValue: _i22.Future<_i18.PaymentCode?>.value(),
) as _i22.Future<_i18.PaymentCode?>);
@override
_i22.Future<_i18.PaymentCode?> unBlindedPaymentCodeFromTransactionBad({
required _i16.Transaction? transaction,
required _i16.Address? myNotificationAddress,
}) =>
(super.noSuchMethod(
Invocation.method(
#unBlindedPaymentCodeFromTransactionBad,
[],
{
#transaction: transaction,
#myNotificationAddress: myNotificationAddress,
},
),
returnValue: _i22.Future<_i18.PaymentCode?>.value(),
) as _i22.Future<_i18.PaymentCode?>);
@override
_i22.Future<List<_i18.PaymentCode>>
getAllPaymentCodesFromNotificationTransactions() => (super.noSuchMethod(
Invocation.method(

View file

@ -662,6 +662,23 @@ class MockChangeNowAPI extends _i1.Mock implements _i11.ChangeNowAPI {
)),
) as _i6.Future<_i2.ExchangeResponse<List<_i13.Currency>>>);
@override
_i6.Future<_i2.ExchangeResponse<List<_i13.Currency>>> getCurrenciesV2() =>
(super.noSuchMethod(
Invocation.method(
#getCurrenciesV2,
[],
),
returnValue:
_i6.Future<_i2.ExchangeResponse<List<_i13.Currency>>>.value(
_FakeExchangeResponse_0<List<_i13.Currency>>(
this,
Invocation.method(
#getCurrenciesV2,
[],
),
)),
) as _i6.Future<_i2.ExchangeResponse<List<_i13.Currency>>>);
@override
_i6.Future<_i2.ExchangeResponse<List<_i13.Currency>>> getPairedCurrencies({
required String? ticker,
bool? fixedRate,

View file

@ -1780,6 +1780,22 @@ class MockBitcoinWallet extends _i1.Mock implements _i25.BitcoinWallet {
returnValue: _i22.Future<_i17.PaymentCode?>.value(),
) as _i22.Future<_i17.PaymentCode?>);
@override
_i22.Future<_i17.PaymentCode?> unBlindedPaymentCodeFromTransactionBad({
required _i15.Transaction? transaction,
required _i15.Address? myNotificationAddress,
}) =>
(super.noSuchMethod(
Invocation.method(
#unBlindedPaymentCodeFromTransactionBad,
[],
{
#transaction: transaction,
#myNotificationAddress: myNotificationAddress,
},
),
returnValue: _i22.Future<_i17.PaymentCode?>.value(),
) as _i22.Future<_i17.PaymentCode?>);
@override
_i22.Future<List<_i17.PaymentCode>>
getAllPaymentCodesFromNotificationTransactions() => (super.noSuchMethod(
Invocation.method(

View file

@ -1767,6 +1767,22 @@ class MockBitcoinWallet extends _i1.Mock implements _i24.BitcoinWallet {
returnValue: _i21.Future<_i17.PaymentCode?>.value(),
) as _i21.Future<_i17.PaymentCode?>);
@override
_i21.Future<_i17.PaymentCode?> unBlindedPaymentCodeFromTransactionBad({
required _i15.Transaction? transaction,
required _i15.Address? myNotificationAddress,
}) =>
(super.noSuchMethod(
Invocation.method(
#unBlindedPaymentCodeFromTransactionBad,
[],
{
#transaction: transaction,
#myNotificationAddress: myNotificationAddress,
},
),
returnValue: _i21.Future<_i17.PaymentCode?>.value(),
) as _i21.Future<_i17.PaymentCode?>);
@override
_i21.Future<List<_i17.PaymentCode>>
getAllPaymentCodesFromNotificationTransactions() => (super.noSuchMethod(
Invocation.method(

View file

@ -2454,6 +2454,21 @@ class MockPriceService extends _i1.Mock implements _i26.PriceService {
),
) as _i15.Tuple2<_i14.Decimal, double>);
@override
_i15.Tuple2<_i14.Decimal, double> getTokenPrice(String? contractAddress) =>
(super.noSuchMethod(
Invocation.method(
#getTokenPrice,
[contractAddress],
),
returnValue: _FakeTuple2_13<_i14.Decimal, double>(
this,
Invocation.method(
#getTokenPrice,
[contractAddress],
),
),
) as _i15.Tuple2<_i14.Decimal, double>);
@override
_i18.Future<void> updatePrice() => (super.noSuchMethod(
Invocation.method(
#updatePrice,

View file

@ -1530,6 +1530,22 @@ class MockBitcoinWallet extends _i1.Mock implements _i23.BitcoinWallet {
returnValue: _i20.Future<_i17.PaymentCode?>.value(),
) as _i20.Future<_i17.PaymentCode?>);
@override
_i20.Future<_i17.PaymentCode?> unBlindedPaymentCodeFromTransactionBad({
required _i15.Transaction? transaction,
required _i15.Address? myNotificationAddress,
}) =>
(super.noSuchMethod(
Invocation.method(
#unBlindedPaymentCodeFromTransactionBad,
[],
{
#transaction: transaction,
#myNotificationAddress: myNotificationAddress,
},
),
returnValue: _i20.Future<_i17.PaymentCode?>.value(),
) as _i20.Future<_i17.PaymentCode?>);
@override
_i20.Future<List<_i17.PaymentCode>>
getAllPaymentCodesFromNotificationTransactions() => (super.noSuchMethod(
Invocation.method(

View file

@ -1779,6 +1779,22 @@ class MockBitcoinWallet extends _i1.Mock implements _i25.BitcoinWallet {
returnValue: _i22.Future<_i17.PaymentCode?>.value(),
) as _i22.Future<_i17.PaymentCode?>);
@override
_i22.Future<_i17.PaymentCode?> unBlindedPaymentCodeFromTransactionBad({
required _i15.Transaction? transaction,
required _i15.Address? myNotificationAddress,
}) =>
(super.noSuchMethod(
Invocation.method(
#unBlindedPaymentCodeFromTransactionBad,
[],
{
#transaction: transaction,
#myNotificationAddress: myNotificationAddress,
},
),
returnValue: _i22.Future<_i17.PaymentCode?>.value(),
) as _i22.Future<_i17.PaymentCode?>);
@override
_i22.Future<List<_i17.PaymentCode>>
getAllPaymentCodesFromNotificationTransactions() => (super.noSuchMethod(
Invocation.method(

View file

@ -1779,6 +1779,22 @@ class MockBitcoinWallet extends _i1.Mock implements _i25.BitcoinWallet {
returnValue: _i22.Future<_i17.PaymentCode?>.value(),
) as _i22.Future<_i17.PaymentCode?>);
@override
_i22.Future<_i17.PaymentCode?> unBlindedPaymentCodeFromTransactionBad({
required _i15.Transaction? transaction,
required _i15.Address? myNotificationAddress,
}) =>
(super.noSuchMethod(
Invocation.method(
#unBlindedPaymentCodeFromTransactionBad,
[],
{
#transaction: transaction,
#myNotificationAddress: myNotificationAddress,
},
),
returnValue: _i22.Future<_i17.PaymentCode?>.value(),
) as _i22.Future<_i17.PaymentCode?>);
@override
_i22.Future<List<_i17.PaymentCode>>
getAllPaymentCodesFromNotificationTransactions() => (super.noSuchMethod(
Invocation.method(