mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2024-11-17 09:47:37 +00:00
use database contract data and contract management updates
This commit is contained in:
parent
a5d8fdde79
commit
babbd75da3
23 changed files with 504 additions and 256 deletions
|
@ -358,4 +358,20 @@ class MainDB {
|
||||||
throw MainDBException("failed addNewTransactionData", e);
|
throw MainDBException("failed addNewTransactionData", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ========== Ethereum =======================================================
|
||||||
|
|
||||||
|
// eth contracts
|
||||||
|
|
||||||
|
QueryBuilder<EthContract, EthContract, QWhere> getEthContracts() =>
|
||||||
|
isar.ethContracts.where();
|
||||||
|
|
||||||
|
Future<void> putEthContract(EthContract contract) => isar.writeTxn(() async {
|
||||||
|
await isar.ethContracts.put(contract);
|
||||||
|
});
|
||||||
|
|
||||||
|
Future<void> putEthContracts(List<EthContract> contracts) =>
|
||||||
|
isar.writeTxn(() async {
|
||||||
|
await isar.ethContracts.putAll(contracts);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import 'package:stackwallet/models/add_wallet_list_entity/add_wallet_list_entity.dart';
|
import 'package:stackwallet/models/add_wallet_list_entity/add_wallet_list_entity.dart';
|
||||||
import 'package:stackwallet/models/ethereum/eth_token.dart';
|
import 'package:stackwallet/models/isar/models/ethereum/eth_contract.dart';
|
||||||
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
|
|
||||||
class EthTokenEntity extends AddWalletListEntity {
|
class EthTokenEntity extends AddWalletListEntity {
|
||||||
EthTokenEntity(this.token);
|
EthTokenEntity(this.token);
|
||||||
|
|
||||||
final EthContractInfo token;
|
final EthContract token;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Coin get coin => Coin.ethereum;
|
Coin get coin => Coin.ethereum;
|
||||||
|
@ -17,5 +17,5 @@ class EthTokenEntity extends AddWalletListEntity {
|
||||||
String get ticker => token.symbol;
|
String get ticker => token.symbol;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object?> get props => [coin, name, ticker, token.contractAddress];
|
List<Object?> get props => [coin, name, ticker, token.address];
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
import 'package:stackwallet/models/ethereum/eth_token.dart';
|
|
||||||
|
|
||||||
class Erc20ContractInfo extends EthContractInfo {
|
|
||||||
const Erc20ContractInfo({
|
|
||||||
required super.contractAddress,
|
|
||||||
required super.name,
|
|
||||||
required super.symbol,
|
|
||||||
required super.decimals,
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
import 'package:stackwallet/models/ethereum/eth_token.dart';
|
|
||||||
|
|
||||||
class Erc721ContractInfo extends EthContractInfo {
|
|
||||||
const Erc721ContractInfo({
|
|
||||||
required super.contractAddress,
|
|
||||||
required super.name,
|
|
||||||
required super.symbol,
|
|
||||||
required super.decimals,
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -1,62 +0,0 @@
|
||||||
import 'dart:convert';
|
|
||||||
|
|
||||||
import 'package:equatable/equatable.dart';
|
|
||||||
import 'package:stackwallet/models/ethereum/erc20_token.dart';
|
|
||||||
import 'package:stackwallet/models/ethereum/erc721_token.dart';
|
|
||||||
|
|
||||||
abstract class EthContractInfo extends Equatable {
|
|
||||||
const EthContractInfo({
|
|
||||||
required this.contractAddress,
|
|
||||||
required this.name,
|
|
||||||
required this.symbol,
|
|
||||||
required this.decimals,
|
|
||||||
});
|
|
||||||
|
|
||||||
final String contractAddress;
|
|
||||||
final String name;
|
|
||||||
final String symbol;
|
|
||||||
final int decimals;
|
|
||||||
|
|
||||||
static EthContractInfo? fromMap(Map<String, dynamic> map) {
|
|
||||||
switch (map["runtimeType"]) {
|
|
||||||
case "Erc20ContractInfo":
|
|
||||||
return Erc20ContractInfo(
|
|
||||||
contractAddress: map["contractAddress"] as String,
|
|
||||||
name: map["name"] as String,
|
|
||||||
symbol: map["symbol"] as String,
|
|
||||||
decimals: map["decimals"] as int,
|
|
||||||
);
|
|
||||||
case "Erc721ContractInfo":
|
|
||||||
return Erc721ContractInfo(
|
|
||||||
contractAddress: map["contractAddress"] as String,
|
|
||||||
name: map["name"] as String,
|
|
||||||
symbol: map["symbol"] as String,
|
|
||||||
decimals: map["decimals"] as int,
|
|
||||||
);
|
|
||||||
default:
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static EthContractInfo? fromJson(String json) => fromMap(
|
|
||||||
Map<String, dynamic>.from(
|
|
||||||
jsonDecode(json) as Map,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> toMap() => {
|
|
||||||
"runtimeType": "$runtimeType",
|
|
||||||
"contractAddress": contractAddress,
|
|
||||||
"name": name,
|
|
||||||
"symbol": symbol,
|
|
||||||
"decimals": decimals,
|
|
||||||
};
|
|
||||||
|
|
||||||
String toJson() => jsonEncode(toMap());
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() => toMap().toString();
|
|
||||||
|
|
||||||
@override
|
|
||||||
List<Object?> get props => [contractAddress];
|
|
||||||
}
|
|
|
@ -11,6 +11,7 @@ class EthContract extends Contract {
|
||||||
required this.symbol,
|
required this.symbol,
|
||||||
required this.decimals,
|
required this.decimals,
|
||||||
required this.type,
|
required this.type,
|
||||||
|
required this.walletIds,
|
||||||
this.abi,
|
this.abi,
|
||||||
this.otherData,
|
this.otherData,
|
||||||
});
|
});
|
||||||
|
@ -28,10 +29,34 @@ class EthContract extends Contract {
|
||||||
|
|
||||||
late final String? abi;
|
late final String? abi;
|
||||||
|
|
||||||
|
late final List<String> walletIds;
|
||||||
|
|
||||||
@enumerated
|
@enumerated
|
||||||
late final EthContractType type;
|
late final EthContractType type;
|
||||||
|
|
||||||
late final String? otherData;
|
late final String? otherData;
|
||||||
|
|
||||||
|
EthContract copyWith({
|
||||||
|
Id? id,
|
||||||
|
String? address,
|
||||||
|
String? name,
|
||||||
|
String? symbol,
|
||||||
|
int? decimals,
|
||||||
|
EthContractType? type,
|
||||||
|
List<String>? walletIds,
|
||||||
|
String? abi,
|
||||||
|
String? otherData,
|
||||||
|
}) =>
|
||||||
|
EthContract(
|
||||||
|
address: address ?? this.address,
|
||||||
|
name: name ?? this.name,
|
||||||
|
symbol: symbol ?? this.symbol,
|
||||||
|
decimals: decimals ?? this.decimals,
|
||||||
|
type: type ?? this.type,
|
||||||
|
walletIds: walletIds ?? this.walletIds,
|
||||||
|
abi: abi ?? this.abi,
|
||||||
|
otherData: otherData ?? this.otherData,
|
||||||
|
)..id = id ?? this.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used in Isar db and stored there as int indexes so adding/removing values
|
// Used in Isar db and stored there as int indexes so adding/removing values
|
||||||
|
|
|
@ -52,6 +52,11 @@ const EthContractSchema = CollectionSchema(
|
||||||
name: r'type',
|
name: r'type',
|
||||||
type: IsarType.byte,
|
type: IsarType.byte,
|
||||||
enumMap: _EthContracttypeEnumValueMap,
|
enumMap: _EthContracttypeEnumValueMap,
|
||||||
|
),
|
||||||
|
r'walletIds': PropertySchema(
|
||||||
|
id: 7,
|
||||||
|
name: r'walletIds',
|
||||||
|
type: IsarType.stringList,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
estimateSize: _ethContractEstimateSize,
|
estimateSize: _ethContractEstimateSize,
|
||||||
|
@ -103,6 +108,13 @@ int _ethContractEstimateSize(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bytesCount += 3 + object.symbol.length * 3;
|
bytesCount += 3 + object.symbol.length * 3;
|
||||||
|
bytesCount += 3 + object.walletIds.length * 3;
|
||||||
|
{
|
||||||
|
for (var i = 0; i < object.walletIds.length; i++) {
|
||||||
|
final value = object.walletIds[i];
|
||||||
|
bytesCount += value.length * 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
return bytesCount;
|
return bytesCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,6 +131,7 @@ void _ethContractSerialize(
|
||||||
writer.writeString(offsets[4], object.otherData);
|
writer.writeString(offsets[4], object.otherData);
|
||||||
writer.writeString(offsets[5], object.symbol);
|
writer.writeString(offsets[5], object.symbol);
|
||||||
writer.writeByte(offsets[6], object.type.index);
|
writer.writeByte(offsets[6], object.type.index);
|
||||||
|
writer.writeStringList(offsets[7], object.walletIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
EthContract _ethContractDeserialize(
|
EthContract _ethContractDeserialize(
|
||||||
|
@ -136,6 +149,7 @@ EthContract _ethContractDeserialize(
|
||||||
symbol: reader.readString(offsets[5]),
|
symbol: reader.readString(offsets[5]),
|
||||||
type: _EthContracttypeValueEnumMap[reader.readByteOrNull(offsets[6])] ??
|
type: _EthContracttypeValueEnumMap[reader.readByteOrNull(offsets[6])] ??
|
||||||
EthContractType.erc20,
|
EthContractType.erc20,
|
||||||
|
walletIds: reader.readStringList(offsets[7]) ?? [],
|
||||||
);
|
);
|
||||||
object.id = id;
|
object.id = id;
|
||||||
return object;
|
return object;
|
||||||
|
@ -163,6 +177,8 @@ P _ethContractDeserializeProp<P>(
|
||||||
case 6:
|
case 6:
|
||||||
return (_EthContracttypeValueEnumMap[reader.readByteOrNull(offset)] ??
|
return (_EthContracttypeValueEnumMap[reader.readByteOrNull(offset)] ??
|
||||||
EthContractType.erc20) as P;
|
EthContractType.erc20) as P;
|
||||||
|
case 7:
|
||||||
|
return (reader.readStringList(offset) ?? []) as P;
|
||||||
default:
|
default:
|
||||||
throw IsarError('Unknown property with id $propertyId');
|
throw IsarError('Unknown property with id $propertyId');
|
||||||
}
|
}
|
||||||
|
@ -1230,6 +1246,231 @@ extension EthContractQueryFilter
|
||||||
));
|
));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EthContract, EthContract, QAfterFilterCondition>
|
||||||
|
walletIdsElementEqualTo(
|
||||||
|
String value, {
|
||||||
|
bool caseSensitive = true,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.equalTo(
|
||||||
|
property: r'walletIds',
|
||||||
|
value: value,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EthContract, EthContract, QAfterFilterCondition>
|
||||||
|
walletIdsElementGreaterThan(
|
||||||
|
String value, {
|
||||||
|
bool include = false,
|
||||||
|
bool caseSensitive = true,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.greaterThan(
|
||||||
|
include: include,
|
||||||
|
property: r'walletIds',
|
||||||
|
value: value,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EthContract, EthContract, QAfterFilterCondition>
|
||||||
|
walletIdsElementLessThan(
|
||||||
|
String value, {
|
||||||
|
bool include = false,
|
||||||
|
bool caseSensitive = true,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.lessThan(
|
||||||
|
include: include,
|
||||||
|
property: r'walletIds',
|
||||||
|
value: value,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EthContract, EthContract, QAfterFilterCondition>
|
||||||
|
walletIdsElementBetween(
|
||||||
|
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'walletIds',
|
||||||
|
lower: lower,
|
||||||
|
includeLower: includeLower,
|
||||||
|
upper: upper,
|
||||||
|
includeUpper: includeUpper,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EthContract, EthContract, QAfterFilterCondition>
|
||||||
|
walletIdsElementStartsWith(
|
||||||
|
String value, {
|
||||||
|
bool caseSensitive = true,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.startsWith(
|
||||||
|
property: r'walletIds',
|
||||||
|
value: value,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EthContract, EthContract, QAfterFilterCondition>
|
||||||
|
walletIdsElementEndsWith(
|
||||||
|
String value, {
|
||||||
|
bool caseSensitive = true,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.endsWith(
|
||||||
|
property: r'walletIds',
|
||||||
|
value: value,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EthContract, EthContract, QAfterFilterCondition>
|
||||||
|
walletIdsElementContains(String value, {bool caseSensitive = true}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.contains(
|
||||||
|
property: r'walletIds',
|
||||||
|
value: value,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EthContract, EthContract, QAfterFilterCondition>
|
||||||
|
walletIdsElementMatches(String pattern, {bool caseSensitive = true}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.matches(
|
||||||
|
property: r'walletIds',
|
||||||
|
wildcard: pattern,
|
||||||
|
caseSensitive: caseSensitive,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EthContract, EthContract, QAfterFilterCondition>
|
||||||
|
walletIdsElementIsEmpty() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.equalTo(
|
||||||
|
property: r'walletIds',
|
||||||
|
value: '',
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EthContract, EthContract, QAfterFilterCondition>
|
||||||
|
walletIdsElementIsNotEmpty() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.greaterThan(
|
||||||
|
property: r'walletIds',
|
||||||
|
value: '',
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EthContract, EthContract, QAfterFilterCondition>
|
||||||
|
walletIdsLengthEqualTo(int length) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.listLength(
|
||||||
|
r'walletIds',
|
||||||
|
length,
|
||||||
|
true,
|
||||||
|
length,
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EthContract, EthContract, QAfterFilterCondition>
|
||||||
|
walletIdsIsEmpty() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.listLength(
|
||||||
|
r'walletIds',
|
||||||
|
0,
|
||||||
|
true,
|
||||||
|
0,
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EthContract, EthContract, QAfterFilterCondition>
|
||||||
|
walletIdsIsNotEmpty() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.listLength(
|
||||||
|
r'walletIds',
|
||||||
|
0,
|
||||||
|
false,
|
||||||
|
999999,
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EthContract, EthContract, QAfterFilterCondition>
|
||||||
|
walletIdsLengthLessThan(
|
||||||
|
int length, {
|
||||||
|
bool include = false,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.listLength(
|
||||||
|
r'walletIds',
|
||||||
|
0,
|
||||||
|
true,
|
||||||
|
length,
|
||||||
|
include,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EthContract, EthContract, QAfterFilterCondition>
|
||||||
|
walletIdsLengthGreaterThan(
|
||||||
|
int length, {
|
||||||
|
bool include = false,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.listLength(
|
||||||
|
r'walletIds',
|
||||||
|
length,
|
||||||
|
include,
|
||||||
|
999999,
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EthContract, EthContract, QAfterFilterCondition>
|
||||||
|
walletIdsLengthBetween(
|
||||||
|
int lower,
|
||||||
|
int upper, {
|
||||||
|
bool includeLower = true,
|
||||||
|
bool includeUpper = true,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.listLength(
|
||||||
|
r'walletIds',
|
||||||
|
lower,
|
||||||
|
includeLower,
|
||||||
|
upper,
|
||||||
|
includeUpper,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension EthContractQueryObject
|
extension EthContractQueryObject
|
||||||
|
@ -1472,6 +1713,12 @@ extension EthContractQueryWhereDistinct
|
||||||
return query.addDistinctBy(r'type');
|
return query.addDistinctBy(r'type');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EthContract, EthContract, QDistinct> distinctByWalletIds() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addDistinctBy(r'walletIds');
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension EthContractQueryProperty
|
extension EthContractQueryProperty
|
||||||
|
@ -1523,4 +1770,11 @@ extension EthContractQueryProperty
|
||||||
return query.addPropertyName(r'type');
|
return query.addPropertyName(r'type');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QueryBuilder<EthContract, List<String>, QQueryOperations>
|
||||||
|
walletIdsProperty() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addPropertyName(r'walletIds');
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ import 'dart:async';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:stackwallet/models/ethereum/eth_token.dart';
|
import 'package:stackwallet/models/isar/models/ethereum/eth_contract.dart';
|
||||||
import 'package:stackwallet/services/ethereum/ethereum_api.dart';
|
import 'package:stackwallet/services/ethereum/ethereum_api.dart';
|
||||||
import 'package:stackwallet/utilities/show_loading.dart';
|
import 'package:stackwallet/utilities/show_loading.dart';
|
||||||
import 'package:stackwallet/utilities/text_styles.dart';
|
import 'package:stackwallet/utilities/text_styles.dart';
|
||||||
|
@ -39,7 +39,7 @@ class _AddCustomTokenViewState extends ConsumerState<AddCustomTokenView> {
|
||||||
bool enableSubFields = false;
|
bool enableSubFields = false;
|
||||||
bool addTokenButtonEnabled = false;
|
bool addTokenButtonEnabled = false;
|
||||||
|
|
||||||
EthContractInfo? currentToken;
|
EthContract? currentToken;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
@ -96,6 +96,7 @@ class _AddCustomTokenViewState extends ConsumerState<AddCustomTokenView> {
|
||||||
nameController.text = currentToken!.name;
|
nameController.text = currentToken!.name;
|
||||||
symbolController.text = currentToken!.symbol;
|
symbolController.text = currentToken!.symbol;
|
||||||
decimalsController.text = currentToken!.decimals.toString();
|
decimalsController.text = currentToken!.decimals.toString();
|
||||||
|
currentToken!.walletIds.add(widget.walletId);
|
||||||
} else {
|
} else {
|
||||||
nameController.text = "";
|
nameController.text = "";
|
||||||
symbolController.text = "";
|
symbolController.text = "";
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
import 'package:stackwallet/models/ethereum/eth_token.dart';
|
import 'package:isar/isar.dart';
|
||||||
|
import 'package:stackwallet/db/isar/main_db.dart';
|
||||||
|
import 'package:stackwallet/models/isar/models/ethereum/eth_contract.dart';
|
||||||
import 'package:stackwallet/pages/add_wallet_views/add_token_view/add_custom_token_view.dart';
|
import 'package:stackwallet/pages/add_wallet_views/add_token_view/add_custom_token_view.dart';
|
||||||
import 'package:stackwallet/pages/add_wallet_views/add_token_view/sub_widgets/add_token_list.dart';
|
import 'package:stackwallet/pages/add_wallet_views/add_token_view/sub_widgets/add_token_list.dart';
|
||||||
import 'package:stackwallet/pages/add_wallet_views/add_token_view/sub_widgets/add_token_list_element.dart';
|
import 'package:stackwallet/pages/add_wallet_views/add_token_view/sub_widgets/add_token_list_element.dart';
|
||||||
|
@ -60,7 +62,7 @@ class _AddTokenViewState extends ConsumerState<AddTokenView> {
|
||||||
(e) =>
|
(e) =>
|
||||||
e.token.name.toLowerCase().contains(lowercaseTerm) ||
|
e.token.name.toLowerCase().contains(lowercaseTerm) ||
|
||||||
e.token.symbol.toLowerCase().contains(lowercaseTerm) ||
|
e.token.symbol.toLowerCase().contains(lowercaseTerm) ||
|
||||||
e.token.contractAddress.toLowerCase().contains(lowercaseTerm),
|
e.token.address.toLowerCase().contains(lowercaseTerm),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,16 +71,16 @@ class _AddTokenViewState extends ConsumerState<AddTokenView> {
|
||||||
|
|
||||||
Future<void> onNextPressed() async {
|
Future<void> onNextPressed() async {
|
||||||
final selectedTokens =
|
final selectedTokens =
|
||||||
tokenEntities.where((e) => e.selected).map((e) => e.token).toSet();
|
tokenEntities.where((e) => e.selected).map((e) => e.token).toList();
|
||||||
|
|
||||||
final ethWallet = ref
|
final ethWallet = ref
|
||||||
.read(walletsChangeNotifierProvider)
|
.read(walletsChangeNotifierProvider)
|
||||||
.getManager(widget.walletId)
|
.getManager(widget.walletId)
|
||||||
.wallet as EthereumWallet;
|
.wallet as EthereumWallet;
|
||||||
|
|
||||||
await ethWallet.addTokenContract(selectedTokens);
|
await ethWallet.addTokenContracts(selectedTokens);
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop(42);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,15 +89,18 @@ class _AddTokenViewState extends ConsumerState<AddTokenView> {
|
||||||
AddCustomTokenView.routeName,
|
AddCustomTokenView.routeName,
|
||||||
arguments: widget.walletId,
|
arguments: widget.walletId,
|
||||||
);
|
);
|
||||||
if (token is EthContractInfo) {
|
if (token is EthContract) {
|
||||||
setState(() {
|
await MainDB.instance.putEthContract(token);
|
||||||
if (tokenEntities
|
if (mounted) {
|
||||||
.where((e) => e.token.contractAddress == token.contractAddress)
|
setState(() {
|
||||||
.isEmpty) {
|
if (tokenEntities
|
||||||
tokenEntities.add(AddTokenListElementData(token)..selected = true);
|
.where((e) => e.token.address == token.address)
|
||||||
tokenEntities.sort((a, b) => a.token.name.compareTo(b.token.name));
|
.isEmpty) {
|
||||||
}
|
tokenEntities.add(AddTokenListElementData(token)..selected = true);
|
||||||
});
|
tokenEntities.sort((a, b) => a.token.name.compareTo(b.token.name));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,9 +109,15 @@ class _AddTokenViewState extends ConsumerState<AddTokenView> {
|
||||||
_searchFieldController = TextEditingController();
|
_searchFieldController = TextEditingController();
|
||||||
_searchFocusNode = FocusNode();
|
_searchFocusNode = FocusNode();
|
||||||
|
|
||||||
tokenEntities
|
final contracts =
|
||||||
.addAll(DefaultTokens.list.map((e) => AddTokenListElementData(e)));
|
MainDB.instance.getEthContracts().sortByName().findAllSync();
|
||||||
tokenEntities.sort((a, b) => a.token.name.compareTo(b.token.name));
|
|
||||||
|
if (contracts.isEmpty) {
|
||||||
|
contracts.addAll(DefaultTokens.list);
|
||||||
|
MainDB.instance.putEthContracts(contracts);
|
||||||
|
}
|
||||||
|
|
||||||
|
tokenEntities.addAll(contracts.map((e) => AddTokenListElementData(e)));
|
||||||
|
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
import 'package:isar/isar.dart';
|
import 'package:isar/isar.dart';
|
||||||
import 'package:stackwallet/models/ethereum/eth_token.dart';
|
|
||||||
import 'package:stackwallet/models/isar/exchange_cache/currency.dart';
|
import 'package:stackwallet/models/isar/exchange_cache/currency.dart';
|
||||||
|
import 'package:stackwallet/models/isar/models/ethereum/eth_contract.dart';
|
||||||
import 'package:stackwallet/services/exchange/change_now/change_now_exchange.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/services/exchange/exchange_data_loading_service.dart';
|
||||||
import 'package:stackwallet/utilities/assets.dart';
|
import 'package:stackwallet/utilities/assets.dart';
|
||||||
|
@ -13,7 +13,7 @@ import 'package:stackwallet/widgets/rounded_white_container.dart';
|
||||||
class AddTokenListElementData {
|
class AddTokenListElementData {
|
||||||
AddTokenListElementData(this.token);
|
AddTokenListElementData(this.token);
|
||||||
|
|
||||||
final EthContractInfo token;
|
final EthContract token;
|
||||||
bool selected = false;
|
bool selected = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ class _AddTokenListElementState extends State<AddTokenListElement> {
|
||||||
.exchangeNameEqualTo(ChangeNowExchange.exchangeName)
|
.exchangeNameEqualTo(ChangeNowExchange.exchangeName)
|
||||||
.filter()
|
.filter()
|
||||||
.tokenContractEqualTo(
|
.tokenContractEqualTo(
|
||||||
widget.data.token.contractAddress,
|
widget.data.token.address,
|
||||||
caseSensitive: false,
|
caseSensitive: false,
|
||||||
)
|
)
|
||||||
.and()
|
.and()
|
||||||
|
|
|
@ -3,9 +3,12 @@ import 'dart:io';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
|
import 'package:isar/isar.dart';
|
||||||
|
import 'package:stackwallet/db/isar/main_db.dart';
|
||||||
import 'package:stackwallet/models/add_wallet_list_entity/add_wallet_list_entity.dart';
|
import 'package:stackwallet/models/add_wallet_list_entity/add_wallet_list_entity.dart';
|
||||||
import 'package:stackwallet/models/add_wallet_list_entity/sub_classes/coin_entity.dart';
|
import 'package:stackwallet/models/add_wallet_list_entity/sub_classes/coin_entity.dart';
|
||||||
import 'package:stackwallet/models/add_wallet_list_entity/sub_classes/eth_token_entity.dart';
|
import 'package:stackwallet/models/add_wallet_list_entity/sub_classes/eth_token_entity.dart';
|
||||||
|
import 'package:stackwallet/models/isar/models/ethereum/eth_contract.dart';
|
||||||
import 'package:stackwallet/pages/add_wallet_views/add_wallet_view/sub_widgets/add_wallet_text.dart';
|
import 'package:stackwallet/pages/add_wallet_views/add_wallet_view/sub_widgets/add_wallet_text.dart';
|
||||||
import 'package:stackwallet/pages/add_wallet_views/add_wallet_view/sub_widgets/expanding_sub_list_item.dart';
|
import 'package:stackwallet/pages/add_wallet_views/add_wallet_view/sub_widgets/expanding_sub_list_item.dart';
|
||||||
import 'package:stackwallet/pages/add_wallet_views/add_wallet_view/sub_widgets/next_button.dart';
|
import 'package:stackwallet/pages/add_wallet_views/add_wallet_view/sub_widgets/next_button.dart';
|
||||||
|
@ -67,7 +70,7 @@ class _AddWalletViewState extends ConsumerState<AddWalletView> {
|
||||||
e.name.toLowerCase().contains(lowercaseTerm) ||
|
e.name.toLowerCase().contains(lowercaseTerm) ||
|
||||||
e.coin.name.toLowerCase().contains(lowercaseTerm) ||
|
e.coin.name.toLowerCase().contains(lowercaseTerm) ||
|
||||||
(e is EthTokenEntity &&
|
(e is EthTokenEntity &&
|
||||||
e.token.contractAddress.toLowerCase().contains(lowercaseTerm)),
|
e.token.address.toLowerCase().contains(lowercaseTerm)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,8 +95,15 @@ class _AddWalletViewState extends ConsumerState<AddWalletView> {
|
||||||
coinEntities.addAll(_coinsTestnet.map((e) => CoinEntity(e)));
|
coinEntities.addAll(_coinsTestnet.map((e) => CoinEntity(e)));
|
||||||
}
|
}
|
||||||
|
|
||||||
tokenEntities.addAll(DefaultTokens.list.map((e) => EthTokenEntity(e)));
|
final contracts =
|
||||||
tokenEntities.sort((a, b) => a.name.compareTo(b.name));
|
MainDB.instance.getEthContracts().sortByName().findAllSync();
|
||||||
|
|
||||||
|
if (contracts.isEmpty) {
|
||||||
|
contracts.addAll(DefaultTokens.list);
|
||||||
|
MainDB.instance.putEthContracts(contracts);
|
||||||
|
}
|
||||||
|
|
||||||
|
tokenEntities.addAll(contracts.map((e) => EthTokenEntity(e)));
|
||||||
|
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:stackwallet/models/ethereum/eth_token.dart';
|
|
||||||
import 'package:stackwallet/notifications/show_flush_bar.dart';
|
import 'package:stackwallet/notifications/show_flush_bar.dart';
|
||||||
import 'package:stackwallet/providers/global/debug_service_provider.dart';
|
import 'package:stackwallet/providers/global/debug_service_provider.dart';
|
||||||
import 'package:stackwallet/providers/providers.dart';
|
import 'package:stackwallet/providers/providers.dart';
|
||||||
|
@ -13,8 +12,6 @@ import 'package:stackwallet/utilities/theme/stack_colors.dart';
|
||||||
import 'package:stackwallet/widgets/background.dart';
|
import 'package:stackwallet/widgets/background.dart';
|
||||||
import 'package:stackwallet/widgets/rounded_white_container.dart';
|
import 'package:stackwallet/widgets/rounded_white_container.dart';
|
||||||
|
|
||||||
import '../../../models/ethereum/erc20_token.dart';
|
|
||||||
|
|
||||||
class HiddenSettings extends StatelessWidget {
|
class HiddenSettings extends StatelessWidget {
|
||||||
const HiddenSettings({Key? key}) : super(key: key);
|
const HiddenSettings({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@ -192,20 +189,20 @@ class HiddenSettings extends StatelessWidget {
|
||||||
Consumer(builder: (_, ref, __) {
|
Consumer(builder: (_, ref, __) {
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
final erc20 = Erc20ContractInfo(
|
// final erc20 = Erc20ContractInfo(
|
||||||
contractAddress: 'some con',
|
// contractAddress: 'some con',
|
||||||
name: "loonamsn",
|
// name: "loonamsn",
|
||||||
symbol: "DD",
|
// symbol: "DD",
|
||||||
decimals: 19,
|
// decimals: 19,
|
||||||
);
|
// );
|
||||||
|
//
|
||||||
final json = erc20.toJson();
|
// final json = erc20.toJson();
|
||||||
|
//
|
||||||
print(json);
|
// print(json);
|
||||||
|
//
|
||||||
final ee = EthContractInfo.fromJson(json);
|
// final ee = EthContractInfo.fromJson(json);
|
||||||
|
//
|
||||||
print(ee);
|
// print(ee);
|
||||||
},
|
},
|
||||||
child: RoundedWhiteContainer(
|
child: RoundedWhiteContainer(
|
||||||
child: Text(
|
child: Text(
|
||||||
|
|
|
@ -3,11 +3,12 @@ import 'dart:async';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
import 'package:stackwallet/models/ethereum/eth_token.dart';
|
import 'package:isar/isar.dart';
|
||||||
|
import 'package:stackwallet/db/isar/main_db.dart';
|
||||||
|
import 'package:stackwallet/models/isar/models/ethereum/eth_contract.dart';
|
||||||
import 'package:stackwallet/pages/add_wallet_views/add_token_view/add_token_view.dart';
|
import 'package:stackwallet/pages/add_wallet_views/add_token_view/add_token_view.dart';
|
||||||
import 'package:stackwallet/pages/token_view/sub_widgets/my_tokens_list.dart';
|
import 'package:stackwallet/pages/token_view/sub_widgets/my_tokens_list.dart';
|
||||||
import 'package:stackwallet/providers/global/wallets_provider.dart';
|
import 'package:stackwallet/providers/global/wallets_provider.dart';
|
||||||
import 'package:stackwallet/services/coins/ethereum/ethereum_wallet.dart';
|
|
||||||
import 'package:stackwallet/utilities/assets.dart';
|
import 'package:stackwallet/utilities/assets.dart';
|
||||||
import 'package:stackwallet/utilities/constants.dart';
|
import 'package:stackwallet/utilities/constants.dart';
|
||||||
import 'package:stackwallet/utilities/text_styles.dart';
|
import 'package:stackwallet/utilities/text_styles.dart';
|
||||||
|
@ -38,6 +39,34 @@ class _TokenDetailsViewState extends ConsumerState<MyTokensView> {
|
||||||
late final String walletAddress;
|
late final String walletAddress;
|
||||||
late final TextEditingController _searchController;
|
late final TextEditingController _searchController;
|
||||||
final searchFieldFocusNode = FocusNode();
|
final searchFieldFocusNode = FocusNode();
|
||||||
|
String _searchString = "";
|
||||||
|
|
||||||
|
List<EthContract> _filter(String searchTerm) {
|
||||||
|
if (searchTerm.isNotEmpty) {
|
||||||
|
final term = searchTerm.toLowerCase();
|
||||||
|
return MainDB.instance
|
||||||
|
.getEthContracts()
|
||||||
|
.filter()
|
||||||
|
.walletIdsElementEqualTo(widget.walletId)
|
||||||
|
.and()
|
||||||
|
.group(
|
||||||
|
(q) => q
|
||||||
|
.nameContains(term, caseSensitive: false)
|
||||||
|
.or()
|
||||||
|
.symbolContains(term, caseSensitive: false)
|
||||||
|
.or()
|
||||||
|
.addressContains(term, caseSensitive: false),
|
||||||
|
)
|
||||||
|
.findAllSync();
|
||||||
|
// return tokens.toList();
|
||||||
|
}
|
||||||
|
//implement search/filter
|
||||||
|
return MainDB.instance
|
||||||
|
.getEthContracts()
|
||||||
|
.filter()
|
||||||
|
.walletIdsElementEqualTo(widget.walletId)
|
||||||
|
.findAllSync();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
|
@ -53,26 +82,10 @@ class _TokenDetailsViewState extends ConsumerState<MyTokensView> {
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
String _searchString = "";
|
|
||||||
|
|
||||||
List<EthContractInfo> _filter(
|
|
||||||
Set<EthContractInfo> tokens, String searchTerm) {
|
|
||||||
if (searchTerm.isEmpty) {
|
|
||||||
return tokens.toList();
|
|
||||||
}
|
|
||||||
//implement search/filter
|
|
||||||
return tokens.toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final isDesktop = Util.isDesktop;
|
final isDesktop = Util.isDesktop;
|
||||||
|
|
||||||
final tokens = (ref.watch(walletsChangeNotifierProvider
|
|
||||||
.select((value) => value.getManager(widget.walletId).wallet))
|
|
||||||
as EthereumWallet)
|
|
||||||
.contracts;
|
|
||||||
|
|
||||||
return MasterScaffold(
|
return MasterScaffold(
|
||||||
background: Theme.of(context).extension<StackColors>()!.background,
|
background: Theme.of(context).extension<StackColors>()!.background,
|
||||||
isDesktop: isDesktop,
|
isDesktop: isDesktop,
|
||||||
|
@ -160,11 +173,15 @@ class _TokenDetailsViewState extends ConsumerState<MyTokensView> {
|
||||||
width: 20,
|
width: 20,
|
||||||
height: 20,
|
height: 20,
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () async {
|
||||||
Navigator.of(context).pushNamed(
|
final result = await Navigator.of(context).pushNamed(
|
||||||
AddTokenView.routeName,
|
AddTokenView.routeName,
|
||||||
arguments: widget.walletId,
|
arguments: widget.walletId,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (mounted && result == 42) {
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -273,7 +290,7 @@ class _TokenDetailsViewState extends ConsumerState<MyTokensView> {
|
||||||
Expanded(
|
Expanded(
|
||||||
child: MyTokensList(
|
child: MyTokensList(
|
||||||
walletId: widget.walletId,
|
walletId: widget.walletId,
|
||||||
tokens: _filter(tokens, _searchString),
|
tokens: _filter(_searchString),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
import 'package:stackwallet/models/ethereum/eth_token.dart';
|
import 'package:stackwallet/models/isar/models/ethereum/eth_contract.dart';
|
||||||
import 'package:stackwallet/pages/token_view/token_view.dart';
|
import 'package:stackwallet/pages/token_view/token_view.dart';
|
||||||
import 'package:stackwallet/providers/global/secure_store_provider.dart';
|
import 'package:stackwallet/providers/global/secure_store_provider.dart';
|
||||||
import 'package:stackwallet/providers/providers.dart';
|
import 'package:stackwallet/providers/providers.dart';
|
||||||
|
@ -24,7 +24,7 @@ class MyTokenSelectItem extends ConsumerStatefulWidget {
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
final String walletId;
|
final String walletId;
|
||||||
final EthContractInfo token;
|
final EthContract token;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
ConsumerState<MyTokenSelectItem> createState() => _MyTokenSelectItemState();
|
ConsumerState<MyTokenSelectItem> createState() => _MyTokenSelectItemState();
|
||||||
|
@ -133,7 +133,7 @@ class _MyTokenSelectItemState extends ConsumerState<MyTokenSelectItem> {
|
||||||
Text("${ref.watch(
|
Text("${ref.watch(
|
||||||
priceAnd24hChangeNotifierProvider.select(
|
priceAnd24hChangeNotifierProvider.select(
|
||||||
(value) => value
|
(value) => value
|
||||||
.getTokenPrice(widget.token.contractAddress)
|
.getTokenPrice(widget.token.address)
|
||||||
.item1
|
.item1
|
||||||
.toStringAsFixed(2),
|
.toStringAsFixed(2),
|
||||||
),
|
),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:stackwallet/models/ethereum/eth_token.dart';
|
import 'package:stackwallet/models/isar/models/ethereum/eth_contract.dart';
|
||||||
import 'package:stackwallet/pages/token_view/sub_widgets/my_token_select_item.dart';
|
import 'package:stackwallet/pages/token_view/sub_widgets/my_token_select_item.dart';
|
||||||
|
|
||||||
class MyTokensList extends StatelessWidget {
|
class MyTokensList extends StatelessWidget {
|
||||||
|
@ -11,7 +11,7 @@ class MyTokensList extends StatelessWidget {
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
final String walletId;
|
final String walletId;
|
||||||
final List<EthContractInfo> tokens;
|
final List<EthContract> tokens;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
@ -22,7 +22,7 @@ class MyTokensList extends StatelessWidget {
|
||||||
itemBuilder: (ctx, index) {
|
itemBuilder: (ctx, index) {
|
||||||
final token = tokens[index];
|
final token = tokens[index];
|
||||||
return Padding(
|
return Padding(
|
||||||
key: Key(token.contractAddress),
|
key: Key(token.address),
|
||||||
padding: const EdgeInsets.all(4),
|
padding: const EdgeInsets.all(4),
|
||||||
child: MyTokenSelectItem(
|
child: MyTokenSelectItem(
|
||||||
walletId: walletId,
|
walletId: walletId,
|
||||||
|
|
|
@ -78,7 +78,7 @@ class _TokenViewState extends ConsumerState<TokenView> {
|
||||||
SvgPicture.asset(
|
SvgPicture.asset(
|
||||||
Assets.svg.iconForToken(
|
Assets.svg.iconForToken(
|
||||||
contractAddress: ref.watch(tokenServiceProvider
|
contractAddress: ref.watch(tokenServiceProvider
|
||||||
.select((value) => value!.token.contractAddress))),
|
.select((value) => value!.token.address))),
|
||||||
width: 24,
|
width: 24,
|
||||||
height: 24,
|
height: 24,
|
||||||
),
|
),
|
||||||
|
@ -118,7 +118,7 @@ class _TokenViewState extends ConsumerState<TokenView> {
|
||||||
walletId: widget.walletId,
|
walletId: widget.walletId,
|
||||||
initialSyncStatus: initialSyncStatus,
|
initialSyncStatus: initialSyncStatus,
|
||||||
tokenContractAddress: ref.watch(tokenServiceProvider
|
tokenContractAddress: ref.watch(tokenServiceProvider
|
||||||
.select((value) => value!.token.contractAddress)),
|
.select((value) => value!.token.address)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -7,7 +7,6 @@ import 'package:http/http.dart';
|
||||||
import 'package:isar/isar.dart';
|
import 'package:isar/isar.dart';
|
||||||
import 'package:stackwallet/db/isar/main_db.dart';
|
import 'package:stackwallet/db/isar/main_db.dart';
|
||||||
import 'package:stackwallet/models/balance.dart';
|
import 'package:stackwallet/models/balance.dart';
|
||||||
import 'package:stackwallet/models/ethereum/eth_token.dart';
|
|
||||||
import 'package:stackwallet/models/isar/models/isar_models.dart';
|
import 'package:stackwallet/models/isar/models/isar_models.dart';
|
||||||
import 'package:stackwallet/models/node_model.dart';
|
import 'package:stackwallet/models/node_model.dart';
|
||||||
import 'package:stackwallet/models/paymint/fee_object_model.dart';
|
import 'package:stackwallet/models/paymint/fee_object_model.dart';
|
||||||
|
@ -18,7 +17,6 @@ import 'package:stackwallet/services/event_bus/events/global/refresh_percent_cha
|
||||||
import 'package:stackwallet/services/event_bus/events/global/updated_in_background_event.dart';
|
import 'package:stackwallet/services/event_bus/events/global/updated_in_background_event.dart';
|
||||||
import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart';
|
import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart';
|
||||||
import 'package:stackwallet/services/event_bus/global_event_bus.dart';
|
import 'package:stackwallet/services/event_bus/global_event_bus.dart';
|
||||||
import 'package:stackwallet/services/mixins/eth_extras_wallet_cache.dart';
|
|
||||||
import 'package:stackwallet/services/mixins/wallet_cache.dart';
|
import 'package:stackwallet/services/mixins/wallet_cache.dart';
|
||||||
import 'package:stackwallet/services/mixins/wallet_db.dart';
|
import 'package:stackwallet/services/mixins/wallet_db.dart';
|
||||||
import 'package:stackwallet/services/node_service.dart';
|
import 'package:stackwallet/services/node_service.dart';
|
||||||
|
@ -39,8 +37,7 @@ import 'package:web3dart/web3dart.dart' as web3;
|
||||||
|
|
||||||
const int MINIMUM_CONFIRMATIONS = 3;
|
const int MINIMUM_CONFIRMATIONS = 3;
|
||||||
|
|
||||||
class EthereumWallet extends CoinServiceAPI
|
class EthereumWallet extends CoinServiceAPI with WalletCache, WalletDB {
|
||||||
with WalletCache, WalletDB, EthExtrasWalletCache {
|
|
||||||
EthereumWallet({
|
EthereumWallet({
|
||||||
required String walletId,
|
required String walletId,
|
||||||
required String walletName,
|
required String walletName,
|
||||||
|
@ -55,7 +52,6 @@ class EthereumWallet extends CoinServiceAPI
|
||||||
_coin = coin;
|
_coin = coin;
|
||||||
_secureStore = secureStore;
|
_secureStore = secureStore;
|
||||||
initCache(walletId, coin);
|
initCache(walletId, coin);
|
||||||
initEthExtrasCache(walletId);
|
|
||||||
initWalletDB(mockableOverride: mockableOverride);
|
initWalletDB(mockableOverride: mockableOverride);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,29 +62,47 @@ class EthereumWallet extends CoinServiceAPI
|
||||||
Timer? timer;
|
Timer? timer;
|
||||||
Timer? _networkAliveTimer;
|
Timer? _networkAliveTimer;
|
||||||
|
|
||||||
Set<EthContractInfo> get contracts => getCachedTokenContracts();
|
Future<void> addTokenContracts(List<EthContract> contracts) async {
|
||||||
|
List<EthContract> updatedContracts = [];
|
||||||
|
for (final contract in contracts) {
|
||||||
|
final updatedWalletIds = contract.walletIds.toList();
|
||||||
|
if (!updatedWalletIds.contains(walletId)) {
|
||||||
|
updatedWalletIds.add(walletId);
|
||||||
|
updatedContracts.add(contract.copyWith(walletIds: updatedWalletIds));
|
||||||
|
} else {
|
||||||
|
updatedContracts.add(contract);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await db.putEthContracts(updatedContracts);
|
||||||
|
|
||||||
Future<void> addTokenContract(Set<EthContractInfo> contractInfo) =>
|
GlobalEventBus.instance.fire(
|
||||||
updateCachedTokenContracts(contracts..addAll(contractInfo)).then(
|
UpdatedInBackgroundEvent(
|
||||||
(value) => GlobalEventBus.instance.fire(
|
"$contracts updated/added for: $walletId $walletName",
|
||||||
UpdatedInBackgroundEvent(
|
walletId,
|
||||||
"$contractInfo updated/added for: $walletId $walletName",
|
),
|
||||||
walletId,
|
);
|
||||||
),
|
}
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
Future<void> removeTokenContract(String contractAddress) =>
|
Future<void> removeTokenContract(String contractAddress) async {
|
||||||
updateCachedTokenContracts(contracts
|
final contract =
|
||||||
..removeWhere((e) => e.contractAddress == contractAddress))
|
await db.getEthContracts().addressEqualTo(contractAddress).findFirst();
|
||||||
.then(
|
|
||||||
(value) => GlobalEventBus.instance.fire(
|
if (contract == null) {
|
||||||
UpdatedInBackgroundEvent(
|
return; // todo some error?
|
||||||
"$contractAddress removed for: $walletId $walletName",
|
}
|
||||||
walletId,
|
|
||||||
),
|
final updatedWalletIds = contract.walletIds.toList();
|
||||||
),
|
updatedWalletIds.removeWhere((e) => e == contractAddress);
|
||||||
);
|
|
||||||
|
await db.putEthContract(contract.copyWith(walletIds: updatedWalletIds));
|
||||||
|
|
||||||
|
GlobalEventBus.instance.fire(
|
||||||
|
UpdatedInBackgroundEvent(
|
||||||
|
"$contractAddress removed for: $walletId $walletName",
|
||||||
|
walletId,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get walletId => _walletId;
|
String get walletId => _walletId;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import 'package:stackwallet/models/ethereum/eth_token.dart';
|
import 'package:stackwallet/models/isar/models/ethereum/eth_contract.dart';
|
||||||
import 'package:stackwallet/models/token_balance.dart';
|
import 'package:stackwallet/models/token_balance.dart';
|
||||||
import 'package:stackwallet/services/ethereum/ethereum_api.dart';
|
import 'package:stackwallet/services/ethereum/ethereum_api.dart';
|
||||||
import 'package:stackwallet/services/mixins/eth_token_cache.dart';
|
import 'package:stackwallet/services/mixins/eth_token_cache.dart';
|
||||||
|
@ -6,7 +6,7 @@ import 'package:stackwallet/utilities/logger.dart';
|
||||||
|
|
||||||
class CachedEthTokenBalance with EthTokenCache {
|
class CachedEthTokenBalance with EthTokenCache {
|
||||||
final String walletId;
|
final String walletId;
|
||||||
final EthContractInfo token;
|
final EthContract token;
|
||||||
|
|
||||||
CachedEthTokenBalance(this.walletId, this.token) {
|
CachedEthTokenBalance(this.walletId, this.token) {
|
||||||
initCache(walletId, token);
|
initCache(walletId, token);
|
||||||
|
@ -15,13 +15,13 @@ class CachedEthTokenBalance with EthTokenCache {
|
||||||
Future<void> fetchAndUpdateCachedBalance(String address) async {
|
Future<void> fetchAndUpdateCachedBalance(String address) async {
|
||||||
final response = await EthereumAPI.getWalletTokenBalance(
|
final response = await EthereumAPI.getWalletTokenBalance(
|
||||||
address: address,
|
address: address,
|
||||||
contractAddress: token.contractAddress,
|
contractAddress: token.address,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (response.value != null) {
|
if (response.value != null) {
|
||||||
await updateCachedBalance(
|
await updateCachedBalance(
|
||||||
TokenBalance(
|
TokenBalance(
|
||||||
contractAddress: token.contractAddress,
|
contractAddress: token.address,
|
||||||
decimalPlaces: token.decimals,
|
decimalPlaces: token.decimals,
|
||||||
total: response.value!,
|
total: response.value!,
|
||||||
spendable: response.value!,
|
spendable: response.value!,
|
||||||
|
|
|
@ -5,9 +5,7 @@ import 'package:decimal/decimal.dart';
|
||||||
import 'package:http/http.dart';
|
import 'package:http/http.dart';
|
||||||
import 'package:stackwallet/dto/ethereum/eth_token_tx_dto.dart';
|
import 'package:stackwallet/dto/ethereum/eth_token_tx_dto.dart';
|
||||||
import 'package:stackwallet/dto/ethereum/eth_tx_dto.dart';
|
import 'package:stackwallet/dto/ethereum/eth_tx_dto.dart';
|
||||||
import 'package:stackwallet/models/ethereum/erc20_token.dart';
|
import 'package:stackwallet/models/isar/models/ethereum/eth_contract.dart';
|
||||||
import 'package:stackwallet/models/ethereum/erc721_token.dart';
|
|
||||||
import 'package:stackwallet/models/ethereum/eth_token.dart';
|
|
||||||
import 'package:stackwallet/models/paymint/fee_object_model.dart';
|
import 'package:stackwallet/models/paymint/fee_object_model.dart';
|
||||||
import 'package:stackwallet/utilities/default_nodes.dart';
|
import 'package:stackwallet/utilities/default_nodes.dart';
|
||||||
import 'package:stackwallet/utilities/eth_commons.dart';
|
import 'package:stackwallet/utilities/eth_commons.dart';
|
||||||
|
@ -64,7 +62,10 @@ abstract class EthereumAPI {
|
||||||
|
|
||||||
final List<EthTxDTO> txns = [];
|
final List<EthTxDTO> txns = [];
|
||||||
for (final map in list!) {
|
for (final map in list!) {
|
||||||
txns.add(EthTxDTO.fromMap(Map<String, dynamic>.from(map as Map)));
|
final txn = EthTxDTO.fromMap(Map<String, dynamic>.from(map as Map));
|
||||||
|
if (txn.hasToken == 0) {
|
||||||
|
txns.add(txn);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return EthereumResponse(
|
return EthereumResponse(
|
||||||
txns,
|
txns,
|
||||||
|
@ -311,7 +312,7 @@ abstract class EthereumAPI {
|
||||||
slow: feesSlow.toInt());
|
slow: feesSlow.toInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<EthereumResponse<EthContractInfo>> getTokenByContractAddress(
|
static Future<EthereumResponse<EthContract>> getTokenByContractAddress(
|
||||||
String contractAddress) async {
|
String contractAddress) async {
|
||||||
try {
|
try {
|
||||||
final response = await get(Uri.parse(
|
final response = await get(Uri.parse(
|
||||||
|
@ -322,20 +323,24 @@ abstract class EthereumAPI {
|
||||||
final json = jsonDecode(response.body);
|
final json = jsonDecode(response.body);
|
||||||
if (json["message"] == "OK") {
|
if (json["message"] == "OK") {
|
||||||
final map = Map<String, dynamic>.from(json["result"] as Map);
|
final map = Map<String, dynamic>.from(json["result"] as Map);
|
||||||
EthContractInfo? token;
|
EthContract? token;
|
||||||
if (map["type"] == "ERC-20") {
|
if (map["type"] == "ERC-20") {
|
||||||
token = Erc20ContractInfo(
|
token = EthContract(
|
||||||
contractAddress: map["contractAddress"] as String,
|
address: map["contractAddress"] as String,
|
||||||
decimals: int.parse(map["decimals"] as String),
|
decimals: int.parse(map["decimals"] as String),
|
||||||
name: map["name"] as String,
|
name: map["name"] as String,
|
||||||
symbol: map["symbol"] as String,
|
symbol: map["symbol"] as String,
|
||||||
|
type: EthContractType.erc20,
|
||||||
|
walletIds: [],
|
||||||
);
|
);
|
||||||
} else if (map["type"] == "ERC-721") {
|
} else if (map["type"] == "ERC-721") {
|
||||||
token = Erc721ContractInfo(
|
token = EthContract(
|
||||||
contractAddress: map["contractAddress"] as String,
|
address: map["contractAddress"] as String,
|
||||||
decimals: int.parse(map["decimals"] as String),
|
decimals: int.parse(map["decimals"] as String),
|
||||||
name: map["name"] as String,
|
name: map["name"] as String,
|
||||||
symbol: map["symbol"] as String,
|
symbol: map["symbol"] as String,
|
||||||
|
type: EthContractType.erc721,
|
||||||
|
walletIds: [],
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
throw EthApiException(
|
throw EthApiException(
|
||||||
|
|
|
@ -5,9 +5,7 @@ import 'package:ethereum_addresses/ethereum_addresses.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:http/http.dart';
|
import 'package:http/http.dart';
|
||||||
import 'package:isar/isar.dart';
|
import 'package:isar/isar.dart';
|
||||||
import 'package:stackwallet/models/ethereum/eth_token.dart';
|
import 'package:stackwallet/models/isar/models/isar_models.dart';
|
||||||
import 'package:stackwallet/models/isar/models/blockchain_data/address.dart';
|
|
||||||
import 'package:stackwallet/models/isar/models/blockchain_data/transaction.dart';
|
|
||||||
import 'package:stackwallet/models/node_model.dart';
|
import 'package:stackwallet/models/node_model.dart';
|
||||||
import 'package:stackwallet/models/paymint/fee_object_model.dart';
|
import 'package:stackwallet/models/paymint/fee_object_model.dart';
|
||||||
import 'package:stackwallet/models/token_balance.dart';
|
import 'package:stackwallet/models/token_balance.dart';
|
||||||
|
@ -30,7 +28,7 @@ import 'package:tuple/tuple.dart';
|
||||||
import 'package:web3dart/web3dart.dart' as web3dart;
|
import 'package:web3dart/web3dart.dart' as web3dart;
|
||||||
|
|
||||||
class EthereumTokenService extends ChangeNotifier with EthTokenCache {
|
class EthereumTokenService extends ChangeNotifier with EthTokenCache {
|
||||||
final EthContractInfo token;
|
final EthContract token;
|
||||||
final EthereumWallet ethWallet;
|
final EthereumWallet ethWallet;
|
||||||
final TransactionNotificationTracker tracker;
|
final TransactionNotificationTracker tracker;
|
||||||
final SecureStorageInterface _secureStore;
|
final SecureStorageInterface _secureStore;
|
||||||
|
@ -51,7 +49,7 @@ class EthereumTokenService extends ChangeNotifier with EthTokenCache {
|
||||||
required SecureStorageInterface secureStore,
|
required SecureStorageInterface secureStore,
|
||||||
required this.tracker,
|
required this.tracker,
|
||||||
}) : _secureStore = secureStore {
|
}) : _secureStore = secureStore {
|
||||||
_contractAddress = web3dart.EthereumAddress.fromHex(token.contractAddress);
|
_contractAddress = web3dart.EthereumAddress.fromHex(token.address);
|
||||||
initCache(ethWallet.walletId, token);
|
initCache(ethWallet.walletId, token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,7 +218,7 @@ class EthereumTokenService extends ChangeNotifier with EthTokenCache {
|
||||||
GlobalEventBus.instance.fire(
|
GlobalEventBus.instance.fire(
|
||||||
WalletSyncStatusChangedEvent(
|
WalletSyncStatusChangedEvent(
|
||||||
WalletSyncStatus.syncing,
|
WalletSyncStatus.syncing,
|
||||||
ethWallet.walletId + token.contractAddress,
|
ethWallet.walletId + token.address,
|
||||||
coin,
|
coin,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -237,7 +235,7 @@ class EthereumTokenService extends ChangeNotifier with EthTokenCache {
|
||||||
GlobalEventBus.instance.fire(
|
GlobalEventBus.instance.fire(
|
||||||
WalletSyncStatusChangedEvent(
|
WalletSyncStatusChangedEvent(
|
||||||
WalletSyncStatus.synced,
|
WalletSyncStatus.synced,
|
||||||
ethWallet.walletId + token.contractAddress,
|
ethWallet.walletId + token.address,
|
||||||
coin,
|
coin,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -256,7 +254,7 @@ class EthereumTokenService extends ChangeNotifier with EthTokenCache {
|
||||||
String _balance = balanceRequest.first.toString();
|
String _balance = balanceRequest.first.toString();
|
||||||
|
|
||||||
final newBalance = TokenBalance(
|
final newBalance = TokenBalance(
|
||||||
contractAddress: token.contractAddress,
|
contractAddress: token.address,
|
||||||
total: int.parse(_balance),
|
total: int.parse(_balance),
|
||||||
spendable: int.parse(_balance),
|
spendable: int.parse(_balance),
|
||||||
blockedTotal: 0,
|
blockedTotal: 0,
|
||||||
|
@ -270,7 +268,7 @@ class EthereumTokenService extends ChangeNotifier with EthTokenCache {
|
||||||
Future<List<Transaction>> get transactions => ethWallet.db
|
Future<List<Transaction>> get transactions => ethWallet.db
|
||||||
.getTransactions(ethWallet.walletId)
|
.getTransactions(ethWallet.walletId)
|
||||||
.filter()
|
.filter()
|
||||||
.otherDataEqualTo(token.contractAddress)
|
.otherDataEqualTo(token.address)
|
||||||
.sortByTimestampDesc()
|
.sortByTimestampDesc()
|
||||||
.findAll();
|
.findAll();
|
||||||
|
|
||||||
|
@ -279,7 +277,7 @@ class EthereumTokenService extends ChangeNotifier with EthTokenCache {
|
||||||
|
|
||||||
final response = await EthereumAPI.getTokenTransactions(
|
final response = await EthereumAPI.getTokenTransactions(
|
||||||
address: addressString,
|
address: addressString,
|
||||||
contractAddress: token.contractAddress,
|
contractAddress: token.address,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (response.value == null) {
|
if (response.value == null) {
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
import 'package:stackwallet/db/hive/db.dart';
|
|
||||||
import 'package:stackwallet/models/ethereum/eth_token.dart';
|
|
||||||
|
|
||||||
mixin EthExtrasWalletCache {
|
|
||||||
late final String _walletId;
|
|
||||||
|
|
||||||
void initEthExtrasCache(String walletId) {
|
|
||||||
_walletId = walletId;
|
|
||||||
}
|
|
||||||
|
|
||||||
// cached list of user added token contracts
|
|
||||||
Set<EthContractInfo> getCachedTokenContracts() {
|
|
||||||
final list = DB.instance.get<dynamic>(
|
|
||||||
boxName: _walletId,
|
|
||||||
key: "ethTokenContracts",
|
|
||||||
) as List<String>? ??
|
|
||||||
[];
|
|
||||||
return list.map((e) => EthContractInfo.fromJson(e)!).toSet();
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> updateCachedTokenContracts(
|
|
||||||
Set<EthContractInfo> contracts) async {
|
|
||||||
await DB.instance.put<dynamic>(
|
|
||||||
boxName: _walletId,
|
|
||||||
key: "ethTokenContracts",
|
|
||||||
value: contracts.map((e) => e.toJson()).toList(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,5 +1,5 @@
|
||||||
import 'package:stackwallet/db/hive/db.dart';
|
import 'package:stackwallet/db/hive/db.dart';
|
||||||
import 'package:stackwallet/models/ethereum/eth_token.dart';
|
import 'package:stackwallet/models/isar/models/ethereum/eth_contract.dart';
|
||||||
import 'package:stackwallet/models/token_balance.dart';
|
import 'package:stackwallet/models/token_balance.dart';
|
||||||
|
|
||||||
abstract class _Keys {
|
abstract class _Keys {
|
||||||
|
@ -10,9 +10,9 @@ abstract class _Keys {
|
||||||
|
|
||||||
mixin EthTokenCache {
|
mixin EthTokenCache {
|
||||||
late final String _walletId;
|
late final String _walletId;
|
||||||
late final EthContractInfo _token;
|
late final EthContract _token;
|
||||||
|
|
||||||
void initCache(String walletId, EthContractInfo token) {
|
void initCache(String walletId, EthContract token) {
|
||||||
_walletId = walletId;
|
_walletId = walletId;
|
||||||
_token = token;
|
_token = token;
|
||||||
}
|
}
|
||||||
|
@ -21,11 +21,11 @@ mixin EthTokenCache {
|
||||||
TokenBalance getCachedBalance() {
|
TokenBalance getCachedBalance() {
|
||||||
final jsonString = DB.instance.get<dynamic>(
|
final jsonString = DB.instance.get<dynamic>(
|
||||||
boxName: _walletId,
|
boxName: _walletId,
|
||||||
key: _Keys.tokenBalance(_token.contractAddress),
|
key: _Keys.tokenBalance(_token.address),
|
||||||
) as String?;
|
) as String?;
|
||||||
if (jsonString == null) {
|
if (jsonString == null) {
|
||||||
return TokenBalance(
|
return TokenBalance(
|
||||||
contractAddress: _token.contractAddress,
|
contractAddress: _token.address,
|
||||||
decimalPlaces: _token.decimals,
|
decimalPlaces: _token.decimals,
|
||||||
total: 0,
|
total: 0,
|
||||||
spendable: 0,
|
spendable: 0,
|
||||||
|
@ -41,7 +41,7 @@ mixin EthTokenCache {
|
||||||
Future<void> updateCachedBalance(TokenBalance balance) async {
|
Future<void> updateCachedBalance(TokenBalance balance) async {
|
||||||
await DB.instance.put<dynamic>(
|
await DB.instance.put<dynamic>(
|
||||||
boxName: _walletId,
|
boxName: _walletId,
|
||||||
key: _Keys.tokenBalance(_token.contractAddress),
|
key: _Keys.tokenBalance(_token.address),
|
||||||
value: balance.toJsonIgnoreCoin(),
|
value: balance.toJsonIgnoreCoin(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,43 +1,54 @@
|
||||||
import 'package:stackwallet/models/ethereum/erc20_token.dart';
|
import 'package:stackwallet/models/isar/models/ethereum/eth_contract.dart';
|
||||||
import 'package:stackwallet/models/ethereum/eth_token.dart';
|
|
||||||
|
|
||||||
abstract class DefaultTokens {
|
abstract class DefaultTokens {
|
||||||
static const List<EthContractInfo> list = [
|
static List<EthContract> list = [
|
||||||
Erc20ContractInfo(
|
EthContract(
|
||||||
contractAddress: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
|
address: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
|
||||||
name: "USD Coin",
|
name: "USD Coin",
|
||||||
symbol: "USDC",
|
symbol: "USDC",
|
||||||
decimals: 6,
|
decimals: 6,
|
||||||
|
type: EthContractType.erc20,
|
||||||
|
walletIds: [],
|
||||||
),
|
),
|
||||||
Erc20ContractInfo(
|
EthContract(
|
||||||
contractAddress: "0xdac17f958d2ee523a2206206994597c13d831ec7",
|
address: "0xdac17f958d2ee523a2206206994597c13d831ec7",
|
||||||
name: "Tether",
|
name: "Tether",
|
||||||
symbol: "USDT",
|
symbol: "USDT",
|
||||||
decimals: 6,
|
decimals: 6,
|
||||||
|
type: EthContractType.erc20,
|
||||||
|
walletIds: [],
|
||||||
),
|
),
|
||||||
Erc20ContractInfo(
|
EthContract(
|
||||||
contractAddress: "0x95ad61b0a150d79219dcf64e1e6cc01f0b64c4ce",
|
address: "0x95ad61b0a150d79219dcf64e1e6cc01f0b64c4ce",
|
||||||
name: "Shiba Inu",
|
name: "Shiba Inu",
|
||||||
symbol: "SHIB",
|
symbol: "SHIB",
|
||||||
decimals: 18,
|
decimals: 18,
|
||||||
|
type: EthContractType.erc20,
|
||||||
|
walletIds: [],
|
||||||
),
|
),
|
||||||
Erc20ContractInfo(
|
EthContract(
|
||||||
contractAddress: "0xB8c77482e45F1F44dE1745F52C74426C631bDD52",
|
address: "0xB8c77482e45F1F44dE1745F52C74426C631bDD52",
|
||||||
name: "BNB Token",
|
name: "BNB Token",
|
||||||
symbol: "BNB",
|
symbol: "BNB",
|
||||||
decimals: 18,
|
decimals: 18,
|
||||||
|
type: EthContractType.erc20,
|
||||||
|
walletIds: [],
|
||||||
),
|
),
|
||||||
Erc20ContractInfo(
|
EthContract(
|
||||||
contractAddress: "0x4Fabb145d64652a948d72533023f6E7A623C7C53",
|
address: "0x4Fabb145d64652a948d72533023f6E7A623C7C53",
|
||||||
name: "BUSD",
|
name: "BUSD",
|
||||||
symbol: "BUSD",
|
symbol: "BUSD",
|
||||||
decimals: 18,
|
decimals: 18,
|
||||||
|
type: EthContractType.erc20,
|
||||||
|
walletIds: [],
|
||||||
),
|
),
|
||||||
Erc20ContractInfo(
|
EthContract(
|
||||||
contractAddress: "0x514910771af9ca656af840dff83e8264ecf986ca",
|
address: "0x514910771af9ca656af840dff83e8264ecf986ca",
|
||||||
name: "Chainlink",
|
name: "Chainlink",
|
||||||
symbol: "LINK",
|
symbol: "LINK",
|
||||||
decimals: 18,
|
decimals: 18,
|
||||||
|
type: EthContractType.erc20,
|
||||||
|
walletIds: [],
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue