Skip to content

Commit e8fbd1f

Browse files
moose-codeclaude
andcommitted
feat: multi-token support with analytics-grade schema for stablescan
- Use event.srcAddress to namespace all entities by token contract - Add holderCount, allTimeVolume, totalVolumeIn/Out tracking - Add HourlySnapshot, WeeklySnapshot, CrossTokenDailySnapshot - Add netMintBurnFlow, uniqueActiveAddresses, newAddressCount on snapshots - Add AccountBalanceSnapshot for per-account balance-over-time charts - Add marker entities for unique address deduplication per period - Optimize composite indexes for leaderboard, time-series, and account queries Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 1bc343c commit e8fbd1f

File tree

3 files changed

+274
-52
lines changed

3 files changed

+274
-52
lines changed

schema.graphql

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ type Account @index(fields: ["token", ["balance", "DESC"]]) {
2424
token: String! @index
2525
address: String! @index
2626
balance: BigInt!
27+
totalVolumeIn: BigInt!
28+
totalVolumeOut: BigInt!
2729
transfersIn: Int!
2830
transfersOut: Int!
2931
firstSeenBlock: Int!
@@ -52,6 +54,8 @@ type TokenSupply @index(fields: ["chainId", "token"]) {
5254
totalSupply: BigInt!
5355
totalMinted: BigInt!
5456
totalBurned: BigInt!
57+
allTimeVolume: BigInt!
58+
holderCount: Int!
5559
mintCount: Int!
5660
burnCount: Int!
5761
transferCount: Int!
@@ -69,8 +73,10 @@ type HourlySnapshot @index(fields: ["token", ["hourId", "DESC"]]) {
6973
transferCount: Int!
7074
mintVolume: BigInt!
7175
burnVolume: BigInt!
76+
netMintBurnFlow: BigInt!
7277
mintCount: Int!
7378
burnCount: Int!
79+
uniqueActiveAddresses: Int!
7480
endOfHourSupply: BigInt!
7581
firstBlockOfHour: Int!
7682
lastBlockOfHour: Int!
@@ -86,8 +92,11 @@ type DailySnapshot @index(fields: ["token", ["dayId", "DESC"]]) {
8692
dailyTransferCount: Int!
8793
dailyMintVolume: BigInt!
8894
dailyBurnVolume: BigInt!
95+
netMintBurnFlow: BigInt!
8996
dailyMintCount: Int!
9097
dailyBurnCount: Int!
98+
uniqueActiveAddresses: Int!
99+
newAddressCount: Int!
91100
endOfDaySupply: BigInt!
92101
firstBlockOfDay: Int!
93102
lastBlockOfDay: Int!
@@ -103,13 +112,39 @@ type WeeklySnapshot @index(fields: ["token", ["weekId", "DESC"]]) {
103112
weeklyTransferCount: Int!
104113
weeklyMintVolume: BigInt!
105114
weeklyBurnVolume: BigInt!
115+
netMintBurnFlow: BigInt!
106116
weeklyMintCount: Int!
107117
weeklyBurnCount: Int!
118+
uniqueActiveAddresses: Int!
108119
endOfWeekSupply: BigInt!
109120
firstBlockOfWeek: Int!
110121
lastBlockOfWeek: Int!
111122
}
112123

124+
type CrossTokenDailySnapshot @index(fields: ["chainId", ["dayId", "DESC"]]) {
125+
id: ID! # ${chainId}-${dayId}
126+
chainId: Int! @index
127+
dayId: Int! @index
128+
dayStartTimestamp: Int!
129+
totalVolume: BigInt!
130+
totalTransferCount: Int!
131+
totalMintVolume: BigInt!
132+
totalBurnVolume: BigInt!
133+
netMintBurnFlow: BigInt!
134+
}
135+
136+
type AccountBalanceSnapshot @index(fields: ["account", "token", ["blockTimestamp", "DESC"]]) {
137+
id: ID! # ${chainId}-${token}-${address}-${blockNumber}-${logIndex}
138+
chainId: Int!
139+
token: String! @index
140+
account: String! @index
141+
blockNumber: Int!
142+
blockTimestamp: Int! @index
143+
balance: BigInt!
144+
balanceChange: BigInt!
145+
txHash: String!
146+
}
147+
113148
type AccountDailyActivity @index(fields: ["account", "token", ["dayId", "DESC"]]) {
114149
id: ID! # ${chainId}-${token}-${address}-${dayId}
115150
chainId: Int! @index
@@ -120,3 +155,16 @@ type AccountDailyActivity @index(fields: ["account", "token", ["dayId", "DESC"]]
120155
volumeIn: BigInt!
121156
volumeOut: BigInt!
122157
}
158+
159+
# Marker entities for unique address deduplication per period
160+
type HourlyActiveAddress {
161+
id: ID! # ${chainId}-${token}-${hourId}-${address}
162+
}
163+
164+
type DailyActiveAddress {
165+
id: ID! # ${chainId}-${token}-${dayId}-${address}
166+
}
167+
168+
type WeeklyActiveAddress {
169+
id: ID! # ${chainId}-${token}-${weekId}-${address}
170+
}

0 commit comments

Comments
 (0)