@reserve-protocol/dtf-sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (234) hide show
  1. package/README.md +134 -0
  2. package/dist/abi/deployer.d.ts +281 -0
  3. package/dist/abi/deployer.d.ts.map +1 -0
  4. package/dist/abi/deployer.js +178 -0
  5. package/dist/abi/deployer.js.map +1 -0
  6. package/dist/abi/erc20.d.ts +73 -0
  7. package/dist/abi/erc20.d.ts.map +1 -0
  8. package/dist/abi/erc20.js +58 -0
  9. package/dist/abi/erc20.js.map +1 -0
  10. package/dist/abi/folio.d.ts +1950 -0
  11. package/dist/abi/folio.d.ts.map +1 -0
  12. package/dist/abi/folio.js +1430 -0
  13. package/dist/abi/folio.js.map +1 -0
  14. package/dist/abi/governance-deployer.d.ts +130 -0
  15. package/dist/abi/governance-deployer.d.ts.map +1 -0
  16. package/dist/abi/governance-deployer.js +77 -0
  17. package/dist/abi/governance-deployer.js.map +1 -0
  18. package/dist/abi/governor.d.ts +1276 -0
  19. package/dist/abi/governor.d.ts.map +1 -0
  20. package/dist/abi/governor.js +1661 -0
  21. package/dist/abi/governor.js.map +1 -0
  22. package/dist/abi/proxy-admin.d.ts +49 -0
  23. package/dist/abi/proxy-admin.d.ts.map +1 -0
  24. package/dist/abi/proxy-admin.js +42 -0
  25. package/dist/abi/proxy-admin.js.map +1 -0
  26. package/dist/abi/spells.d.ts +67 -0
  27. package/dist/abi/spells.d.ts.map +1 -0
  28. package/dist/abi/spells.js +61 -0
  29. package/dist/abi/spells.js.map +1 -0
  30. package/dist/abi/timelock.d.ts +673 -0
  31. package/dist/abi/timelock.d.ts.map +1 -0
  32. package/dist/abi/timelock.js +469 -0
  33. package/dist/abi/timelock.js.map +1 -0
  34. package/dist/abi/vote-lock.d.ts +164 -0
  35. package/dist/abi/vote-lock.d.ts.map +1 -0
  36. package/dist/abi/vote-lock.js +116 -0
  37. package/dist/abi/vote-lock.js.map +1 -0
  38. package/dist/clients/chains.d.ts +5 -0
  39. package/dist/clients/chains.d.ts.map +1 -0
  40. package/dist/clients/chains.js +23 -0
  41. package/dist/clients/chains.js.map +1 -0
  42. package/dist/clients/create-clients.d.ts +14 -0
  43. package/dist/clients/create-clients.d.ts.map +1 -0
  44. package/dist/clients/create-clients.js +32 -0
  45. package/dist/clients/create-clients.js.map +1 -0
  46. package/dist/clients/create-price-client.d.ts +7 -0
  47. package/dist/clients/create-price-client.d.ts.map +1 -0
  48. package/dist/clients/create-price-client.js +15 -0
  49. package/dist/clients/create-price-client.js.map +1 -0
  50. package/dist/constants.d.ts +35 -0
  51. package/dist/constants.d.ts.map +1 -0
  52. package/dist/constants.js +100 -0
  53. package/dist/constants.js.map +1 -0
  54. package/dist/deploy/build-deploy.d.ts +7 -0
  55. package/dist/deploy/build-deploy.d.ts.map +1 -0
  56. package/dist/deploy/build-deploy.js +84 -0
  57. package/dist/deploy/build-deploy.js.map +1 -0
  58. package/dist/deploy/extract-deployed-address.d.ts +8 -0
  59. package/dist/deploy/extract-deployed-address.d.ts.map +1 -0
  60. package/dist/deploy/extract-deployed-address.js +36 -0
  61. package/dist/deploy/extract-deployed-address.js.map +1 -0
  62. package/dist/deploy/permissionless-defaults.d.ts +35 -0
  63. package/dist/deploy/permissionless-defaults.d.ts.map +1 -0
  64. package/dist/deploy/permissionless-defaults.js +76 -0
  65. package/dist/deploy/permissionless-defaults.js.map +1 -0
  66. package/dist/deploy/token-registry.d.ts +9 -0
  67. package/dist/deploy/token-registry.d.ts.map +1 -0
  68. package/dist/deploy/token-registry.js +68 -0
  69. package/dist/deploy/token-registry.js.map +1 -0
  70. package/dist/deploy/zap-deploy.d.ts +4 -0
  71. package/dist/deploy/zap-deploy.d.ts.map +1 -0
  72. package/dist/deploy/zap-deploy.js +50 -0
  73. package/dist/deploy/zap-deploy.js.map +1 -0
  74. package/dist/dtf/fees.d.ts +10 -0
  75. package/dist/dtf/fees.d.ts.map +1 -0
  76. package/dist/dtf/fees.js +103 -0
  77. package/dist/dtf/fees.js.map +1 -0
  78. package/dist/dtf/fetch-analytics.d.ts +27 -0
  79. package/dist/dtf/fetch-analytics.d.ts.map +1 -0
  80. package/dist/dtf/fetch-analytics.js +63 -0
  81. package/dist/dtf/fetch-analytics.js.map +1 -0
  82. package/dist/dtf/fetch-basket.d.ts +16 -0
  83. package/dist/dtf/fetch-basket.d.ts.map +1 -0
  84. package/dist/dtf/fetch-basket.js +32 -0
  85. package/dist/dtf/fetch-basket.js.map +1 -0
  86. package/dist/dtf/fetch-discover.d.ts +10 -0
  87. package/dist/dtf/fetch-discover.d.ts.map +1 -0
  88. package/dist/dtf/fetch-discover.js +17 -0
  89. package/dist/dtf/fetch-discover.js.map +1 -0
  90. package/dist/dtf/fetch-dtf.d.ts +25 -0
  91. package/dist/dtf/fetch-dtf.d.ts.map +1 -0
  92. package/dist/dtf/fetch-dtf.js +39 -0
  93. package/dist/dtf/fetch-dtf.js.map +1 -0
  94. package/dist/dtf/mint.d.ts +9 -0
  95. package/dist/dtf/mint.d.ts.map +1 -0
  96. package/dist/dtf/mint.js +82 -0
  97. package/dist/dtf/mint.js.map +1 -0
  98. package/dist/dtf/read-basket.d.ts +4 -0
  99. package/dist/dtf/read-basket.d.ts.map +1 -0
  100. package/dist/dtf/read-basket.js +20 -0
  101. package/dist/dtf/read-basket.js.map +1 -0
  102. package/dist/dtf/read-config.d.ts +4 -0
  103. package/dist/dtf/read-config.d.ts.map +1 -0
  104. package/dist/dtf/read-config.js +80 -0
  105. package/dist/dtf/read-config.js.map +1 -0
  106. package/dist/dtf/read-dtf.d.ts +6 -0
  107. package/dist/dtf/read-dtf.d.ts.map +1 -0
  108. package/dist/dtf/read-dtf.js +32 -0
  109. package/dist/dtf/read-dtf.js.map +1 -0
  110. package/dist/dtf/read-rebalance-control.d.ts +4 -0
  111. package/dist/dtf/read-rebalance-control.d.ts.map +1 -0
  112. package/dist/dtf/read-rebalance-control.js +14 -0
  113. package/dist/dtf/read-rebalance-control.js.map +1 -0
  114. package/dist/dtf/read-roles.d.ts +4 -0
  115. package/dist/dtf/read-roles.d.ts.map +1 -0
  116. package/dist/dtf/read-roles.js +29 -0
  117. package/dist/dtf/read-roles.js.map +1 -0
  118. package/dist/dtf/read-version.d.ts +3 -0
  119. package/dist/dtf/read-version.d.ts.map +1 -0
  120. package/dist/dtf/read-version.js +9 -0
  121. package/dist/dtf/read-version.js.map +1 -0
  122. package/dist/dtf/redeem.d.ts +5 -0
  123. package/dist/dtf/redeem.d.ts.map +1 -0
  124. package/dist/dtf/redeem.js +27 -0
  125. package/dist/dtf/redeem.js.map +1 -0
  126. package/dist/governance/build-proposal.d.ts +11 -0
  127. package/dist/governance/build-proposal.d.ts.map +1 -0
  128. package/dist/governance/build-proposal.js +78 -0
  129. package/dist/governance/build-proposal.js.map +1 -0
  130. package/dist/governance/build-settings-calldata.d.ts +39 -0
  131. package/dist/governance/build-settings-calldata.d.ts.map +1 -0
  132. package/dist/governance/build-settings-calldata.js +145 -0
  133. package/dist/governance/build-settings-calldata.js.map +1 -0
  134. package/dist/governance/compute-proposal-state.d.ts +18 -0
  135. package/dist/governance/compute-proposal-state.d.ts.map +1 -0
  136. package/dist/governance/compute-proposal-state.js +87 -0
  137. package/dist/governance/compute-proposal-state.js.map +1 -0
  138. package/dist/governance/decode-proposal.d.ts +22 -0
  139. package/dist/governance/decode-proposal.d.ts.map +1 -0
  140. package/dist/governance/decode-proposal.js +164 -0
  141. package/dist/governance/decode-proposal.js.map +1 -0
  142. package/dist/governance/fetch-proposals.d.ts +41 -0
  143. package/dist/governance/fetch-proposals.d.ts.map +1 -0
  144. package/dist/governance/fetch-proposals.js +173 -0
  145. package/dist/governance/fetch-proposals.js.map +1 -0
  146. package/dist/governance/read-governance.d.ts +7 -0
  147. package/dist/governance/read-governance.d.ts.map +1 -0
  148. package/dist/governance/read-governance.js +97 -0
  149. package/dist/governance/read-governance.js.map +1 -0
  150. package/dist/governance/read-proposals.d.ts +11 -0
  151. package/dist/governance/read-proposals.d.ts.map +1 -0
  152. package/dist/governance/read-proposals.js +104 -0
  153. package/dist/governance/read-proposals.js.map +1 -0
  154. package/dist/governance/read-voting-power.d.ts +8 -0
  155. package/dist/governance/read-voting-power.d.ts.map +1 -0
  156. package/dist/governance/read-voting-power.js +25 -0
  157. package/dist/governance/read-voting-power.js.map +1 -0
  158. package/dist/index.d.ts +57 -0
  159. package/dist/index.d.ts.map +1 -0
  160. package/dist/index.js +73 -0
  161. package/dist/index.js.map +1 -0
  162. package/dist/prices/chainlink.d.ts +8 -0
  163. package/dist/prices/chainlink.d.ts.map +1 -0
  164. package/dist/prices/chainlink.js +116 -0
  165. package/dist/prices/chainlink.js.map +1 -0
  166. package/dist/prices/reserve-api.d.ts +7 -0
  167. package/dist/prices/reserve-api.d.ts.map +1 -0
  168. package/dist/prices/reserve-api.js +47 -0
  169. package/dist/prices/reserve-api.js.map +1 -0
  170. package/dist/rebalance/build-auction.d.ts +25 -0
  171. package/dist/rebalance/build-auction.d.ts.map +1 -0
  172. package/dist/rebalance/build-auction.js +73 -0
  173. package/dist/rebalance/build-auction.js.map +1 -0
  174. package/dist/rebalance/build-rebalance.d.ts +22 -0
  175. package/dist/rebalance/build-rebalance.d.ts.map +1 -0
  176. package/dist/rebalance/build-rebalance.js +30 -0
  177. package/dist/rebalance/build-rebalance.js.map +1 -0
  178. package/dist/rebalance/read-auction.d.ts +4 -0
  179. package/dist/rebalance/read-auction.d.ts.map +1 -0
  180. package/dist/rebalance/read-auction.js +31 -0
  181. package/dist/rebalance/read-auction.js.map +1 -0
  182. package/dist/rebalance/read-rebalance.d.ts +4 -0
  183. package/dist/rebalance/read-rebalance.d.ts.map +1 -0
  184. package/dist/rebalance/read-rebalance.js +50 -0
  185. package/dist/rebalance/read-rebalance.js.map +1 -0
  186. package/dist/rebalance/transform.d.ts +22 -0
  187. package/dist/rebalance/transform.d.ts.map +1 -0
  188. package/dist/rebalance/transform.js +47 -0
  189. package/dist/rebalance/transform.js.map +1 -0
  190. package/dist/revenue/compute-revenue.d.ts +45 -0
  191. package/dist/revenue/compute-revenue.d.ts.map +1 -0
  192. package/dist/revenue/compute-revenue.js +216 -0
  193. package/dist/revenue/compute-revenue.js.map +1 -0
  194. package/dist/revenue/fetch-revenue.d.ts +8 -0
  195. package/dist/revenue/fetch-revenue.d.ts.map +1 -0
  196. package/dist/revenue/fetch-revenue.js +182 -0
  197. package/dist/revenue/fetch-revenue.js.map +1 -0
  198. package/dist/revenue/fetch-rsr-burns.d.ts +9 -0
  199. package/dist/revenue/fetch-rsr-burns.d.ts.map +1 -0
  200. package/dist/revenue/fetch-rsr-burns.js +106 -0
  201. package/dist/revenue/fetch-rsr-burns.js.map +1 -0
  202. package/dist/types.d.ts +546 -0
  203. package/dist/types.d.ts.map +1 -0
  204. package/dist/types.js +2 -0
  205. package/dist/types.js.map +1 -0
  206. package/dist/utils/assert.d.ts +2 -0
  207. package/dist/utils/assert.d.ts.map +1 -0
  208. package/dist/utils/assert.js +5 -0
  209. package/dist/utils/assert.js.map +1 -0
  210. package/dist/utils/fetch-token-metadata.d.ts +7 -0
  211. package/dist/utils/fetch-token-metadata.d.ts.map +1 -0
  212. package/dist/utils/fetch-token-metadata.js +29 -0
  213. package/dist/utils/fetch-token-metadata.js.map +1 -0
  214. package/dist/utils/fetch-with-retry.d.ts +7 -0
  215. package/dist/utils/fetch-with-retry.d.ts.map +1 -0
  216. package/dist/utils/fetch-with-retry.js +38 -0
  217. package/dist/utils/fetch-with-retry.js.map +1 -0
  218. package/dist/utils/query-subgraph.d.ts +7 -0
  219. package/dist/utils/query-subgraph.d.ts.map +1 -0
  220. package/dist/utils/query-subgraph.js +25 -0
  221. package/dist/utils/query-subgraph.js.map +1 -0
  222. package/dist/utils/validate-price-control.d.ts +3 -0
  223. package/dist/utils/validate-price-control.d.ts.map +1 -0
  224. package/dist/utils/validate-price-control.js +6 -0
  225. package/dist/utils/validate-price-control.js.map +1 -0
  226. package/dist/vote-lock/build-vote-lock.d.ts +10 -0
  227. package/dist/vote-lock/build-vote-lock.d.ts.map +1 -0
  228. package/dist/vote-lock/build-vote-lock.js +73 -0
  229. package/dist/vote-lock/build-vote-lock.js.map +1 -0
  230. package/dist/vote-lock/read-vote-lock.d.ts +7 -0
  231. package/dist/vote-lock/read-vote-lock.d.ts.map +1 -0
  232. package/dist/vote-lock/read-vote-lock.js +64 -0
  233. package/dist/vote-lock/read-vote-lock.js.map +1 -0
  234. package/package.json +28 -0
