content: package com.alphawallet.app.viewmodel;
  
  import android.app.Activity;
  import android.content.Context;
  import android.content.Intent;
  
  import androidx.lifecycle.MutableLiveData;
  
  import com.alphawallet.app.C;
  import com.alphawallet.app.entity.ContractType;
  import com.alphawallet.app.entity.GasEstimate;
  import com.alphawallet.app.entity.NetworkInfo;
  import com.alphawallet.app.entity.SignAuthenticationCallback;
  import com.alphawallet.app.entity.TransactionReturn;
  import com.alphawallet.app.entity.Wallet;
  import com.alphawallet.app.entity.tokens.Token;
  import com.alphawallet.app.entity.tokens.TokenInfo;
  import com.alphawallet.app.interact.CreateTransactionInteract;
  import com.alphawallet.app.repository.EthereumNetworkRepositoryType;
  import com.alphawallet.app.repository.TokenRepository;
  import com.alphawallet.app.router.MyAddressRouter;
  import com.alphawallet.app.service.AnalyticsServiceType;
  import com.alphawallet.app.service.AssetDefinitionService;
  import com.alphawallet.app.service.GasService;
  import com.alphawallet.app.service.KeyService;
  import com.alphawallet.app.service.TokensService;
  import com.alphawallet.app.service.TransactionSendHandlerInterface;
  import com.alphawallet.app.ui.ImportTokenActivity;
  import com.alphawallet.app.web3.entity.Web3Transaction;
  import com.alphawallet.hardware.SignatureFromKey;
  
  import java.math.BigDecimal;
  import java.math.BigInteger;
  
  import javax.inject.Inject;
  
  import dagger.hilt.android.lifecycle.HiltViewModel;
  import io.reactivex.Single;
  import io.reactivex.android.schedulers.AndroidSchedulers;
  import io.reactivex.schedulers.Schedulers;
  
  @HiltViewModel
  public class SendViewModel extends BaseViewModel implements TransactionSendHandlerInterface
  {
      private final MutableLiveData<Token> finalisedToken = new MutableLiveData<>();
      private final MutableLiveData<TransactionReturn> transactionFinalised = new MutableLiveData<>();
      private final MutableLiveData<TransactionReturn> transactionError = new MutableLiveData<>();
  
      private final MyAddressRouter myAddressRouter;
      private final EthereumNetworkRepositoryType networkRepository;
      private final TokensService tokensService;
      private final GasService gasService;
      private final AssetDefinitionService assetDefinitionService;
      private final KeyService keyService;
      private final CreateTransactionInteract createTransactionInteract;
  
      @Inject
      public SendViewModel(MyAddressRouter myAddressRouter,
                           EthereumNetworkRepositoryType ethereumNetworkRepositoryType,
                           TokensService tokensService,
                           CreateTransactionInteract createTransactionInteract,
                           GasService gasService,
                           AssetDefinitionService assetDefinitionService,
                           KeyService keyService,
                           AnalyticsServiceType analyticsService)
      {
          this.myAddressRouter = myAddressRouter;
          this.networkRepository = ethereumNetworkRepositoryType;
          this.tokensService = tokensService;
          this.gasService = gasService;
          this.assetDefinitionService = assetDefinitionService;
          this.keyService = keyService;
          this.createTransactionInteract = createTransactionInteract;
          setAnalyticsService(analyticsService);
      }
  
      public MutableLiveData<TransactionReturn> transactionFinalised()
      {
          return transactionFinalised;
      }
  
      public MutableLiveData<TransactionReturn> transactionError()
      {
          return transactionError;
      }
  
      public void showContractInfo(Context ctx, Wallet wallet, Token token)
      {
          myAddressRouter.open(ctx, wallet, token);
      }
  
      public NetworkInfo getNetworkInfo(long chainId)
      {
          return networkRepository.getNetworkByChain(chainId);
      }
  
      public Token getToken(long chainId, String tokenAddress)
      {
          return tokensService.getToken(chainId, tokenAddress);
      }
  
      public void showImportLink(Context context, String importTxt)
      {
          Intent intent = new Intent(context, ImportTokenActivity.class);
          intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
          intent.putExtra(C.IMPORT_STRING, importTxt);
          context.startActivity(intent);
      }
  
      public void fetchToken(long chainId, String address, String walletAddress)
      {
          tokensService.update(address, chainId, ContractType.NOT_SET)
                  .subscribeOn(Schedulers.io())
                  .observeOn(AndroidSchedulers.mainThread())
                  .subscribe(tokenInfo -> gotTokenUpdate(tokenInfo, walletAddress), this::onError).isDisposed();
      }
  
      private void gotTokenUpdate(TokenInfo tokenInfo, String walletAddress)
      {
          disposable = tokensService.addToken(tokenInfo, walletAddress)
                  .subscribeOn(Schedulers.io())
                  .observeOn(AndroidSchedulers.mainThread())
                  .subscribe(finalisedToken::postValue, this::onError);
      }
  
      public AssetDefinitionService getAssetDefinitionService()
      {
          return assetDefinitionService;
      }
  
      public TokensService getTokenService()
      {
          return tokensService;
      }
  
      public void startGasCycle(long chainId)
      {
          gasService.startGasPriceCycle(chainId);
      }
  
      public void onDestroy()
      {
          gasService.stopGasPriceCycle();
      }
  
      public byte[] getTransactionBytes(Token token, String sendAddress, BigDecimal sendAmount)
      {
          byte[] txBytes;
          if (token.isEthereum())
          {
              txBytes = new byte[0];
          }
          else
          {
              txBytes = TokenRepository.createTokenTransferData(sendAddress, sendAmount.toBigInteger());
          }
  
          return txBytes;
      }
  
      public Single<GasEstimate> calculateGasEstimate(Wallet wallet, byte[] transactionBytes, long chainId, String sendAddress, BigDecimal sendAmount)
      {
          return gasService.calculateGasEstimate(transactionBytes, chainId, sendAddress, sendAmount.toBigInteger(), wallet, BigInteger.ZERO);
      }
  
      public void getAuthentication(Activity activity, Wallet wallet, SignAuthenticationCallback callback)
      {
          keyService.getAuthenticationForSignature(wallet, activity, callback);
      }
  
      public void requestSignature(Web3Transaction finalTx, Wallet wallet, long chainId)
      {
          createTransactionInteract.requestSignature(finalTx, wallet, chainId, this);
      }
  
      public void sendTransaction(Wallet wallet, long chainId, Web3Transaction tx, SignatureFromKey signatureFromKey)
      {
          createTransactionInteract.sendTransaction(wallet, chainId, tx, signatureFromKey);
      }
  
      @Override
      public void transactionFinalised(TransactionReturn txData)
      {
          transactionFinalised.postValue(txData);
      }
  
      @Override
      public void transactionError(TransactionReturn txError)
      {
          transactionError.postValue(txError);
      }
  
      public GasService getGasService()
      {
          return gasService;
      }
  }
  