Fetch all DAO treasury wallets and their holdings.
Given a DAO, we need to fetch its treasury info. In order to do this, we need the DAO's realm address. -
Once we have the realm address, we will fetch all the governance accounts for it.
Treasury wallets are a PDA(program derived address) of governance pubkeys and 'native-treasury' text. Code snippet in the below section.
Once we have the treasury wallets, we use Get Portfolio to fetch Sol, Token balances and NFTs in a single call. You can usr any other approach you want.
Here's a fully working code snippet for you to try out in replit.
Fetch Treasury Info For Grape Dao
// Node doesn't implement fetch so we have to import itimport fetch from"node-fetch";import { PublicKey } from"@solana/web3.js";import { promises } from"dns";constSHYFT_API_KEY="YOUR-KEY"asyncfunctionfetchGraphQL(query, variables = {}, name ="MyQuery") {constresult=awaitfetch(`https://programs.shyft.to/v0/graphql/?api_key=${SHYFT_API_KEY}`, { method:"POST", body:JSON.stringify({ query: query, variables: variables, operationName: name }) } );returnawaitresult.json();}asyncfunctiongetGovernanceAccountsForDAO(realmAddress) {//realms should be an arrayconstquery=` query MyQuery($_in: [String!] = "") { GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw_GovernanceV1( where: {realm: {_eq: ${JSON.stringify(realmAddress)}}} ) { pubkey } GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw_GovernanceV2( where: {realm: {_eq: ${JSON.stringify(realmAddress)}}} ) { pubkey }}`const { errors,data } =awaitfetchGraphQL(query);if (errors) {// handle those errors like a proconsole.error(errors); }constgovAccts= []data.GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw_GovernanceV1.forEach((dao) => {govAccts.push(dao?.pubkey) })data.GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw_GovernanceV2.forEach((dao) => {govAccts.push(dao?.pubkey) })console.log(govAccts);return govAccts;}functiongetNativeTreasuryAddress(governanceAccounts) {constprogramId=newPublicKey("GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw")consttreasuryAddress= []governanceAccounts.forEach(async (governance) => {constacc=newPublicKey(governance)const [address] =awaitPublicKey.findProgramAddress( [Buffer.from('native-treasury'),acc.toBuffer()], programId );constaddy=address.toBase58()console.log(addy)treasuryAddress.push(address.toBase58()); })return treasuryAddress;}asyncfunctionfetchTreasuryInfo(wallets) {console.time('portfolio')constpromises= []//Once we have the treasury wallets, we can fetch their holdingswallets.map(async (wallet) => {promises.push(getPortfolio(wallet)) })returnawaitPromise.all(promises);}asyncfunctiongetPortfolio(wallet) {try {console.log('fetching portfolio for ', wallet)constresult=awaitfetch(`https://api.shyft.to/sol/v1/wallet/get_portfolio?network=mainnet-beta&wallet=${wallet}`, { method:"GET", headers: {"Content-Type":"application/json","x-api-key":SHYFT_API_KEY }, } );constres=awaitresult.json()return res; } catch (err) {console.error(err) }}asyncfunctiongetDaoTreasury(realmAddress) {//Get governance accounts for all realmsconstgovernanceAccounts=awaitgetGovernanceAccountsForDAO(realmAddress);console.log('gov accounts fetched');consttreasuryWallets=awaitgetNativeTreasuryAddress(governanceAccounts);console.log('treasury wallets: ', treasuryWallets);returnawaitfetchTreasuryInfo(treasuryWallets);}//Grape DAO treasuryconsttreasury=awaitgetDaoTreasury("By2sVGZXwfQq6rAiAM3rNPJ9iQfb5e2QhnF4YjJ4Bip");console.dir(treasury, {depth:null})