text: from typing import Callable, List, Optional
  
  import blspy
  from blspy import AugSchemeMPL, PrivateKey
  
  from chia.types.coin_solution import CoinSolution
  from chia.types.spend_bundle import SpendBundle
  from chia.util.condition_tools import conditions_dict_for_solution, pkm_pairs_for_conditions_dict
  
  
  async def sign_coin_solutions(
      coin_solutions: List[CoinSolution],
      secret_key_for_public_key_f: Callable[[blspy.G1Element], Optional[PrivateKey]],
      additional_data: bytes,
      max_cost: int,
  ) -> SpendBundle:
      signatures: List[blspy.G2Element] = []
      pk_list: List[blspy.G1Element] = []
      msg_list: List[bytes] = []
      for coin_solution in coin_solutions:
          # Get AGG_SIG conditions
          err, conditions_dict, cost = conditions_dict_for_solution(
              coin_solution.puzzle_reveal, coin_solution.solution, max_cost
          )
          if err or conditions_dict is None:
              error_msg = f"Sign transaction failed, con:{conditions_dict}, error: {err}"
              raise ValueError(error_msg)
  
          # Create signature
          for pk, msg in pkm_pairs_for_conditions_dict(
              conditions_dict, bytes(coin_solution.coin.name()), additional_data
          ):
              pk_list.append(pk)
              msg_list.append(msg)
              secret_key = secret_key_for_public_key_f(pk)
              if secret_key is None:
                  e_msg = f"no secret key for {pk}"
                  raise ValueError(e_msg)
              assert bytes(secret_key.get_g1()) == bytes(pk)
              signature = AugSchemeMPL.sign(secret_key, msg)
              assert AugSchemeMPL.verify(pk, msg, signature)
              signatures.append(signature)
  
      # Aggregate signatures
      aggsig = AugSchemeMPL.aggregate(signatures)
      assert AugSchemeMPL.aggregate_verify(pk_list, msg_list, aggsig)
      return SpendBundle(coin_solutions, aggsig)
  