remove unused code
This commit is contained in:
parent
3a6b17f03d
commit
b77e338c4b
|
@ -16,40 +16,11 @@ import {
|
||||||
SystemProgram,
|
SystemProgram,
|
||||||
} from "@solana/web3.js"
|
} from "@solana/web3.js"
|
||||||
|
|
||||||
import {
|
|
||||||
publicKey,
|
|
||||||
u64LEBuffer,
|
|
||||||
uint64,
|
|
||||||
BufferLayout,
|
|
||||||
} from "solray/lib/util/encoding"
|
|
||||||
|
|
||||||
import { decodeOracleInfo } from "./utils"
|
|
||||||
|
|
||||||
// @ts-ignore
|
|
||||||
// import BufferLayout from "buffer-layout";
|
|
||||||
|
|
||||||
import { AggregatorConfig, IAggregatorConfig, schema } from "./schema"
|
import { AggregatorConfig, IAggregatorConfig, schema } from "./schema"
|
||||||
import * as encoding from "./schema"
|
import * as encoding from "./schema"
|
||||||
import { deserialize, serialize } from "borsh"
|
import { deserialize, serialize } from "borsh"
|
||||||
import { conn } from "./context"
|
import { conn } from "./context"
|
||||||
|
|
||||||
export const AggregatorLayout = BufferLayout.struct([])
|
|
||||||
|
|
||||||
export const OracleLayout = BufferLayout.struct([
|
|
||||||
uint64("nextSubmitTime"),
|
|
||||||
BufferLayout.blob(32, "description"),
|
|
||||||
BufferLayout.u8("isInitialized"),
|
|
||||||
uint64("withdrawable"),
|
|
||||||
publicKey("aggregator"),
|
|
||||||
publicKey("owner"),
|
|
||||||
])
|
|
||||||
|
|
||||||
export const SubmissionLayout = BufferLayout.struct([
|
|
||||||
uint64("time"),
|
|
||||||
uint64("value"),
|
|
||||||
publicKey("oracle"),
|
|
||||||
])
|
|
||||||
|
|
||||||
interface InitializeParams {
|
interface InitializeParams {
|
||||||
config: IAggregatorConfig
|
config: IAggregatorConfig
|
||||||
owner: Account
|
owner: Account
|
||||||
|
|
344
src/cli.ts
344
src/cli.ts
|
@ -1,344 +0,0 @@
|
||||||
import { Command, option } from "commander"
|
|
||||||
|
|
||||||
import fs from "fs"
|
|
||||||
import path from "path"
|
|
||||||
|
|
||||||
import {
|
|
||||||
BPFLoader,
|
|
||||||
PublicKey,
|
|
||||||
Wallet,
|
|
||||||
NetworkName,
|
|
||||||
solana,
|
|
||||||
Deployer,
|
|
||||||
SPLToken,
|
|
||||||
ProgramAccount,
|
|
||||||
} from "solray"
|
|
||||||
|
|
||||||
import dotenv from "dotenv"
|
|
||||||
|
|
||||||
import FluxAggregator from "./FluxAggregator"
|
|
||||||
|
|
||||||
import { decodeAggregatorInfo, sleep } from "./utils"
|
|
||||||
|
|
||||||
import * as feed from "./feed"
|
|
||||||
import { AggregatorConfig } from "./schema"
|
|
||||||
|
|
||||||
dotenv.config()
|
|
||||||
|
|
||||||
const cli = new Command()
|
|
||||||
|
|
||||||
const FLUX_AGGREGATOR_SO = path.resolve(
|
|
||||||
__dirname,
|
|
||||||
"../build/flux_aggregator.so"
|
|
||||||
)
|
|
||||||
const network = (process.env.NETWORK || "local") as NetworkName
|
|
||||||
const conn = solana.connect(network)
|
|
||||||
|
|
||||||
import { AppContext } from "./context"
|
|
||||||
|
|
||||||
function color(s, c = "black", b = false): string {
|
|
||||||
// 30m Black, 31m Red, 32m Green, 33m Yellow, 34m Blue, 35m Magenta, 36m Cyanic, 37m White
|
|
||||||
const cArr = [
|
|
||||||
"black",
|
|
||||||
"red",
|
|
||||||
"green",
|
|
||||||
"yellow",
|
|
||||||
"blue",
|
|
||||||
"megenta",
|
|
||||||
"cyanic",
|
|
||||||
"white",
|
|
||||||
]
|
|
||||||
|
|
||||||
let cIdx = cArr.indexOf(c)
|
|
||||||
let bold = b ? "\x1b[1m" : ""
|
|
||||||
|
|
||||||
return `\x1b[${30 + (cIdx > -1 ? cIdx : 0)}m${bold}${s}\x1b[0m`
|
|
||||||
}
|
|
||||||
|
|
||||||
function error(message: string) {
|
|
||||||
console.log("\n")
|
|
||||||
console.error(color(message, "red"))
|
|
||||||
console.log("\n")
|
|
||||||
process.exit()
|
|
||||||
}
|
|
||||||
|
|
||||||
function log(message: any) {
|
|
||||||
console.log(message)
|
|
||||||
}
|
|
||||||
|
|
||||||
cli.command("generate-wallet").action(async () => {
|
|
||||||
const mnemonic = Wallet.generateMnemonic()
|
|
||||||
const wallet = await Wallet.fromMnemonic(mnemonic, conn)
|
|
||||||
|
|
||||||
log(`address: ${wallet.address}`)
|
|
||||||
log(`mnemonic: ${mnemonic}`)
|
|
||||||
})
|
|
||||||
|
|
||||||
cli
|
|
||||||
.command("airdrop <address>")
|
|
||||||
.description(`request airdrop to the address`)
|
|
||||||
.option("-m, --amount <amount>", "request amount in sol (10e9)", "10")
|
|
||||||
.action(async (address, opts) => {
|
|
||||||
const dest = new PublicKey(address)
|
|
||||||
|
|
||||||
const { amount } = opts
|
|
||||||
|
|
||||||
log(`requesting 10 sol airdrop to: ${address}`)
|
|
||||||
await conn.requestAirdrop(dest, amount * 1e9)
|
|
||||||
log("airdrop success")
|
|
||||||
})
|
|
||||||
|
|
||||||
cli
|
|
||||||
.command("deploy-program")
|
|
||||||
.description("deploy the aggregator program")
|
|
||||||
.action(async () => {
|
|
||||||
const { wallet, deployer } = await AppContext.forAdmin()
|
|
||||||
|
|
||||||
const programAccount = await deployer.ensure(
|
|
||||||
AppContext.AGGREGATOR_PROGRAM,
|
|
||||||
async () => {
|
|
||||||
const programBinary = fs.readFileSync(FLUX_AGGREGATOR_SO)
|
|
||||||
|
|
||||||
log(`deploying ${FLUX_AGGREGATOR_SO}...`)
|
|
||||||
const bpfLoader = new BPFLoader(wallet)
|
|
||||||
|
|
||||||
return bpfLoader.load(programBinary)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
log(
|
|
||||||
`deployed aggregator program. program id: ${color(
|
|
||||||
programAccount.publicKey.toBase58(),
|
|
||||||
"blue"
|
|
||||||
)}`
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
cli
|
|
||||||
.command("add-aggregator")
|
|
||||||
.description("create an aggregator")
|
|
||||||
.option("--feedName <string>", "feed pair name")
|
|
||||||
.option("--decimals <number>", "submission decimals", "2")
|
|
||||||
.option("--minSubmissions <number>", "minSubmissions", "1")
|
|
||||||
.option("--maxSubmissions <number>", "maxSubmissions", "12")
|
|
||||||
.option("--rewardAmount <number>", "rewardAmount", "1")
|
|
||||||
.option("--restartDelay <number>", "restartDelay", "1")
|
|
||||||
.action(async (opts) => {
|
|
||||||
const {
|
|
||||||
deployer,
|
|
||||||
wallet,
|
|
||||||
aggregatorProgramAccount: aggregatorProgram,
|
|
||||||
} = await AppContext.forAdmin()
|
|
||||||
|
|
||||||
const {
|
|
||||||
feedName,
|
|
||||||
restartDelay,
|
|
||||||
minSubmissions,
|
|
||||||
maxSubmissions,
|
|
||||||
decimals,
|
|
||||||
rewardAmount,
|
|
||||||
} = opts
|
|
||||||
|
|
||||||
const aggregator = new FluxAggregator(wallet, aggregatorProgram.publicKey)
|
|
||||||
|
|
||||||
const feed = await deployer.ensure(feedName, async () => {
|
|
||||||
return aggregator.initialize({
|
|
||||||
config: new AggregatorConfig({
|
|
||||||
description: feedName,
|
|
||||||
decimals,
|
|
||||||
minSubmissions,
|
|
||||||
maxSubmissions,
|
|
||||||
restartDelay,
|
|
||||||
rewardAmount: BigInt(rewardAmount),
|
|
||||||
}),
|
|
||||||
owner: wallet.account,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
log(`feed initialized, pubkey: ${color(feed.publicKey.toBase58(), "blue")}`)
|
|
||||||
})
|
|
||||||
|
|
||||||
// cli
|
|
||||||
// .command("aggregators")
|
|
||||||
// .description("show all aggregators")
|
|
||||||
// .action(() => {
|
|
||||||
// // show current network
|
|
||||||
// showNetwork()
|
|
||||||
|
|
||||||
// if (!fs.existsSync(deployedPath)) {
|
|
||||||
// error("program haven't deployed yet")
|
|
||||||
// }
|
|
||||||
|
|
||||||
// const deployed = JSON.parse(fs.readFileSync(deployedPath).toString())
|
|
||||||
|
|
||||||
// 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")
|
|
||||||
// }
|
|
||||||
|
|
||||||
// log(deployed.pairs)
|
|
||||||
// })
|
|
||||||
|
|
||||||
cli
|
|
||||||
.command("add-oracle")
|
|
||||||
.description("add an oracle to aggregator")
|
|
||||||
.option("--aggregatorAddress <string>", "aggregator address")
|
|
||||||
.option("--oracleName <string>", "oracle name")
|
|
||||||
.option("--oracleOwner <string>", "oracle owner address")
|
|
||||||
.action(async (opts) => {
|
|
||||||
const { wallet, aggregator, deployer } = await AppContext.forAdmin()
|
|
||||||
|
|
||||||
const { oracleName, oracleOwner, feedAddress } = opts
|
|
||||||
|
|
||||||
log("add oracle...")
|
|
||||||
const oracle = await aggregator.addOracle({
|
|
||||||
oracleOwner: new PublicKey(oracleOwner),
|
|
||||||
description: oracleName,
|
|
||||||
aggregator: new PublicKey(feedAddress),
|
|
||||||
aggregatorOwner: wallet.account,
|
|
||||||
})
|
|
||||||
|
|
||||||
log(`added oracle. pubkey: ${color(oracle.publicKey.toBase58(), "blue")}`)
|
|
||||||
})
|
|
||||||
|
|
||||||
cli
|
|
||||||
.command("remove-oracle")
|
|
||||||
.option("--feedAddress <string>", "feed to remove oracle from")
|
|
||||||
.option("--oracleAddress <string>", "oracle address")
|
|
||||||
.action(async (opts) => {
|
|
||||||
const { feedAddress, oracleAddress } = opts
|
|
||||||
|
|
||||||
const { aggregator } = await AppContext.forAdmin()
|
|
||||||
|
|
||||||
await aggregator.removeOracle({
|
|
||||||
aggregator: new PublicKey(feedAddress),
|
|
||||||
oracle: new PublicKey(oracleAddress),
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
// cli
|
|
||||||
// .command("oracles")
|
|
||||||
// .description("show all oracles")
|
|
||||||
// .action(() => {
|
|
||||||
// // show current network
|
|
||||||
// showNetwork()
|
|
||||||
|
|
||||||
// if (!fs.existsSync(deployedPath)) {
|
|
||||||
// error("program haven't deployed yet")
|
|
||||||
// }
|
|
||||||
|
|
||||||
// const deployed = JSON.parse(fs.readFileSync(deployedPath).toString())
|
|
||||||
|
|
||||||
// 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")
|
|
||||||
// }
|
|
||||||
|
|
||||||
// log(deployed.oracles)
|
|
||||||
// })
|
|
||||||
|
|
||||||
cli
|
|
||||||
.command("feed-poll")
|
|
||||||
.description("poll current feed value")
|
|
||||||
.option("--feedAddress <string>", "feed address to submit values to")
|
|
||||||
.action(async (opts) => {
|
|
||||||
const { feedAddress } = opts
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
const feedInfo = await conn.getAccountInfo(new PublicKey(feedAddress))
|
|
||||||
log(decodeAggregatorInfo(feedInfo))
|
|
||||||
|
|
||||||
await sleep(1000)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
cli
|
|
||||||
.command("feed")
|
|
||||||
.description("oracle feeds to aggregator")
|
|
||||||
.option("--feedAddress <string>", "feed address to submit values to")
|
|
||||||
.option("--oracleAddress <string>", "feed address to submit values to")
|
|
||||||
.option("--pairSymbol <string>", "market pair to feed")
|
|
||||||
.action(async (opts) => {
|
|
||||||
const {
|
|
||||||
wallet,
|
|
||||||
aggregatorProgramAccount: aggregatorProgram,
|
|
||||||
} = await AppContext.forOracle()
|
|
||||||
|
|
||||||
const { feedAddress, oracleAddress, pairSymbol } = opts
|
|
||||||
|
|
||||||
feed.start({
|
|
||||||
oracle: new PublicKey(oracleAddress),
|
|
||||||
oracleOwner: wallet.account,
|
|
||||||
feed: new PublicKey(feedAddress),
|
|
||||||
pairSymbol: pairSymbol,
|
|
||||||
payerWallet: wallet,
|
|
||||||
programId: aggregatorProgram.publicKey,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
cli
|
|
||||||
.command("testToken")
|
|
||||||
.description("create test token")
|
|
||||||
.option("--amount <number>", "amount of the test token")
|
|
||||||
.action(async (opts) => {
|
|
||||||
const {
|
|
||||||
wallet,
|
|
||||||
aggregatorProgramAccount: aggregatorProgram,
|
|
||||||
deployer,
|
|
||||||
} = await AppContext.forAdmin()
|
|
||||||
|
|
||||||
const { amount } = opts
|
|
||||||
|
|
||||||
if (!amount || amount < 0) {
|
|
||||||
error("invalid amount")
|
|
||||||
}
|
|
||||||
|
|
||||||
const spltoken = new SPLToken(wallet)
|
|
||||||
|
|
||||||
log(`create test token...`)
|
|
||||||
// 1. create token
|
|
||||||
const token = await spltoken.initializeMint({
|
|
||||||
mintAuthority: wallet.account.publicKey,
|
|
||||||
decimals: 8,
|
|
||||||
})
|
|
||||||
|
|
||||||
// 2. create tokenOwner (program account)
|
|
||||||
const tokenOwner = await ProgramAccount.forSeed(
|
|
||||||
Buffer.from(token.publicKey.toBuffer()).slice(0, 30),
|
|
||||||
aggregatorProgram.publicKey
|
|
||||||
)
|
|
||||||
|
|
||||||
log(`create token acount...`)
|
|
||||||
// 3. create token account
|
|
||||||
const tokenAccount = await spltoken.initializeAccount({
|
|
||||||
token: token.publicKey,
|
|
||||||
owner: tokenOwner.pubkey,
|
|
||||||
})
|
|
||||||
|
|
||||||
log(`mint ${amount} token to token account...`)
|
|
||||||
// 4. and then, mint tokens to that account
|
|
||||||
await spltoken.mintTo({
|
|
||||||
token: token.publicKey,
|
|
||||||
to: tokenAccount.publicKey,
|
|
||||||
amount: BigInt(amount),
|
|
||||||
authority: wallet.account,
|
|
||||||
})
|
|
||||||
|
|
||||||
log({
|
|
||||||
token: token.publicKey.toBase58(),
|
|
||||||
tokenAccount: tokenAccount.publicKey.toBase58(),
|
|
||||||
tokenOwner: {
|
|
||||||
address: tokenOwner.address,
|
|
||||||
seed: tokenOwner.noncedSeed.toString("hex"),
|
|
||||||
nonce: tokenOwner.nonce,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
cli.parse(process.argv)
|
|
94
src/feed.ts
94
src/feed.ts
|
@ -1,94 +0,0 @@
|
||||||
import { PublicKey, Account, Wallet } from "solray"
|
|
||||||
import WebSocket from "ws"
|
|
||||||
|
|
||||||
import { decodeOracleInfo, sleep } from "./utils"
|
|
||||||
|
|
||||||
import FluxAggregator from "./FluxAggregator"
|
|
||||||
|
|
||||||
const submitInterval = 10 * 1000
|
|
||||||
|
|
||||||
interface StartParams {
|
|
||||||
oracle: PublicKey;
|
|
||||||
oracleOwner: Account;
|
|
||||||
feed: PublicKey;
|
|
||||||
pairSymbol: string;
|
|
||||||
payerWallet: Wallet;
|
|
||||||
programId: PublicKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function start(params: StartParams) {
|
|
||||||
const {
|
|
||||||
oracle,
|
|
||||||
oracleOwner,
|
|
||||||
feed,
|
|
||||||
pairSymbol,
|
|
||||||
payerWallet,
|
|
||||||
programId,
|
|
||||||
} = params
|
|
||||||
|
|
||||||
console.log("connecting to wss://ws-feed.pro.coinbase.com ()")
|
|
||||||
const ws = new WebSocket("wss://ws-feed.pro.coinbase.com")
|
|
||||||
|
|
||||||
ws.on("open", () => {
|
|
||||||
console.log(`${pairSymbol} price feed connected`)
|
|
||||||
ws.send(JSON.stringify({
|
|
||||||
"type": "subscribe",
|
|
||||||
"product_ids": [
|
|
||||||
pairSymbol.replace("/", "-").toUpperCase(),
|
|
||||||
],
|
|
||||||
"channels": [
|
|
||||||
"ticker"
|
|
||||||
]
|
|
||||||
}))
|
|
||||||
})
|
|
||||||
|
|
||||||
// in penny
|
|
||||||
let curPriceCent = 0
|
|
||||||
|
|
||||||
ws.on("message", async (data) => {
|
|
||||||
const json = JSON.parse(data)
|
|
||||||
if (!json || !json.price) {
|
|
||||||
return console.log(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
curPriceCent = Math.floor(json.price * 100)
|
|
||||||
|
|
||||||
console.log("current price:", json.price)
|
|
||||||
})
|
|
||||||
|
|
||||||
ws.on("close", (err) => {
|
|
||||||
console.error(`websocket closed: ${err}`)
|
|
||||||
process.exit(1)
|
|
||||||
})
|
|
||||||
|
|
||||||
const program = new FluxAggregator(payerWallet, programId)
|
|
||||||
|
|
||||||
console.log(await program.oracleInfo(oracle))
|
|
||||||
console.log({ owner: oracleOwner.publicKey.toString() })
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
if (curPriceCent == 0) {
|
|
||||||
await sleep(1000)
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
await program.submit({
|
|
||||||
aggregator: feed,
|
|
||||||
oracle,
|
|
||||||
submission: BigInt(curPriceCent),
|
|
||||||
owner: oracleOwner,
|
|
||||||
})
|
|
||||||
} catch(err) {
|
|
||||||
console.log(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log("submit success!")
|
|
||||||
|
|
||||||
payerWallet.conn.getAccountInfo(oracle).then((accountInfo) => {
|
|
||||||
console.log("oracle info:", decodeOracleInfo(accountInfo))
|
|
||||||
})
|
|
||||||
|
|
||||||
console.log("wait for cooldown success!")
|
|
||||||
await sleep(submitInterval)
|
|
||||||
}
|
|
||||||
}
|
|
67
src/utils.ts
67
src/utils.ts
|
@ -1,11 +1,5 @@
|
||||||
import { Connection, PublicKey } from "@solana/web3.js"
|
import { Connection, PublicKey } from "@solana/web3.js"
|
||||||
|
|
||||||
import {
|
|
||||||
AggregatorLayout,
|
|
||||||
SubmissionLayout,
|
|
||||||
OracleLayout,
|
|
||||||
} from "./FluxAggregator"
|
|
||||||
|
|
||||||
import { solana, Wallet, NetworkName, Deployer } from "solray"
|
import { solana, Wallet, NetworkName, Deployer } from "solray"
|
||||||
|
|
||||||
export function getMedian(submissions: number[]): number {
|
export function getMedian(submissions: number[]): number {
|
||||||
|
@ -33,67 +27,6 @@ export function sleep(ms: number): Promise<void> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function decodeAggregatorInfo(accountInfo) {
|
|
||||||
const data = Buffer.from(accountInfo.data)
|
|
||||||
const aggregator = AggregatorLayout.decode(data)
|
|
||||||
|
|
||||||
const minSubmissionValue = aggregator.minSubmissionValue.readBigUInt64LE()
|
|
||||||
const maxSubmissionValue = aggregator.maxSubmissionValue.readBigUInt64LE()
|
|
||||||
const submitInterval = aggregator.submitInterval.readInt32LE()
|
|
||||||
const description = (aggregator.description.toString() as String).trim()
|
|
||||||
|
|
||||||
// decode oracles
|
|
||||||
let submissions: any[] = []
|
|
||||||
let submissionSpace = SubmissionLayout.span
|
|
||||||
let latestUpdateTime = BigInt(0)
|
|
||||||
|
|
||||||
for (let i = 0; i < aggregator.submissions.length / submissionSpace; i++) {
|
|
||||||
let submission = SubmissionLayout.decode(
|
|
||||||
aggregator.submissions.slice(
|
|
||||||
i * submissionSpace,
|
|
||||||
(i + 1) * submissionSpace
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
submission.oracle = new PublicKey(submission.oracle)
|
|
||||||
submission.time = submission.time.readBigInt64LE()
|
|
||||||
submission.value = submission.value.readBigInt64LE()
|
|
||||||
|
|
||||||
if (!submission.oracle.equals(new PublicKey(0))) {
|
|
||||||
submissions.push(submission)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (submission.time > latestUpdateTime) {
|
|
||||||
latestUpdateTime = submission.time
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
minSubmissionValue: minSubmissionValue,
|
|
||||||
maxSubmissionValue: maxSubmissionValue,
|
|
||||||
submissionValue: getMedian(submissions),
|
|
||||||
submitInterval,
|
|
||||||
description,
|
|
||||||
oracles: submissions.map((s) => s.oracle.toString()),
|
|
||||||
latestUpdateTime: new Date(Number(latestUpdateTime) * 1000),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function decodeOracleInfo(accountInfo) {
|
|
||||||
const data = Buffer.from(accountInfo.data)
|
|
||||||
|
|
||||||
const oracle = OracleLayout.decode(data)
|
|
||||||
|
|
||||||
oracle.nextSubmitTime = oracle.nextSubmitTime.readBigUInt64LE().toString()
|
|
||||||
oracle.description = oracle.description.toString()
|
|
||||||
oracle.isInitialized = oracle.isInitialized != 0
|
|
||||||
oracle.withdrawable = oracle.withdrawable.readBigUInt64LE().toString()
|
|
||||||
oracle.aggregator = new PublicKey(oracle.aggregator).toBase58()
|
|
||||||
oracle.owner = new PublicKey(oracle.owner).toBase58()
|
|
||||||
|
|
||||||
return oracle
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function walletFromEnv(
|
export async function walletFromEnv(
|
||||||
key: string,
|
key: string,
|
||||||
conn: Connection
|
conn: Connection
|
||||||
|
|
Loading…
Reference in New Issue