Adapter

CoinMetrics - Fees, TX Count, Active Addresses

Sub-Adapters 13

Preview and test each sub adapter.

Ethereum (eth)

Bitcoin (btc)

Litecoin (ltc)

Cardano (ada)

Tezos (xtz)

Bitcoin SV (bsv)

Bitcoin Cash (bch)

Ripple (xrp)

Dogecoin (doge)

Monero (xmr)

Stellar (xlm)

Decred (dcr)

Ethereum Classic (etc)

Adapter Code

Check the entire code written for the Adapter.

Source code

Showing TS source.
1export const name = 'CoinMetrics - Fees, TX Count, Active Addresses';
2export const version = '1.0.0';
3export const license = 'MIT';
4export const changeLog = 'Add protocol fees';
5
6const ALL_FEES = 'ALL_FEES';
7
8interface Protocol {
9  id: string
10  protocolRevenue: typeof ALL_FEES | ((date: string) => Promise<number>) | (() => Promise<number>);
11  events?: { date: string, description: string }[]
12  [key: string]: any
13}
14
15export function setup(sdk: Context) {
16  const getETHBurnedUSD = async (date: string): Promise<number> => {
17    const startOfDayBlock = await sdk.chainData.getBlockNumber(date, 'ethereum');
18    const endOfDayBlock = await sdk.chainData.getBlockNumber(sdk.date.getNextDay(date), 'ethereum');
19
20    const query = `query ethBurned{
21        startOfDay: ethburned(id: "1", block: {number: ${startOfDayBlock}}) {
22          burnedUSD
23        }
24        endOfDay: ethburned(id: "1", block: {number: ${endOfDayBlock}}) {
25          burnedUSD
26        }
27      }`
28
29    const data = await sdk.graph.query('dmihal/eth-burned', query);
30
31    const ethBurned = parseFloat(data.endOfDay.burnedUSD) - parseFloat(data.startOfDay.burnedUSD);
32
33    return ethBurned;
34  }
35
36  const protocols: Protocol[] = [
37    {
38      id: 'eth',
39      icon: sdk.ipfs.getDataURILoader('QmedJLPy6R7x3dDEy2cfMd8gXbZm9e3vxvgBLXp3YZEHCy', 'image/svg+xml'),
40      name: 'Ethereum',
41      description: 'Ethereum is the first blockchain for turing-complete smart contracts.',
42      feeDescription: 'Transaction fees are partially burnt and partially paid to miners.',
43      tokenTicker: 'ETH',
44      tokenCoingecko: 'ethereum',
45      website: 'https://ethereum.org',
46      blockchain: 'Ethereum',
47      source: 'CoinMetrics',
48      events: [
49        {
50          date: '2021-08-05',
51          description: 'London hard fork, including EIP-1559',
52        },
53      ],
54      protocolRevenue: getETHBurnedUSD,
55    },
56    {
57      id: 'btc',
58      icon: sdk.ipfs.getDataURILoader('QmerwCGnYE4DE9oe4a6hppgKRz2vvMdx1AuwvgFLgrdeh7', 'image/svg+xml'),
59      name: 'Bitcoin',
60      description: 'Bitcoin is the first decentralized cryptocurrency.',
61      feeDescription: 'Transaction fees are paid by users to miners.',
62      tokenTicker: 'BTC',
63      tokenCoingecko: 'bitcoin',
64      website: 'https://bitcoin.org',
65      source: 'CoinMetrics',
66      protocolRevenue: async () => 0,
67    },
68    {
69      id: 'ltc',
70      icon: sdk.ipfs.getDataURILoader('QmQfWmmsfGDsVfgkjMwneB9MRgg8SEumgM7ZaGSP98ZsgW', 'image/svg+xml'),
71      name: 'Litecoin',
72      description: 'Litecoin is cryptocurrency based on a fork of the Bitcoin Core codebase.',
73      feeDescription: 'Transaction fees are paid by users to miners.',
74      website: 'https://litecoin.org',
75      source: 'CoinMetrics',
76      tokenTicker: 'LTC',
77      tokenCoingecko: 'litecoin',
78      protocolRevenue: async () => 0,
79    },
80    {
81      id: 'ada',
82      icon: sdk.ipfs.getDataURILoader('QmbyTYm2BzcwgbRXoXXjihYT2mrwVPejFgKaJJXy6SHBRT', 'image/svg+xml'),
83      name: 'Cardano',
84      description: 'Cardano is a PoS blockchain which will support smart contracts in the future.',
85      feeDescription: 'Transaction fees are paid by users to validators.',
86      website: 'https://cardano.org',
87      source: 'CoinMetrics',
88      tokenTicker: 'ADA',
89      tokenCoingecko: 'cardano',
90      events: [
91        {
92          date: '2021-09-12',
93          description: 'Alonzo upgrade introduces smart contracts',
94        },
95      ],
96      protocolRevenue: async () => 0,
97    },
98    {
99      id: 'xtz',
100      icon: sdk.ipfs.getDataURILoader('QmS1MvZJqD3CAxnos5t64HXtMsTh2SqXoWWndkL6dHVduW', 'image/svg+xml'),
101      name: 'Tezos',
102      description: 'Tezos is a PoS blockchain that supports smart contracts',
103      feeDescription: 'Transaction fees are paid by users to validators (bakers).',
104      website: 'https://tezos.com',
105      source: 'CoinMetrics',
106      tokenTicker: 'XTZ',
107      tokenCoingecko: 'tezos',
108      protocolRevenue: async () => 0,
109    },
110    {
111      id: 'bsv',
112      icon: sdk.ipfs.getDataURILoader('QmPLRz1dZCbm2T5DeXrqULuqZU35TxcwYnbQFfN9GNiCf5', 'image/svg+xml'),
113      name: 'Bitcoin SV',
114      description: 'Bitcoin SV is a fork of the Bitcoin Cash blockchain',
115      feeDescription: 'Transaction fees are paid by users to miners.',
116      website: 'https://bitcoinsv.com',
117      source: 'CoinMetrics',
118      tokenTicker: 'BSV',
119      tokenCoingecko: 'bitcoin-cash-sv',
120      protocolRevenue: async () => 0,
121    },
122    {
123      id: 'bch',
124      icon: sdk.ipfs.getDataURILoader('QmT1RaaEdJiJnyGMWLpHxamk3mhjrqoodAkjpD2wCxHeyS', 'image/svg+xml'),
125      name: 'Bitcoin Cash',
126      description: 'Bitcoin Cash is a fork of the Bitcoin blockchain',
127      feeDescription: 'Transaction fees are paid by users to miners.',
128      website: 'https://bitcoincash.org',
129      source: 'CoinMetrics',
130      tokenTicker: 'BCH',
131      tokenCoingecko: 'bitcoin-cash',
132      protocolRevenue: async () => 0,
133    },
134    {
135      id: 'xrp',
136      icon: sdk.ipfs.getDataURILoader('QmYU37p3av9QDNLpG6sY2hiDDsVXewbovs9KtTzZAocasm', 'image/svg+xml'),
137      name: 'Ripple',
138      description: 'Ripple is a payment & settlment platform.',
139      feeDescription: 'Transaction fees are paid by users and burned.',
140      website: 'https://ripple.com',
141      source: 'CoinMetrics',
142      tokenTicker: 'XRP',
143      tokenCoingecko: 'ripple',
144      protocolRevenue: ALL_FEES,
145    },
146    {
147      id: 'doge',
148      icon: sdk.ipfs.getDataURILoader('QmRpogZjZEKLX33245zT6QSiDENMb26fS922Ds6pp3VzE3', 'image/svg+xml'),
149      name: 'Dogecoin',
150      description: 'Dogecoin is a cryptocurrency based on the "Doge" meme.',
151      feeDescription: 'Transaction fees are paid by users to miners.',
152      website: 'https://dogecoin.com',
153      source: 'CoinMetrics',
154      tokenTicker: 'DOGE',
155      tokenCoingecko: 'dogecoin',
156      protocolRevenue: async () => 0,
157    },
158    {
159      id: 'xmr',
160      icon: sdk.ipfs.getDataURILoader('QmWVPtKiQYo2up8ewEzGWLWRZHRNcQLn5U38NFBGm7X6cd', 'image/svg+xml'),
161      name: 'Monero',
162      description: 'Monero is a privacy-focused cryptocurrency.',
163      feeDescription: 'Transaction fees are paid by users to miners.',
164      website: 'https://getmonero.org',
165      source: 'CoinMetrics',
166      tokenTicker: 'XMR',
167      tokenCoingecko: 'monero',
168      protocolRevenue: async () => 0,
169    },
170    {
171      id: 'xlm',
172      icon: sdk.ipfs.getDataURILoader('QmZJAgQbxghu7c47wnY7eqPhFBHcwZedp5ZqA99wEm92UK', 'image/svg+xml'),
173      name: 'Stellar',
174      description: 'Stellar is global payment network.',
175      feeDescription: 'Transaction fees are paid by users into a pool.',
176      website: 'https://stellar.org',
177      source: 'CoinMetrics',
178      tokenTicker: 'XLM',
179      tokenCoingecko: 'stellar',
180      protocolRevenue: ALL_FEES, // https://www.stellar.org/developers-blog/transaction-submission-timeouts-and-dynamic-fees-faq
181    },
182    {
183      id: 'dcr',
184      icon: sdk.ipfs.getDataURILoader('QmTSz4gXBzNeLPQKdEJTVaAjcH68E39uvkgTUCKwcK44VT', 'image/webp'),
185      name: 'Decred',
186      description: 'Decred aims to build a community-directed digital currency.',
187      feeDescription: 'Transaction fees are paid by users to miners.',
188      website: 'https://www.decred.org/',
189      source: 'CoinMetrics',
190      tokenTicker: 'DCR',
191      tokenCoingecko: 'decred',
192      protocolRevenue: async () => 0,
193    },
194    {
195      id: 'etc',
196      icon: sdk.ipfs.getDataURILoader('QmNywrrDCXW76wbhG75jAiDWBpEb15riAscadrzxtMrrjn', 'image/svg+xml'),
197      name: 'Ethereum Classic',
198      description: 'Ethereum Classic is an open source, blockchain-based distributed computing platform featuring smart contract functionality. It supports a modified version of Nakamoto consensus via transaction-based state transitions executed on a public Ethereum Virtual Machine.',
199      feeDescription: 'Transaction fees are paid by users to miners',
200      website: 'https://ethereumclassic.org/',
201      source: "CoinMetrics",
202      tokenTicker: 'ETC',
203      tokenCoingecko: 'ethereum-classic',
204      protocolRevenue: async () => 0,
205    }
206  ];
207
208
209  const getOneDayMetricCount = (metric: string, id: string) => async (date: string) => {
210    const result = await sdk.http.get(`https://community-api.coinmetrics.io/v4/timeseries/asset-metrics?page_size=10000&metrics=${metric}&assets=${id}&start_time=${date}&end_time=${date}`);
211
212    if (!result.data[0]) {
213      throw new Error(`Failed to fetch CoinMetrics data for ${id} on ${date}`);
214    }
215
216    return parseFloat(result.data[0][metric]);
217  }
218
219  const getFeeRangeQuery = (id: string) => async (startDate: string, endDate: string) => {
220    const result = await sdk.http.get(`https://community-api.coinmetrics.io/v4/timeseries/asset-metrics?page_size=10000&metrics=FeeTotUSD&assets=${id}&start_time=${startDate}&end_time=${endDate}`);
221
222    if (!result.data[0]) {
223      throw new Error(`Failed to fetch CoinMetrics data for ${id} on ${startDate}`);
224    }
225
226    let totalFees = 0;
227    // return endDate
228    // We skip the last value, since CoinMetrics date queries include the
229    // last date, but CryptoStats skips it
230    for (let i = 0; i < result.data.length - 1; i += 1) {
231      totalFees += parseFloat(result.data[i].FeeTotUSD);
232    }
233
234    return totalFees;
235  }
236
237  for (const protocol of protocols) {
238    const { id, protocolRevenue, ...metadata } = protocol;
239
240    const queries: { [id: string]: (...args: any[]) => Promise<number> } = {
241      oneDayTotalFees: getOneDayMetricCount('FeeTotUSD', id),
242      dateRangeTotalFees: getFeeRangeQuery(id),
243      txCountOneDay: getOneDayMetricCount('TxCnt', id),
244      activeAddressesOneDay: getOneDayMetricCount('AdrActCnt', id),
245      oneDayProtocolFees: protocolRevenue === ALL_FEES
246        ? getOneDayMetricCount('FeeTotUSD', id)
247        : protocolRevenue,
248    };
249
250    sdk.register({
251      id,
252      queries,
253      metadata: {
254        category: 'l1',
255        ...metadata,
256      },
257    });
258  }
259}
260

It's something off?

Report it to the discussion board on Discord, we will take care of it.

Adapter Info

Version

1.0.0

License

MIT

IPFS CID

QmX9GvQpSZHh4fFwd4iMVrKj6ZPZEib4aTZyha7CLMHGTt

CID (source)

QmRdAqXoC2EECFBZmdaAWaMtt1FQ4fxrMhecrEP7a7inzB

Collections

Author

mihal.eth