From ad563b1bca287d6bdd09def23704ce56f40b2a1d Mon Sep 17 00:00:00 2001 From: dd Date: Mon, 22 Feb 2021 17:49:18 -0500 Subject: [PATCH] removed all schema.ts --- src/client.ts | 10 +- src/index.ts | 5 - src/schema.ts | 812 +++++++++++++++++++++++++------------------------- 3 files changed, 411 insertions(+), 416 deletions(-) diff --git a/src/client.ts b/src/client.ts index 100d011..1082749 100644 --- a/src/client.ts +++ b/src/client.ts @@ -25,7 +25,7 @@ import { SRM_DECIMALS, TOKEN_PROGRAM_ID } from '@project-serum/serum/lib/token-i import { Order } from '@project-serum/serum/lib/market'; import Wallet from '@project-serum/sol-wallet-adapter'; import { makeCancelOrderInstruction, makeSettleFundsInstruction } from './instruction'; -import { Aggregator } from './schema' +// import { Aggregator } from './schema' export class MangoGroup { publicKey: PublicKey; @@ -58,11 +58,11 @@ export class MangoGroup { connection: Connection, ): Promise { - const aggs = await Promise.all(this.oracles.map((pk) => (Aggregator.loadWithConnection(pk, connection)))) - return aggs.map((agg) => (agg.answer.median.toNumber())).concat(1.0) + // const aggs = await Promise.all(this.oracles.map((pk) => (Aggregator.loadWithConnection(pk, connection)))) + // return aggs.map((agg) => (agg.answer.median.toNumber())).concat(1.0) - // const oracleAccs = await getMultipleAccounts(connection, this.oracles); - // return oracleAccs.map((oa) => decodeAggregatorInfo(oa.accountInfo).submissionValue).concat(1.0) + const oracleAccs = await getMultipleAccounts(connection, this.oracles); + return oracleAccs.map((oa) => decodeAggregatorInfo(oa.accountInfo).submissionValue).concat(1.0) } getMarketIndex(spotMarket: Market): number { diff --git a/src/index.ts b/src/index.ts index f13e765..b0c15e2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,4 @@ import { MangoClient, MangoGroup } from './client'; -import { Account, Connection, PublicKey } from '@solana/web3.js'; -import * as fs from 'fs'; -import { Market } from '@project-serum/serum'; import { NUM_TOKENS } from './layout'; export { MangoClient, MangoGroup, MarginAccount } from './client'; @@ -9,8 +6,6 @@ export { MangoIndexLayout, MarginAccountLayout, MangoGroupLayout } from './layou export { NUM_TOKENS } from './layout'; import IDS from "./ids.json"; -import { Aggregator } from './schema'; -import { nativeToUi } from './utils'; export { IDS } // diff --git a/src/schema.ts b/src/schema.ts index 98a07ed..8efeb7e 100644 --- a/src/schema.ts +++ b/src/schema.ts @@ -1,407 +1,407 @@ -import { PublicKey } from "solray" -import BN from "bn.js" -import { deserialize, serialize } from "borsh" -import {Connection} from "@solana/web3.js"; - - -// const conn = new Connection("https://devnet.solana.com", 'singleGossip') - -const MAX_ORACLES = 13 - -const boolMapper = { - encode: boolToInt, - decode: intToBool, -} - -const pubkeyMapper = { - encode: (key: PublicKey) => { - // if (key.constructor == PublicKey) { - // // key. - // } else { - // key - // } - // TODO: support either account or public key - return key.toBuffer() - }, - - decode: (buf: Uint8Array) => { - return new PublicKey(buf) - }, -} - -// support strings that can be contained in at most 32 bytes -const str32Mapper = { - encode: (str: String) => { - str = str.substr(0, 32).padEnd(32) - return Buffer.from(str, "utf8").slice(0, 32) // truncate at 32 bytes - }, - - decode: (bytes: Uint8Array) => { - return Buffer.from(bytes).toString("utf8").trim() - }, -} - -const u64Date = { - encode: (date: Date) => { - return new BN(Math.floor(date.getTime() / 1000)) - }, - - decode: (unixtime: BN) => { - return new Date(unixtime.toNumber() * 1000) - }, -} - -export abstract class Serialization { - public static async loadWithConnection( - this: { new (data: any): T }, - key: PublicKey, - connection: Connection - ): Promise { - const info = await connection.getAccountInfo(key) - if (!info) { - throw new Error("account does not exist") - } - - return deserialize(schema, this, info.data) - } - // public static async load( - // this: { new (data: any): T }, - // key: PublicKey - // ): Promise { - // const info = await conn.getAccountInfo(key, "recent") - // if (!info) { - // throw new Error("account does not exist") - // } - // - // return deserialize(schema, this, info.data) - // } - - public static deserialize(this: { new (data: any): T }, data: Buffer): T { - return deserialize(schema, this, data) - } - - public static serialize( - this: { new (data: any): T }, - data: object - ): Buffer { - return new this(data).serialize() - } - - public serialize(): Buffer { - let buf = Buffer.from(serialize(schema, this)) - if (buf.length == 0) { - throw new Error("serialized buffer is 0. something wrong with schema") - } - return buf - } - - // public toJSON(pretty = true) { - // return JSON.stringify( - // this[Serialization.DATA_KEY], - // jsonReplacer, - // pretty ? 2 : 0 - // ) - // } - - // public static DATA_KEY = Symbol("DATA") - - constructor(data) { - // this[Serialization.DATA_KEY] = data - Object.assign(this, data) - } -} - -class Submission { - public updatedAt!: BN - public value!: BN - public oracle!: PublicKey - - public static schema = { - kind: "struct", - fields: [ - ["updatedAt", "u64"], - ["value", "u64"], - ["oracle", [32], pubkeyMapper], - ], - } - - constructor(data: any) { - Object.assign(this, data) - } -} - -export interface IAggregatorConfig { - decimals: number - description: string - restartDelay: number - rewardAmount: number - maxSubmissions: number - minSubmissions: number - rewardTokenAccount: PublicKey -} - -export class AggregatorConfig - extends Serialization - implements IAggregatorConfig { - public decimals!: number - public description!: string - public restartDelay!: number - public rewardAmount!: number - public maxSubmissions!: number - public minSubmissions!: number - public rewardTokenAccount!: PublicKey - - public static schema = { - kind: "struct", - fields: [ - ["description", [32], str32Mapper], - ["decimals", "u8"], - ["restartDelay", "u8"], - ["maxSubmissions", "u8"], - ["minSubmissions", "u8"], - ["rewardAmount", "u64"], - ["rewardTokenAccount", [32], pubkeyMapper], - ], - } -} - -export class Submissions extends Serialization { - public isInitialized!: boolean - public submissions!: Submission[] - - public static size = 625 - public static schema = { - kind: "struct", - fields: [ - ["isInitialized", "u8", boolMapper], - ["submissions", [Submission, MAX_ORACLES]], - ], - } - - // if not already submitted, and has empty spot - public canSubmit(pk: PublicKey, cfg: AggregatorConfig): boolean { - if (this.hadSubmitted(pk)) { - return false - } - - let emptyIndex = this.submissions.findIndex((s) => { - return s.updatedAt.isZero() - }) - - return emptyIndex > 0 && emptyIndex < cfg.maxSubmissions - } - - public hadSubmitted(pk: PublicKey): boolean { - return !!this.submissions.find((s) => { - return s.oracle.equals(pk) - }) - } -} - -export class Round extends Serialization { - public id!: BN - public createdAt!: BN - public updatedAt!: BN - - public static schema = { - kind: "struct", - fields: [ - ["id", "u64"], - ["createdAt", "u64"], - ["updatedAt", "u64"], - ], - } -} - -export class Answer extends Serialization { - public roundID!: BN - public median!: BN - public createdAt!: BN - public updatedAt!: BN - - public static schema = { - kind: "struct", - fields: [ - ["roundID", "u64"], - ["median", "u64"], - ["createdAt", "u64"], - ["updatedAt", "u64"], - ], - } -} - -export class Aggregator extends Serialization { - public static size = 229 - - public config!: AggregatorConfig - public roundSubmissions!: PublicKey - public answerSubmissions!: PublicKey - public answer!: Answer - public round!: Round - - public static schema = { - kind: "struct", - fields: [ - ["config", AggregatorConfig], - ["isInitialized", "u8", boolMapper], - ["owner", [32], pubkeyMapper], - ["round", Round], - ["roundSubmissions", [32], pubkeyMapper], - ["answer", Answer], - ["answerSubmissions", [32], pubkeyMapper], - ], - } - - -} - -abstract class InstructionSerialization extends Serialization { - public serialize(): Buffer { - return new Instruction({ [this.constructor.name]: this }).serialize() - } -} - -export class Initialize extends InstructionSerialization { - // public submitInterval!: number - // public minSubmissionValue!: number - // public maxSubmissionValue!: number - // public submissionDecimals!: number - // /// A short description of what is being reported - // public description!: string - - public static schema = { - kind: "struct", - fields: [["config", AggregatorConfig]], - } -} - -export class Configure extends InstructionSerialization { - public static schema = { - kind: "struct", - fields: [["config", AggregatorConfig]], - } -} - -export class AddOracle extends InstructionSerialization { - public static schema = { - kind: "struct", - fields: [["description", [32], str32Mapper]], - } -} - -export class RemoveOracle extends InstructionSerialization { - public static schema = { - kind: "struct", - fields: [], - } -} - -export class Withdraw extends InstructionSerialization { - public static schema = { - kind: "struct", - fields: [["faucetOwnerSeed", ["u8"]]], - } -} - -export class Submit extends InstructionSerialization { - public static schema = { - kind: "struct", - fields: [ - ["round_id", "u64"], - ["value", "u64"], - ], - } -} - -export class Instruction extends Serialization { - public enum!: string - - public static schema = { - kind: "enum", - field: "enum", - values: [ - [Initialize.name, Initialize], - [Configure.name, Configure], - [AddOracle.name, AddOracle], - [RemoveOracle.name, RemoveOracle], - [Submit.name, Submit], - ], - } - - public constructor(prop: { [key: string]: any }) { - super({}) - // deserializer calls the construction with `{ [enum]: value }`, so we need - // to figure out the enum type - // - // expect only one key-value (what a retarded interface) - for (let key of Object.keys(prop)) { - this.enum = key - this[key] = prop[key] - return - } - - throw new Error("not an expected enum object") - } - - public get value() { - return this[this.enum] - } -} - -function intToBool(i: number) { - if (i == 0) { - return false - } else { - return true - } -} - -function boolToInt(t: boolean) { - if (t) { - return 1 - } else { - return 0 - } -} - -export class Oracle extends Serialization { - public static size = 113 - public allowStartRound!: BN - public withdrawable!: BN - - public static schema = { - kind: "struct", - fields: [ - ["description", [32], str32Mapper], - ["isInitialized", "u8", boolMapper], - ["withdrawable", "u64"], - ["allowStartRound", "u64"], - ["aggregator", [32], pubkeyMapper], - ["owner", [32], pubkeyMapper], - ], - } - - public canStartNewRound(round: BN): boolean { - return this.allowStartRound.lte(round) - } -} - -// if there is optional or variable length items, what is: borsh_utils::get_packed_len::()? +// import { PublicKey } from "solray" +// import BN from "bn.js" +// import { deserialize, serialize } from "borsh" +// import {Connection} from "@solana/web3.js"; // -// would panic given variable sized types - -export const schema = new Map([ - [Aggregator, Aggregator.schema], - [Oracle, Oracle.schema], - [Round, Round.schema], - [Answer, Answer.schema], - [AggregatorConfig, AggregatorConfig.schema], - [Submissions, Submissions.schema], - [Submission, Submission.schema], - - [Instruction, Instruction.schema], - [Initialize, Initialize.schema], - [AddOracle, AddOracle.schema], - [Submit, Submit.schema], - -] as any) as any +// +// // const conn = new Connection("https://devnet.solana.com", 'singleGossip') +// +// const MAX_ORACLES = 13 +// +// const boolMapper = { +// encode: boolToInt, +// decode: intToBool, +// } +// +// const pubkeyMapper = { +// encode: (key: PublicKey) => { +// // if (key.constructor == PublicKey) { +// // // key. +// // } else { +// // key +// // } +// // TODO: support either account or public key +// return key.toBuffer() +// }, +// +// decode: (buf: Uint8Array) => { +// return new PublicKey(buf) +// }, +// } +// +// // support strings that can be contained in at most 32 bytes +// const str32Mapper = { +// encode: (str: String) => { +// str = str.substr(0, 32).padEnd(32) +// return Buffer.from(str, "utf8").slice(0, 32) // truncate at 32 bytes +// }, +// +// decode: (bytes: Uint8Array) => { +// return Buffer.from(bytes).toString("utf8").trim() +// }, +// } +// +// const u64Date = { +// encode: (date: Date) => { +// return new BN(Math.floor(date.getTime() / 1000)) +// }, +// +// decode: (unixtime: BN) => { +// return new Date(unixtime.toNumber() * 1000) +// }, +// } +// +// export abstract class Serialization { +// public static async loadWithConnection( +// this: { new (data: any): T }, +// key: PublicKey, +// connection: Connection +// ): Promise { +// const info = await connection.getAccountInfo(key) +// if (!info) { +// throw new Error("account does not exist") +// } +// +// return deserialize(schema, this, info.data) +// } +// // public static async load( +// // this: { new (data: any): T }, +// // key: PublicKey +// // ): Promise { +// // const info = await conn.getAccountInfo(key, "recent") +// // if (!info) { +// // throw new Error("account does not exist") +// // } +// // +// // return deserialize(schema, this, info.data) +// // } +// +// public static deserialize(this: { new (data: any): T }, data: Buffer): T { +// return deserialize(schema, this, data) +// } +// +// public static serialize( +// this: { new (data: any): T }, +// data: object +// ): Buffer { +// return new this(data).serialize() +// } +// +// public serialize(): Buffer { +// let buf = Buffer.from(serialize(schema, this)) +// if (buf.length == 0) { +// throw new Error("serialized buffer is 0. something wrong with schema") +// } +// return buf +// } +// +// // public toJSON(pretty = true) { +// // return JSON.stringify( +// // this[Serialization.DATA_KEY], +// // jsonReplacer, +// // pretty ? 2 : 0 +// // ) +// // } +// +// // public static DATA_KEY = Symbol("DATA") +// +// constructor(data) { +// // this[Serialization.DATA_KEY] = data +// Object.assign(this, data) +// } +// } +// +// class Submission { +// public updatedAt!: BN +// public value!: BN +// public oracle!: PublicKey +// +// public static schema = { +// kind: "struct", +// fields: [ +// ["updatedAt", "u64"], +// ["value", "u64"], +// ["oracle", [32], pubkeyMapper], +// ], +// } +// +// constructor(data: any) { +// Object.assign(this, data) +// } +// } +// +// export interface IAggregatorConfig { +// decimals: number +// description: string +// restartDelay: number +// rewardAmount: number +// maxSubmissions: number +// minSubmissions: number +// rewardTokenAccount: PublicKey +// } +// +// export class AggregatorConfig +// extends Serialization +// implements IAggregatorConfig { +// public decimals!: number +// public description!: string +// public restartDelay!: number +// public rewardAmount!: number +// public maxSubmissions!: number +// public minSubmissions!: number +// public rewardTokenAccount!: PublicKey +// +// public static schema = { +// kind: "struct", +// fields: [ +// ["description", [32], str32Mapper], +// ["decimals", "u8"], +// ["restartDelay", "u8"], +// ["maxSubmissions", "u8"], +// ["minSubmissions", "u8"], +// ["rewardAmount", "u64"], +// ["rewardTokenAccount", [32], pubkeyMapper], +// ], +// } +// } +// +// export class Submissions extends Serialization { +// public isInitialized!: boolean +// public submissions!: Submission[] +// +// public static size = 625 +// public static schema = { +// kind: "struct", +// fields: [ +// ["isInitialized", "u8", boolMapper], +// ["submissions", [Submission, MAX_ORACLES]], +// ], +// } +// +// // if not already submitted, and has empty spot +// public canSubmit(pk: PublicKey, cfg: AggregatorConfig): boolean { +// if (this.hadSubmitted(pk)) { +// return false +// } +// +// let emptyIndex = this.submissions.findIndex((s) => { +// return s.updatedAt.isZero() +// }) +// +// return emptyIndex > 0 && emptyIndex < cfg.maxSubmissions +// } +// +// public hadSubmitted(pk: PublicKey): boolean { +// return !!this.submissions.find((s) => { +// return s.oracle.equals(pk) +// }) +// } +// } +// +// export class Round extends Serialization { +// public id!: BN +// public createdAt!: BN +// public updatedAt!: BN +// +// public static schema = { +// kind: "struct", +// fields: [ +// ["id", "u64"], +// ["createdAt", "u64"], +// ["updatedAt", "u64"], +// ], +// } +// } +// +// export class Answer extends Serialization { +// public roundID!: BN +// public median!: BN +// public createdAt!: BN +// public updatedAt!: BN +// +// public static schema = { +// kind: "struct", +// fields: [ +// ["roundID", "u64"], +// ["median", "u64"], +// ["createdAt", "u64"], +// ["updatedAt", "u64"], +// ], +// } +// } +// +// export class Aggregator extends Serialization { +// public static size = 229 +// +// public config!: AggregatorConfig +// public roundSubmissions!: PublicKey +// public answerSubmissions!: PublicKey +// public answer!: Answer +// public round!: Round +// +// public static schema = { +// kind: "struct", +// fields: [ +// ["config", AggregatorConfig], +// ["isInitialized", "u8", boolMapper], +// ["owner", [32], pubkeyMapper], +// ["round", Round], +// ["roundSubmissions", [32], pubkeyMapper], +// ["answer", Answer], +// ["answerSubmissions", [32], pubkeyMapper], +// ], +// } +// +// +// } +// +// abstract class InstructionSerialization extends Serialization { +// public serialize(): Buffer { +// return new Instruction({ [this.constructor.name]: this }).serialize() +// } +// } +// +// export class Initialize extends InstructionSerialization { +// // public submitInterval!: number +// // public minSubmissionValue!: number +// // public maxSubmissionValue!: number +// // public submissionDecimals!: number +// // /// A short description of what is being reported +// // public description!: string +// +// public static schema = { +// kind: "struct", +// fields: [["config", AggregatorConfig]], +// } +// } +// +// export class Configure extends InstructionSerialization { +// public static schema = { +// kind: "struct", +// fields: [["config", AggregatorConfig]], +// } +// } +// +// export class AddOracle extends InstructionSerialization { +// public static schema = { +// kind: "struct", +// fields: [["description", [32], str32Mapper]], +// } +// } +// +// export class RemoveOracle extends InstructionSerialization { +// public static schema = { +// kind: "struct", +// fields: [], +// } +// } +// +// export class Withdraw extends InstructionSerialization { +// public static schema = { +// kind: "struct", +// fields: [["faucetOwnerSeed", ["u8"]]], +// } +// } +// +// export class Submit extends InstructionSerialization { +// public static schema = { +// kind: "struct", +// fields: [ +// ["round_id", "u64"], +// ["value", "u64"], +// ], +// } +// } +// +// export class Instruction extends Serialization { +// public enum!: string +// +// public static schema = { +// kind: "enum", +// field: "enum", +// values: [ +// [Initialize.name, Initialize], +// [Configure.name, Configure], +// [AddOracle.name, AddOracle], +// [RemoveOracle.name, RemoveOracle], +// [Submit.name, Submit], +// ], +// } +// +// public constructor(prop: { [key: string]: any }) { +// super({}) +// // deserializer calls the construction with `{ [enum]: value }`, so we need +// // to figure out the enum type +// // +// // expect only one key-value (what a retarded interface) +// for (let key of Object.keys(prop)) { +// this.enum = key +// this[key] = prop[key] +// return +// } +// +// throw new Error("not an expected enum object") +// } +// +// public get value() { +// return this[this.enum] +// } +// } +// +// function intToBool(i: number) { +// if (i == 0) { +// return false +// } else { +// return true +// } +// } +// +// function boolToInt(t: boolean) { +// if (t) { +// return 1 +// } else { +// return 0 +// } +// } +// +// export class Oracle extends Serialization { +// public static size = 113 +// public allowStartRound!: BN +// public withdrawable!: BN +// +// public static schema = { +// kind: "struct", +// fields: [ +// ["description", [32], str32Mapper], +// ["isInitialized", "u8", boolMapper], +// ["withdrawable", "u64"], +// ["allowStartRound", "u64"], +// ["aggregator", [32], pubkeyMapper], +// ["owner", [32], pubkeyMapper], +// ], +// } +// +// public canStartNewRound(round: BN): boolean { +// return this.allowStartRound.lte(round) +// } +// } +// +// // if there is optional or variable length items, what is: borsh_utils::get_packed_len::()? +// // +// // would panic given variable sized types +// +// export const schema = new Map([ +// [Aggregator, Aggregator.schema], +// [Oracle, Oracle.schema], +// [Round, Round.schema], +// [Answer, Answer.schema], +// [AggregatorConfig, AggregatorConfig.schema], +// [Submissions, Submissions.schema], +// [Submission, Submission.schema], +// +// [Instruction, Instruction.schema], +// [Initialize, Initialize.schema], +// [AddOracle, AddOracle.schema], +// [Submit, Submit.schema], +// +// ] as any) as any