moody.m.b_send.looper API documentation

# Module `moody.m.b_send.looper`

Expand source code

    # !/usr/bin/env python
    # -*- coding: utf-8 -*-
    # pylint: disable=C0116,W0613
    # This program is dedicated to the public domain under the CC0 license.
    import math
    import time

    import pandas as pd
    from web3 import exceptions, _utils

    from ..b_send import BSend
    from ..b_send.basec import BaseBulk, PrintNetworkName
    from ..pharaohs import pharaohs
    from ...libeb import MiliDoS

    class LooperBulk(BaseBulk):
        """
        Bulk manager execution now
        @
        """

        def __init__(self, mHold: MiliDoS):
            self.dos = mHold
            PrintNetworkName(mHold.network_cfg)
            super().__init__()
            self.__n = 0
            self.__t = 0
            self.wait_pause = False

        def ActivateWaitPause(self):
            self.wait_pause = True

        def _line_progress(self, notify=None) -> None:
            if notify is None:
                return
            else:
                perc = "{0:.0f}%".format(self.__n / self.__t * 100)
                notify(self.__n, self.__t, perc)

        def _line_error(self, errorNotify=None, info: str = "") -> None:
            if errorNotify is None:
                print(f"======{info}")
            else:
                errorNotify(info)

        def executeTokenTransferOnContractBusTg(
                self,
                express_contract: BSend,
                coin_contract: pharaohs,
                notify=None, errorNotify=None) -> None:

            coin_address = coin_contract.contract_address
            express_address = express_contract.contract_address
            self.__t = len(self._batch)

            if not self._batch_contract:
                self._line_error(errorNotify, f"⚠️ Batch contract is not activated")
                return

            if not self._is_valid_address(coin_address):
                self._line_error(errorNotify, f"⚠️ ERC20 is not valid {coin_address}")
                return

            for batch in self._batch:
                try:
                    batch_size = len(batch[0])
                    total_approval = sum(batch[1])
                    _address = batch[0]
                    _amount = batch[1]

                    print(f"====== result batch len: {len(batch[0])}, approving: {total_approval}")
                    balance = coin_contract.balance_of(self.dos.accountAddr)

                    if balance >= total_approval:
                        coin_contract.EnforceTxReceipt(True)
                        coin_contract.approve(express_address, total_approval)
                    else:
                        self._line_error(errorNotify, f"⚠️ not enough in the balance")
                        return

                    print(f"====== start batch transactions")
                    express_contract.EnforceTxReceipt(False).bulk_send_token(
                        coin_address, _address, _amount, 0
                    )

                    self.__n += 1
                    self._line_progress(notify)

                    if batch_size == self.batch_limit and self.wait_pause:
                        print("====== result bulk_send_token, the next batch will start in 30 seconds")
                        time.sleep(30)
                    else:
                        print("====== Now the next wave of token send will start immediately")

                except exceptions.CannotHandleRequest:
                    self._line_error(errorNotify, f"⚠️ request is not handled")
                    return
                except _utils.threads.Timeout:
                    self._line_error(errorNotify, f"⚠️ threads timeout")
                    return
                except exceptions.TimeExhausted:
                    self._line_error(errorNotify, f"⚠️ the transaction is not on chain after timeout")
                    return

    class TestBulkManager(LooperBulk):
        """
        Bulk manager execution now
        @
        """

        def __init__(self, dat: list, mHold: MiliDoS):
            self.datlist = dat
            super().__init__(mHold)
            self._enableContractBatch()

        def prep(self) -> "TestBulkManager":
            self._status_busy = True
            for row in self.datlist:
                address = str(row[0])
                amount = float(row[1])
                enter_digit = int(amount * 10 ** self.decimal)
                if self._is_valid_address(address):
                    self._line_read_code(address, amount, enter_digit)
                    self.entryAdd(address, enter_digit)
                else:
                    self._line_invalid_address(address)
                    self.entryErrAdd(address, enter_digit)

            self._batch_preprocess()
            self.PreStatement()

            return self

        def getSENDAddresses(self) -> list:
            return self.list_address

        def getSENDAmountBalances(self) -> list:
            return self.list_amount

        def getPlatformVal(self) -> int:
            """
            since the entry for python function on SAP is required to be int
            """
            return math.ceil(self.total / TestBulkManager.wei)

    class ExcelBasic(LooperBulk):

        def __init__(self, filepath, mHold: MiliDoS):
            super().__init__(mHold)
            self.exeFilepath = filepath
            self.kAddress = "address"
            self.kAmount = "amount"
            PrintNetworkName(mHold.network_cfg)

        def useKeyChinese(self) -> "ExcelBasic":
            self.kAddress = "提现地址"
            self.kAmount = "提现金额"
            return self

        def useKeyEng(self) -> "ExcelBasic":
            self.kAddress = "address"
            self.kAmount = "amount"
            return self

    class ExcelBulkManager(ExcelBasic):
        """
        using contract on making at least 250 transactions in a batch.
        """

        def __init__(self, filepath, m: MiliDoS):
            super().__init__(filepath, m)
            self._enableContractBatch()

        def prep(self) -> "ExcelBulkManager":
            self._status_busy = True
            # df = pd.read_excel(r'C:\Users\Ron\Desktop\Product List.xlsx')
            data = pd.read_excel(self.exeFilepath)
            # data = pd.read_excel(r'C:\Users\Ron\Desktop\Product List.xlsx')
            df = pd.DataFrame(data, columns=[self.kAddress, self.kAmount])
            for index, row in df.iterrows():

                # trim line
                address = str(row[self.kAddress]).translate(str.maketrans('', '', ' \n\t\r'))
                amount = float(row[self.kAmount])
                enter_digit = int(amount * 10 ** self.decimal)
                if self._is_valid_address(address):
                    self._line_read_code(row[self.kAddress], amount, enter_digit)
                    self.entryAdd(address, enter_digit)
                else:
                    self._line_invalid_address(address)
                    self.entryErrAdd(address, enter_digit)
                    continue

            self._batch_preprocess()
            self.PreStatement()

            return self

        def getSENDAddresses(self) -> list:
            return self.list_address

        def getSENDAmountBalances(self) -> list:
            return self.list_amount

        def getSENDTotal(self) -> int:
            return self.total

        def getPlatformVal(self) -> int:
            return int(self.total / TestBulkManager.wei)

    class ExcelBulkManagerClassic(ExcelBasic):
        """
        This is the traditional wallet to wallet transaction transfer using the native method
        """

        def __init__(self, filepath, tron):
            super().__init__(filepath, tron)

        def prep(self) -> "ExcelBulkManagerClassic":
            self._status_busy = True
            # df = pd.read_excel(r'C:\Users\Ron\Desktop\Product List.xlsx')
            data = pd.read_excel(self.exeFilepath)
            # data = pd.read_excel(r'C:\Users\Ron\Desktop\Product List.xlsx')
            df = pd.DataFrame(data, columns=[self.kAddress, self.kAmount])
            for index, row in df.iterrows():
                # trim line
                address = str(row[self.kAddress]).translate(str.maketrans('', '', ' \n\t\r'))
                amount = float(row[self.kAmount])
                enter_digit = int(amount * 10 ** self.decimal)
                try:
                    if self._is_valid_address(address):
                        self._line_color_code(address, amount, enter_digit)
                        self.entryAdd(address, enter_digit)
                    else:
                        self._line_color_invalid_address(address, enter_digit)
                        self.entryErrAdd(address, enter_digit)

                except ValueError as h:
                    self._line_color_invalid_address(address, enter_digit, h)
                    self.entryErrAdd(address, enter_digit)

            self.PreStatement()

            return self

        def getSENDAddresses(self) -> list:
            return self.list_address

        def getSENDAmountBalances(self) -> list:
            return self.list_amount

        def getSENDTotal(self) -> int:
            return self.total

        def executeTokenDistribution(self, token: pharaohs, notify=None):
            v = 0
            self._status_busy = True

            if len(self.list_amount) != len(self.list_address):
                print("error in checking the length of transaction list")
                return

            for address in self.list_address:
                token.transfer(address, self.list_amount[v])
                v += 1
                if notify is not None:
                    self.processed_count = v
                    perc = "{0:.0f}%".format(v / self.transaction_count * 100)
                    notify(v, self.transaction_count, perc)

            self._status_busy = False

        def executeTokenTransferDistributionTg(self, token: pharaohs, notify=None, errorNotify=None):
            """
             limitation: https://core.telegram.org/bots/faq#my-bot-is-hitting-limits-how-do-i-avoid-this
             When sending messages inside a particular chat, avoid sending more than one message per second. We may allow short bursts that go over this limit, but eventually you'll begin receiving 429 errors.
             If you're sending bulk notifications to multiple users, the API will not allow more than 30 messages per second or so. Consider spreading out notifications over large intervals of 8—12 hours for best results.
             Also note that your bot will not be able to send more than 20 messages per minute to the same group.

             errors from the operation

            """
            v = 0
            self._status_busy = True

            _timestamp = self.nowSec
            if len(self.list_amount) != len(self.list_address):
                errorNotify("error in checking the length of transaction list")
                return
            try:

                for address in self.list_address:
                    recipient = address
                    report_amount = self.list_amount[v]
                    token.transfer(recipient, report_amount)
                    v += 1
                    _dela = self.nowSec
                    if notify is not None and _dela > _timestamp + 5:
                        _timestamp = self.nowSec
                        self.processed_count = v
                        _perc = "{0:.0f}%".format(v / self.transaction_count * 100)
                        notify(v, self.transaction_count, _perc)

                    if self._file_logger is not None:
                        self._file_logger(f"#{v} {recipient} {report_amount} 📤 ")

                    time.sleep(0.5)

            except ValueError:
                errorNotify("Value error. unknown error")
                return

            self._status_busy = False

## Classes

`class ExcelBasic (filepath, mHold: MiliDoS)`

  Bulk manager execution now @

  Expand source code

      class ExcelBasic(LooperBulk):

          def __init__(self, filepath, mHold: MiliDoS):
              super().__init__(mHold)
              self.exeFilepath = filepath
              self.kAddress = "address"
              self.kAmount = "amount"
              PrintNetworkName(mHold.network_cfg)

          def useKeyChinese(self) -> "ExcelBasic":
              self.kAddress = "提现地址"
              self.kAmount = "提现金额"
              return self

          def useKeyEng(self) -> "ExcelBasic":
              self.kAddress = "address"
              self.kAmount = "amount"
              return self

  ### Ancestors

  - LooperBulk
  - BaseBulk

  ### Subclasses

  - ExcelBulkManager
  - ExcelBulkManagerClassic

  ### Methods

  `def useKeyChinese(self) ‑> ExcelBasic`
    Expand source code

        def useKeyChinese(self) -> "ExcelBasic":
            self.kAddress = "提现地址"
            self.kAmount = "提现金额"
            return self

  `def useKeyEng(self) ‑> ExcelBasic`
    Expand source code

        def useKeyEng(self) -> "ExcelBasic":
            self.kAddress = "address"
            self.kAmount = "amount"
            return self

  ### Inherited members

  - `LooperBulk`:
    - `entryAdd`
    - `weiUpdate`
    - `withDecimal`
`class ExcelBulkManager (filepath, m: MiliDoS)`

  using contract on making at least 250 transactions in a batch.

  Expand source code

      class ExcelBulkManager(ExcelBasic):
          """
          using contract on making at least 250 transactions in a batch.
          """

          def __init__(self, filepath, m: MiliDoS):
              super().__init__(filepath, m)
              self._enableContractBatch()

          def prep(self) -> "ExcelBulkManager":
              self._status_busy = True
              # df = pd.read_excel(r'C:\Users\Ron\Desktop\Product List.xlsx')
              data = pd.read_excel(self.exeFilepath)
              # data = pd.read_excel(r'C:\Users\Ron\Desktop\Product List.xlsx')
              df = pd.DataFrame(data, columns=[self.kAddress, self.kAmount])
              for index, row in df.iterrows():

                  # trim line
                  address = str(row[self.kAddress]).translate(str.maketrans('', '', ' \n\t\r'))
                  amount = float(row[self.kAmount])
                  enter_digit = int(amount * 10 ** self.decimal)
                  if self._is_valid_address(address):
                      self._line_read_code(row[self.kAddress], amount, enter_digit)
                      self.entryAdd(address, enter_digit)
                  else:
                      self._line_invalid_address(address)
                      self.entryErrAdd(address, enter_digit)
                      continue

              self._batch_preprocess()
              self.PreStatement()

              return self

          def getSENDAddresses(self) -> list:
              return self.list_address

          def getSENDAmountBalances(self) -> list:
              return self.list_amount

          def getSENDTotal(self) -> int:
              return self.total

          def getPlatformVal(self) -> int:
              return int(self.total / TestBulkManager.wei)

  ### Ancestors

  - ExcelBasic
  - LooperBulk
  - BaseBulk

  ### Methods

  `def getPlatformVal(self) ‑> int`
    Expand source code

        def getPlatformVal(self) -> int:
            return int(self.total / TestBulkManager.wei)

  `def getSENDAddresses(self) ‑> list`
    Expand source code

        def getSENDAddresses(self) -> list:
            return self.list_address

  `def getSENDAmountBalances(self) ‑> list`
    Expand source code

        def getSENDAmountBalances(self) -> list:
            return self.list_amount

  `def getSENDTotal(self) ‑> int`
    Expand source code

        def getSENDTotal(self) -> int:
            return self.total

  `def prep(self) ‑> ExcelBulkManager`
    Expand source code

        def prep(self) -> "ExcelBulkManager":
            self._status_busy = True
            # df = pd.read_excel(r'C:\Users\Ron\Desktop\Product List.xlsx')
            data = pd.read_excel(self.exeFilepath)
            # data = pd.read_excel(r'C:\Users\Ron\Desktop\Product List.xlsx')
            df = pd.DataFrame(data, columns=[self.kAddress, self.kAmount])
            for index, row in df.iterrows():

                # trim line
                address = str(row[self.kAddress]).translate(str.maketrans('', '', ' \n\t\r'))
                amount = float(row[self.kAmount])
                enter_digit = int(amount * 10 ** self.decimal)
                if self._is_valid_address(address):
                    self._line_read_code(row[self.kAddress], amount, enter_digit)
                    self.entryAdd(address, enter_digit)
                else:
                    self._line_invalid_address(address)
                    self.entryErrAdd(address, enter_digit)
                    continue

            self._batch_preprocess()
            self.PreStatement()

            return self

  ### Inherited members

  - `ExcelBasic`:
    - `entryAdd`
    - `weiUpdate`
    - `withDecimal`
`class ExcelBulkManagerClassic (filepath, tron)`

  This is the traditional wallet to wallet transaction transfer using the native method

  Expand source code

      class ExcelBulkManagerClassic(ExcelBasic):
          """
          This is the traditional wallet to wallet transaction transfer using the native method
          """

          def __init__(self, filepath, tron):
              super().__init__(filepath, tron)

          def prep(self) -> "ExcelBulkManagerClassic":
              self._status_busy = True
              # df = pd.read_excel(r'C:\Users\Ron\Desktop\Product List.xlsx')
              data = pd.read_excel(self.exeFilepath)
              # data = pd.read_excel(r'C:\Users\Ron\Desktop\Product List.xlsx')
              df = pd.DataFrame(data, columns=[self.kAddress, self.kAmount])
              for index, row in df.iterrows():
                  # trim line
                  address = str(row[self.kAddress]).translate(str.maketrans('', '', ' \n\t\r'))
                  amount = float(row[self.kAmount])
                  enter_digit = int(amount * 10 ** self.decimal)
                  try:
                      if self._is_valid_address(address):
                          self._line_color_code(address, amount, enter_digit)
                          self.entryAdd(address, enter_digit)
                      else:
                          self._line_color_invalid_address(address, enter_digit)
                          self.entryErrAdd(address, enter_digit)

                  except ValueError as h:
                      self._line_color_invalid_address(address, enter_digit, h)
                      self.entryErrAdd(address, enter_digit)

              self.PreStatement()

              return self

          def getSENDAddresses(self) -> list:
              return self.list_address

          def getSENDAmountBalances(self) -> list:
              return self.list_amount

          def getSENDTotal(self) -> int:
              return self.total

          def executeTokenDistribution(self, token: pharaohs, notify=None):
              v = 0
              self._status_busy = True

              if len(self.list_amount) != len(self.list_address):
                  print("error in checking the length of transaction list")
                  return

              for address in self.list_address:
                  token.transfer(address, self.list_amount[v])
                  v += 1
                  if notify is not None:
                      self.processed_count = v
                      perc = "{0:.0f}%".format(v / self.transaction_count * 100)
                      notify(v, self.transaction_count, perc)

              self._status_busy = False

          def executeTokenTransferDistributionTg(self, token: pharaohs, notify=None, errorNotify=None):
              """
               limitation: https://core.telegram.org/bots/faq#my-bot-is-hitting-limits-how-do-i-avoid-this
               When sending messages inside a particular chat, avoid sending more than one message per second. We may allow short bursts that go over this limit, but eventually you'll begin receiving 429 errors.
               If you're sending bulk notifications to multiple users, the API will not allow more than 30 messages per second or so. Consider spreading out notifications over large intervals of 8—12 hours for best results.
               Also note that your bot will not be able to send more than 20 messages per minute to the same group.

               errors from the operation

              """
              v = 0
              self._status_busy = True

              _timestamp = self.nowSec
              if len(self.list_amount) != len(self.list_address):
                  errorNotify("error in checking the length of transaction list")
                  return
              try:

                  for address in self.list_address:
                      recipient = address
                      report_amount = self.list_amount[v]
                      token.transfer(recipient, report_amount)
                      v += 1
                      _dela = self.nowSec
                      if notify is not None and _dela > _timestamp + 5:
                          _timestamp = self.nowSec
                          self.processed_count = v
                          _perc = "{0:.0f}%".format(v / self.transaction_count * 100)
                          notify(v, self.transaction_count, _perc)

                      if self._file_logger is not None:
                          self._file_logger(f"#{v} {recipient} {report_amount} 📤 ")

                      time.sleep(0.5)

              except ValueError:
                  errorNotify("Value error. unknown error")
                  return

              self._status_busy = False

  ### Ancestors

  - ExcelBasic
  - LooperBulk
  - BaseBulk

  ### Methods

  `def executeTokenDistribution(self, token: pharaohs, notify=None)`
    Expand source code

        def executeTokenDistribution(self, token: pharaohs, notify=None):
            v = 0
            self._status_busy = True

            if len(self.list_amount) != len(self.list_address):
                print("error in checking the length of transaction list")
                return

            for address in self.list_address:
                token.transfer(address, self.list_amount[v])
                v += 1
                if notify is not None:
                    self.processed_count = v
                    perc = "{0:.0f}%".format(v / self.transaction_count * 100)
                    notify(v, self.transaction_count, perc)

            self._status_busy = False

  `def executeTokenTransferDistributionTg(self, token: pharaohs, notify=None, errorNotify=None)`

    limitation: https://core.telegram.org/bots/faq#my-bot-is-hitting-limits-how-do-i-avoid-this When sending messages inside a particular chat, avoid sending more than one message per second. We may allow short bursts that go over this limit, but eventually you'll begin receiving 429 errors. If you're sending bulk notifications to multiple users, the API will not allow more than 30 messages per second or so. Consider spreading out notifications over large intervals of 8—12 hours for best results. Also note that your bot will not be able to send more than 20 messages per minute to the same group.

    errors from the operation

    Expand source code

        def executeTokenTransferDistributionTg(self, token: pharaohs, notify=None, errorNotify=None):
            """
             limitation: https://core.telegram.org/bots/faq#my-bot-is-hitting-limits-how-do-i-avoid-this
             When sending messages inside a particular chat, avoid sending more than one message per second. We may allow short bursts that go over this limit, but eventually you'll begin receiving 429 errors.
             If you're sending bulk notifications to multiple users, the API will not allow more than 30 messages per second or so. Consider spreading out notifications over large intervals of 8—12 hours for best results.
             Also note that your bot will not be able to send more than 20 messages per minute to the same group.

             errors from the operation

            """
            v = 0
            self._status_busy = True

            _timestamp = self.nowSec
            if len(self.list_amount) != len(self.list_address):
                errorNotify("error in checking the length of transaction list")
                return
            try:

                for address in self.list_address:
                    recipient = address
                    report_amount = self.list_amount[v]
                    token.transfer(recipient, report_amount)
                    v += 1
                    _dela = self.nowSec
                    if notify is not None and _dela > _timestamp + 5:
                        _timestamp = self.nowSec
                        self.processed_count = v
                        _perc = "{0:.0f}%".format(v / self.transaction_count * 100)
                        notify(v, self.transaction_count, _perc)

                    if self._file_logger is not None:
                        self._file_logger(f"#{v} {recipient} {report_amount} 📤 ")

                    time.sleep(0.5)

            except ValueError:
                errorNotify("Value error. unknown error")
                return

            self._status_busy = False

  `def getSENDAddresses(self) ‑> list`
    Expand source code

        def getSENDAddresses(self) -> list:
            return self.list_address

  `def getSENDAmountBalances(self) ‑> list`
    Expand source code

        def getSENDAmountBalances(self) -> list:
            return self.list_amount

  `def getSENDTotal(self) ‑> int`
    Expand source code

        def getSENDTotal(self) -> int:
            return self.total

  `def prep(self) ‑> ExcelBulkManagerClassic`
    Expand source code

        def prep(self) -> "ExcelBulkManagerClassic":
            self._status_busy = True
            # df = pd.read_excel(r'C:\Users\Ron\Desktop\Product List.xlsx')
            data = pd.read_excel(self.exeFilepath)
            # data = pd.read_excel(r'C:\Users\Ron\Desktop\Product List.xlsx')
            df = pd.DataFrame(data, columns=[self.kAddress, self.kAmount])
            for index, row in df.iterrows():
                # trim line
                address = str(row[self.kAddress]).translate(str.maketrans('', '', ' \n\t\r'))
                amount = float(row[self.kAmount])
                enter_digit = int(amount * 10 ** self.decimal)
                try:
                    if self._is_valid_address(address):
                        self._line_color_code(address, amount, enter_digit)
                        self.entryAdd(address, enter_digit)
                    else:
                        self._line_color_invalid_address(address, enter_digit)
                        self.entryErrAdd(address, enter_digit)

                except ValueError as h:
                    self._line_color_invalid_address(address, enter_digit, h)
                    self.entryErrAdd(address, enter_digit)

            self.PreStatement()

            return self

  ### Inherited members

  - `ExcelBasic`:
    - `entryAdd`
    - `weiUpdate`
    - `withDecimal`
