From 11397702e6ee7212bd2662f1e14590aea8943930 Mon Sep 17 00:00:00 2001
From: julian <julian@cypherstack.com>
Date: Tue, 21 May 2024 11:11:40 -0600
Subject: [PATCH] eth contract abi fixes

---
 lib/services/ethereum/ethereum_api.dart       |  2 +-
 .../impl/sub_wallets/eth_token_wallet.dart    | 83 +++++++++----------
 2 files changed, 39 insertions(+), 46 deletions(-)

diff --git a/lib/services/ethereum/ethereum_api.dart b/lib/services/ethereum/ethereum_api.dart
index b9ac2224b..3931b4573 100644
--- a/lib/services/ethereum/ethereum_api.dart
+++ b/lib/services/ethereum/ethereum_api.dart
@@ -686,7 +686,7 @@ abstract class EthereumAPI {
     try {
       final response = await client.get(
         url: Uri.parse(
-          "$stackBaseServer/abis?addrs=$contractAddress",
+          "$stackBaseServer/abis?addrs=$contractAddress&verbose=true",
         ),
         proxyInfo: Prefs.instance.useTor
             ? TorService.sharedInstance.getProxyInfo()
diff --git a/lib/wallets/wallet/impl/sub_wallets/eth_token_wallet.dart b/lib/wallets/wallet/impl/sub_wallets/eth_token_wallet.dart
index d5c4bc31d..bede12bab 100644
--- a/lib/wallets/wallet/impl/sub_wallets/eth_token_wallet.dart
+++ b/lib/wallets/wallet/impl/sub_wallets/eth_token_wallet.dart
@@ -16,7 +16,6 @@ import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/enums/fee_rate_type_enum.dart';
 import 'package:stackwallet/utilities/eth_commons.dart';
 import 'package:stackwallet/utilities/extensions/extensions.dart';
-import 'package:stackwallet/utilities/extensions/impl/contract_abi.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/wallets/isar/models/token_wallet_info.dart';
 import 'package:stackwallet/wallets/models/tx_data.dart';
@@ -85,11 +84,17 @@ class EthTokenWallet extends Wallet {
       final contractAddress =
           web3dart.EthereumAddress.fromHex(tokenContract.address);
 
-      if (tokenContract.abi == null) {
+      // first try to update the abi regardless just in case something has changed
+      try {
         _tokenContract = await _updateTokenABI(
           forContract: tokenContract,
           usingContractAddress: contractAddress.hex,
         );
+      } catch (e, s) {
+        Logging.instance.log(
+          "$runtimeType _updateTokenABI(): $e\n$s",
+          level: LogLevel.Warning,
+        );
       }
 
       try {
@@ -102,50 +107,36 @@ class EthTokenWallet extends Wallet {
           contractAddress,
         );
         _sendFunction = _deployedContract.function('transfer');
+        // success
+        return;
       } catch (_) {
-        // some failure so first try to make sure we have the latest abi
+        // continue
+      }
+
+      // Some failure, try for proxy contract
+      final contractAddressResponse =
+          await EthereumAPI.getProxyTokenImplementationAddress(
+        contractAddress.hex,
+      );
+
+      if (contractAddressResponse.value != null) {
         _tokenContract = await _updateTokenABI(
           forContract: tokenContract,
-          usingContractAddress: contractAddress.hex,
+          usingContractAddress: contractAddressResponse.value!,
         );
-
-        try {
-          // try again to parse abi and extract transfer function
-          _deployedContract = web3dart.DeployedContract(
-            ContractAbiExtensions.fromJsonList(
-              jsonList: tokenContract.abi!,
-              name: tokenContract.name,
-            ),
-            contractAddress,
-          );
-          _sendFunction = _deployedContract.function('transfer');
-        } catch (_) {
-          // if it fails again we check if there is a proxy token impl and
-          // then try one last time to update and parse the abi
-          final contractAddressResponse =
-              await EthereumAPI.getProxyTokenImplementationAddress(
-                  contractAddress.hex);
-
-          if (contractAddressResponse.value != null) {
-            _tokenContract = await _updateTokenABI(
-              forContract: tokenContract,
-              usingContractAddress: contractAddressResponse.value!,
-            );
-          } else {
-            throw contractAddressResponse.exception!;
-          }
-
-          _deployedContract = web3dart.DeployedContract(
-            ContractAbiExtensions.fromJsonList(
-              jsonList: tokenContract.abi!,
-              name: tokenContract.name,
-            ),
-            contractAddress,
-          );
-
-          _sendFunction = _deployedContract.function('transfer');
-        }
+      } else {
+        throw contractAddressResponse.exception!;
       }
+
+      _deployedContract = web3dart.DeployedContract(
+        ContractAbiExtensions.fromJsonList(
+          jsonList: tokenContract.abi!,
+          name: tokenContract.name,
+        ),
+        contractAddress,
+      );
+
+      _sendFunction = _deployedContract.function('transfer');
     } catch (e, s) {
       Logging.instance.log(
         "$runtimeType wallet failed init(): $e\n$s",
@@ -181,8 +172,10 @@ class EthTokenWallet extends Wallet {
     final myWeb3Address = web3dart.EthereumAddress.fromHex(myAddress);
 
     final nonce = txData.nonce ??
-        await client.getTransactionCount(myWeb3Address,
-            atBlock: const web3dart.BlockNum.pending());
+        await client.getTransactionCount(
+          myWeb3Address,
+          atBlock: const web3dart.BlockNum.pending(),
+        );
 
     final amount = txData.recipients!.first.amount;
     final address = txData.recipients!.first.address;
@@ -408,7 +401,7 @@ class EthTokenWallet extends Wallet {
           final List<OutputV2> outputs = [];
           final List<InputV2> inputs = [];
 
-          OutputV2 output = OutputV2.isarCantDoRequiredInDefaultConstructor(
+          final output = OutputV2.isarCantDoRequiredInDefaultConstructor(
             scriptPubKeyHex: "00",
             valueStringSats: amount.raw.toString(),
             addresses: [
@@ -416,7 +409,7 @@ class EthTokenWallet extends Wallet {
             ],
             walletOwns: addressTo == addressString,
           );
-          InputV2 input = InputV2.isarCantDoRequiredInDefaultConstructor(
+          final input = InputV2.isarCantDoRequiredInDefaultConstructor(
             scriptSigHex: null,
             scriptSigAsm: null,
             sequence: null,