def to_dict(self) -> dict:
        """ Generates a graph representation in terms of a dictionary.

        The dictionary contains only native python types and can be encoded
        to json.
        """
        with self.lock:
            graph = {'nodes': [], 'channels': []}

            # gather nodes
            for pk, nodeinfo in self._nodes.items():
                # use _asdict() to convert NamedTuples to json encodable dicts
                graph['nodes'].append(
                    nodeinfo._asdict(),
                )
                graph['nodes'][-1]['addresses'] = [
                    {'host': str(addr.host), 'port': addr.port, 'timestamp': ts}
                    for addr, ts in self._addresses[pk].items()
                ]

            # gather channels
            for cid, channelinfo in self._channels.items():
                graph['channels'].append(
                    channelinfo._asdict(),
                )
                policy1 = self._policies.get(
                    (channelinfo.node1_id, channelinfo.short_channel_id))
                policy2 = self._policies.get(
                    (channelinfo.node2_id, channelinfo.short_channel_id))
                graph['channels'][-1]['policy1'] = policy1._asdict() if policy1 else None
                graph['channels'][-1]['policy2'] = policy2._asdict() if policy2 else None

        # need to use json_normalize otherwise json encoding in rpc server fails
        graph = json_normalize(graph)
        return graph
 Generates a graph representation in terms of a dictionary.

        The dictionary contains only native python types and can be encoded
        to json.
        
electrum/channel_db.py