properly load eth token wallets

This commit is contained in:
julian 2024-01-10 17:40:42 -06:00
parent 6942a9b3dd
commit 187f3bc462
4 changed files with 142 additions and 111 deletions

View file

@ -30,6 +30,7 @@ import 'package:stackwallet/wallets/isar/providers/eth/token_balance_provider.da
import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
import 'package:stackwallet/wallets/wallet/impl/ethereum_wallet.dart';
import 'package:stackwallet/wallets/wallet/impl/sub_wallets/eth_token_wallet.dart';
import 'package:stackwallet/wallets/wallet/wallet.dart';
import 'package:stackwallet/widgets/desktop/primary_button.dart';
import 'package:stackwallet/widgets/dialogs/basic_dialog.dart';
import 'package:stackwallet/widgets/icon_widgets/eth_token_icon.dart';
@ -88,10 +89,11 @@ class _MyTokenSelectItemState extends ConsumerState<MyTokenSelectItem> {
final old = ref.read(tokenServiceStateProvider);
// exit previous if there is one
unawaited(old?.exit());
ref.read(tokenServiceStateProvider.state).state = EthTokenWallet(
ref.read(pWallets).getWallet(widget.walletId) as EthereumWallet,
widget.token,
);
ref.read(tokenServiceStateProvider.state).state = Wallet.loadTokenWallet(
ethWallet:
ref.read(pWallets).getWallet(widget.walletId) as EthereumWallet,
contract: widget.token,
) as EthTokenWallet;
final success = await showLoading<bool>(
whileFuture: _loadTokenWallet(context, ref),

View file

@ -79,119 +79,126 @@ class EthTokenWallet extends Wallet {
@override
Future<void> init() async {
await super.init();
final contractAddress =
web3dart.EthereumAddress.fromHex(tokenContract.address);
if (tokenContract.abi == null) {
_tokenContract = await _updateTokenABI(
forContract: tokenContract,
usingContractAddress: contractAddress.hex,
);
}
// String? mnemonicString = await ethWallet.getMnemonic();
//
// //Get private key for given mnemonic
// String privateKey = getPrivateKey(
// mnemonicString,
// (await ethWallet.getMnemonicPassphrase()),
// );
// _credentials = web3dart.EthPrivateKey.fromHex(privateKey);
try {
_deployedContract = web3dart.DeployedContract(
ContractAbiExtensions.fromJsonList(
jsonList: tokenContract.abi!,
name: tokenContract.name,
),
contractAddress,
);
} catch (_) {
rethrow;
}
await super.init();
try {
_sendFunction = _deployedContract.function('transfer');
} catch (_) {
//====================================================================
// final list = List<Map<String, dynamic>>.from(
// jsonDecode(tokenContract.abi!) as List);
// final functionNames = list.map((e) => e["name"] as String);
//
// if (!functionNames.contains("balanceOf")) {
// list.add(
// {
// "encoding": "0x70a08231",
// "inputs": [
// {"name": "account", "type": "address"}
// ],
// "name": "balanceOf",
// "outputs": [
// {"name": "val_0", "type": "uint256"}
// ],
// "signature": "balanceOf(address)",
// "type": "function"
// },
// );
// }
//
// if (!functionNames.contains("transfer")) {
// list.add(
// {
// "encoding": "0xa9059cbb",
// "inputs": [
// {"name": "dst", "type": "address"},
// {"name": "rawAmount", "type": "uint256"}
// ],
// "name": "transfer",
// "outputs": [
// {"name": "val_0", "type": "bool"}
// ],
// "signature": "transfer(address,uint256)",
// "type": "function"
// },
// );
// }
//--------------------------------------------------------------------
//====================================================================
final contractAddress =
web3dart.EthereumAddress.fromHex(tokenContract.address);
// function not found so likely a proxy so we need to fetch the impl
//====================================================================
// final updatedToken = tokenContract.copyWith(abi: jsonEncode(list));
// // Store updated contract
// final id = await MainDB.instance.putEthContract(updatedToken);
// _tokenContract = updatedToken..id = id;
//--------------------------------------------------------------------
final contractAddressResponse =
await EthereumAPI.getProxyTokenImplementationAddress(
contractAddress.hex);
if (contractAddressResponse.value != null) {
if (tokenContract.abi == null) {
_tokenContract = await _updateTokenABI(
forContract: tokenContract,
usingContractAddress: contractAddressResponse.value!,
usingContractAddress: contractAddress.hex,
);
} else {
throw contractAddressResponse.exception!;
}
//====================================================================
}
try {
_deployedContract = web3dart.DeployedContract(
ContractAbiExtensions.fromJsonList(
jsonList: tokenContract.abi!,
name: tokenContract.name,
),
contractAddress,
// String? mnemonicString = await ethWallet.getMnemonic();
//
// //Get private key for given mnemonic
// String privateKey = getPrivateKey(
// mnemonicString,
// (await ethWallet.getMnemonicPassphrase()),
// );
// _credentials = web3dart.EthPrivateKey.fromHex(privateKey);
try {
_deployedContract = web3dart.DeployedContract(
ContractAbiExtensions.fromJsonList(
jsonList: tokenContract.abi!,
name: tokenContract.name,
),
contractAddress,
);
} catch (_) {
rethrow;
}
try {
_sendFunction = _deployedContract.function('transfer');
} catch (_) {
//====================================================================
// final list = List<Map<String, dynamic>>.from(
// jsonDecode(tokenContract.abi!) as List);
// final functionNames = list.map((e) => e["name"] as String);
//
// if (!functionNames.contains("balanceOf")) {
// list.add(
// {
// "encoding": "0x70a08231",
// "inputs": [
// {"name": "account", "type": "address"}
// ],
// "name": "balanceOf",
// "outputs": [
// {"name": "val_0", "type": "uint256"}
// ],
// "signature": "balanceOf(address)",
// "type": "function"
// },
// );
// }
//
// if (!functionNames.contains("transfer")) {
// list.add(
// {
// "encoding": "0xa9059cbb",
// "inputs": [
// {"name": "dst", "type": "address"},
// {"name": "rawAmount", "type": "uint256"}
// ],
// "name": "transfer",
// "outputs": [
// {"name": "val_0", "type": "bool"}
// ],
// "signature": "transfer(address,uint256)",
// "type": "function"
// },
// );
// }
//--------------------------------------------------------------------
//====================================================================
// function not found so likely a proxy so we need to fetch the impl
//====================================================================
// final updatedToken = tokenContract.copyWith(abi: jsonEncode(list));
// // Store updated contract
// final id = await MainDB.instance.putEthContract(updatedToken);
// _tokenContract = updatedToken..id = id;
//--------------------------------------------------------------------
final contractAddressResponse =
await EthereumAPI.getProxyTokenImplementationAddress(
contractAddress.hex);
if (contractAddressResponse.value != null) {
_tokenContract = await _updateTokenABI(
forContract: tokenContract,
usingContractAddress: contractAddressResponse.value!,
);
} else {
throw contractAddressResponse.exception!;
}
//====================================================================
}
try {
_deployedContract = web3dart.DeployedContract(
ContractAbiExtensions.fromJsonList(
jsonList: tokenContract.abi!,
name: tokenContract.name,
),
contractAddress,
);
} catch (_) {
rethrow;
}
_sendFunction = _deployedContract.function('transfer');
} catch (e, s) {
Logging.instance.log(
"$runtimeType wallet failed init(): $e\n$s",
level: LogLevel.Warning,
);
} catch (_) {
rethrow;
}
_sendFunction = _deployedContract.function('transfer');
}
@override

View file

@ -5,6 +5,7 @@ import 'package:meta/meta.dart';
import 'package:mutex/mutex.dart';
import 'package:stackwallet/db/isar/main_db.dart';
import 'package:stackwallet/models/isar/models/blockchain_data/address.dart';
import 'package:stackwallet/models/isar/models/ethereum/eth_contract.dart';
import 'package:stackwallet/models/node_model.dart';
import 'package:stackwallet/models/paymint/fee_object_model.dart';
import 'package:stackwallet/services/event_bus/events/global/node_connection_status_changed_event.dart';
@ -35,6 +36,7 @@ import 'package:stackwallet/wallets/wallet/impl/monero_wallet.dart';
import 'package:stackwallet/wallets/wallet/impl/namecoin_wallet.dart';
import 'package:stackwallet/wallets/wallet/impl/nano_wallet.dart';
import 'package:stackwallet/wallets/wallet/impl/particl_wallet.dart';
import 'package:stackwallet/wallets/wallet/impl/sub_wallets/eth_token_wallet.dart';
import 'package:stackwallet/wallets/wallet/impl/tezos_wallet.dart';
import 'package:stackwallet/wallets/wallet/impl/wownero_wallet.dart';
import 'package:stackwallet/wallets/wallet/intermediate/cryptonote_wallet.dart';
@ -203,6 +205,26 @@ abstract class Wallet<T extends CryptoCurrency> {
);
}
// TODO: [prio=med] refactor to more generalized token rather than eth specific
static Wallet loadTokenWallet({
required EthereumWallet ethWallet,
required EthContract contract,
}) {
final Wallet wallet = EthTokenWallet(
ethWallet,
contract,
);
wallet.prefs = ethWallet.prefs;
wallet.nodeService = ethWallet.nodeService;
wallet.secureStorageInterface = ethWallet.secureStorageInterface;
wallet.mainDB = ethWallet.mainDB;
return wallet
.._walletInfo = ethWallet.info
.._watchWalletInfo();
}
//============================================================================
// ========== Static Util ====================================================

View file

@ -57,10 +57,10 @@ class SimpleWalletCard extends ConsumerWidget {
final old = ref.read(tokenServiceStateProvider);
// exit previous if there is one
unawaited(old?.exit());
ref.read(tokenServiceStateProvider.state).state = EthTokenWallet(
wallet as EthereumWallet,
contract,
);
ref.read(tokenServiceStateProvider.state).state = Wallet.loadTokenWallet(
ethWallet: wallet as EthereumWallet,
contract: contract,
) as EthTokenWallet;
try {
await ref.read(pCurrentTokenWallet)!.init();