Files

352 lines
5.4 KiB
Markdown
Raw Permalink Normal View History

# GraphQL API Specification
## Overview
This document specifies the GraphQL API for the explorer platform, providing flexible queries, mutations for user data, and subscriptions for real-time updates.
**Endpoint**: `https://api.explorer.d-bis.org/graphql`
## Schema Overview
### Core Types
#### Block
```graphql
type Block {
chainId: Int!
number: BigInt!
hash: String!
parentHash: String!
timestamp: DateTime!
miner: Address
transactionCount: Int!
gasUsed: BigInt!
gasLimit: BigInt!
transactions: [Transaction!]!
}
```
#### Transaction
```graphql
type Transaction {
chainId: Int!
hash: String!
block: Block
blockNumber: BigInt
from: Address!
to: Address
value: BigInt!
gasPrice: BigInt
gasUsed: BigInt
status: TransactionStatus!
logs: [Log!]!
traces: [Trace!]!
}
```
#### Address
```graphql
type Address {
address: String!
chainId: Int!
balance: BigInt!
balanceUSD: Float
transactionCount: Int!
transactions: TransactionConnection!
tokens: [TokenBalance!]!
nfts: [NFT!]!
label: String
tags: [String!]!
isContract: Boolean!
contract: Contract
}
```
#### Token
```graphql
type Token {
address: String!
chainId: Int!
name: String
symbol: String
type: TokenType!
decimals: Int
totalSupply: BigInt
holderCount: Int!
transfers: TokenTransferConnection!
holders: HolderConnection!
}
```
#### Contract
```graphql
type Contract {
address: String!
chainId: Int!
name: String
verificationStatus: VerificationStatus!
sourceCode: String
abi: JSON
compilerVersion: String
createdAt: DateTime
}
```
## Queries
### Block Queries
```graphql
query GetBlock($chainId: Int!, $number: BigInt!) {
block(chainId: $chainId, number: $number) {
number
hash
timestamp
transactionCount
transactions {
hash
from
to
value
}
}
}
```
### Transaction Queries
```graphql
query GetTransaction($chainId: Int!, $hash: String!) {
transaction(chainId: $chainId, hash: $hash) {
hash
from
to
value
status
logs {
address
topics
data
}
traces {
type
from
to
value
}
}
}
```
### Address Queries
```graphql
query GetAddress($chainId: Int!, $address: String!) {
address(chainId: $chainId, address: $address) {
address
balance
balanceUSD
transactionCount
transactions(first: 10) {
edges {
node {
hash
blockNumber
value
}
}
}
tokens {
token {
symbol
name
}
balance
}
}
}
```
### Search Query
```graphql
query Search($query: String!, $chainId: Int) {
search(query: $query, chainId: $chainId) {
... on Block {
number
hash
}
... on Transaction {
hash
from
to
}
... on Address {
address
label
}
... on Token {
address
symbol
name
}
}
}
```
## Mutations
### User Preferences
```graphql
mutation UpdateWatchlist($chainId: Int!, $address: String!, $label: String) {
addToWatchlist(chainId: $chainId, address: $address, label: $label) {
success
watchlistItem {
address
label
}
}
}
mutation RemoveFromWatchlist($chainId: Int!, $address: String!) {
removeFromWatchlist(chainId: $chainId, address: $address) {
success
}
}
```
### Address Labels
```graphql
mutation AddAddressLabel($chainId: Int!, $address: String!, $label: String!) {
addAddressLabel(chainId: $chainId, address: $address, label: $label) {
success
label {
address
label
}
}
}
```
## Subscriptions
### New Blocks
```graphql
subscription NewBlocks($chainId: Int!) {
newBlock(chainId: $chainId) {
number
hash
timestamp
transactionCount
}
}
```
### Address Transactions
```graphql
subscription AddressTransactions($chainId: Int!, $address: String!) {
addressTransaction(chainId: $chainId, address: $address) {
hash
from
to
value
status
}
}
```
### Pending Transactions
```graphql
subscription PendingTransactions($chainId: Int!) {
pendingTransaction(chainId: $chainId) {
hash
from
to
value
gasPrice
}
}
```
## Resolver Architecture
### DataLoader Pattern
**Purpose**: Prevent N+1 query problems.
**Implementation**:
- Batch load related entities
- Cache within request context
- Example: Batch load all blocks for transactions in a query
### Field Resolvers
**Strategy**: Lazy loading of related fields.
**Example**:
```javascript
Block: {
transactions: (block, args, context) => {
return context.loaders.transactions.load({
chainId: block.chainId,
blockNumber: block.number
});
}
}
```
## Performance Considerations
### Query Complexity
**Limits**:
- Max depth: 10 levels
- Max complexity score: 1000
- Rate limit based on complexity
### Caching
**Strategy**:
- Cache frequently accessed fields (blocks, tokens)
- Cache duration: 1-60 seconds depending on data freshness needs
- Invalidate on updates
## Authentication
Same as REST API: API Key via header or OAuth Bearer token.
## Error Handling
**GraphQL Error Format**:
```json
{
"errors": [
{
"message": "Resource not found",
"extensions": {
"code": "NOT_FOUND",
"requestId": "uuid"
},
"path": ["block"]
}
],
"data": null
}
```
## References
- REST API: See `rest-api.md`
- API Gateway: See `api-gateway.md`