forked from suntzu93/threshold-tBTC
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathschema.graphql
More file actions
421 lines (372 loc) · 12.9 KB
/
Copy pathschema.graphql
File metadata and controls
421 lines (372 loc) · 12.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
enum DepositStatus {
UNKNOWN
REVEALED #-> bridge.revealDeposit() / DepositRevealed event
MINTING_REQUESTED
SWEPT # -> bridge.submitDepositSweepProof() / DepositSwept event && bank.increaseBalances() / BalanceIncreased event
MINTING_FINALIZED
CANCELED # -> Guardian cancel , The optimistic minting request for the given deposit exis or The optimistic minting request for the given deposit has not been finalized yet.
REFUNDED
}
enum RedemptionStatus {
UNKNOWN
REQUESTED #-> bridge.requestRedemption() / RedemptionRequested event && bank.transferBalanceFrom() / BalanceTransferred event
COMPLETED #-> bridge.submitRedemptionProof() / RedemptionCompleted event && bank.DecreaseBalance() / BalanceDecreased event && bank.trasferBalance() / BalanceTransferred event
TIMEDOUT #-> bridge.notifyRedemptionTimeout() / RedemptionTimedOut
VETOED #-> redemptionWatchTower.raiseObjection()
}
# Wormhole chain IDs for cross-chain redemption tracking
enum WormholeChain {
UNKNOWN
SOLANA # Chain ID: 1
ETHEREUM # Chain ID: 2
BSC # Chain ID: 4
POLYGON # Chain ID: 5
AVALANCHE # Chain ID: 6
FANTOM # Chain ID: 10
KLAYTN # Chain ID: 13
CELO # Chain ID: 14
MOONBEAM # Chain ID: 16
SUI # Chain ID: 21
ARBITRUM # Chain ID: 23
OPTIMISM # Chain ID: 24
BASE # Chain ID: 30
STARKNET # Chain ID: 10006
}
# Fulltext search removed for local testing (causes non-determinism error in graph-node)
# type _Schema_
# @fulltext(
# name: "searchRedemption"
# language: en
# algorithm: rank
# include: [{ entity: "Redemption", fields: [{ name: "id" }] }]
# )
type Transaction @entity {
id: ID!
txHash: Bytes!
timestamp: BigInt!
from: Bytes!
to: Bytes
amount: BigInt
description: String
deposits: [Deposit!] @derivedFrom(field: "transactions")
redemptions: [Redemption!] @derivedFrom(field: "transactions")
}
type User @entity {
id: Bytes!
mintingDebt: BigInt!
tokenBalance: BigInt!
totalTokensHeld: BigInt!
tbtcToken: TBTCToken!
deposits: [Deposit!]!
redemptions: [Redemption!]!
isRedeemerBanned: Boolean!
}
type Deposit @entity {
#keccak256(fundingTxHash|fundingOutputIndex)
id: Bytes!
status: DepositStatus
user: User!
amount: BigInt!
newDebt: BigInt!
actualAmountReceived: BigInt!
treasuryFee: BigInt!
walletPubKeyHash: Bytes
fundingTxHash: Bytes
fundingOutputIndex: BigInt
blindingFactor: Bytes
refundPubKeyHash: Bytes
refundLocktime: Bytes
vault: Bytes
transactions: [Transaction!]!
sweptAt: BigInt
depositTimestamp: BigInt
updateTimestamp: BigInt
# --- Routed (gasless / direct-mint) destination ---
# Populated from the L1 depositor DepositInitialized/DepositFinalized events
# (see mappingRoutedDeposit). destinationOwner is the 32-byte indexed owner
# topic exactly as the dapp's normalizeDestinationTopic() produces it (EVM
# address left-padded to 32 bytes; Sui/StarkNet raw bytes32), so a
# `where: { destinationOwner: $owner }` lookup is a drop-in for the client's
# chunked eth_getLogs scan. Null for standard deposits.
destinationOwner: Bytes
# L1 msg.sender of the FIRST routed event seen for this deposit — the
# initializer when it is in range, otherwise the (permissionless, typically
# relayer) finalizer. Cheap to carry and useful for debugging/attribution.
l1Sender: Bytes
# True once a routed DepositInitialized/DepositFinalized has attached here.
isRouted: Boolean
}
type Redemption @entity {
#keccak256(keccak256(redeemerOutputScript) | walletPubKeyHash) + "-" + count
id: ID!
status: RedemptionStatus
user: User!
amount: BigInt!
walletPubKeyHash: Bytes
redeemerOutputScript: Bytes
redemptionTxHash: Bytes
treasuryFee: BigInt
txMaxFee: BigInt
completedTxHash: Bytes
transactions: [Transaction!]!
redemptionTimestamp: BigInt
updateTimestamp: BigInt!
# Cross-chain origin tracking for L2 redemptions via Wormhole
sourceChainId: Int # Wormhole chain ID (null = Ethereum native)
sourceChain: WormholeChain # Human-readable chain enum
wormholeSequence: BigInt # Wormhole message sequence number
}
# Track allowed Wormhole senders for cross-chain redemptions
type WormholeSender @entity {
id: ID! # Sender address (bytes32 as hex)
chainId: Int! # Wormhole chain ID
chain: WormholeChain! # Human-readable chain
allowed: Boolean! # Whether currently allowed
addedAt: BigInt! # Block timestamp when added
updatedAt: BigInt! # Last update timestamp
}
# Temporary tracker for linking VAA data to redemptions
type CrossChainRedemptionTracker @entity {
id: ID! # Transaction hash
sourceChainId: Int! # Wormhole chain ID from VAA
sourceChain: WormholeChain! # Human-readable chain
emitterAddress: Bytes! # L2BitcoinRedeemer address (bytes32)
sequence: BigInt! # Wormhole message sequence
processed: Boolean! # Whether linked to redemption
}
# C-1 prep: scheme classification for wallets. ECDSA wallets are
# created via the legacy ECDSA wallet registry; FROST wallets are
# created via the FROST wallet registry (B-1) and register through
# `Bridge.__frostWalletCreatedCallback`. Defaults to ECDSA for
# pre-#431 records.
enum WalletScheme {
ECDSA
FROST
}
type Wallet @entity {
# Canonical wallet ID. For legacy wallets, this is the left-padded walletPubKeyHash.
id: Bytes!
walletID: Bytes!
ecdsaWalletID: Bytes!
walletPubKeyHash: Bytes!
registeredAt: BigInt!
registeredAtBlock: BigInt!
transactionHash: Bytes!
# C-1 prep: defaults to ECDSA for pre-#431 records. Populated
# at registration time via the matching handler:
# `handleNewWalletRegistered` (= ECDSA) /
# `handleNewFrostWalletRegistered` (= FROST).
scheme: WalletScheme!
# FROST-only: the 32-byte x-only Taproot output key. Null for
# ECDSA wallets.
xOnlyOutputKey: Bytes
}
# C-1 prep: singleton entity tracking Bridge governance state
# that is hard to derive from individual events alone
# (currently-selected scheme; addresses of the
# governance-configured routers). The singleton uses a fixed id
# `"singleton"`.
#
# RFC v6 also specified counter + seed fields (`ecdsaWalletCount`,
# `ecdsaWalletCountSeeded`, `historicalSeedAmount`, the seed
# timestamps), but the matching on-chain mechanism is deferred
# from the C-2 PR (#439) for bytecode-budget reasons; the C-1.1c
# follow-up will re-add these fields alongside the new
# `handleEcdsaWalletCountSeeded` handler that uses
# `event.params.totalAfterSeed` for idempotent absolute-set
# (per Codex P2 feedback on the earlier C-1.1a iteration).
type BridgeState @entity {
id: ID!
# C-2: current default scheme used by `requestNewWallet`.
# Defaults to ECDSA at C-2 activation. Updated by
# `handleNewWalletSchemeSet`.
currentScheme: WalletScheme!
# Governance-configured router / registry addresses. Each is
# null until the matching one-time setter event fires.
frostWalletRegistry: Bytes
ecdsaFraudRouter: Bytes
p2trFraudRouter: Bytes
lifecycleRouter: Bytes
}
# C-1 prep: append-only audit log of scheme flips. Each entry is
# created by `handleNewWalletSchemeSet`; useful for governance
# review.
type WalletSchemeChange @entity {
id: ID!
scheme: WalletScheme!
changedAt: BigInt!
changedAtBlock: BigInt!
transactionHash: Bytes!
}
type TBTCToken @entity{
"TBTCToken"
id: ID!
name: String!
symbol: String!
decimals: Int!
address: Bytes!
totalSupply: BigInt!
totalMint: BigInt!
totalBurn: BigInt!
currentTokenHolders: BigInt!
holders: [User!] @derivedFrom(field: "tbtcToken")
}
enum TransactionEvent {
STAKED,
TOPUP,
UNSTAKE,
AUTHORIZED_RANDOM_BEACON,
AUTHORIZED_TBTC,
AUTHORIZED_UNKNOW,
DECREASE_AUTHORIZED_RANDOM_BEACON,
DECREASE_AUTHORIZED_TBTC,
REGISTERED_OPERATOR,
BOND_OPERATOR,
JOINED_SORTITION_POOL,
SLASHED,
WITHDRAW_REWARD
}
type Event @entity {
#Hash of transaction
id: ID!
txHash: Bytes!
timestamp: BigInt!
from: Bytes!
to: Bytes
amount: BigInt!
isRandomBeaconEvent: Boolean!
event: TransactionEvent!
operator: [Operator!] @derivedFrom(field: "events")
}
type GroupPublicKey @entity {
# Group id
id: ID!
# Group public key
pubKey: Bytes!
group : RandomBeaconGroup!
}
type RandomBeaconGroup @entity {
id: ID!
createdAt: BigInt!
createdAtBlock: BigInt!
groupPublicKey: GroupPublicKey! @derivedFrom(field: "group")
memberships: [RandomBeaconGroupMembership!]! @derivedFrom(field: "group")
"The total number of slots."
size: Int!
uniqueMemberCount: Int!
"Total fault."
misbehavedCount: Int!
totalSlashedAmount: BigInt!
terminated: Boolean!
nonce: BigInt!
notifier : Bytes
"Create from WalletRegistry"
isWalletRegistry: Boolean!
relayEntries: [RelayEntry!]! @derivedFrom(field: "group")
}
"""
Represents the membership of an operator in a beacon group.
"""
type RandomBeaconGroupMembership @entity {
#keccak256(group id , operator address)
id: ID!
group: RandomBeaconGroup!
operator: Operator!
seats: [Int!]!
"The same operator can fill multiple membership slots within a group."
count: Int!
# These are denormalized fields from the group & operator, to allow sorting memberships by these fields.
groupCreatedAt: BigInt!
}
type RelayEntry @entity {
"Request Id"
id: ID!
requestedAt: BigInt!
requestedBy: Bytes!
group: RandomBeaconGroup!
value: Bytes
submitter: Bytes!
submittedAt: BigInt
isInProgress: Boolean!
}
type Operator @entity {
#Staking Provider address
id: ID!
#Operator address
address: Bytes!
registeredOperatorAddress: Int!
"registered operator address use PreApplication"
isBondRegisteredOperatorAddress: Boolean!
"When this operator had a stake delegated to them. This is like a createdAt, and the operation also assigns the beneficiary/authorizer roles."
stakedAt: BigInt!
stakeType: Int!
randomBeaconGroupMemberships: [RandomBeaconGroupMembership!]! @derivedFrom(field: "operator")
# The other "staker" roles.
owner: Bytes
beneficiary: Bytes
authorizer: Bytes
# Authorizations
randomBeaconAuthorized: Boolean!
tBTCAuthorized: Boolean!
# Statistics
tBTCAuthorizedAmount: BigInt!
randomBeaconAuthorizedAmount: BigInt!
stakedAmount: BigInt!
"Total reward withdrew"
rewardDispensed : BigInt!
"The reward available to withdraw."
availableReward: BigInt!
"How often this operator was involved in a fault."
misbehavedCount: Int!
totalSlashedAmount: BigInt!
"Duration of the sortition pool rewards ban imposed on operators who misbehaved"
poolRewardBanDuration: BigInt!
beaconGroupCount: Int!
events: [Event!]!
}
enum State {
"Group creation is not in progress. It is a state set after group creation completion either by timeout or by a result approval."
IDLE,
"Group creation is awaiting the seed and sortition pool is locked."
AWAITING_SEED,
"Off-chain DKG protocol execution is in progress. A result is being calculated by the clients in this state. It's not yet possible to submit the result."
KEY_GENERATION,
""" After off-chain DKG protocol execution the contract awaits result submission.
This is a state to which group creation returns in case of a result
challenge notification."""
AWAITING_RESULT,
"""DKG result was submitted and awaits an approval or a challenge. If a result
gets challenge the state returns to `AWAITING_RESULT`. If a result gets
approval the state changes to `IDLE`."""
CHALLENGE
}
"""
Exposes some global system statistics. Only a single record with the id "current" is available.
"""
type StatsRecord @entity {
id: ID!
"The total number of stakers with a stake larger than 0."
numOperators: Int!
numDeposits: Int!
numRedemptions: Int!
numOperatorsRegisteredNode: Int!
totalTBTCAuthorizedAmount: BigInt!
totalRandomBeaconAuthorizedAmount: BigInt!
totalStaked: BigInt!
"True is not pause"
mintingStatus: Boolean!
}
"""
Exposes some global system status data. Only a single record with the id "status" is available.
"""
type StatusRecord @entity {
id: ID!
"The currently requested RandomBeacon relay entry, if any. Only a single request can exist at a time."
groupState: State!
ecdsaState: State!
challenger: Bytes
reason: String
pendingRedemptions: [Bytes!]!
lastMintedInfo: [String!]!
lastMintedHash: Bytes!
}