@@ -0,0 +1,216 @@
1
+ /**
2
+ * Convert raw revenue (BigDecimal in DTF shares) to USD.
3
+ * WHY: Subgraph BigDecimal is in wei-scale (e.g. "6277028174388650175775" for 6277 shares).
4
+ * Must divide by 10^decimals before multiplying by price.
5
+ */
6
+ export function computeRevenueUsd(raw, price) {
7
+ const decimals = raw.token.decimals;
8
+ const divisor = 10 ** decimals;
9
+ return {
10
+ address: raw.address,
11
+ chainId: raw.chainId,
12
+ symbol: raw.token.symbol,
13
+ totalUsd: (Number(raw.totalRevenue) / divisor) * price,
14
+ protocolUsd: (Number(raw.protocolRevenue) / divisor) * price,
15
+ governanceUsd: (Number(raw.governanceRevenue) / divisor) * price,
16
+ externalUsd: (Number(raw.externalRevenue) / divisor) * price,
17
+ };
18
+ }
19
+ export function aggregateEcosystemRevenue(items) {
20
+ let totalUsd = 0;
21
+ let protocolUsd = 0;
22
+ let governanceUsd = 0;
23
+ let externalUsd = 0;
24
+ for (const item of items) {
25
+ totalUsd += item.totalUsd;
26
+ protocolUsd += item.protocolUsd;
27
+ governanceUsd += item.governanceUsd;
28
+ externalUsd += item.externalUsd;
29
+ }
30
+ const sorted = [...items].sort((a, b) => b.totalUsd - a.totalUsd);
31
+ return {
32
+ totalUsd,
33
+ protocolUsd,
34
+ governanceUsd,
35
+ externalUsd,
36
+ protocolPercent: totalUsd > 0 ? (protocolUsd / totalUsd) * 100 : 0,
37
+ governancePercent: totalUsd > 0 ? (governanceUsd / totalUsd) * 100 : 0,
38
+ externalPercent: totalUsd > 0 ? (externalUsd / totalUsd) * 100 : 0,
39
+ dtfCount: items.length,
40
+ topDtfs: sorted,
41
+ };
42
+ }
43
+ /**
44
+ * Compute weighted (by TVL) and simple average fee metrics.
45
+ * Fees are D18 in subgraph — divide by 1e18 for decimal.
46
+ */
47
+ export function computeFeeMetrics(raws, prices) {
48
+ let totalTvl = 0;
49
+ let weightedMinting = 0;
50
+ let weightedTvl = 0;
51
+ let sumMinting = 0;
52
+ let sumTvl = 0;
53
+ for (const raw of raws) {
54
+ const price = prices[raw.address.toLowerCase()] ?? 0;
55
+ // WHY: totalSupply is wei-scale BigDecimal from subgraph, must divide by 10^decimals
56
+ const supply = Number(raw.token.totalSupply) / 10 ** raw.token.decimals;
57
+ const tvl = supply * price;
58
+ const mintFee = Number(raw.mintingFee) / 1e18;
59
+ const tvlFee = Number(raw.annualizedTvlFee) / 1e18;
60
+ totalTvl += tvl;
61
+ weightedMinting += mintFee * tvl;
62
+ weightedTvl += tvlFee * tvl;
63
+ sumMinting += mintFee;
64
+ sumTvl += tvlFee;
65
+ }
66
+ const count = raws.length || 1;
67
+ return {
68
+ weightedMintingFee: totalTvl > 0 ? weightedMinting / totalTvl : 0,
69
+ weightedTvlFee: totalTvl > 0 ? weightedTvl / totalTvl : 0,
70
+ averageMintingFee: sumMinting / count,
71
+ averageTvlFee: sumTvl / count,
72
+ };
73
+ }
74
+ /**
75
+ * Compute RSR burn projection from actual burn history + theoretical model.
76
+ *
77
+ * WHY: The theoretical "5% of TVL" formula overestimates by ~5x.
78
+ * Trailing average from actual monthly snapshots is the primary signal.
79
+ * Theoretical is kept as "Protocol Target" for context.
80
+ */
81
+ export function computeRsrBurnProjection(burnData, rsrPrice, totalTvl) {
82
+ // -- Trailing average from actual monthly snapshots --
83
+ // WHY: Use up to 3 months for a stable average that still responds to trends
84
+ const snapshots = burnData.monthlySnapshots.slice(0, 3);
85
+ const monthsUsed = snapshots.length;
86
+ let trailingMonthlyRsr = 0;
87
+ if (monthsUsed > 0) {
88
+ const totalRsr = snapshots.reduce((sum, s) => sum + Number(s.monthlyBurnAmount) / 1e18, 0);
89
+ trailingMonthlyRsr = totalRsr / monthsUsed;
90
+ }
91
+ const trailingMonthlyUsd = trailingMonthlyRsr * rsrPrice;
92
+ const trailingAnnualRsr = trailingMonthlyRsr * 12;
93
+ const trailingAnnualUsd = trailingMonthlyUsd * 12;
94
+ // -- Theoretical target (protocol fee model) --
95
+ const platformTierPercent = getPlatformTierPercent(totalTvl);
96
+ const theoreticalAnnualUsd = totalTvl * 0.05 * (platformTierPercent / 100);
97
+ const theoreticalMonthlyUsd = theoreticalAnnualUsd / 12;
98
+ const theoreticalMonthlyRsr = rsrPrice > 0 ? theoreticalMonthlyUsd / rsrPrice : 0;
99
+ // -- Effective burn rate: what % of TVL is actually burned annually --
100
+ const effectiveBurnRate = totalTvl > 0 ? trailingAnnualUsd / totalTvl : 0;
101
+ const totalBurnedRsr = Number(burnData.totalBurned) / 1e18;
102
+ const totalBurnedUsd = totalBurnedRsr * rsrPrice;
103
+ return {
104
+ trailing: {
105
+ monthlyBurnRsr: trailingMonthlyRsr,
106
+ monthlyBurnUsd: trailingMonthlyUsd,
107
+ annualBurnRsr: trailingAnnualRsr,
108
+ annualBurnUsd: trailingAnnualUsd,
109
+ monthsUsed,
110
+ },
111
+ theoretical: {
112
+ annualBurnUsd: theoreticalAnnualUsd,
113
+ monthlyBurnUsd: theoreticalMonthlyUsd,
114
+ monthlyBurnRsr: theoreticalMonthlyRsr,
115
+ platformTierPercent,
116
+ },
117
+ effectiveBurnRate,
118
+ totalBurnedRsr,
119
+ totalBurnedUsd,
120
+ };
121
+ }
122
+ function getPlatformTierPercent(tvl) {
123
+ if (tvl < 100_000_000)
124
+ return 50;
125
+ if (tvl < 1_000_000_000)
126
+ return 40;
127
+ if (tvl < 10_000_000_000)
128
+ return 30;
129
+ if (tvl < 100_000_000_000)
130
+ return 20;
131
+ return 10;
132
+ }
133
+ /**
134
+ * Compare latest month's burn vs trailing average.
135
+ * WHY: "Accuracy" against a broken theoretical was meaningless.
136
+ * Comparing latest vs trailing shows whether burns are accelerating or decelerating.
137
+ */
138
+ export function computeBurnAccuracy(projection, burnData, rsrPrice) {
139
+ const trailingMonthlyRsr = projection.trailing.monthlyBurnRsr;
140
+ const latestSnapshot = burnData.monthlySnapshots[0];
141
+ const latestMonthlyRsr = latestSnapshot
142
+ ? Number(latestSnapshot.monthlyBurnAmount) / 1e18
143
+ : 0;
144
+ const latestVsTrailingPct = trailingMonthlyRsr > 0
145
+ ? (latestMonthlyRsr / trailingMonthlyRsr) * 100
146
+ : 0;
147
+ return {
148
+ trailingMonthlyRsr,
149
+ latestMonthlyRsr,
150
+ latestVsTrailingPct,
151
+ totalBurnedRsr: projection.totalBurnedRsr,
152
+ totalBurnedUsd: projection.totalBurnedUsd,
153
+ };
154
+ }
155
+ /**
156
+ * Calculate total RSR locked in DTF stTokens.
157
+ * Checks each DTF's stToken.underlying.address against known RSR addresses.
158
+ */
159
+ export function computeLockedRsr(raws, rsrAddresses) {
160
+ const rsrSet = new Set(rsrAddresses.map((a) => a.toLowerCase()));
161
+ let total = 0;
162
+ for (const raw of raws) {
163
+ if (!raw.stToken)
164
+ continue;
165
+ const underlyingAddr = raw.stToken.underlying.address.toLowerCase();
166
+ if (!rsrSet.has(underlyingAddr))
167
+ continue;
168
+ const supply = Number(raw.stToken.token.totalSupply);
169
+ const decimals = raw.stToken.token.decimals;
170
+ // WHY: stToken.token.totalSupply might be wei or BigDecimal depending on subgraph.
171
+ // Register divides by 10^decimals, so we do the same defensively.
172
+ total += supply / 10 ** decimals;
173
+ }
174
+ return total;
175
+ }
176
+ /**
177
+ * Binary search for the closest price record to a given timestamp.
178
+ * Expects prices sorted by timestamp ascending.
179
+ * Returns 0 if empty.
180
+ */
181
+ export function nearestPrice(timestamp, prices) {
182
+ if (prices.length === 0)
183
+ return 0;
184
+ let lo = 0;
185
+ let hi = prices.length - 1;
186
+ while (lo < hi) {
187
+ const mid = (lo + hi) >> 1;
188
+ if (prices[mid].timestamp < timestamp) {
189
+ lo = mid + 1;
190
+ }
191
+ else {
192
+ hi = mid;
193
+ }
194
+ }
195
+ // lo is the first index >= timestamp. Compare lo and lo-1 for closest.
196
+ if (lo === 0)
197
+ return prices[0].priceUsd;
198
+ const before = prices[lo - 1];
199
+ const after = prices[lo];
200
+ const diffBefore = timestamp - before.timestamp;
201
+ const diffAfter = after.timestamp - timestamp;
202
+ return diffBefore <= diffAfter ? before.priceUsd : after.priceUsd;
203
+ }
204
+ /**
205
+ * Compute total historical USD value of burns using time-matched prices.
206
+ */
207
+ export function computeHistoricalBurnTotals(burns, prices) {
208
+ let totalBurnedUsdHistorical = 0;
209
+ for (const burn of burns) {
210
+ const amountRsr = Number(burn.amount) / 1e18;
211
+ const price = nearestPrice(burn.timestamp, prices);
212
+ totalBurnedUsdHistorical += amountRsr * price;
213
+ }
214
+ return { totalBurnedUsdHistorical };
215
+ }
216
+ //# sourceMappingURL=compute-revenue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compute-revenue.js","sourceRoot":"","sources":["../../src/revenue/compute-revenue.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { DtfRevenueRaw, RevenueSnapshot, SupportedChainId } from '../types';
2
+ export declare function fetchDtfRevenue(chainId: SupportedChainId, folioAddress: string): Promise<DtfRevenueRaw>;
3
+ export declare function fetchEcosystemRevenue(chains?: SupportedChainId[]): Promise<DtfRevenueRaw[]>;
4
+ export declare function fetchRevenueSnapshots(chainId: SupportedChainId, folioAddress: string, opts?: {
5
+ period?: 'daily' | 'monthly';
6
+ first?: number;
7
+ }): Promise<RevenueSnapshot[]>;
8
+ //# sourceMappingURL=fetch-revenue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch-revenue.d.ts","sourceRoot":"","sources":["../../src/revenue/fetch-revenue.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,aAAa,EACb,eAAe,EACf,gBAAgB,EACjB,MAAM,UAAU,CAAA;AAiLjB,wBAAsB,eAAe,CACnC,OAAO,EAAE,gBAAgB,EACzB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,aAAa,CAAC,CAWxB;AAED,wBAAsB,qBAAqB,CACzC,MAAM,CAAC,EAAE,gBAAgB,EAAE,GAC1B,OAAO,CAAC,aAAa,EAAE,CAAC,CAoB1B;AAED,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,gBAAgB,EACzB,YAAY,EAAE,MAAM,EACpB,IAAI,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GACtD,OAAO,CAAC,eAAe,EAAE,CAAC,CAyB5B"}
@@ -0,0 +1,182 @@
1
+ import { SUPPORTED_CHAINS } from '../constants';
2
+ import { querySubgraph } from '../utils/query-subgraph';
3
+ const REVENUE_QUERY = `
4
+ query GetDTFRevenue($id: String!) {
5
+ dtf(id: $id) {
6
+ id
7
+ totalRevenue
8
+ protocolRevenue
9
+ governanceRevenue
10
+ externalRevenue
11
+ mintingFee
12
+ tvlFee
13
+ annualizedTvlFee
14
+ token {
15
+ decimals
16
+ symbol
17
+ totalSupply
18
+ }
19
+ stToken {
20
+ id
21
+ token {
22
+ totalSupply
23
+ decimals
24
+ }
25
+ underlying {
26
+ symbol
27
+ id
28
+ decimals
29
+ }
30
+ }
31
+ }
32
+ }
33
+ `;
34
+ const ECOSYSTEM_REVENUE_QUERY = `
35
+ query GetEcosystemRevenue {
36
+ dtfs(first: 100, where: { totalRevenue_gt: "0" }) {
37
+ id
38
+ totalRevenue
39
+ protocolRevenue
40
+ governanceRevenue
41
+ externalRevenue
42
+ mintingFee
43
+ tvlFee
44
+ annualizedTvlFee
45
+ token {
46
+ decimals
47
+ symbol
48
+ totalSupply
49
+ }
50
+ stToken {
51
+ id
52
+ token {
53
+ totalSupply
54
+ decimals
55
+ }
56
+ underlying {
57
+ symbol
58
+ id
59
+ decimals
60
+ }
61
+ }
62
+ }
63
+ }
64
+ `;
65
+ const DAILY_SNAPSHOTS_QUERY = `
66
+ query GetDailySnapshots($tokenId: String!, $first: Int!) {
67
+ tokenDailySnapshots(
68
+ first: $first
69
+ orderBy: timestamp
70
+ orderDirection: desc
71
+ where: { token: $tokenId }
72
+ ) {
73
+ timestamp
74
+ totalRevenue
75
+ protocolRevenue
76
+ governanceRevenue
77
+ externalRevenue
78
+ }
79
+ }
80
+ `;
81
+ const MONTHLY_SNAPSHOTS_QUERY = `
82
+ query GetMonthlySnapshots($tokenId: String!, $first: Int!) {
83
+ tokenMonthlySnapshots(
84
+ first: $first
85
+ orderBy: timestamp
86
+ orderDirection: desc
87
+ where: { token: $tokenId }
88
+ ) {
89
+ timestamp
90
+ totalRevenue
91
+ protocolRevenue
92
+ governanceRevenue
93
+ externalRevenue
94
+ }
95
+ }
96
+ `;
97
+ function parseDtfRevenue(raw, chainId) {
98
+ return {
99
+ address: raw.id,
100
+ chainId,
101
+ totalRevenue: raw.totalRevenue ?? '0',
102
+ protocolRevenue: raw.protocolRevenue ?? '0',
103
+ governanceRevenue: raw.governanceRevenue ?? '0',
104
+ externalRevenue: raw.externalRevenue ?? '0',
105
+ mintingFee: raw.mintingFee ?? '0',
106
+ tvlFee: raw.tvlFee ?? '0',
107
+ annualizedTvlFee: raw.annualizedTvlFee ?? '0',
108
+ token: {
109
+ // WHY: DTF share tokens are always 18 decimals (protocol enforced).
110
+ // The default is safe here unlike general ERC20s.
111
+ decimals: Number(raw.token?.decimals ?? 18),
112
+ symbol: raw.token?.symbol ?? '',
113
+ totalSupply: raw.token?.totalSupply ?? '0',
114
+ },
115
+ stToken: raw.stToken
116
+ ? {
117
+ id: raw.stToken.id,
118
+ token: {
119
+ totalSupply: raw.stToken.token?.totalSupply ?? '0',
120
+ // WHY: stToken (vote-lock) is always 18 decimals — wraps the underlying RSR/DTF token.
121
+ decimals: Number(raw.stToken.token?.decimals ?? 18),
122
+ },
123
+ underlying: {
124
+ symbol: raw.stToken.underlying?.symbol ?? '',
125
+ address: raw.stToken.underlying?.id ?? '',
126
+ // WHY: Underlying is RSR (18 dec) or a DTF share token (18 dec). Safe default.
127
+ decimals: Number(raw.stToken.underlying?.decimals ?? 18),
128
+ },
129
+ }
130
+ : undefined,
131
+ };
132
+ }
133
+ export async function fetchDtfRevenue(chainId, folioAddress) {
134
+ const data = await querySubgraph(chainId, REVENUE_QUERY, {
135
+ id: folioAddress.toLowerCase(),
136
+ });
137
+ const dtf = data?.dtf;
138
+ if (!dtf) {
139
+ throw new Error(`DTF not found for revenue: ${folioAddress} on chain ${chainId}`);
140
+ }
141
+ return parseDtfRevenue(dtf, chainId);
142
+ }
143
+ export async function fetchEcosystemRevenue(chains) {
144
+ const targetChains = chains ?? SUPPORTED_CHAINS;
145
+ const results = await Promise.allSettled(targetChains.map(async (chainId) => {
146
+ const data = await querySubgraph(chainId, ECOSYSTEM_REVENUE_QUERY);
147
+ const dtfs = data?.dtfs ?? [];
148
+ return dtfs.map((raw) => parseDtfRevenue(raw, chainId));
149
+ }));
150
+ const all = [];
151
+ for (const result of results) {
152
+ if (result.status === 'fulfilled') {
153
+ all.push(...result.value);
154
+ }
155
+ // WHY: Skip failed chains (BSC subgraph might be down)
156
+ }
157
+ return all;
158
+ }
159
+ export async function fetchRevenueSnapshots(chainId, folioAddress, opts) {
160
+ const period = opts?.period ?? 'monthly';
161
+ const first = opts?.first ?? 12;
162
+ const query = period === 'daily' ? DAILY_SNAPSHOTS_QUERY : MONTHLY_SNAPSHOTS_QUERY;
163
+ const vars = { tokenId: folioAddress.toLowerCase(), first };
164
+ let snapshots;
165
+ if (period === 'daily') {
166
+ const data = await querySubgraph(chainId, query, vars);
167
+ snapshots = data?.tokenDailySnapshots ?? [];
168
+ }
169
+ else {
170
+ const data = await querySubgraph(chainId, query, vars);
171
+ snapshots = data?.tokenMonthlySnapshots ?? [];
172
+ }
173
+ return snapshots.map((s) => ({
174
+ timestamp: Number(s.timestamp),
175
+ totalRevenue: s.totalRevenue ?? '0',
176
+ protocolRevenue: s.protocolRevenue ?? '0',
177
+ governanceRevenue: s.governanceRevenue ?? '0',
178
+ externalRevenue: s.externalRevenue ?? '0',
179
+ period,
180
+ }));
181
+ }
182
+ //# sourceMappingURL=fetch-revenue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch-revenue.js","sourceRoot":"","sources":["../../src/revenue/fetch-revenue.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { PriceRecord, RsrBurnData, RsrBurnEvent, SupportedChainId } from '../types';
2
+ export declare function fetchRsrBurns(chains?: SupportedChainId[]): Promise<RsrBurnData>;
3
+ /**
4
+ * Fetch historical RSR/USD prices from Chainlink covering the burn timespan.
5
+ * Creates its own Ethereum mainnet client internally.
6
+ * WHY: Ethereum mainnet price is accurate for all chains — RSR is the same token.
7
+ */
8
+ export declare function fetchRsrPriceHistory(burns: RsrBurnEvent[]): Promise<PriceRecord[]>;
9
+ //# sourceMappingURL=fetch-rsr-burns.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch-rsr-burns.d.ts","sourceRoot":"","sources":["../../src/revenue/fetch-rsr-burns.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAqCxF,wBAAsB,aAAa,CACjC,MAAM,CAAC,EAAE,gBAAgB,EAAE,GAC1B,OAAO,CAAC,WAAW,CAAC,CA+EtB;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,YAAY,EAAE,GACpB,OAAO,CAAC,WAAW,EAAE,CAAC,CASxB"}
@@ -0,0 +1,106 @@
1
+ import { createPriceClient } from '../clients/create-price-client';
2
+ import { CHAINLINK_RSR_USD, SUPPORTED_CHAINS } from '../constants';
3
+ import { backfillChainlinkPrices } from '../prices/chainlink';
4
+ import { querySubgraph } from '../utils/query-subgraph';
5
+ const RSR_BURNS_QUERY = `
6
+ query GetRsrBurns {
7
+ rsrburns(first: 1000, orderBy: timestamp, orderDirection: desc) {
8
+ amount
9
+ burner
10
+ timestamp
11
+ transactionHash
12
+ }
13
+ rsrburnGlobal(id: "1") {
14
+ totalBurned
15
+ totalBurnCount
16
+ }
17
+ rsrburnMonthlySnapshots(first: 12, orderBy: timestamp, orderDirection: desc) {
18
+ timestamp
19
+ monthlyBurnAmount
20
+ monthlyBurnCount
21
+ cumulativeBurned
22
+ }
23
+ }
24
+ `;
25
+ export async function fetchRsrBurns(chains) {
26
+ const targetChains = chains ?? SUPPORTED_CHAINS;
27
+ const results = await Promise.allSettled(targetChains.map(async (chainId) => {
28
+ const data = await querySubgraph(chainId, RSR_BURNS_QUERY);
29
+ return { data, chainId };
30
+ }));
31
+ const allBurns = [];
32
+ let totalBurned = 0n;
33
+ let totalBurnCount = 0;
34
+ const monthlyByTimestamp = new Map();
35
+ for (const result of results) {
36
+ if (result.status !== 'fulfilled')
37
+ continue;
38
+ const { data, chainId } = result.value;
39
+ // Burns
40
+ const burns = data?.rsrburns ?? [];
41
+ for (const b of burns) {
42
+ allBurns.push({
43
+ amount: b.amount ?? '0',
44
+ burner: b.burner ?? '',
45
+ timestamp: Number(b.timestamp ?? 0),
46
+ transactionHash: b.transactionHash ?? '',
47
+ chainId,
48
+ });
49
+ }
50
+ // Global
51
+ const global = data?.rsrburnGlobal;
52
+ if (global) {
53
+ totalBurned += BigInt(global.totalBurned ?? '0');
54
+ totalBurnCount += Number(global.totalBurnCount ?? 0);
55
+ }
56
+ // Monthly snapshots — merge by timestamp, sum amounts
57
+ const snapshots = data?.rsrburnMonthlySnapshots ?? [];
58
+ for (const s of snapshots) {
59
+ const ts = Number(s.timestamp ?? 0);
60
+ const existing = monthlyByTimestamp.get(ts);
61
+ const amount = BigInt(s.monthlyBurnAmount ?? '0');
62
+ const count = Number(s.monthlyBurnCount ?? 0);
63
+ const cumulative = BigInt(s.cumulativeBurned ?? '0');
64
+ if (existing) {
65
+ existing.amount += amount;
66
+ existing.count += count;
67
+ existing.cumulative += cumulative;
68
+ }
69
+ else {
70
+ monthlyByTimestamp.set(ts, { amount, count, cumulative });
71
+ }
72
+ }
73
+ }
74
+ // Sort burns by timestamp desc
75
+ allBurns.sort((a, b) => b.timestamp - a.timestamp);
76
+ // Convert monthly map to sorted array
77
+ const monthlySnapshots = Array.from(monthlyByTimestamp.entries())
78
+ .sort((a, b) => b[0] - a[0])
79
+ .map(([timestamp, v]) => ({
80
+ timestamp,
81
+ monthlyBurnAmount: v.amount.toString(),
82
+ monthlyBurnCount: v.count,
83
+ cumulativeBurned: v.cumulative.toString(),
84
+ }));
85
+ return {
86
+ burns: allBurns,
87
+ totalBurned: totalBurned.toString(),
88
+ totalBurnCount,
89
+ monthlySnapshots,
90
+ };
91
+ }
92
+ /**
93
+ * Fetch historical RSR/USD prices from Chainlink covering the burn timespan.
94
+ * Creates its own Ethereum mainnet client internally.
95
+ * WHY: Ethereum mainnet price is accurate for all chains — RSR is the same token.
96
+ */
97
+ export async function fetchRsrPriceHistory(burns) {
98
+ if (burns.length === 0)
99
+ return [];
100
+ const oldestTimestamp = Math.min(...burns.map((b) => b.timestamp));
101
+ const now = Math.floor(Date.now() / 1000);
102
+ const days = Math.ceil((now - oldestTimestamp) / 86400) + 1;
103
+ const priceClient = createPriceClient();
104
+ return backfillChainlinkPrices(priceClient, days, 50, CHAINLINK_RSR_USD);
105
+ }
106
+ //# sourceMappingURL=fetch-rsr-burns.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch-rsr-burns.js","sourceRoot":"","sources":["../../src/revenue/fetch-rsr-burns.ts"],"names":[],"mappings":"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"}