Sub-Adapters 1
Preview and test each sub adapter.
Aave (aave)
Metadata
- ID
- aave
- icon
- category
"app"
- name
"Aave"
- website
"https://aave.com"
- governanceSite
"https://app.aave.com/governance"
- governanceForum
"https://governance.aave.com"
- governanceModel
""
- treasuries
[ "0x25F2226B597E8F9514B3F68F00f494cF4f286491", "0x464C71f6c2F760DdA6093dCB91C24c39e5d6e18c" ]
Queries
Adapter Code
Check the entire code written for the Adapter.
Source code
Showing TS source.
1export const name = 'Aave Treasury';
2export const version = '0.1.0';
3export const license = 'MIT';
4
5const ECOSYSTEM_RESERVE = '0x25F2226B597E8F9514B3F68F00f494cF4f286491';
6const revenueCollector = '0x464C71f6c2F760DdA6093dCB91C24c39e5d6e18c';
7
8interface PortfolioAsset {
9 address: string
10 amount: number
11 name: string
12 symbol: string
13 icon: string
14 price: number
15 value: number
16}
17
18export async function setup(sdk: Context) {
19 let treasuryPortfolioPromise: Promise<any> | null
20 const getEcosystemReservePortfolio = (): Promise<any> => {
21 if (!treasuryPortfolioPromise) {
22 treasuryPortfolioPromise = sdk.http.get(`https://zerion-api.vercel.app/api/portfolio/${ECOSYSTEM_RESERVE}`)
23 .then(result => {
24 if (result.success) {
25 return result.value
26 }
27 throw new Error(result.message)
28 })
29 }
30 return treasuryPortfolioPromise
31 }
32
33 const cache: { [address: string]: Promise<any> } = {}
34
35 function getEthplorerPortfolio(address: string) {
36 if (!cache[address]) {
37 cache[address] = getEthplorerPortfolioInternal(address)
38 }
39 return cache[address]
40 }
41
42 async function getEthplorerPortfolioInternal(address: string) {
43 const data = await sdk.http.get(`https://api.ethplorer.io/getAddressInfo/${address}?apiKey=freekey`)
44
45 let totalValue = data.ETH.balance * data.ETH.price.rate
46
47 const pricesBySymbol: { [symbol: string]: number } = {}
48 const portfolio: PortfolioAsset[] = []
49
50 for (const token of data.tokens) {
51 if (token.tokenInfo.price) {
52 const amount = token.balance / (10 ** token.tokenInfo.decimals)
53 const value = amount * token.tokenInfo.price.rate
54 totalValue += value
55 pricesBySymbol[token.tokenInfo.symbol] = token.tokenInfo.price.rate
56
57 portfolio.push({
58 address: token.tokenInfo.address,
59 amount,
60 value,
61 price: token.tokenInfo.price.rate,
62 name: token.tokenInfo.name,
63 symbol: token.tokenInfo.symbol,
64 icon: `https://s3.amazonaws.com/token-icons/${token.tokenInfo.address}.png`,
65 })
66 }
67 }
68 for (const token of data.tokens) {
69 if (!token.tokenInfo.price && token.tokenInfo.name.indexOf('Aave interest bearing') === 0) {
70 const underlyingSymbol = token.tokenInfo.name.substr(22)
71
72 if (pricesBySymbol[underlyingSymbol]) {
73 const amount = token.balance / (10 ** token.tokenInfo.decimals)
74 const value = amount * pricesBySymbol[underlyingSymbol]
75 totalValue += value
76
77 portfolio.push({
78 address: token.tokenInfo.address,
79 amount,
80 value,
81 price: pricesBySymbol[underlyingSymbol],
82 name: token.tokenInfo.name,
83 symbol: token.tokenInfo.symbol,
84 icon: `https://s3.amazonaws.com/token-icons/${token.tokenInfo.address}.png`,
85 })
86 }
87 }
88 }
89 return { totalValue, portfolio }
90 }
91
92 const getTreasuryInUSD = async () => {
93 const ecosystemReserve = await getEcosystemReservePortfolio()
94
95 // The revenue collector has too many txs to be supported by Zerion
96 const { totalValue: revenueCollectorTreasury } = await getEthplorerPortfolio(revenueCollector)
97
98 return ecosystemReserve.totalValue + revenueCollectorTreasury
99 }
100
101 const getPortfolio = async () => {
102 const [{ portfolio: reservePortfolio }, { portfolio: collectorPortfolio }] = await Promise.all([
103 getEcosystemReservePortfolio(),
104 getEthplorerPortfolio(revenueCollector),
105 ])
106 return [...reservePortfolio, ...collectorPortfolio]
107 }
108
109 const getRecentProposals = async () => {
110 const query = `{
111 proposals(
112 first: 5,
113 orderBy: createdTimestamp,
114 orderDirection: desc
115 ) {
116 title
117 id
118 ipfsHash
119 createdTimestamp
120 state
121 }
122 }`
123 const data = await sdk.graph.query('aave/governance-v2', query);
124 return data.proposals.map((proposal: any) => ({
125 title: proposal.title,
126 start: proposal.createdTimestamp,
127 state: proposal.state,
128 link: `https://app.aave.com/governance/${proposal.id}-${proposal.ipfsHash}`,
129 }))
130 }
131
132 sdk.register({
133 id: 'aave',
134 queries: {
135 currentTreasuryUSD: getTreasuryInUSD,
136 currentLiquidTreasuryUSD: getTreasuryInUSD,
137 currentTreasuryPortfolio: getPortfolio,
138 recentProposals: getRecentProposals,
139 },
140 metadata: {
141 icon: sdk.ipfs.getDataURILoader('QmW4X8Q36jjPm8fzU21NzFKRxNzReQy4JnehKbRrgybFh6', 'image/svg+xml'),
142 category: 'app',
143 name: 'Aave',
144 website: 'https://aave.com',
145 governanceSite: 'https://app.aave.com/governance',
146 governanceForum: 'https://governance.aave.com',
147 governanceModel: '',
148 treasuries: [ECOSYSTEM_RESERVE, revenueCollector],
149 },
150 })
151}
It's something off?
Report it to the discussion board on Discord, we will take care of it.