Optimize getting all incoming and outgoing edges for each node and computing the difference in amounts

That looks much better. I would make one suggest, which is to move the match(w) outside the union query. It is the same query repeated three times.

More importantly, you are assuming each query will return the same results in the same order, so line n in each result corresponds to the same Wallet node. Theoretically it would be possible in a multi user environment that a new Wallet node is added during the execution of this query and now it is possible the three match(w) queries in the union do not return the same results. I know this is probably very unlikely, but it seems like it could be possible.

MATCH (w:Wallet)
CALL {
    WITH w
    OPTIONAL MATCH (w)-[tx:SENT_TO {at: "at"}]-()
    RETURN sum(tx.value) AS total
    UNION ALL
    WITH w
    OPTIONAL MATCH (w)-[tx:SENT_TO {at: "at"}]->()
    RETURN sum(tx.value) AS total
    UNION ALL
    WITH w
    OPTIONAL MATCH (w)<-[tx:SENT_TO {at: "at"}]-() 
    RETURN sum(tx.value) AS total
}
WITH w.address AS address, collect(total) AS values
WHERE values[0] > 0
RETURN address, values[0] AS total, values[1] AS totalOut, values[2] AS totalIn
1 Like