With nested queries, Airstack finds the intersection of common token holders of multiple ERC20 tokens or NFTs in the following order:
Filtering token holders on the 1st outermost query
Comparing token holders of 1st outermost query against the token holders on 2nd outermost query
Comparing token holders of the 1st and 2nd outermost query against the token holders on the 3rd outermost query
Comparing token holders of 1st, 2nd, ..., nth outermost query against the token holders on (n + 1)-th outermost query
Since the number of objects returned in the responses will be dependent on the number of token holders on the 1st outermost query, it's most efficient that you have the token with the least amount of holders on the 1st outermost query.
Suppose there are two tokens:
Token A: 100,000 holders
Token B: 1,000 holders.
If Token A is the input on the 1st outermost query, then the end result will be 100,000 objects in the response array.
On the other hand, if Token B is the input on the 1st outermost query, then the end result will be instead ONLY 1,000 objects in the response array.
The latter approach will be more efficient and easier for further formatting.
Common Holders of 2 ERC20 Tokens
Fetching
You can fetch the common holders of two given ERC20, e.g. USDT and USDC:
defformat_function(data): result = []if data isnotNoneand'TokenBalances'in data and'TokenBalance'in data['TokenBalances']:for item in data['TokenBalances']['TokenBalance']:if'owner'in item and'tokenBalances'in item['owner']andlen(item['owner']['tokenBalances'])>0and'owner'in item['owner']['tokenBalances'][0] and'addresses'in item['owner']['tokenBalances'][0]['owner']: result.append(item['owner']['tokenBalances'] [0]['owner']['addresses']) result = [item for sublist in result for item in sublist] result =list(set(result))return result
The final result will the the list of all common holders in an array:
{"data": {"TokenBalances": {"TokenBalance": [ {"owner": {"tokenBalances": [ {"owner": {"addresses": ["0x020ca66c30bec2c4fe3861a94e4db4a498a35872" ] },"tokenId":"411" } ] } }, {"owner": {"tokenBalances": [] // Have BAYC, but no Moonbirds } } ] } }}
All the common holders' addresses will be returned inside the innermost owner.addresses field and tokenId is optional for determining which NFT is specifically held by the user as there can be multiple NFTs held by a single user.
Formatting
To get the list of all holders in a flat array, use the following format function:
defformat_function(data): result = []if data isnotNoneand'TokenBalances'in data and'TokenBalance'in data['TokenBalances']:for item in data['TokenBalances']['TokenBalance']:if'owner'in item and'tokenBalances'in item['owner']andlen(item['owner']['tokenBalances'])>0and'owner'in item['owner']['tokenBalances'][0] and'addresses'in item['owner']['tokenBalances'][0]['owner']: result.append(item['owner']['tokenBalances'] [0]['owner']['addresses']) result = [item for sublist in result for item in sublist] result =list(set(result))return result
The final result will the the list of all common holders in an array:
defformat_function(data): result = []if data isnotNoneand'TokenBalances'in data and'TokenBalance'in data['TokenBalances']:for item in data['TokenBalances']['TokenBalance']:if'owner'in item and'tokenBalances'in item['owner']andlen(item['owner']['tokenBalances'])>0and'owner'in item['owner']['tokenBalances'][0] and'addresses'in item['owner']['tokenBalances'][0]['owner']: result.append(item['owner']['tokenBalances'] [0]['owner']['addresses']) result = [item for sublist in result for item in sublist] result =list(set(result))return result
The final result will the the list of all common holders in an array:
defformat_function(data): result = []if data isnotNoneand'TokenBalances'in data and'TokenBalance'in data['TokenBalances']:for item in data['TokenBalances']['TokenBalance']:if'owner'in item and'tokenBalances'in item['owner']andlen(item['owner']['tokenBalances'])>0and'owner'in item['owner']['tokenBalances'][0] and'addresses'in item['owner']['tokenBalances'][0]['owner']: result.append(item['owner']['tokenBalances'] [0]['owner']['addresses']) result = [item for sublist in result for item in sublist] result =list(set(result))return result
The final result will the the list of all common holders in an array:
Common Holders of More Than 2 ERC20 Tokens or NFTs
Fetching
Fetching common holders for more than 2 ERC20 tokens or NFTs works the same way as fetching only 2 ERC20 tokens or NFTs with the addition of more token address parameters and nesting:
defformat_function(data): result = []if data isnotNoneand'TokenBalances'in data and'TokenBalance'in data['TokenBalances']:for item in data['TokenBalances']['TokenBalance']: if 'owner' in item and 'tokenBalances' in item['owner'] and len(item['owner']['tokenBalances']) > 0 and 'owner' in item['owner']['tokenBalances'][0] and 'tokenBalances' in item['owner']['tokenBalances'][0]['owner'] and len(item['owner']['tokenBalances'][0]['owner']['tokenBalances']) > 0 and 'owner' in item['owner']['tokenBalances'][0]['owner']['tokenBalances'][0] and 'addresses' in item['owner']['tokenBalances'][0]['owner']['tokenBalances'][0]['owner']:
result.append(item['owner']['tokenBalances'][0]['owner'] ['tokenBalances'][0]['owner']['addresses']) result = [item for sublist in result for item in sublist] result =list(set(result))return result
The final result will the the list of all common holders in an array: