Without using a subgraph.
My current approach is to getLogs(filter) after tx 1 confirmation using ethers.js filter
const filter = {
address: contractAddress,
topics: [
ethers.utils.id("Transfer(address,address,uint256)"),
null,
ethers.utils.hexZeroPad(toAdress, 32)
]
}
provider.getLogs(filter).then((logs) => {
resolve(logs)
})