docs: def get_proof(self, index):
          """
          Returns the proof for a leaf at the given index as an array of merkle siblings in hex format
          :param index:
          :return:
          """
  
          if not self.tree['is_ready']:
              return None
          current_row_index = len(self.tree['levels']) - 1
          if index < 0 or index > len(self.tree['levels'][current_row_index]) - 1:
              # the index it out of the bounds of the leaf array
              return None
  
          proof = []
          for current_level in range(current_row_index, 0, -1):
              current_level_node_count = len(self.tree['levels'][current_level])
              # skip if this is an odd end node
              if index == current_level_node_count - 1 and current_level_node_count % 2 == 1:
                  index = int(math.floor(index / 2))
                  continue
  
              # determine the sibling for the current index and get its value
              is_right_node = index % 2
              if is_right_node:
                  sibling_index = index - 1
              else:
                  sibling_index = index + 1
              sibling = {}
  
              if is_right_node:
                  sibling_position = 'left'
              else:
                  sibling_position = 'right'
  
              sibling_value = self.tree['levels'][current_level][sibling_index]
              sibling[sibling_position] = hexlify(sibling_value)
  
              proof.append(sibling)
  
              index = int(math.floor(index / 2))  # set index to the parent index
  
          return proof