mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2025-01-10 20:54:33 +00:00
commit
1b8300129d
9 changed files with 86 additions and 31 deletions
|
@ -116,13 +116,13 @@ class EthTokenTxExtraDTO {
|
||||||
map['timestamp'] = timestamp;
|
map['timestamp'] = timestamp;
|
||||||
map['from'] = from;
|
map['from'] = from;
|
||||||
map['to'] = to;
|
map['to'] = to;
|
||||||
map['value'] = value;
|
map['value'] = value.toJsonString();
|
||||||
map['gas'] = gas;
|
map['gas'] = gas.toJsonString();
|
||||||
map['gasPrice'] = gasPrice;
|
map['gasPrice'] = gasPrice.toJsonString();
|
||||||
map['input'] = input;
|
map['input'] = input;
|
||||||
map['nonce'] = nonce;
|
map['nonce'] = nonce;
|
||||||
map['gasCost'] = gasCost;
|
map['gasCost'] = gasCost.toJsonString();
|
||||||
map['gasUsed'] = gasUsed;
|
map['gasUsed'] = gasUsed.toJsonString();
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -680,6 +680,7 @@ class _WalletViewState extends ConsumerState<WalletView> {
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||||
child: WalletSummary(
|
child: WalletSummary(
|
||||||
walletId: walletId,
|
walletId: walletId,
|
||||||
|
aspectRatio: 1.75,
|
||||||
initialSyncStatus: ref.watch(managerProvider
|
initialSyncStatus: ref.watch(managerProvider
|
||||||
.select((value) => value.isRefreshing))
|
.select((value) => value.isRefreshing))
|
||||||
? WalletSyncStatus.syncing
|
? WalletSyncStatus.syncing
|
||||||
|
|
|
@ -265,17 +265,23 @@ class EthereumWallet extends CoinServiceAPI with WalletCache, WalletDB {
|
||||||
@override
|
@override
|
||||||
Future<FeeObject> get fees => EthereumAPI.getFees();
|
Future<FeeObject> get fees => EthereumAPI.getFees();
|
||||||
|
|
||||||
//Full rescan is not needed for ETH since we have a balance
|
|
||||||
@override
|
@override
|
||||||
Future<void> fullRescan(
|
Future<void> fullRescan(
|
||||||
int maxUnusedAddressGap, int maxNumberOfIndexesToCheck) {
|
int maxUnusedAddressGap,
|
||||||
// TODO: implement fullRescan
|
int maxNumberOfIndexesToCheck,
|
||||||
throw UnimplementedError();
|
) async {
|
||||||
|
await db.deleteWalletBlockchainData(walletId);
|
||||||
|
await _generateAndSaveAddress(
|
||||||
|
(await mnemonicString)!,
|
||||||
|
(await mnemonicPassphrase)!,
|
||||||
|
);
|
||||||
|
await updateBalance();
|
||||||
|
await _refreshTransactions(isRescan: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<bool> generateNewAddress() {
|
Future<bool> generateNewAddress() {
|
||||||
// TODO: implement generateNewAddress - might not be needed for ETH
|
// not used for ETH
|
||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -291,10 +297,10 @@ class EthereumWallet extends CoinServiceAPI with WalletCache, WalletDB {
|
||||||
level: LogLevel.Info,
|
level: LogLevel.Info,
|
||||||
);
|
);
|
||||||
|
|
||||||
//First get mnemonic so we can initialize credentials
|
await _initCredentials(
|
||||||
String privateKey =
|
(await mnemonicString)!,
|
||||||
getPrivateKey((await mnemonicString)!, (await mnemonicPassphrase)!);
|
(await mnemonicPassphrase)!,
|
||||||
_credentials = web3.EthPrivateKey.fromHex(privateKey);
|
);
|
||||||
|
|
||||||
if (getCachedId() == null) {
|
if (getCachedId() == null) {
|
||||||
throw Exception(
|
throw Exception(
|
||||||
|
@ -367,8 +373,24 @@ class EthereumWallet extends CoinServiceAPI with WalletCache, WalletDB {
|
||||||
value: "",
|
value: "",
|
||||||
);
|
);
|
||||||
|
|
||||||
String privateKey = getPrivateKey(mnemonic, "");
|
await _generateAndSaveAddress(mnemonic, "");
|
||||||
|
|
||||||
|
Logging.instance.log("_generateNewWalletFinished", level: LogLevel.Info);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _initCredentials(
|
||||||
|
String mnemonic,
|
||||||
|
String mnemonicPassphrase,
|
||||||
|
) async {
|
||||||
|
String privateKey = getPrivateKey(mnemonic, mnemonicPassphrase);
|
||||||
_credentials = web3.EthPrivateKey.fromHex(privateKey);
|
_credentials = web3.EthPrivateKey.fromHex(privateKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _generateAndSaveAddress(
|
||||||
|
String mnemonic,
|
||||||
|
String mnemonicPassphrase,
|
||||||
|
) async {
|
||||||
|
await _initCredentials(mnemonic, mnemonicPassphrase);
|
||||||
|
|
||||||
final address = Address(
|
final address = Address(
|
||||||
walletId: walletId,
|
walletId: walletId,
|
||||||
|
@ -381,8 +403,6 @@ class EthereumWallet extends CoinServiceAPI with WalletCache, WalletDB {
|
||||||
);
|
);
|
||||||
|
|
||||||
await db.putAddress(address);
|
await db.putAddress(address);
|
||||||
|
|
||||||
Logging.instance.log("_generateNewWalletFinished", level: LogLevel.Info);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _isConnected = false;
|
bool _isConnected = false;
|
||||||
|
@ -649,7 +669,7 @@ class EthereumWallet extends CoinServiceAPI with WalletCache, WalletDB {
|
||||||
if (!needsRefresh) {
|
if (!needsRefresh) {
|
||||||
var allOwnAddresses = await _fetchAllOwnAddresses();
|
var allOwnAddresses = await _fetchAllOwnAddresses();
|
||||||
final response = await EthereumAPI.getEthTransactions(
|
final response = await EthereumAPI.getEthTransactions(
|
||||||
allOwnAddresses.elementAt(0).value,
|
address: allOwnAddresses.elementAt(0).value,
|
||||||
);
|
);
|
||||||
if (response.value != null) {
|
if (response.value != null) {
|
||||||
final allTxs = response.value!;
|
final allTxs = response.value!;
|
||||||
|
@ -985,10 +1005,25 @@ class EthereumWallet extends CoinServiceAPI with WalletCache, WalletDB {
|
||||||
return isValidEthereumAddress(address);
|
return isValidEthereumAddress(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _refreshTransactions() async {
|
Future<void> _refreshTransactions({bool isRescan = false}) async {
|
||||||
String thisAddress = await currentReceivingAddress;
|
String thisAddress = await currentReceivingAddress;
|
||||||
|
|
||||||
final response = await EthereumAPI.getEthTransactions(thisAddress);
|
int firstBlock = 0;
|
||||||
|
|
||||||
|
if (!isRescan) {
|
||||||
|
firstBlock =
|
||||||
|
await db.getTransactions(walletId).heightProperty().max() ?? 0;
|
||||||
|
|
||||||
|
if (firstBlock > 10) {
|
||||||
|
// add some buffer
|
||||||
|
firstBlock -= 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final response = await EthereumAPI.getEthTransactions(
|
||||||
|
address: thisAddress,
|
||||||
|
firstBlock: isRescan ? 0 : firstBlock,
|
||||||
|
);
|
||||||
|
|
||||||
if (response.value == null) {
|
if (response.value == null) {
|
||||||
Logging.instance.log(
|
Logging.instance.log(
|
||||||
|
@ -999,6 +1034,11 @@ class EthereumWallet extends CoinServiceAPI with WalletCache, WalletDB {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (response.value!.isEmpty) {
|
||||||
|
// no new transactions found
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
final txsResponse =
|
final txsResponse =
|
||||||
await EthereumAPI.getEthTransactionNonces(response.value!);
|
await EthereumAPI.getEthTransactionNonces(response.value!);
|
||||||
|
|
||||||
|
|
|
@ -864,6 +864,10 @@ class MoneroWallet extends CoinServiceAPI with WalletCache, WalletDB {
|
||||||
//
|
//
|
||||||
String address = walletBase!.getTransactionAddress(chain, index);
|
String address = walletBase!.getTransactionAddress(chain, index);
|
||||||
|
|
||||||
|
if (address.contains("111")) {
|
||||||
|
return await _generateAddressForChain(chain, index + 1);
|
||||||
|
}
|
||||||
|
|
||||||
return isar_models.Address(
|
return isar_models.Address(
|
||||||
walletId: walletId,
|
walletId: walletId,
|
||||||
derivationIndex: index,
|
derivationIndex: index,
|
||||||
|
|
|
@ -47,12 +47,14 @@ class EthereumResponse<T> {
|
||||||
abstract class EthereumAPI {
|
abstract class EthereumAPI {
|
||||||
static String get stackBaseServer => DefaultNodes.ethereum.host;
|
static String get stackBaseServer => DefaultNodes.ethereum.host;
|
||||||
|
|
||||||
static Future<EthereumResponse<List<EthTxDTO>>> getEthTransactions(
|
static Future<EthereumResponse<List<EthTxDTO>>> getEthTransactions({
|
||||||
String address) async {
|
required String address,
|
||||||
|
int firstBlock = 0,
|
||||||
|
}) async {
|
||||||
try {
|
try {
|
||||||
final response = await get(
|
final response = await get(
|
||||||
Uri.parse(
|
Uri.parse(
|
||||||
"$stackBaseServer/export?addrs=$address",
|
"$stackBaseServer/export?addrs=$address&firstBlock=$firstBlock",
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -507,9 +507,13 @@ class EthTokenWallet extends ChangeNotifier with EthTokenCache {
|
||||||
} else if (toAddress == addressString) {
|
} else if (toAddress == addressString) {
|
||||||
isIncoming = true;
|
isIncoming = true;
|
||||||
} else {
|
} else {
|
||||||
throw Exception("Unknown token transaction found for "
|
// ignore for now I guess since anything here is not reflected in
|
||||||
"${ethWallet.walletName} ${ethWallet.walletId}: "
|
// balance anyways
|
||||||
"${tuple.item1.toString()}");
|
continue;
|
||||||
|
|
||||||
|
// throw Exception("Unknown token transaction found for "
|
||||||
|
// "${ethWallet.walletName} ${ethWallet.walletId}: "
|
||||||
|
// "${tuple.item1.toString()}");
|
||||||
}
|
}
|
||||||
|
|
||||||
final txn = Transaction(
|
final txn = Transaction(
|
||||||
|
|
|
@ -30,8 +30,6 @@ final coinIconProvider = Provider.family<String, Coin>((ref, coin) {
|
||||||
case Coin.dogecoin:
|
case Coin.dogecoin:
|
||||||
case Coin.dogecoinTestNet:
|
case Coin.dogecoinTestNet:
|
||||||
return assets.dogecoin;
|
return assets.dogecoin;
|
||||||
case Coin.eCash:
|
|
||||||
return assets.bitcoin;
|
|
||||||
case Coin.epicCash:
|
case Coin.epicCash:
|
||||||
return assets.epicCash;
|
return assets.epicCash;
|
||||||
case Coin.firo:
|
case Coin.firo:
|
||||||
|
@ -48,7 +46,7 @@ final coinIconProvider = Provider.family<String, Coin>((ref, coin) {
|
||||||
case Coin.ethereum:
|
case Coin.ethereum:
|
||||||
return assets.ethereum;
|
return assets.ethereum;
|
||||||
default:
|
default:
|
||||||
return assets.bitcoin;
|
return assets.stackIcon;
|
||||||
}
|
}
|
||||||
} else if (assets is ThemeAssetsV2) {
|
} else if (assets is ThemeAssetsV2) {
|
||||||
return (assets).coinIcons[coin.mainNetVersion]!;
|
return (assets).coinIcons[coin.mainNetVersion]!;
|
||||||
|
|
|
@ -98,7 +98,10 @@ class ThemeService {
|
||||||
await db.isar.writeTxn(() async {
|
await db.isar.writeTxn(() async {
|
||||||
await db.isar.stackThemes.delete(isarId);
|
await db.isar.stackThemes.delete(isarId);
|
||||||
});
|
});
|
||||||
await Directory("${themesDir.path}/$themeId").delete(recursive: true);
|
final dir = Directory("${themesDir.path}/$themeId");
|
||||||
|
if (dir.existsSync()) {
|
||||||
|
await dir.delete(recursive: true);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Logging.instance.log(
|
Logging.instance.log(
|
||||||
"Failed to delete theme $themeId",
|
"Failed to delete theme $themeId",
|
||||||
|
|
|
@ -47,8 +47,11 @@ class CoinCard extends ConsumerWidget {
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(
|
||||||
|
Constants.size.circularBorderRadius,
|
||||||
|
),
|
||||||
image: DecorationImage(
|
image: DecorationImage(
|
||||||
fit: BoxFit.fill,
|
fit: BoxFit.cover,
|
||||||
image: FileImage(
|
image: FileImage(
|
||||||
File(
|
File(
|
||||||
ref.watch(coinCardProvider(coin))!,
|
ref.watch(coinCardProvider(coin))!,
|
||||||
|
|
Loading…
Reference in a new issue