feed polling and oracle removal
This commit is contained in:
parent
26f529d304
commit
3e097081c4
2
.env
2
.env
|
@ -1,4 +1,4 @@
|
||||||
NETWORK=dev
|
NETWORK=dev
|
||||||
DEPLOY_FILE=deploy.json
|
DEPLOY_FILE=deploy.json
|
||||||
ADMIN_MNEMONIC="summer fuel twin history item learn flip marble ginger knee mix ten"
|
ADMIN_MNEMONIC="summer fuel twin history item learn flip marble ginger knee mix ten"
|
||||||
ORACLE_MNEMONIC="pet retreat peasant wing search rug dwarf high city pill giggle dinner"
|
ORACLE_MNEMONIC="amount smoke bar coil current trial toward minimum model pass moral liberty"
|
|
@ -1,4 +1,7 @@
|
||||||
/node_modules
|
node_modules
|
||||||
/program/target
|
target
|
||||||
/integration-example/target
|
target
|
||||||
yarn.lock
|
yarn.lock
|
||||||
|
build
|
||||||
|
.yarn
|
||||||
|
dist
|
31
README.md
31
README.md
|
@ -42,7 +42,7 @@ yarn build:program
|
||||||
```
|
```
|
||||||
yarn solink deploy-program
|
yarn solink deploy-program
|
||||||
|
|
||||||
deployed aggregator program. program id: 9KXbVqUrMgtti7Jx4rrV1NqXjQNxWaKgtYCEwJ8AESS5
|
deployed aggregator program. program id: HFHbe2uckzz9Xh633mbJPYcukzpyJRVcwL87fUrVddiq
|
||||||
```
|
```
|
||||||
|
|
||||||
Create the `btc:usd` feed (that accepts max and min u64 as valid submission values):
|
Create the `btc:usd` feed (that accepts max and min u64 as valid submission values):
|
||||||
|
@ -54,7 +54,7 @@ yarn solink add-aggregator \
|
||||||
--minSubmissionValue 0 \
|
--minSubmissionValue 0 \
|
||||||
--maxSubmissionValue 18446744073709551615
|
--maxSubmissionValue 18446744073709551615
|
||||||
|
|
||||||
feed initialized, pubkey: AUK9X6QLgauAUvEA3Ajc91fZytb9ccA7qVR72ErDFNg2
|
feed initialized, pubkey: 2jReuMRoYi3pKTF8YLnZEvT2bXcw56SdBxvssrVzu41v
|
||||||
```
|
```
|
||||||
|
|
||||||
## Adding an oracle
|
## Adding an oracle
|
||||||
|
@ -83,17 +83,36 @@ Next we create a new oracle to the feed we've created previously, and set its ow
|
||||||
```
|
```
|
||||||
yarn solink add-oracle \
|
yarn solink add-oracle \
|
||||||
--index 0 \
|
--index 0 \
|
||||||
--feedAddress AUK9X6QLgauAUvEA3Ajc91fZytb9ccA7qVR72ErDFNg2 \
|
--feedAddress 2jReuMRoYi3pKTF8YLnZEvT2bXcw56SdBxvssrVzu41v \
|
||||||
--oracleName solink-test \
|
--oracleName solink-test \
|
||||||
--oracleOwner FosLwbttPgkEDv36VJLU3wwXcBSSoUGkh7dyZPsXNtT4
|
--oracleOwner FosLwbttPgkEDv36VJLU3wwXcBSSoUGkh7dyZPsXNtT4
|
||||||
|
|
||||||
added oracle. pubkey: 4vH5L2jSNXGfcCx42N4sqPiMzEbp1PaQjQ6XngDBu8zR
|
added oracle. pubkey: 4jWLbd2Vm98RrqunVvaSXZuP1AFbgQSM2hAHMvZSdNCu
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Start submitting data from a price feed (e.g. coinbase BTC-USDT):
|
||||||
|
|
||||||
```
|
```
|
||||||
yarn solink feed \
|
yarn solink feed \
|
||||||
--feedAddress AUK9X6QLgauAUvEA3Ajc91fZytb9ccA7qVR72ErDFNg2 \
|
--feedAddress 2jReuMRoYi3pKTF8YLnZEvT2bXcw56SdBxvssrVzu41v \
|
||||||
--oracleAddress 4vH5L2jSNXGfcCx42N4sqPiMzEbp1PaQjQ6XngDBu8zR
|
--oracleAddress 4jWLbd2Vm98RrqunVvaSXZuP1AFbgQSM2hAHMvZSdNCu
|
||||||
|
```
|
||||||
|
|
||||||
|
## Read price
|
||||||
|
|
||||||
|
Poll the latest aggregated (median) value from a feed:
|
||||||
|
|
||||||
|
```
|
||||||
|
yarn solink feed-poll \
|
||||||
|
--feedAddress 2jReuMRoYi3pKTF8YLnZEvT2bXcw56SdBxvssrVzu41v
|
||||||
|
```
|
||||||
|
|
||||||
|
## Remove oracle
|
||||||
|
|
||||||
|
```
|
||||||
|
yarn solink remove-oracle \
|
||||||
|
--index 0 \
|
||||||
|
--feedAddress 2jReuMRoYi3pKTF8YLnZEvT2bXcw56SdBxvssrVzu41v
|
||||||
```
|
```
|
||||||
|
|
||||||
## Test Token
|
## Test Token
|
||||||
|
|
Binary file not shown.
|
@ -14,5 +14,9 @@
|
||||||
"tokenAccount": {
|
"tokenAccount": {
|
||||||
"pubkey": "A4xJLiJrtVigYjJ2NRUrcFza7eB7Y8XeGZh5KmkoxDs1",
|
"pubkey": "A4xJLiJrtVigYjJ2NRUrcFza7eB7Y8XeGZh5KmkoxDs1",
|
||||||
"secret": "19c19ac59d379f3d669b6b5957bbf99060b2b15dd4d266b3f76e164f665c512986bc739598f0e5f0252b3e2fbd0c54a9a08b295a4c5c2901b91c6e3d1e8ace5c"
|
"secret": "19c19ac59d379f3d669b6b5957bbf99060b2b15dd4d266b3f76e164f665c512986bc739598f0e5f0252b3e2fbd0c54a9a08b295a4c5c2901b91c6e3d1e8ace5c"
|
||||||
|
},
|
||||||
|
"oracle[0]": {
|
||||||
|
"pubkey": "4jWLbd2Vm98RrqunVvaSXZuP1AFbgQSM2hAHMvZSdNCu",
|
||||||
|
"secret": "83369edeffc2f5b870da6595cd7a916723566a1307e722f29e7db6bc8fd01b643776a09078c98230dd23a3aeab3e870e7fb6651ddae3cbf772afa4eba4735e16"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -16,11 +16,12 @@
|
||||||
"buffer-layout": "^1.2.0",
|
"buffer-layout": "^1.2.0",
|
||||||
"commander": "^6.2.0",
|
"commander": "^6.2.0",
|
||||||
"dotenv": "^8.2.0",
|
"dotenv": "^8.2.0",
|
||||||
"solray": "git+https://github.com/defactojob/solray.git"
|
"solray": "git+https://github.com/defactojob/solray.git",
|
||||||
|
"ws": "^7.4.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tsconfig/recommended": "^1.0.1",
|
"@tsconfig/recommended": "^1.0.1",
|
||||||
"@types/node": "^14.14.10",
|
"@types/node": "^14.14.12",
|
||||||
"ts-node": "^9.1.1",
|
"ts-node": "^9.1.1",
|
||||||
"typescript": "^4.1.2"
|
"typescript": "^4.1.2"
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,10 +73,8 @@ interface RemoveOracleParams {
|
||||||
// oracle index
|
// oracle index
|
||||||
index: number;
|
index: number;
|
||||||
aggregator: PublicKey;
|
aggregator: PublicKey;
|
||||||
// The oracle key
|
|
||||||
oracle: PublicKey;
|
|
||||||
// To prove you are the aggregator owner
|
// To prove you are the aggregator owner
|
||||||
authority: Account;
|
authority?: Account;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface RemoveOracleInstructionParams extends RemoveOracleParams {
|
interface RemoveOracleInstructionParams extends RemoveOracleParams {
|
||||||
|
@ -172,7 +170,7 @@ export default class FluxAggregator extends BaseProgram {
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async addOracle(params: AddOracleParams): Promise<PublicKey> {
|
public async addOracle(params: AddOracleParams): Promise<Account> {
|
||||||
const account = new Account();
|
const account = new Account();
|
||||||
|
|
||||||
await this.sendTx([
|
await this.sendTx([
|
||||||
|
@ -187,7 +185,7 @@ export default class FluxAggregator extends BaseProgram {
|
||||||
})
|
})
|
||||||
], [this.account, account, params.aggregatorOwner]);
|
], [this.account, account, params.aggregatorOwner]);
|
||||||
|
|
||||||
return account.publicKey;
|
return account;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async oracleInfo(pubkey: PublicKey) {
|
public async oracleInfo(pubkey: PublicKey) {
|
||||||
|
@ -227,14 +225,14 @@ export default class FluxAggregator extends BaseProgram {
|
||||||
public async removeOracle(params: RemoveOracleParams): Promise<void> {
|
public async removeOracle(params: RemoveOracleParams): Promise<void> {
|
||||||
await this.sendTx([
|
await this.sendTx([
|
||||||
this.removeOracleInstruction(params)
|
this.removeOracleInstruction(params)
|
||||||
], [this.account, params.authority]);
|
], [this.account, params.authority || this.wallet.account]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private removeOracleInstruction(params: RemoveOracleInstructionParams): TransactionInstruction {
|
private removeOracleInstruction(params: RemoveOracleInstructionParams): TransactionInstruction {
|
||||||
const {
|
const {
|
||||||
index,
|
index,
|
||||||
authority,
|
authority,
|
||||||
|
aggregator,
|
||||||
} = params;
|
} = params;
|
||||||
|
|
||||||
const layout = BufferLayout.struct([
|
const layout = BufferLayout.struct([
|
||||||
|
@ -246,7 +244,9 @@ export default class FluxAggregator extends BaseProgram {
|
||||||
instruction: 2, // remove oracle instruction
|
instruction: 2, // remove oracle instruction
|
||||||
index,
|
index,
|
||||||
}, [
|
}, [
|
||||||
{ write: authority },
|
//
|
||||||
|
{ write: aggregator },
|
||||||
|
authority || this.wallet.account,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
96
src/cli.ts
96
src/cli.ts
|
@ -16,6 +16,7 @@ import {
|
||||||
decodeAggregatorInfo,
|
decodeAggregatorInfo,
|
||||||
walletFromEnv,
|
walletFromEnv,
|
||||||
openDeployer,
|
openDeployer,
|
||||||
|
sleep,
|
||||||
} from "./utils"
|
} from "./utils"
|
||||||
|
|
||||||
import * as feed from "./feed"
|
import * as feed from "./feed"
|
||||||
|
@ -48,7 +49,15 @@ class AppContext {
|
||||||
|
|
||||||
constructor(public deployer: Deployer, public wallet: Wallet) { }
|
constructor(public deployer: Deployer, public wallet: Wallet) { }
|
||||||
|
|
||||||
get aggregatorProgram() {
|
get aggregatorProgramID() {
|
||||||
|
return this.aggregatorProgramAccount.publicKey
|
||||||
|
}
|
||||||
|
|
||||||
|
get aggregator() {
|
||||||
|
return new FluxAggregator(this.wallet, this.aggregatorProgramID)
|
||||||
|
}
|
||||||
|
|
||||||
|
get aggregatorProgramAccount() {
|
||||||
const program = this.deployer.account(AppContext.AGGREGATOR_PROGRAM)
|
const program = this.deployer.account(AppContext.AGGREGATOR_PROGRAM)
|
||||||
|
|
||||||
if (program == null) {
|
if (program == null) {
|
||||||
|
@ -129,7 +138,7 @@ cli
|
||||||
.option("--minSubmissionValue <number>", "minSubmissionValue", "0")
|
.option("--minSubmissionValue <number>", "minSubmissionValue", "0")
|
||||||
.option("--maxSubmissionValue <number>", "maxSubmissionValue", "18446744073709551615")
|
.option("--maxSubmissionValue <number>", "maxSubmissionValue", "18446744073709551615")
|
||||||
.action(async (opts) => {
|
.action(async (opts) => {
|
||||||
const { deployer, wallet, aggregatorProgram } = await AppContext.forAdmin()
|
const { deployer, wallet, aggregatorProgramAccount: aggregatorProgram } = await AppContext.forAdmin()
|
||||||
|
|
||||||
const { feedName, submitInterval, minSubmissionValue, maxSubmissionValue } = opts
|
const { feedName, submitInterval, minSubmissionValue, maxSubmissionValue } = opts
|
||||||
|
|
||||||
|
@ -180,25 +189,41 @@ cli
|
||||||
.option("--oracleName <string>", "oracle name")
|
.option("--oracleName <string>", "oracle name")
|
||||||
.option("--oracleOwner <string>", "oracle owner address")
|
.option("--oracleOwner <string>", "oracle owner address")
|
||||||
.action(async (opts) => {
|
.action(async (opts) => {
|
||||||
const { wallet, aggregatorProgram } = await AppContext.forAdmin()
|
const { wallet, aggregator, deployer } = await AppContext.forAdmin()
|
||||||
|
|
||||||
const { index, oracleName, oracleOwner, feedAddress } = opts
|
const { index, oracleName, oracleOwner, feedAddress } = opts
|
||||||
|
|
||||||
if (!index || index < 0 || index > 21) {
|
if (!index || index < 0 || index > 21) {
|
||||||
error("invalid index (0-20)")
|
error("invalid index. requires (0-20)")
|
||||||
}
|
}
|
||||||
const program = new FluxAggregator(wallet, aggregatorProgram.publicKey)
|
|
||||||
|
|
||||||
log("add oracle...")
|
log("add oracle...")
|
||||||
const oracle = await program.addOracle({
|
const oracle = await deployer.ensure(`oracle[${index}]`, async () => {
|
||||||
|
return aggregator.addOracle({
|
||||||
index,
|
index,
|
||||||
owner: new PublicKey(oracleOwner),
|
owner: new PublicKey(oracleOwner),
|
||||||
description: oracleName.substr(0, 32).padEnd(32),
|
description: oracleName.substr(0, 32).padEnd(32),
|
||||||
aggregator: new PublicKey(feedAddress),
|
aggregator: new PublicKey(feedAddress),
|
||||||
aggregatorOwner: wallet.account,
|
aggregatorOwner: wallet.account,
|
||||||
})
|
})
|
||||||
|
})
|
||||||
|
|
||||||
log(`added oracle. pubkey: ${color(oracle.toBase58(), "blue")}`)
|
log(`added oracle. pubkey: ${color(oracle.publicKey.toBase58(), "blue")}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
cli
|
||||||
|
.command("remove-oracle")
|
||||||
|
.option("--index <number>", "remove oracle from index (0-20)")
|
||||||
|
.option("--feedAddress <string>", "feed to remove oracle from")
|
||||||
|
.action(async (opts) => {
|
||||||
|
const { index, feedAddress } = opts
|
||||||
|
|
||||||
|
const { aggregator } = await AppContext.forAdmin()
|
||||||
|
|
||||||
|
await aggregator.removeOracle({
|
||||||
|
aggregator: new PublicKey(feedAddress),
|
||||||
|
index,
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
// cli
|
// cli
|
||||||
|
@ -225,43 +250,20 @@ cli
|
||||||
// log(deployed.oracles)
|
// log(deployed.oracles)
|
||||||
// })
|
// })
|
||||||
|
|
||||||
// cli
|
cli
|
||||||
// .command("aggregatorInfo")
|
.command("feed-poll")
|
||||||
// .description("show aggregatorInfo")
|
.description("poll current feed value")
|
||||||
// .action(async () => {
|
.option("--feedAddress <string>", "feed address to submit values to")
|
||||||
// // show current network
|
.action(async (opts) => {
|
||||||
// showNetwork()
|
const { feedAddress } = opts
|
||||||
|
|
||||||
// if (!fs.existsSync(deployedPath)) {
|
while (true) {
|
||||||
// error("program haven't deployed yet")
|
const feedInfo = await conn.getAccountInfo(new PublicKey(feedAddress))
|
||||||
// }
|
log(decodeAggregatorInfo(feedInfo))
|
||||||
|
|
||||||
// const deployed = JSON.parse(fs.readFileSync(deployedPath).toString())
|
await sleep(1000)
|
||||||
|
}
|
||||||
// if (deployed.network != network) {
|
})
|
||||||
// error("deployed network not match, please try `npm run clean:deployed`, and deploy again")
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (!deployed.programId) {
|
|
||||||
// error("program haven't deployed yet")
|
|
||||||
// }
|
|
||||||
|
|
||||||
// const inputs = await inquirer
|
|
||||||
// .prompt([
|
|
||||||
// {
|
|
||||||
// message: "Choose an aggregator", type: "list", name: "aggregator", choices: () => {
|
|
||||||
// return deployed.pairs.map(p => ({ name: p.pairName.trim() + ` [${p.aggregator}]`, value: p.aggregator }))
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// ])
|
|
||||||
|
|
||||||
// const { aggregator } = inputs
|
|
||||||
// const conn = await connectTo(network)
|
|
||||||
|
|
||||||
// const accountInfo = await conn.getAccountInfo(new PublicKey(aggregator))
|
|
||||||
|
|
||||||
// log(decodeAggregatorInfo(accountInfo))
|
|
||||||
// })
|
|
||||||
|
|
||||||
cli
|
cli
|
||||||
.command("feed")
|
.command("feed")
|
||||||
|
@ -270,7 +272,7 @@ cli
|
||||||
.option("--oracleAddress <string>", "feed address to submit values to")
|
.option("--oracleAddress <string>", "feed address to submit values to")
|
||||||
.action(async (opts) => {
|
.action(async (opts) => {
|
||||||
|
|
||||||
const { wallet, aggregatorProgram } = await AppContext.forOracle()
|
const { wallet, aggregatorProgramAccount: aggregatorProgram } = await AppContext.forOracle()
|
||||||
|
|
||||||
const { feedAddress, oracleAddress } = opts
|
const { feedAddress, oracleAddress } = opts
|
||||||
|
|
||||||
|
@ -289,7 +291,7 @@ cli
|
||||||
.description("create test token")
|
.description("create test token")
|
||||||
.option("--amount <number>", "amount of the test token")
|
.option("--amount <number>", "amount of the test token")
|
||||||
.action(async (opts) => {
|
.action(async (opts) => {
|
||||||
const { admin, aggregatorProgram, deployer } = await AdminContext.load()
|
const { wallet, aggregatorProgramAccount: aggregatorProgram, deployer } = await AppContext.forAdmin()
|
||||||
|
|
||||||
const { amount } = opts
|
const { amount } = opts
|
||||||
|
|
||||||
|
@ -297,12 +299,12 @@ cli
|
||||||
error("invalid amount")
|
error("invalid amount")
|
||||||
}
|
}
|
||||||
|
|
||||||
const spltoken = new SPLToken(admin)
|
const spltoken = new SPLToken(wallet)
|
||||||
|
|
||||||
log(`create test token...`)
|
log(`create test token...`)
|
||||||
// 1. create token
|
// 1. create token
|
||||||
const token = await spltoken.initializeMint({
|
const token = await spltoken.initializeMint({
|
||||||
mintAuthority: admin.account.publicKey,
|
mintAuthority: wallet.account.publicKey,
|
||||||
decimals: 8,
|
decimals: 8,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -325,7 +327,7 @@ cli
|
||||||
token: token.publicKey,
|
token: token.publicKey,
|
||||||
to: tokenAccount.publicKey,
|
to: tokenAccount.publicKey,
|
||||||
amount: BigInt(amount),
|
amount: BigInt(amount),
|
||||||
authority: admin.account,
|
authority: wallet.account,
|
||||||
})
|
})
|
||||||
|
|
||||||
log({
|
log({
|
||||||
|
|
34
src/utils.ts
34
src/utils.ts
|
@ -4,7 +4,7 @@ import { AggregatorLayout, SubmissionLayout, OracleLayout } from "./FluxAggregat
|
||||||
|
|
||||||
import { solana, Wallet, NetworkName, Deployer } from "solray"
|
import { solana, Wallet, NetworkName, Deployer } from "solray"
|
||||||
|
|
||||||
export function getSubmissionValue(submissions: []): number {
|
export function getMedian(submissions: number[]): number {
|
||||||
const values = submissions
|
const values = submissions
|
||||||
.filter((s: any) => s.value != 0)
|
.filter((s: any) => s.value != 0)
|
||||||
.map((s: any) => s.value)
|
.map((s: any) => s.value)
|
||||||
|
@ -31,47 +31,45 @@ export function sleep(ms: number): Promise<void> {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function decodeAggregatorInfo(accountInfo) {
|
export function decodeAggregatorInfo(accountInfo) {
|
||||||
|
|
||||||
const data = Buffer.from(accountInfo.data)
|
const data = Buffer.from(accountInfo.data)
|
||||||
const aggregator = AggregatorLayout.decode(data)
|
const aggregator = AggregatorLayout.decode(data)
|
||||||
|
|
||||||
const minSubmissionValue = aggregator.minSubmissionValue.readBigUInt64LE().toString()
|
const minSubmissionValue = aggregator.minSubmissionValue.readBigUInt64LE()
|
||||||
const maxSubmissionValue = aggregator.maxSubmissionValue.readBigUInt64LE().toString()
|
const maxSubmissionValue = aggregator.maxSubmissionValue.readBigUInt64LE()
|
||||||
const submitInterval = aggregator.submitInterval.readInt32LE()
|
const submitInterval = aggregator.submitInterval.readInt32LE()
|
||||||
const description = aggregator.description.toString()
|
const description = (aggregator.description.toString() as String).trim()
|
||||||
|
|
||||||
// decode oracles
|
// decode oracles
|
||||||
let submissions: [] = []
|
let submissions: any[] = []
|
||||||
let oracles: [] = []
|
|
||||||
let submissionSpace = SubmissionLayout.span
|
let submissionSpace = SubmissionLayout.span
|
||||||
let updateTime = '0'
|
let latestUpdateTime = BigInt(0)
|
||||||
|
|
||||||
for (let i = 0; i < aggregator.submissions.length / submissionSpace; i++) {
|
for (let i = 0; i < aggregator.submissions.length / submissionSpace; i++) {
|
||||||
let submission = SubmissionLayout.decode(
|
let submission = SubmissionLayout.decode(
|
||||||
aggregator.submissions.slice(i*submissionSpace, (i+1)*submissionSpace)
|
aggregator.submissions.slice(i*submissionSpace, (i+1)*submissionSpace)
|
||||||
)
|
)
|
||||||
|
|
||||||
submission.oracle = new PublicKey(submission.oracle)
|
submission.oracle = new PublicKey(submission.oracle)
|
||||||
|
submission.time = submission.time.readBigInt64LE()
|
||||||
|
submission.value = submission.value.readBigInt64LE()
|
||||||
|
|
||||||
submission.time = submission.time.readBigInt64LE().toString()
|
|
||||||
submission.value = submission.value.readBigInt64LE().toString()*1
|
|
||||||
if (!submission.oracle.equals(new PublicKey(0))) {
|
if (!submission.oracle.equals(new PublicKey(0))) {
|
||||||
submissions.push(submission as never)
|
submissions.push(submission)
|
||||||
oracles.push(submission.oracle.toBase58() as never)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
if (submission.time > updateTime) {
|
|
||||||
updateTime = submission.time
|
if (submission.time > latestUpdateTime) {
|
||||||
|
latestUpdateTime = submission.time
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
minSubmissionValue: minSubmissionValue,
|
minSubmissionValue: minSubmissionValue,
|
||||||
maxSubmissionValue: maxSubmissionValue,
|
maxSubmissionValue: maxSubmissionValue,
|
||||||
submissionValue: getSubmissionValue(submissions),
|
submissionValue: getMedian(submissions),
|
||||||
submitInterval,
|
submitInterval,
|
||||||
description,
|
description,
|
||||||
oracles,
|
oracles: submissions.map(s => s.oracle.toString()),
|
||||||
updateTime,
|
latestUpdateTime: new Date(Number(latestUpdateTime)*1000),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
/* Visit https://aka.ms/tsconfig.json to read more about this file */
|
/* Visit https://aka.ms/tsconfig.json to read more about this file */
|
||||||
|
|
||||||
/* Basic Options */
|
/* Basic Options */
|
||||||
// "incremental": true, /* Enable incremental compilation */
|
"incremental": true, /* Enable incremental compilation */
|
||||||
"target": "ES2019", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
|
"target": "ES2019", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
|
||||||
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
|
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
|
||||||
// "lib": [], /* Specify library files to be included in the compilation. */
|
// "lib": [], /* Specify library files to be included in the compilation. */
|
||||||
|
@ -67,8 +67,5 @@
|
||||||
/* Advanced Options */
|
/* Advanced Options */
|
||||||
"skipLibCheck": true, /* Skip type checking of declaration files. */
|
"skipLibCheck": true, /* Skip type checking of declaration files. */
|
||||||
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
|
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
|
||||||
},
|
}
|
||||||
"include": [
|
|
||||||
"./src/**/*"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue