Merge pull request #7 from blockworks-foundation/add_spport_for_legacy_oracles
Add support for legacy oracles
This commit is contained in:
commit
208759f577
|
@ -22,7 +22,7 @@
|
||||||
"blockworks"
|
"blockworks"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"sol:usd": {
|
"btc:usdt": {
|
||||||
"decimals": 2,
|
"decimals": 2,
|
||||||
"minSubmissions": 1,
|
"minSubmissions": 1,
|
||||||
"maxSubmissions": 13,
|
"maxSubmissions": 13,
|
||||||
|
@ -33,7 +33,7 @@
|
||||||
"blockworks"
|
"blockworks"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"srm:usd": {
|
"eth:usdt": {
|
||||||
"decimals": 2,
|
"decimals": 2,
|
||||||
"minSubmissions": 1,
|
"minSubmissions": 1,
|
||||||
"maxSubmissions": 13,
|
"maxSubmissions": 13,
|
||||||
|
@ -43,6 +43,28 @@
|
||||||
"oracles": [
|
"oracles": [
|
||||||
"blockworks"
|
"blockworks"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"sol:usd": {
|
||||||
|
"decimals": 4,
|
||||||
|
"minSubmissions": 1,
|
||||||
|
"maxSubmissions": 13,
|
||||||
|
"restartDelay": 0,
|
||||||
|
"rewardAmount": 10000,
|
||||||
|
"rewardTokenAccount": "3oLHHTaRqNsuTMjsTtkVy8bock6Bx8gCmDxku4TurVj1",
|
||||||
|
"oracles": [
|
||||||
|
"blockworks"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"srm:usd": {
|
||||||
|
"decimals": 4,
|
||||||
|
"minSubmissions": 1,
|
||||||
|
"maxSubmissions": 13,
|
||||||
|
"restartDelay": 0,
|
||||||
|
"rewardAmount": 10000,
|
||||||
|
"rewardTokenAccount": "3oLHHTaRqNsuTMjsTtkVy8bock6Bx8gCmDxku4TurVj1",
|
||||||
|
"oracles": [
|
||||||
|
"blockworks"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"oracles": {
|
"oracles": {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"aggregators": {
|
"aggregators": {
|
||||||
"btc:usd": {
|
"btc:usdt": {
|
||||||
"pubkey": {
|
"pubkey": {
|
||||||
"type": "PublicKey",
|
"type": "PublicKey",
|
||||||
"base58": "6Xvk6VC423bbhwnCfMyPfE4C1vytoqsVMUY1Lbqeh6pf"
|
"base58": "6Xvk6VC423bbhwnCfMyPfE4C1vytoqsVMUY1Lbqeh6pf"
|
||||||
|
@ -10,7 +10,7 @@
|
||||||
"base58": "GXdZLSvnreqyUd92tXFShpF8DPvpqDBRkukAtraZ3rCf"
|
"base58": "GXdZLSvnreqyUd92tXFShpF8DPvpqDBRkukAtraZ3rCf"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"description": "btc:usd",
|
"description": "btc:usdt",
|
||||||
"decimals": 2,
|
"decimals": 2,
|
||||||
"minSubmissions": 1,
|
"minSubmissions": 1,
|
||||||
"maxSubmissions": 13,
|
"maxSubmissions": 13,
|
||||||
|
@ -34,7 +34,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"eth:usd": {
|
"eth:usdt": {
|
||||||
"pubkey": {
|
"pubkey": {
|
||||||
"type": "PublicKey",
|
"type": "PublicKey",
|
||||||
"base58": "4CoKvk3NUXYiHKGbQvihadw6TC8LTN1qjfadPcsaURbW"
|
"base58": "4CoKvk3NUXYiHKGbQvihadw6TC8LTN1qjfadPcsaURbW"
|
||||||
|
@ -44,7 +44,7 @@
|
||||||
"base58": "GXdZLSvnreqyUd92tXFShpF8DPvpqDBRkukAtraZ3rCf"
|
"base58": "GXdZLSvnreqyUd92tXFShpF8DPvpqDBRkukAtraZ3rCf"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"description": "eth:usd",
|
"description": "eth:usdt",
|
||||||
"decimals": 2,
|
"decimals": 2,
|
||||||
"minSubmissions": 1,
|
"minSubmissions": 1,
|
||||||
"maxSubmissions": 13,
|
"maxSubmissions": 13,
|
||||||
|
@ -68,17 +68,17 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sol:usd": {
|
"btc:usd": {
|
||||||
"pubkey": {
|
"pubkey": {
|
||||||
"type": "PublicKey",
|
"type": "PublicKey",
|
||||||
"base58": "Ej5FrNjhXaePK7cVMZtSooatzXMeunNsjxrnubefEyNC"
|
"base58": "FuEnReoxhqW8Li6EMLoaaUWbWAEjTfSRuBARo5GrGCqN"
|
||||||
},
|
},
|
||||||
"owner": {
|
"owner": {
|
||||||
"type": "PublicKey",
|
"type": "PublicKey",
|
||||||
"base58": "GXdZLSvnreqyUd92tXFShpF8DPvpqDBRkukAtraZ3rCf"
|
"base58": "GXdZLSvnreqyUd92tXFShpF8DPvpqDBRkukAtraZ3rCf"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"description": "sol:usd",
|
"description": "btc:usd",
|
||||||
"decimals": 2,
|
"decimals": 2,
|
||||||
"minSubmissions": 1,
|
"minSubmissions": 1,
|
||||||
"maxSubmissions": 13,
|
"maxSubmissions": 13,
|
||||||
|
@ -93,7 +93,75 @@
|
||||||
"blockworks": {
|
"blockworks": {
|
||||||
"pubkey": {
|
"pubkey": {
|
||||||
"type": "PublicKey",
|
"type": "PublicKey",
|
||||||
"base58": "4fuTrajqBHGGM1ig4b57DD9JxcN5Q2MmoDVnMtnucjS7"
|
"base58": "AhD1vCnNBgECpoBrfsqP83KSZsd4TtrWvP3FgebUDoRu"
|
||||||
|
},
|
||||||
|
"owner": {
|
||||||
|
"type": "PublicKey",
|
||||||
|
"base58": "GXdZLSvnreqyUd92tXFShpF8DPvpqDBRkukAtraZ3rCf"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"eth:usd": {
|
||||||
|
"pubkey": {
|
||||||
|
"type": "PublicKey",
|
||||||
|
"base58": "GzfYWGM1oeVrha9zvM1awnTJEUAuinpnVRUyYQYELzqg"
|
||||||
|
},
|
||||||
|
"owner": {
|
||||||
|
"type": "PublicKey",
|
||||||
|
"base58": "GXdZLSvnreqyUd92tXFShpF8DPvpqDBRkukAtraZ3rCf"
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"description": "eth:usd",
|
||||||
|
"decimals": 2,
|
||||||
|
"minSubmissions": 1,
|
||||||
|
"maxSubmissions": 13,
|
||||||
|
"restartDelay": 0,
|
||||||
|
"rewardTokenAccount": {
|
||||||
|
"type": "PublicKey",
|
||||||
|
"base58": "3oLHHTaRqNsuTMjsTtkVy8bock6Bx8gCmDxku4TurVj1"
|
||||||
|
},
|
||||||
|
"rewardAmount": 10000
|
||||||
|
},
|
||||||
|
"oracles": {
|
||||||
|
"blockworks": {
|
||||||
|
"pubkey": {
|
||||||
|
"type": "PublicKey",
|
||||||
|
"base58": "HhBmYDPRzJDCbtsTcaB2j6sbpcNDK41CUciev94eroUE"
|
||||||
|
},
|
||||||
|
"owner": {
|
||||||
|
"type": "PublicKey",
|
||||||
|
"base58": "GXdZLSvnreqyUd92tXFShpF8DPvpqDBRkukAtraZ3rCf"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sol:usd": {
|
||||||
|
"pubkey": {
|
||||||
|
"type": "PublicKey",
|
||||||
|
"base58": "AshULbjkGvse8YW2ojjeqHdMbFGigLy2xxiGVhsLqX5T"
|
||||||
|
},
|
||||||
|
"owner": {
|
||||||
|
"type": "PublicKey",
|
||||||
|
"base58": "GXdZLSvnreqyUd92tXFShpF8DPvpqDBRkukAtraZ3rCf"
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"description": "sol:usd",
|
||||||
|
"decimals": 4,
|
||||||
|
"minSubmissions": 1,
|
||||||
|
"maxSubmissions": 13,
|
||||||
|
"restartDelay": 0,
|
||||||
|
"rewardTokenAccount": {
|
||||||
|
"type": "PublicKey",
|
||||||
|
"base58": "3oLHHTaRqNsuTMjsTtkVy8bock6Bx8gCmDxku4TurVj1"
|
||||||
|
},
|
||||||
|
"rewardAmount": 10000
|
||||||
|
},
|
||||||
|
"oracles": {
|
||||||
|
"blockworks": {
|
||||||
|
"pubkey": {
|
||||||
|
"type": "PublicKey",
|
||||||
|
"base58": "2K38TaiEJEiPZY3TGKjuLMoHgZgXxX7YX2wRD2WvfUDM"
|
||||||
},
|
},
|
||||||
"owner": {
|
"owner": {
|
||||||
"type": "PublicKey",
|
"type": "PublicKey",
|
||||||
|
@ -105,7 +173,7 @@
|
||||||
"srm:usd": {
|
"srm:usd": {
|
||||||
"pubkey": {
|
"pubkey": {
|
||||||
"type": "PublicKey",
|
"type": "PublicKey",
|
||||||
"base58": "GR9tYpi8CM8u8sdRaJZoP32KoWBphyoWV3xoNt4XwmRV"
|
"base58": "B3nWGxqNQzJeRfpYSXU8qJaTQxspZmqAt91FRAhfoFQL"
|
||||||
},
|
},
|
||||||
"owner": {
|
"owner": {
|
||||||
"type": "PublicKey",
|
"type": "PublicKey",
|
||||||
|
@ -113,7 +181,7 @@
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"description": "srm:usd",
|
"description": "srm:usd",
|
||||||
"decimals": 2,
|
"decimals": 4,
|
||||||
"minSubmissions": 1,
|
"minSubmissions": 1,
|
||||||
"maxSubmissions": 13,
|
"maxSubmissions": 13,
|
||||||
"restartDelay": 0,
|
"restartDelay": 0,
|
||||||
|
@ -127,7 +195,7 @@
|
||||||
"blockworks": {
|
"blockworks": {
|
||||||
"pubkey": {
|
"pubkey": {
|
||||||
"type": "PublicKey",
|
"type": "PublicKey",
|
||||||
"base58": "8tn58rnF1QzPqQea4xegck556s45DUGBJvWLNdsLpT69"
|
"base58": "CsyV4JuPjdYRusw4sa7Ba8Ab8yR7vjyp4wAPuC2neejS"
|
||||||
},
|
},
|
||||||
"owner": {
|
"owner": {
|
||||||
"type": "PublicKey",
|
"type": "PublicKey",
|
||||||
|
@ -141,4 +209,4 @@
|
||||||
"type": "PublicKey",
|
"type": "PublicKey",
|
||||||
"base58": "Agc6kwhaMw6rmAtfL7jfaFx1Su4QbjGBD5M42YwetqDe"
|
"base58": "Agc6kwhaMw6rmAtfL7jfaFx1Su4QbjGBD5M42YwetqDe"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ async function main() {
|
||||||
// const aggfeed2 = new AggregatedFeed(feeds, "eth:usd")
|
// const aggfeed2 = new AggregatedFeed(feeds, "eth:usd")
|
||||||
|
|
||||||
for (let pair of ["btc:usd", "eth:usd"]) {
|
for (let pair of ["btc:usd", "eth:usd"]) {
|
||||||
const aggfeed = new AggregatedFeed(feeds, pair)
|
const aggfeed = new AggregatedFeed(feeds, [], 2, pair)
|
||||||
|
|
||||||
setImmediate(async () => {
|
setImmediate(async () => {
|
||||||
for await (let _ of aggfeed.updates()) {
|
for await (let _ of aggfeed.updates()) {
|
||||||
|
|
|
@ -16,22 +16,44 @@ import { Submitter, SubmitterConfig } from "./Submitter"
|
||||||
import { log } from "./log"
|
import { log } from "./log"
|
||||||
import { conn } from "./context"
|
import { conn } from "./context"
|
||||||
|
|
||||||
|
// 0 => Coinbase, BTC-USD
|
||||||
|
// 1 => BitStamp, live_trades_btcusd
|
||||||
|
// 2 => FTX, BTC/USD
|
||||||
|
// 3 => Binance, BTCBUSD
|
||||||
|
// 4 => OKEx, BTC-USDC
|
||||||
|
|
||||||
const priceFeedMapping = {
|
const priceFeedMapping = {
|
||||||
|
'btc:usdt': {
|
||||||
|
minValueChangeForNewRound: 5000,
|
||||||
|
useFeeds: [0,2,3,4],
|
||||||
|
pairNames: ['BTC-USDT', 'BTC/USDT', 'BTCUSDT', 'BTC-USDT']
|
||||||
|
},
|
||||||
'btc:usd': {
|
'btc:usd': {
|
||||||
minValueChangeForNewRound: 5000,
|
minValueChangeForNewRound: 5000,
|
||||||
useFeeds: [0,1,2,3]
|
useFeeds: [0,1,2,3,4],
|
||||||
|
pairNames: ['BTC-USD', 'live_trades_btcusd', 'BTC/USD', 'BTCBUSD', 'BTC-USDC']
|
||||||
|
},
|
||||||
|
'eth:usdt': {
|
||||||
|
minValueChangeForNewRound: 150,
|
||||||
|
useFeeds: [0,2,3,4],
|
||||||
|
pairNames: ['ETH-USDT', 'ETH/USDT', 'ETHUSDT', 'ETH-USDT']
|
||||||
},
|
},
|
||||||
'eth:usd': {
|
'eth:usd': {
|
||||||
minValueChangeForNewRound: 150,
|
minValueChangeForNewRound: 150,
|
||||||
useFeeds: [0,1,2,3]
|
useFeeds: [0,1,2,3,4],
|
||||||
|
pairNames: ['ETH-USD', 'live_trades_ethusd', 'ETH/USD', 'ETHBUSD', 'ETH-USDC']
|
||||||
},
|
},
|
||||||
'sol:usd': {
|
'sol:usd': {
|
||||||
minValueChangeForNewRound: 4,
|
minValueChangeForNewRound: 4,
|
||||||
useFeeds: [2,3,4]
|
useFeeds: [2,3,4],
|
||||||
|
pairNames: ['SOL/USD', 'SOLBUSD', 'SOL-USDT']
|
||||||
|
// uses USDT for OKEx
|
||||||
},
|
},
|
||||||
'srm:usd': {
|
'srm:usd': {
|
||||||
minValueChangeForNewRound: 1,
|
minValueChangeForNewRound: 1,
|
||||||
useFeeds: [2,3,4]
|
useFeeds: [2,3,4],
|
||||||
|
pairNames: ['SRM/USD', 'SRMBUSD', 'SRM-USDT']
|
||||||
|
// uses USDT for OKEx
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +99,7 @@ export class PriceFeeder {
|
||||||
}
|
}
|
||||||
|
|
||||||
const useFeeds = (priceFeedMapping[name]) ? priceFeedMapping[name].useFeeds.map(x => this.feeds[x]) : this.feeds;
|
const useFeeds = (priceFeedMapping[name]) ? priceFeedMapping[name].useFeeds.map(x => this.feeds[x]) : this.feeds;
|
||||||
const feed = new AggregatedFeed(useFeeds, name)
|
const feed = new AggregatedFeed(useFeeds, priceFeedMapping[name].pairNames, aggregatorInfo.config.decimals, name)
|
||||||
const priceFeed = feed.medians()
|
const priceFeed = feed.medians()
|
||||||
|
|
||||||
const minValueChangeForNewRound = priceFeedMapping[name].minValueChangeForNewRound || 100
|
const minValueChangeForNewRound = priceFeedMapping[name].minValueChangeForNewRound || 100
|
||||||
|
|
187
src/feeds.ts
187
src/feeds.ts
|
@ -97,6 +97,58 @@ export abstract class PriceFeed {
|
||||||
abstract handleSubscribe(pair: string): Promise<void>
|
abstract handleSubscribe(pair: string): Promise<void>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class CoinBase extends PriceFeed {
|
||||||
|
protected log = log.child({ class: CoinBase.name })
|
||||||
|
protected baseurl = "wss://ws-feed.pro.coinbase.com"
|
||||||
|
|
||||||
|
parseMessage(data) {
|
||||||
|
const payload = JSON.parse(data)
|
||||||
|
|
||||||
|
// {
|
||||||
|
// "type": "ticker",
|
||||||
|
// "sequence": 22772426228,
|
||||||
|
// "product_id": "BTC-USD",
|
||||||
|
// "price": "53784.59",
|
||||||
|
// "open_24h": "58795.78",
|
||||||
|
// "volume_24h": "35749.39437842",
|
||||||
|
// "low_24h": "53221",
|
||||||
|
// "high_24h": "58799.66",
|
||||||
|
// "volume_30d": "733685.27275521",
|
||||||
|
// "best_bid": "53784.58",
|
||||||
|
// "best_ask": "53784.59",
|
||||||
|
// "side": "buy",
|
||||||
|
// "time": "2021-03-16T06:26:06.791440Z",
|
||||||
|
// "trade_id": 145698988,
|
||||||
|
// "last_size": "0.00474597"
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (payload.type != "ticker") {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const pair = payload.product_id as string
|
||||||
|
|
||||||
|
const price: IPrice = {
|
||||||
|
source: CoinBase.name,
|
||||||
|
pair,
|
||||||
|
decimals: 2,
|
||||||
|
value: Math.floor(payload.price * 100),
|
||||||
|
}
|
||||||
|
|
||||||
|
return price
|
||||||
|
}
|
||||||
|
|
||||||
|
async handleSubscribe(pair: string) {
|
||||||
|
this.conn.send(
|
||||||
|
JSON.stringify({
|
||||||
|
type: "subscribe",
|
||||||
|
product_ids: [pair],
|
||||||
|
channels: ["ticker"],
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class BitStamp extends PriceFeed {
|
export class BitStamp extends PriceFeed {
|
||||||
protected log = log.child({ class: BitStamp.name })
|
protected log = log.child({ class: BitStamp.name })
|
||||||
protected baseurl = "wss://ws.bitstamp.net"
|
protected baseurl = "wss://ws.bitstamp.net"
|
||||||
|
@ -125,10 +177,7 @@ export class BitStamp extends PriceFeed {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const channel = (payload.channel as string).replace("live_trades_", "")
|
const pair = payload.channel as string
|
||||||
|
|
||||||
// assume that the base symbol for the pair is 3 letters
|
|
||||||
const pair = channel.slice(0, 3) + ":" + channel.slice(3)
|
|
||||||
|
|
||||||
const price: IPrice = {
|
const price: IPrice = {
|
||||||
source: BitStamp.name,
|
source: BitStamp.name,
|
||||||
|
@ -141,14 +190,11 @@ export class BitStamp extends PriceFeed {
|
||||||
}
|
}
|
||||||
|
|
||||||
async handleSubscribe(pair: string) {
|
async handleSubscribe(pair: string) {
|
||||||
// "btc:usd" => "BTCUSD"
|
|
||||||
const targetPair = pair.replace(":", "").toUpperCase()
|
|
||||||
|
|
||||||
this.conn.send(
|
this.conn.send(
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
event: "bts:subscribe",
|
event: "bts:subscribe",
|
||||||
data: {
|
data: {
|
||||||
channel: `live_trades_${targetPair.replace("/", "").toLowerCase()}`,
|
channel: pair,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
@ -180,7 +226,7 @@ export class FTX extends PriceFeed {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const pair = (payload.market as string).replace("/", ":").toLowerCase()
|
const pair = payload.market as string
|
||||||
|
|
||||||
const price: IPrice = {
|
const price: IPrice = {
|
||||||
source: FTX.name,
|
source: FTX.name,
|
||||||
|
@ -193,70 +239,11 @@ export class FTX extends PriceFeed {
|
||||||
}
|
}
|
||||||
|
|
||||||
async handleSubscribe(pair: string) {
|
async handleSubscribe(pair: string) {
|
||||||
// "btc:usd" => "BTC-USD"
|
|
||||||
const targetPair = pair.replace(":", "/").toUpperCase()
|
|
||||||
|
|
||||||
this.conn.send(
|
this.conn.send(
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
op: "subscribe",
|
op: "subscribe",
|
||||||
channel: "ticker",
|
channel: "ticker",
|
||||||
market: targetPair,
|
market: pair,
|
||||||
})
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class CoinBase extends PriceFeed {
|
|
||||||
protected log = log.child({ class: CoinBase.name })
|
|
||||||
protected baseurl = "wss://ws-feed.pro.coinbase.com"
|
|
||||||
|
|
||||||
parseMessage(data) {
|
|
||||||
const payload = JSON.parse(data)
|
|
||||||
|
|
||||||
// {
|
|
||||||
// "type": "ticker",
|
|
||||||
// "sequence": 22772426228,
|
|
||||||
// "product_id": "BTC-USD",
|
|
||||||
// "price": "53784.59",
|
|
||||||
// "open_24h": "58795.78",
|
|
||||||
// "volume_24h": "35749.39437842",
|
|
||||||
// "low_24h": "53221",
|
|
||||||
// "high_24h": "58799.66",
|
|
||||||
// "volume_30d": "733685.27275521",
|
|
||||||
// "best_bid": "53784.58",
|
|
||||||
// "best_ask": "53784.59",
|
|
||||||
// "side": "buy",
|
|
||||||
// "time": "2021-03-16T06:26:06.791440Z",
|
|
||||||
// "trade_id": 145698988,
|
|
||||||
// "last_size": "0.00474597"
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (payload.type != "ticker") {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// "BTC-USD" => "btc:usd"
|
|
||||||
const pair = (payload.product_id as string).replace("-", ":").toLowerCase()
|
|
||||||
|
|
||||||
const price: IPrice = {
|
|
||||||
source: CoinBase.name,
|
|
||||||
pair,
|
|
||||||
decimals: 2,
|
|
||||||
value: Math.floor(payload.price * 100),
|
|
||||||
}
|
|
||||||
|
|
||||||
return price
|
|
||||||
}
|
|
||||||
|
|
||||||
async handleSubscribe(pair: string) {
|
|
||||||
// "btc:usd" => "BTC-USD"
|
|
||||||
const targetPair = pair.replace(":", "-").toUpperCase()
|
|
||||||
|
|
||||||
this.conn.send(
|
|
||||||
JSON.stringify({
|
|
||||||
type: "subscribe",
|
|
||||||
product_ids: [targetPair],
|
|
||||||
channels: ["ticker"],
|
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -286,11 +273,8 @@ export class Binance extends PriceFeed {
|
||||||
if (payload.e != "trade") {
|
if (payload.e != "trade") {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// "btcbusd" => "btc:usd"
|
|
||||||
// assume that the base symbol for the pair is 3 letters
|
const pair = payload.s;
|
||||||
const baseCurrency = payload.s.slice(0, 3).toLowerCase();
|
|
||||||
const quoteCurrency = payload.s.slice(3).toLowerCase();
|
|
||||||
const pair = `${baseCurrency}:${quoteCurrency == 'busd' ? 'usd' : quoteCurrency}`;
|
|
||||||
|
|
||||||
|
|
||||||
const price: IPrice = {
|
const price: IPrice = {
|
||||||
|
@ -304,9 +288,7 @@ export class Binance extends PriceFeed {
|
||||||
}
|
}
|
||||||
|
|
||||||
async handleSubscribe(pair: string) {
|
async handleSubscribe(pair: string) {
|
||||||
// "btc:usd" => "btcbusd"
|
const targetPair = `${pair}@trade`.toLowerCase()
|
||||||
const [baseCurrency, quoteCurrency] = pair.split(':')
|
|
||||||
const targetPair = `${baseCurrency}${(quoteCurrency.toLowerCase() === 'usd' ? 'busd' : quoteCurrency)}@trade`.toLowerCase()
|
|
||||||
this.conn.send(
|
this.conn.send(
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
method: "SUBSCRIBE",
|
method: "SUBSCRIBE",
|
||||||
|
@ -354,10 +336,8 @@ export class OKEx extends PriceFeed {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// "BTC-USDT" => "btc:usd"
|
const pair = payload.data[0].instrument_id as string;
|
||||||
const [baseCurrency, quoteCurrency] = (payload.data[0].instrument_id as string).toLowerCase().split('-');
|
|
||||||
// assume that quote is always any form of usd/usdt/usdc so map to usd
|
|
||||||
const pair = `${baseCurrency}:${quoteCurrency.slice(0, 3)}`;
|
|
||||||
const price: IPrice = {
|
const price: IPrice = {
|
||||||
source: OKEx.name,
|
source: OKEx.name,
|
||||||
pair,
|
pair,
|
||||||
|
@ -369,9 +349,7 @@ export class OKEx extends PriceFeed {
|
||||||
}
|
}
|
||||||
|
|
||||||
async handleSubscribe(pair: string) {
|
async handleSubscribe(pair: string) {
|
||||||
// "btc:usd" => "BTC-USDT"
|
const targetPair = `spot/ticker:${pair}`
|
||||||
const [baseCurrency, quoteCurrency] = pair.split(':')
|
|
||||||
const targetPair = `spot/ticker:${baseCurrency.toUpperCase()}-${(quoteCurrency.toLowerCase() === 'usd' ? 'USDT' : quoteCurrency)}`
|
|
||||||
this.conn.send(
|
this.conn.send(
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
"op": "subscribe",
|
"op": "subscribe",
|
||||||
|
@ -388,31 +366,32 @@ export class AggregatedFeed {
|
||||||
public prices: IPrice[] = []
|
public prices: IPrice[] = []
|
||||||
|
|
||||||
// assume that the feeds are already connected
|
// assume that the feeds are already connected
|
||||||
constructor(public feeds: PriceFeed[], public pair: string) {
|
constructor(public feeds: PriceFeed[], public pairMappings: string[], public decimals: number, public pair: string) {
|
||||||
this.subscribe()
|
this.subscribe()
|
||||||
}
|
}
|
||||||
|
|
||||||
private subscribe() {
|
private subscribe() {
|
||||||
const pair = this.pair
|
const pair = this.pair
|
||||||
|
const pairMappings = this.pairMappings;
|
||||||
|
const decimals = this.decimals;
|
||||||
|
|
||||||
let i = 0
|
let j = 0
|
||||||
for (let feed of this.feeds) {
|
|
||||||
feed.subscribe(pair)
|
|
||||||
|
|
||||||
const index = i
|
for (let i = 0; i < this.feeds.length; i++) {
|
||||||
i++
|
const feed = this.feeds[i];
|
||||||
|
feed.subscribe(pairMappings[i]);
|
||||||
// store the price updates in the ith position of `this.prices`
|
const index = j;
|
||||||
feed.emitter.on(UPDATE, (price: IPrice) => {
|
j++;
|
||||||
if (price.pair != pair) {
|
// store the price updates in the ith position of `this.prices`
|
||||||
return
|
feed.emitter.on(UPDATE, (price: IPrice) => {
|
||||||
}
|
if (price.pair != pairMappings[i]) {
|
||||||
|
return
|
||||||
price.timestamp = Date.now()
|
}
|
||||||
this.prices[index] = price
|
price.timestamp = Date.now()
|
||||||
|
price.decimals = decimals;
|
||||||
this.onPriceUpdate(price)
|
this.prices[index] = price
|
||||||
})
|
this.onPriceUpdate(price)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -515,7 +494,7 @@ export function coinbase(pair: string): IPriceFeed {
|
||||||
|
|
||||||
export function file(pair: string, filepath: string): IPriceFeed {
|
export function file(pair: string, filepath: string): IPriceFeed {
|
||||||
const emitter = new EventEmitter()
|
const emitter = new EventEmitter()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
fs.accessSync(filepath);
|
fs.accessSync(filepath);
|
||||||
} catch {
|
} catch {
|
||||||
|
@ -540,4 +519,4 @@ export function file(pair: string, filepath: string): IPriceFeed {
|
||||||
});
|
});
|
||||||
|
|
||||||
return eventsIter(emitter, UPDATE)
|
return eventsIter(emitter, UPDATE)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue