📈Subgraph Queries
Complete guide to querying DreamLend protocol data using The Graph subgraph. Access real-time and historical data for loans, users, and protocol statistics.
🌐 Subgraph Endpoint
GraphQL Endpoint: https://api.subgraph.somnia.network/api/public/d5671b32-2846-489e-a577-e7d9702dd17b/subgraphs/dreamlend-graph/v0.0.3/
Playground: Open GraphQL Playground
📊 Entity Schema
Loan Entity
type Loan @entity {
id: ID!
lender: Bytes!
borrower: Bytes
tokenAddress: Bytes!
amount: BigInt!
interestRate: BigInt!
duration: BigInt!
collateralAddress: Bytes!
collateralAmount: BigInt!
minCollateralRatioBPS: BigInt!
liquidationThresholdBPS: BigInt!
maxPriceStaleness: BigInt!
status: LoanStatus!
startTime: BigInt
repaidAmount: BigInt!
blockNumber: BigInt!
blockTimestamp: BigInt!
transactionHash: Bytes!
}User Entity
type User @entity {
id: ID!
address: Bytes!
totalLoansCreated: BigInt!
totalLoansBorrowed: BigInt!
totalAmountLent: BigInt!
totalAmountBorrowed: BigInt!
totalInterestEarned: BigInt!
totalInterestPaid: BigInt!
activeLoansAsLender: [Loan!]! @derivedFrom(field: "lender")
activeLoansAsBorrower: [Loan!]! @derivedFrom(field: "borrower")
}ProtocolStats Entity
type ProtocolStats @entity {
id: ID!
totalLoansCreated: BigInt!
totalActiveLoans: BigInt!
totalLoanVolume: BigInt!
totalLoanVolumeUSD: BigDecimal!
totalInterestEarned: BigInt!
totalCollateralLocked: BigInt!
totalLiquidations: BigInt!
totalUsers: BigInt!
}🔍 Common Queries
Get All Active Loans
query GetActiveLoans {
loans(
where: { status: Active }
orderBy: blockTimestamp
orderDirection: desc
first: 100
) {
id
lender
borrower
tokenAddress
amount
interestRate
duration
collateralAddress
collateralAmount
startTime
blockTimestamp
}
}Get Pending Loan Offers
query GetPendingOffers {
loans(
where: { status: Pending }
orderBy: blockTimestamp
orderDirection: desc
first: 50
) {
id
lender
tokenAddress
amount
interestRate
duration
collateralAddress
collateralAmount
minCollateralRatioBPS
liquidationThresholdBPS
blockTimestamp
}
}Get User's Loans
query GetUserLoans($userAddress: Bytes!) {
# Loans where user is lender
lenderLoans: loans(
where: { lender: $userAddress }
orderBy: blockTimestamp
orderDirection: desc
) {
id
borrower
tokenAddress
amount
interestRate
duration
status
startTime
repaidAmount
blockTimestamp
}
# Loans where user is borrower
borrowerLoans: loans(
where: { borrower: $userAddress }
orderBy: blockTimestamp
orderDirection: desc
) {
id
lender
tokenAddress
amount
interestRate
duration
collateralAddress
collateralAmount
status
startTime
repaidAmount
blockTimestamp
}
}Get Loan Details
query GetLoanDetails($loanId: ID!) {
loan(id: $loanId) {
id
lender
borrower
tokenAddress
amount
interestRate
duration
collateralAddress
collateralAmount
minCollateralRatioBPS
liquidationThresholdBPS
maxPriceStaleness
status
startTime
repaidAmount
blockNumber
blockTimestamp
transactionHash
}
}Get Protocol Statistics
query GetProtocolStats {
protocolStats(id: "global") {
totalLoansCreated
totalActiveLoans
totalLoanVolume
totalLoanVolumeUSD
totalInterestEarned
totalCollateralLocked
totalLiquidations
totalUsers
}
}Get User Statistics
query GetUserStats($userAddress: ID!) {
user(id: $userAddress) {
address
totalLoansCreated
totalLoansBorrowed
totalAmountLent
totalAmountBorrowed
totalInterestEarned
totalInterestPaid
activeLoansAsLender {
id
amount
status
}
activeLoansAsBorrower {
id
amount
status
}
}
}Get Loans by Token
query GetLoansByToken($tokenAddress: Bytes!) {
loans(
where: { tokenAddress: $tokenAddress }
orderBy: blockTimestamp
orderDirection: desc
first: 100
) {
id
lender
borrower
amount
interestRate
duration
status
blockTimestamp
}
}Get Recent Liquidations
query GetRecentLiquidations {
loans(
where: { status: Defaulted }
orderBy: blockTimestamp
orderDirection: desc
first: 50
) {
id
lender
borrower
tokenAddress
amount
collateralAddress
collateralAmount
blockTimestamp
}
}Get Loans with Filters
query GetFilteredLoans(
$minAmount: BigInt!
$maxInterestRate: BigInt!
$tokenAddress: Bytes!
) {
loans(
where: {
status: Pending
amount_gte: $minAmount
interestRate_lte: $maxInterestRate
tokenAddress: $tokenAddress
}
orderBy: interestRate
orderDirection: asc
first: 20
) {
id
lender
amount
interestRate
duration
collateralAddress
collateralAmount
blockTimestamp
}
}📊 Advanced Queries
Get Loan History with Events
query GetLoanHistory($loanId: ID!) {
loan(id: $loanId) {
id
lender
borrower
status
# Add related events when available
loanOfferCreatedEvents: loanOfferCreatedEvents(where: { loanId: $loanId }) {
blockTimestamp
transactionHash
}
loanOfferAcceptedEvents: loanOfferAcceptedEvents(
where: { loanId: $loanId }
) {
borrower
blockTimestamp
transactionHash
}
}
}Get Top Lenders
query GetTopLenders {
users(
orderBy: totalAmountLent
orderDirection: desc
first: 10
where: { totalLoansCreated_gt: 0 }
) {
address
totalLoansCreated
totalAmountLent
totalInterestEarned
}
}Get Market Overview
query GetMarketOverview {
# Get protocol stats
protocolStats(id: "global") {
totalLoansCreated
totalActiveLoans
totalLoanVolumeUSD
}
# Get recent loans
recentLoans: loans(orderBy: blockTimestamp, orderDirection: desc, first: 10) {
id
tokenAddress
amount
interestRate
status
blockTimestamp
}
# Get active offers
activeOffers: loans(
where: { status: Pending }
orderBy: interestRate
orderDirection: asc
first: 10
) {
id
tokenAddress
amount
interestRate
duration
}
}🛠️ JavaScript Integration
Using Apollo Client
import { ApolloClient, InMemoryCache, gql } from "@apollo/client";
const client = new ApolloClient({
uri: "https://api.subgraph.somnia.network/api/public/d5671b32-2846-489e-a577-e7d9702dd17b/subgraphs/dreamlend-graph/v0.0.3/",
cache: new InMemoryCache(),
});
const GET_ACTIVE_LOANS = gql`
query GetActiveLoans {
loans(where: { status: Active }, first: 100) {
id
lender
borrower
amount
interestRate
tokenAddress
}
}
`;
const { data, loading, error } = await client.query({
query: GET_ACTIVE_LOANS,
});Using Fetch API
const query = `
query GetUserLoans($userAddress: String!) {
loans(where: { lender: $userAddress }) {
id
amount
interestRate
status
}
}
`;
const response = await fetch(
"https://api.subgraph.somnia.network/api/public/d5671b32-2846-489e-a577-e7d9702dd17b/subgraphs/dreamlend-graph/v0.0.3/",
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
query,
variables: { userAddress: "0x..." },
}),
}
);
const { data } = await response.json();React Hook Example
import { useQuery } from "@apollo/client";
function useUserLoans(userAddress) {
const { data, loading, error } = useQuery(GET_USER_LOANS, {
variables: { userAddress },
pollInterval: 30000, // Poll every 30 seconds
});
return {
lenderLoans: data?.lenderLoans || [],
borrowerLoans: data?.borrowerLoans || [],
loading,
error,
};
}📋 Query Parameters
Filtering
where: Filter entities by field valueswhere_not: Exclude entities matching criteriawhere_gt/gte/lt/lte: Numeric comparisonswhere_in/not_in: Array membership
Sorting
orderBy: Field to sort byorderDirection:ascordesc
Pagination
first: Number of entities to return (max 1000)skip: Number of entities to skiplast: Get last N entities
Example with All Parameters
query GetFilteredLoans {
loans(
where: {
status_in: [Pending, Active]
amount_gte: "1000000000"
interestRate_lte: "2000"
}
orderBy: blockTimestamp
orderDirection: desc
first: 50
skip: 0
) {
id
amount
interestRate
status
}
}🔄 Real-time Updates
Subscriptions (if supported)
subscription OnNewLoans {
loans(orderBy: blockTimestamp, orderDirection: desc, first: 1) {
id
lender
amount
interestRate
blockTimestamp
}
}Polling Strategy
// Poll for updates every 30 seconds
const { data } = useQuery(GET_ACTIVE_LOANS, {
pollInterval: 30000,
fetchPolicy: "cache-and-network",
});🎯 Best Practices
Performance Optimization
Limit Results: Always use
firstparameterSpecific Fields: Only query fields you need
Proper Indexing: Use indexed fields for filtering
Batch Queries: Combine related queries
Error Handling
const { data, loading, error } = useQuery(QUERY, {
errorPolicy: "all", // Return partial data on error
onError: (error) => {
console.error("Subgraph query error:", error);
},
});Caching Strategy
const client = new ApolloClient({
cache: new InMemoryCache({
typePolicies: {
Loan: {
fields: {
// Cache loans by ID for 5 minutes
loans: {
merge: false,
},
},
},
},
}),
});For more examples and integration patterns, see our Developer Integration Guide.
Last updated