`class LooperBulk (mHold: MiliDoS)`

  Bulk manager execution now @

  Expand source code

      class LooperBulk(BaseBulk):
          """
          Bulk manager execution now
          @
          """

          def __init__(self, mHold: MiliDoS):
              self.dos = mHold
              PrintNetworkName(mHold.network_cfg)
              super().__init__()
              self.__n = 0
              self.__t = 0
              self.wait_pause = False

          def ActivateWaitPause(self):
              self.wait_pause = True

          def _line_progress(self, notify=None) -> None:
              if notify is None:
                  return
              else:
                  perc = "{0:.0f}%".format(self.__n / self.__t * 100)
                  notify(self.__n, self.__t, perc)

          def _line_error(self, errorNotify=None, info: str = "") -> None:
              if errorNotify is None:
                  print(f"======{info}")
              else:
                  errorNotify(info)

          def executeTokenTransferOnContractBusTg(
                  self,
                  express_contract: BSend,
                  coin_contract: pharaohs,
                  notify=None, errorNotify=None) -> None:

              coin_address = coin_contract.contract_address
              express_address = express_contract.contract_address
              self.__t = len(self._batch)

              if not self._batch_contract:
                  self._line_error(errorNotify, f"⚠️ Batch contract is not activated")
                  return

              if not self._is_valid_address(coin_address):
                  self._line_error(errorNotify, f"⚠️ ERC20 is not valid {coin_address}")
                  return

              for batch in self._batch:
                  try:
                      batch_size = len(batch[0])
                      total_approval = sum(batch[1])
                      _address = batch[0]
                      _amount = batch[1]

                      print(f"====== result batch len: {len(batch[0])}, approving: {total_approval}")
                      balance = coin_contract.balance_of(self.dos.accountAddr)

                      if balance >= total_approval:
                          coin_contract.EnforceTxReceipt(True)
                          coin_contract.approve(express_address, total_approval)
                      else:
                          self._line_error(errorNotify, f"⚠️ not enough in the balance")
                          return

                      print(f"====== start batch transactions")
                      express_contract.EnforceTxReceipt(False).bulk_send_token(
                          coin_address, _address, _amount, 0
                      )

                      self.__n += 1
                      self._line_progress(notify)

                      if batch_size == self.batch_limit and self.wait_pause:
                          print("====== result bulk_send_token, the next batch will start in 30 seconds")
                          time.sleep(30)
                      else:
                          print("====== Now the next wave of token send will start immediately")

                  except exceptions.CannotHandleRequest:
                      self._line_error(errorNotify, f"⚠️ request is not handled")
                      return
                  except _utils.threads.Timeout:
                      self._line_error(errorNotify, f"⚠️ threads timeout")
                      return
                  except exceptions.TimeExhausted:
                      self._line_error(errorNotify, f"⚠️ the transaction is not on chain after timeout")
                      return

  ### Ancestors

  - BaseBulk

  ### Subclasses

  - ExcelBasic
  - TestBulkManager

  ### Methods

  `def ActivateWaitPause(self)`
    Expand source code

        def ActivateWaitPause(self):
            self.wait_pause = True

  `def executeTokenTransferOnContractBusTg(self, express_contract: BSend, coin_contract: pharaohs, notify=None, errorNotify=None) ‑> NoneType`
    Expand source code

        def executeTokenTransferOnContractBusTg(
                self,
                express_contract: BSend,
                coin_contract: pharaohs,
                notify=None, errorNotify=None) -> None:

            coin_address = coin_contract.contract_address
            express_address = express_contract.contract_address
            self.__t = len(self._batch)

            if not self._batch_contract:
                self._line_error(errorNotify, f"⚠️ Batch contract is not activated")
                return

            if not self._is_valid_address(coin_address):
                self._line_error(errorNotify, f"⚠️ ERC20 is not valid {coin_address}")
                return

            for batch in self._batch:
                try:
                    batch_size = len(batch[0])
                    total_approval = sum(batch[1])
                    _address = batch[0]
                    _amount = batch[1]

                    print(f"====== result batch len: {len(batch[0])}, approving: {total_approval}")
                    balance = coin_contract.balance_of(self.dos.accountAddr)

                    if balance >= total_approval:
                        coin_contract.EnforceTxReceipt(True)
                        coin_contract.approve(express_address, total_approval)
                    else:
                        self._line_error(errorNotify, f"⚠️ not enough in the balance")
                        return

                    print(f"====== start batch transactions")
                    express_contract.EnforceTxReceipt(False).bulk_send_token(
                        coin_address, _address, _amount, 0
                    )

                    self.__n += 1
                    self._line_progress(notify)

                    if batch_size == self.batch_limit and self.wait_pause:
                        print("====== result bulk_send_token, the next batch will start in 30 seconds")
                        time.sleep(30)
                    else:
                        print("====== Now the next wave of token send will start immediately")

                except exceptions.CannotHandleRequest:
                    self._line_error(errorNotify, f"⚠️ request is not handled")
                    return
                except _utils.threads.Timeout:
                    self._line_error(errorNotify, f"⚠️ threads timeout")
                    return
                except exceptions.TimeExhausted:
                    self._line_error(errorNotify, f"⚠️ the transaction is not on chain after timeout")
                    return

  ### Inherited members

  - `BaseBulk`:
    - `entryAdd`
    - `weiUpdate`
    - `withDecimal`
