docs: def fetch_wallet_balances(wallets, fiat, **modes):
      """
      Wallets must be list of two item lists. First item is crypto, second item
      is the address. example:
  
      [
          ['btc', '1PZ3Ps9RvCmUW1s1rHE25FeR8vtKUrhEai'],
          ['ltc', 'Lb78JDGxMcih1gs3AirMeRW6jaG5V9hwFZ']
      ]
      """
      price_fetch = set([x[0] for x in wallets])
      balances = {}
      prices = {}
  
      fetch_length = len(wallets) + len(price_fetch)
  
      helpers = {fiat.lower(): {}}
      if not modes.get('async', False):
          # synchronous fetching
          for crypto in price_fetch:
              try:
                  p = get_current_price(
                      crypto, fiat, helper_prices=helpers, report_services=True, **modes
                  )
                  prices[crypto] = {'price': p}
                  if crypto in ['btc', 'ltc', 'doge', 'uno']:
                      helpers[fiat.lower()][crypto] = p
              except NoService as exc:
                  prices[crypto] = {'error': str(exc)}
  
          for crypto, address in wallets:
              if address.replace('.', '').isdigit():
                  balances[address] = {'balance': float(address)}
                  continue
  
              try:
                  balances[address] = {'balance': get_address_balance(crypto, address.strip(), **modes)}
              except NoService as exc:
                  balances[address] = {'error': str(exc)}
  
      else:
          # asynchronous fetching
          if modes.get('verbose', False):
              print("Need to make", fetch_length, "external calls")
  
          with futures.ThreadPoolExecutor(max_workers=int(fetch_length / 2)) as executor:
              future_to_key = dict(
                  (executor.submit(
                      get_current_price, crypto, fiat, report_services=True, **modes
                  ), crypto) for crypto in price_fetch
              )
  
              future_to_key.update(dict(
                  (executor.submit(
                      get_address_balance, crypto, address.strip(), **modes
                  ), address) for crypto, address in wallets
              ))
  
              done, not_done = futures.wait(future_to_key, return_when=futures.ALL_COMPLETED)
              if len(not_done) > 0:
                  print (not_done)
                  import debug
                  raise Exception("Broke") #not_done.pop().exception()
  
              for future in done:
                  key = future_to_key[future]
                  if len(key) > 5: # this will break if a crypto symbol is longer than 5 chars.
                      which = balances
                  else:
                      which = prices
  
                  res = future.result()
                  which[key] = res
  
      ret = []
  
      for crypto, address in wallets:
          error = None
          if 'balance' in balances[address]:
              crypto_value = balances[address]['balance']
          else:
              crypto_value = 0
              error = balances[address]['error']
  
          if 'price' in prices[crypto]:
              sources, fiat_price = prices[crypto]['price']
          else:
              sources, fiat_price = [], 0
              error = prices[crypto]['error']
  
          ret.append({
              'crypto': crypto,
              'address': address,
              'crypto_value': crypto_value,
              'fiat_value': (crypto_value or 0) * (fiat_price or 0),
              'conversion_price': fiat_price,
              'price_source': sources[0].name if sources else "None",
              'error': error
          })
  
      return ret