work on reward faucet

This commit is contained in:
De Facto 2021-02-25 10:52:20 +08:00
parent a528f29958
commit 2f071eb75e
4 changed files with 196 additions and 40 deletions

View File

@ -20,15 +20,25 @@ import FluxAggregator from "./FluxAggregator"
import { AggregatorConfig, IAggregatorConfig } from "./schema"
import { jsonReplacer, jsonReviver } from "./json"
import { log } from "./log"
import { config } from "dotenv/types"
interface OracleDeployInfo {
pubkey: PublicKey
owner: PublicKey
}
interface FaucetInfo {
pubkey: PublicKey
// program account public key
owner: PublicKey
ownerSeed: Buffer
}
interface AggregatorDeployInfo {
pubkey: PublicKey
owner: PublicKey
config: IAggregatorConfig
faucet: FaucetInfo
oracles: {
[key: string]: OracleDeployInfo
@ -124,6 +134,34 @@ export class Deployer {
return new FluxAggregator(this.wallet, this.state.programID)
}
async createRewardFaucet(
aggregatorInfo: AggregatorDeployInfo
): Promise<FaucetInfo> {
if (aggregatorInfo.faucet) {
return aggregatorInfo.faucet
}
const seed = Buffer.from(aggregatorInfo.config.description)
const faucetOwner = await ProgramAccount.forSeed(seed, this.state.programID)
const spltoken = new SPLToken(this.wallet)
const faucet = await spltoken.initializeAccount({
// TODO: check if rewardTokenAccount is null
token: aggregatorInfo.config.rewardTokenAccount,
owner: faucetOwner.pubkey,
})
aggregatorInfo.faucet = {
pubkey: faucet.publicKey,
owner: faucetOwner.pubkey,
ownerSeed: seed,
}
return aggregatorInfo.faucet
}
async createOracle(
aggregatorInfo: AggregatorDeployInfo,
name: string,
@ -164,11 +202,18 @@ export class Deployer {
owner: this.wallet.account,
})
return {
const info: AggregatorDeployInfo = {
pubkey: account.publicKey,
owner: this.wallet.pubkey,
config,
// to be set by `createRewardFaucet`
faucet: undefined,
oracles: {},
}
} as any
// will set
await this.createRewardFaucet(info)
return info
}
}

View File