`class TestBulkManager (dat: list, mHold: MiliDoS)`

  Bulk manager execution now @

  Expand source code

      class TestBulkManager(LooperBulk):
          """
          Bulk manager execution now
          @
          """

          def __init__(self, dat: list, mHold: MiliDoS):
              self.datlist = dat
              super().__init__(mHold)
              self._enableContractBatch()

          def prep(self) -> "TestBulkManager":
              self._status_busy = True
              for row in self.datlist:
                  address = str(row[0])
                  amount = float(row[1])
                  enter_digit = int(amount * 10 ** self.decimal)
                  if self._is_valid_address(address):
                      self._line_read_code(address, amount, enter_digit)
                      self.entryAdd(address, enter_digit)
                  else:
                      self._line_invalid_address(address)
                      self.entryErrAdd(address, enter_digit)

              self._batch_preprocess()
              self.PreStatement()

              return self

          def getSENDAddresses(self) -> list:
              return self.list_address

          def getSENDAmountBalances(self) -> list:
              return self.list_amount

          def getPlatformVal(self) -> int:
              """
              since the entry for python function on SAP is required to be int
              """
              return math.ceil(self.total / TestBulkManager.wei)

  ### Ancestors

  - LooperBulk
  - BaseBulk

  ### Methods

  `def getPlatformVal(self) ‑> int`

    since the entry for python function on SAP is required to be int

    Expand source code

        def getPlatformVal(self) -> int:
            """
            since the entry for python function on SAP is required to be int
            """
            return math.ceil(self.total / TestBulkManager.wei)

  `def getSENDAddresses(self) ‑> list`
    Expand source code

        def getSENDAddresses(self) -> list:
            return self.list_address

  `def getSENDAmountBalances(self) ‑> list`
    Expand source code

        def getSENDAmountBalances(self) -> list:
            return self.list_amount

  `def prep(self) ‑> TestBulkManager`
    Expand source code

        def prep(self) -> "TestBulkManager":
            self._status_busy = True
            for row in self.datlist:
                address = str(row[0])
                amount = float(row[1])
                enter_digit = int(amount * 10 ** self.decimal)
                if self._is_valid_address(address):
                    self._line_read_code(address, amount, enter_digit)
                    self.entryAdd(address, enter_digit)
                else:
                    self._line_invalid_address(address)
                    self.entryErrAdd(address, enter_digit)

            self._batch_preprocess()
            self.PreStatement()

            return self

  ### Inherited members

  - `LooperBulk`:
    - `entryAdd`
    - `weiUpdate`
    - `withDecimal`