Data Source
Smart Contracts
We see smart contracts as the default data source. For anything that is retrievable via smart contracts directly, we mostly will get them by reading the contracts.
Exploring Data
Please find the contract addresses in the metadata
- Optimistic: https://metadata.perp.exchange/v2/optimism.json
- Optimistic Kovan: https://metadata.perp.exchange/v2/optimism-kovan.json
You can then search the address with the blockchain explorer to see the read/write interface of the contracts
- Optimistic: https://optimistic.etherscan.io/
- Optimistic Kovan: https://kovan-optimistic.etherscan.io/
Usage Examples
Please check out https://github.com/perpetual-protocol/sdk-curie, a Javascript SDK to interface with our v2 smart contracts.
The Graph
We use The Graph as the default on-chain data indexing service. For any data that cannot be retrieved from smart contracts directly, for example some aggregated data, we mostly will fetch from The Graph.
Exploring Data
Use the provided server:
"graphServerConfigs": [
{
"url": "https://api.thegraph.com/subgraphs/name/perpetual-protocol/perpetual-v2-optimism",
"wsUrl": "wss://api.thegraph.com/subgraphs/name/perpetual-protocol/perpetual-v2-optimism",
"healthUrl": "https://api.thegraph.com/index-node/graphql",
"name": "perpetual-protocol/perpetual-v2-optimism"
}
]You will see a GraphQL explorer interface by opening the URL.
Usage Examples
- Market Detail / Funding Rate (8h)
- Market Detail / Trades
- Market Detail / Fills
- History (all tabs)
AppSync
We use AppSync as an alternative to The Graph for time sensitive data, e.g. price chart series, since The Graph can sometimes be out of sync or unstable. We use as little data from AppSync as possible since AppSync is centralized.
Exploring Data
Please contact the team to get the api-key if needed.
Service Configs
"candleServerConfigs": [
{
"url": "https://4b3vdz2hdjho7gzuo4wl2jgsoe.appsync-api.ap-southeast-1.amazonaws.com/graphql",
"region": "ap-southeast-1",
"key": "xxxxxxxxxx"
}
],
"statisticsServerConfigs": [
{
"url": "https://4b3vdz2hdjho7gzuo4wl2jgsoe.appsync-api.ap-southeast-1.amazonaws.com/graphql",
"region": "ap-southeast-1",
"key": "xxxxxxxxxx"
}
]Example
curl -L -X POST 'https://4b3vdz2hdjho7gzuo4wl2jgsoe.appsync-api.ap-southeast-1.amazonaws.com/graphql' \
-H 'x-api-key: xxxxxxxxxx' \
-H 'Content-Type: application/json' \
-d '{"query":"query MyQuery {\n getStatistics(ammAddr: \"0x8C835DFaA34e2AE61775e80EE29E2c724c6AE2BB\") {\n lastTradePriceUsd\n volume24h\n baseVolume24h\n priceChangeRate24h\n priceHigh24h\n priceLow24h\n }\n}\n","variables":{}}'Candle Service Schema
#
# Models
#
type CandleStick {
market: String!,
resolution: String!,
startTime: Int!,
open: String!,
high: String!,
low: String!,
close: String!,
volume: String!,
baseAssetVol: String!,
txCount: Int!
version: Int!
blockNumber: Int!
}
#
# Operations
#
type Query {
listCandleSticks(
query: TableCandleStickQueryInput!,
limit: Int,
nextToken: String
): CandleStickConnection
}
type Subscription {
onUpsertCandleStick(
market: String,
resolution: String,
startTime: String
): CandleStick
onDeleteCandleStick(
market: String,
resolution: String,
startTime: String
): CandleStick
}
#
# Operation Models
#
type CandleStickConnection {
items: [CandleStick]
# token to get next page data if any
nextToken: String
}
input TableCandleStickQueryInput {
# format: baseToken#resolution
# ex: 0x7EAdA83e15AcD08d22ad85A1dCE92E5A257Acb92#5m
marketResolution: TableStringFilterInput
startTime: TableIntFilterInput
}
input TableStringFilterInput {
ne: String
eq: String
le: String
lt: String
ge: String
gt: String
contains: String
notContains: String
between: [String]
beginsWith: String
}
input TableIntFilterInput {
ne: Int
eq: Int
le: Int
lt: Int
ge: Int
gt: Int
contains: Int
notContains: Int
between: [Int]
}Statistics Service Schema
#
# Models
#
type Statistics {
ammAddr: String! # ammAddr is used in place of baseToken in perp v2
lastTradePriceUsd: String
volume24h: String
baseVolume24h: String
priceChangeRate24h: String
priceHigh24h: String
priceLow24h: String
timestamp: Int!
blockNumber: Int!
}
#
# Operations
#
type Query {
getStatistics(ammAddr: String!): Statistics
}
type Subscription {
onUpsertStatistics(ammAddr: String): Statistics
}
#
# Operation Models
#
input TableStringFilterInput {
ne: String
eq: String
le: String
lt: String
ge: String
gt: String
contains: String
notContains: String
between: [String]
beginsWith: String
}
input TableIntFilterInput {
ne: Int
eq: Int
le: Int
lt: Int
ge: Int
gt: Int
contains: Int
notContains: Int
between: [Int]
}
Usage Examples
Candle Price Chart
Market Statistics
- funding rate
- volume24h
- Change (24h)
Reward
Gas Rebate
Liquidity Mining
Pool APR
Examples of Mixed Data Sources
- TVL
pool
from The GraphmarkPrice
from smart contractspool.baseAmount.mul(markPrice).add(pool.quoteAmount)
- 24h Fees
volume24h
from AppSyncexchangeFeeRatios
from smart contractspool
from The Graphvolume24h.mul(exchangeFeeRatios[pool.baseAddress])
- Liquidity Pool