@ -36,6 +36,7 @@ export class Submitter {
public aggregatorPK: PublicKey,
public oraclePK: PublicKey,
private oracleOwnerWallet: Wallet,
private priceFeed: IPriceFeed,
private cfg: SubmitterConfig
) {
@ -58,7 +59,20 @@ export class Submitter {
await Promise.all([this.observeAggregatorState(), this.observePriceFeed()])
}
public async withdrawRewards() {}
public async withdrawRewards() {
// if (this.oracle.withdrawable.isZero()) {
// return
// }
// //
// this.program.withdraw({
// accounts: {
// aggregator: this.aggregatorPK,
// // faucet
// }
// })
}
private async reloadState(loadAggregator = true) {
if (loadAggregator) {

View File

@ -7,18 +7,41 @@ export function jsonReviver(_key: string, val: any) {
if (val["type"] == "PublicKey") {
return new PublicKey(val.base58)
}
if (val["type"] == "Buffer") {
return Buffer.from(val.hex, "hex")
}
}
return val
}
export function jsonReplacer(key: string, value: any) {
if (value && typeof value == "object") {
console.log("jsonReplacer", key, value)
if (value.constructor == PublicKey) {
return {
type: "PublicKey",
base58: value.toBase58(),
}
}
// The Buffer class defines a `toJSON` method that returns:
//
// {
// type: 'Buffer',
// data: [
// 100, 101, 97, 100,
// 98, 101, 97, 102
// ]
// }
//
// Convert this to an hex string
if (value.type == "Buffer") {
return {
type: "Buffer",
hex: Buffer.from(value).toString("hex"),
}
}
}
return value

148
test.ts
View File

@ -1,67 +1,141 @@
import dotenv from "dotenv"
import { ProgramAccount, PublicKey, SPLToken, Wallet } from "solray"
dotenv.config()
import { AppContext, conn, network } from "./src/context"
import { AggregatorDeployFile, Deployer } from "./src/Deployer"
import { coinbase } from "./src/feeds"
import { loadJSONFile } from "./src/json"
import { jsonReplacer, jsonReviver, loadJSONFile } from "./src/json"
import { log } from "./src/log"
import { PriceFeeder } from "./src/PriceFeeder"
import { stateFromJSON } from "./src/state"
interface State {
rewardTokenPK: PublicKey
faucetPK: PublicKey
isMinted: boolean
}
class TestHarness {
public state: State
constructor(
stateFile: string,
private wallet: Wallet,
) {
this.state = stateFromJSON<State>(stateFile, {} as State, {
replacer: jsonReplacer,
reviver: jsonReviver,
})
// this.state = stateFromJSON<State>(`state.${network}.json`, {} as State)
}
// async setup() {
// // setup reward token plus mint
// await this.setupRewardTokenPK()
// await this.setupFaucet()
// await this.mintToFaucet(1e6 * 1e9)
// }
get spltoken() {
return new SPLToken(this.wallet)
}
// async mintToFaucet(amount: number) {
// if (this.state.isMinted) {
// return
// }
// await this.spltoken.mintTo({
// token: this.state.rewardTokenPK,
// to: await this.faucetOwnerPK(),
// amount: BigInt(amount), // 1M
// authority: this.wallet.pubkey,
// })
// }
// async faucetOwnerPK(): Promise<PublicKey> {
// const rewardTokenOwner = await ProgramAccount.forSeed(
// Buffer.from("solink"),
// this.aggregatorProgramID
// )
// return rewardTokenOwner.pubkey
// }
async setupFaucet(aggregatorProgramID: PublicKey): Promise<PublicKey> {
if (this.state.faucetPK) {
return this.state.faucetPK
}
const faucetOwner = await ProgramAccount.forSeed(
Buffer.from("solink"),
aggregatorProgramID
)
const faucet = await this.spltoken.initializeAccount({
token: this.state.rewardTokenPK,
owner: faucetOwner.pubkey,
})
await this.spltoken.mintTo({
token: this.state.rewardTokenPK,
to: faucet.publicKey,
amount: BigInt(1e6*1e9), // 1M
authority: this.wallet.pubkey,
})
this.state.faucetPK = faucet.publicKey
return faucet.publicKey
}
async setupRewardTokenPK(): Promise<PublicKey> {
if (this.state.rewardTokenPK) {
return this.state.rewardTokenPK
}
log.info("setup reward token")
const token = await this.spltoken.initializeMint({
mintAuthority: this.wallet.pubkey,
decimals: 9,
// account: this.wallet.deriveAccount("0")
})
this.state.rewardTokenPK = token.publicKey
return token.publicKey
}
}
async function main() {
// persistent JSON state for test script
const setupFile = `config/setup.${network}.json`
const deployFile = `deploy.${network}.json`
const feederConfigFile = "feeder.json"
let ctx = new AppContext()
let adminWallet = await ctx.adminWallet()
let oracleWallet = await ctx.oracleWallet()
await conn.requestAirdrop(adminWallet.pubkey, 10 * 1e9)
await conn.requestAirdrop(oracleWallet.pubkey, 10 * 1e9)
const deployer = new Deployer(deployFile, setupFile, adminWallet)
const t = new TestHarness(`test.${network}.json`, adminWallet)
await t.setupRewardTokenPK()
// return
const deployer = new Deployer(deployFile, setupFile, adminWallet)
await deployer.runAll()
// TODO: actually, creating the faucet should be in the deployer
// await t.setupFaucet(deployer.state.programID)
const deploy = loadJSONFile<AggregatorDeployFile>(deployFile)
const feeder = new PriceFeeder(deploy, oracleWallet)
feeder.start()
// TODO: try to to harvest rewards
return
// const spltoken = new SPLToken(adminWallet)
// const rewardToken = await deployer.ensure("create reward token", async () => {
// return spltoken.initializeMint({
// mintAuthority: adminWallet.pubkey,
// decimals: 8,
// })
// })
// const rewardTokenOwner = await ProgramAccount.forSeed(
// Buffer.from("solink"),
// aggregatorProgram.publicKey
// )
// const rewardTokenAccount = await deployer.ensure(
// "initialize reward token account",
// async () => {
// const vault = await spltoken.initializeAccount({
// token: rewardToken.publicKey,
// owner: rewardTokenOwner.pubkey,
// })
// await spltoken.mintTo({
// token: rewardToken.publicKey,
// to: vault.publicKey,
// amount: BigInt(1e6 * 1e8), // 1M
// authority: adminWallet.pubkey,
// })
// return vault
// }
// )
// console.log(await spltoken.mintInfo(rewardToken.publicKey))
}
main().catch((err) => console.log(err))