fund oracle instruction (#1672)

This commit is contained in:
Adrian Brzeziński 2023-06-11 22:45:52 +02:00 committed by GitHub
parent d43b0e1fdb
commit af97e5b65c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 325 additions and 6 deletions

View File

@ -30,7 +30,7 @@ export default function InstructionAccount({
fetchTokenAccountByPubkey(connection.current, accountMeta.pubkey).then(
(ta) => {
if (ta.result) {
setAccountLabel(`owner: ${ta.result?.owner.toBase58()}`)
setAccountLabel(`owner: ${ta.result?.owner?.toBase58()}`)
}
isFetching.current = false
}

View File

@ -0,0 +1,19 @@
import { Connection } from '@solana/web3.js'
const INSTRUCTIONS = {
202: {
name: 'Fund Oracle',
accounts: [],
getDataUI: async (connection: Connection, data: Uint8Array) => {
return (
<>
<div>{JSON.stringify(data)}</div>
</>
)
},
},
}
export const SWITCHBOARD_INSTRUCTIONS = {
SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f: INSTRUCTIONS,
}

View File

@ -35,6 +35,7 @@ import { VALIDATORDAO_INSTRUCTIONS } from './programs/validatordao'
import { POSEIDON_INSTRUCTIONS } from './programs/poseidon'
import { MANGO_V4_INSTRUCTIONS } from './programs/mangoV4'
import { DUAL_INSTRUCTIONS } from './programs/dual'
import { SWITCHBOARD_INSTRUCTIONS } from './programs/switchboard'
/**
* Default governance program id instance
@ -332,6 +333,7 @@ export const INSTRUCTION_DESCRIPTORS = {
...RAYDIUM_INSTRUCTIONS,
...MARINADE_INSTRUCTIONS,
...LIDO_INSTRUCTIONS,
...SWITCHBOARD_INSTRUCTIONS,
...SOLEND_PROGRAM_INSTRUCTIONS,
...FORESIGHT_INSTRUCTIONS,
...ATA_PROGRAM_INSTRUCTIONS,

View File

@ -796,6 +796,10 @@ export default function useGovernanceAssets() {
name: 'Remove Oracle from Queue',
packageId: PackageEnum.Switchboard,
},
[Instructions.SwitchboardFundOracle]: {
name: 'Fund Oracle',
packageId: PackageEnum.Switchboard,
},
/*

View File

@ -106,6 +106,7 @@
"@solendprotocol/solend-sdk": "0.5.5",
"@sqds/iframe-adapter": "1.0.16",
"@streamflow/stream": "3.0.16",
"@switchboard-xyz/solana.js": "2.2.0",
"@switchboard-xyz/switchboard-v2": "0.0.174",
"@tailwindcss/line-clamp": "0.4.2",
"@tanstack/react-query": "4.14.3",

View File

@ -0,0 +1,218 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import React, { useContext, useEffect, useState } from 'react'
import * as yup from 'yup'
import { isFormValid } from '@utils/formValidation'
import { UiInstruction } from '@utils/uiTypes/proposalCreationTypes'
import useGovernanceAssets from '@hooks/useGovernanceAssets'
import { Governance } from '@solana/spl-governance'
import { ProgramAccount } from '@solana/spl-governance'
import { serializeInstructionToBase64 } from '@solana/spl-governance'
import { AccountType, AssetAccount } from '@utils/uiTypes/assets'
import useWalletOnePointOh from '@hooks/useWalletOnePointOh'
import InstructionForm, {
InstructionInput,
InstructionInputType,
} from '../FormCreator'
import { NewProposalContext } from '../../../new'
import {
AggregatorAccount,
SwitchboardProgram,
} from '@switchboard-xyz/solana.js'
import useLegacyConnectionContext from '@hooks/useLegacyConnectionContext'
import {
Keypair,
LAMPORTS_PER_SOL,
PublicKey,
SystemProgram,
TransactionInstruction,
} from '@solana/web3.js'
import { notify } from '@utils/notifications'
import {
ASSOCIATED_TOKEN_PROGRAM_ID,
TOKEN_PROGRAM_ID,
Token,
} from '@solana/spl-token'
import { WSOL_MINT } from '@components/instructions/tools'
import { syncNative } from '@solendprotocol/solend-sdk'
interface TokenAddBankForm {
governedAccount: AssetAccount | null
solAmount: number
oraclePublicKey: string
}
const SwitchboardFundOracle = ({
index,
governance,
}: {
index: number
governance: ProgramAccount<Governance> | null
}) => {
const wallet = useWalletOnePointOh()
const connection = useLegacyConnectionContext()
const { assetAccounts } = useGovernanceAssets()
const solAccounts = assetAccounts.filter((x) => x.type === AccountType.SOL)
const shouldBeGoverned = !!(index !== 0 && governance)
const [form, setForm] = useState<TokenAddBankForm>({
governedAccount: null,
solAmount: 0,
oraclePublicKey: '',
})
const [formErrors, setFormErrors] = useState({})
const { handleSetInstructions } = useContext(NewProposalContext)
const validateInstruction = async (): Promise<boolean> => {
const { isValid, validationErrors } = await isFormValid(schema, form)
setFormErrors(validationErrors)
return isValid
}
async function getInstruction(): Promise<UiInstruction> {
const isValid = await validateInstruction()
const prerequisiteInstructions: TransactionInstruction[] = []
const prerequsieInstructionsSigners: Keypair[] = []
const additionalSerializedInstructions: string[] = []
let serializedInstruction = ''
if (
isValid &&
form.governedAccount?.governance?.account &&
wallet?.publicKey
) {
const program = await SwitchboardProgram.load(
connection.cluster === 'devnet' ? 'devnet' : 'mainnet-beta',
connection.current
)
const [oracle, oracleAccountData] = await AggregatorAccount.load(
program,
form.oraclePublicKey
)
if (
oracleAccountData.authority.toBase58() === wallet.publicKey.toBase58()
) {
const transferAuthIx = oracle.setAuthorityInstruction(
wallet.publicKey,
{
newAuthority: form.governedAccount.extensions.transferAddress!,
}
)
prerequsieInstructionsSigners.push(...transferAuthIx.signers)
prerequisiteInstructions.push(...transferAuthIx.ixns)
}
const [ix, amountToFund] = await oracle.fundUpToInstruction(
form.governedAccount.extensions.transferAddress!,
form.solAmount,
false
)
if (ix === undefined) {
notify({
type: 'error',
message: 'Amount lower then current lease amount',
})
}
const wsolAddress = await Token.getAssociatedTokenAddress(
ASSOCIATED_TOKEN_PROGRAM_ID,
TOKEN_PROGRAM_ID,
new PublicKey(WSOL_MINT),
form.governedAccount.extensions.transferAddress!,
true
)
const wsolAccount = await connection.current.getAccountInfo(wsolAddress)
if (!wsolAccount) {
const createWsolacc = await Token.createAssociatedTokenAccountInstruction(
ASSOCIATED_TOKEN_PROGRAM_ID,
TOKEN_PROGRAM_ID,
new PublicKey(WSOL_MINT),
wsolAddress,
form.governedAccount.extensions.transferAddress!,
wallet.publicKey
)
prerequisiteInstructions.push(createWsolacc)
}
const transferWSolIx = SystemProgram.transfer({
fromPubkey: form.governedAccount.extensions.transferAddress!,
toPubkey: wsolAddress,
lamports: Math.round(amountToFund! * LAMPORTS_PER_SOL),
})
const syncIx = syncNative(wsolAddress)
additionalSerializedInstructions.push(
serializeInstructionToBase64(transferWSolIx)
)
additionalSerializedInstructions.push(
serializeInstructionToBase64(syncIx)
)
additionalSerializedInstructions.push(
serializeInstructionToBase64(ix!.ixns[0])
)
serializedInstruction = ''
}
const obj: UiInstruction = {
prerequisiteInstructions: prerequisiteInstructions,
prerequisiteInstructionsSigners: prerequsieInstructionsSigners,
serializedInstruction: serializedInstruction,
additionalSerializedInstructions: additionalSerializedInstructions,
isValid,
governance: form.governedAccount?.governance,
}
return obj
}
useEffect(() => {
handleSetInstructions(
{ governedAccount: form.governedAccount?.governance, getInstruction },
index
)
// eslint-disable-next-line react-hooks/exhaustive-deps -- TODO please fix, it can cause difficult bugs. You might wanna check out https://bobbyhadz.com/blog/react-hooks-exhaustive-deps for info. -@asktree
}, [form])
const schema = yup.object().shape({
governedAccount: yup
.object()
.nullable()
.required('Program governed account is required'),
})
const inputs: InstructionInput[] = [
{
label: 'Governance',
initialValue: form.governedAccount,
name: 'governedAccount',
type: InstructionInputType.GOVERNED_ACCOUNT,
shouldBeGoverned: shouldBeGoverned as any,
governance: governance,
options: solAccounts,
},
{
label: 'Oracle PublicKey',
initialValue: form.oraclePublicKey,
type: InstructionInputType.INPUT,
inputType: 'text',
name: 'oraclePublicKey',
},
{
label:
'Fund up to SOL (Number must be higher then current sol amount inside oracle)',
initialValue: form.solAmount,
type: InstructionInputType.INPUT,
inputType: 'number',
name: 'solAmount',
},
]
return (
<>
{form && (
<InstructionForm
outerForm={form}
setForm={setForm}
inputs={inputs}
setFormErrors={setFormErrors}
formErrors={formErrors}
></InstructionForm>
)}
</>
)
}
export default SwitchboardFundOracle

View File

@ -54,6 +54,7 @@ import CreateNftPluginMaxVoterWeightRecord from './components/instructions/NftVo
import ConfigureNftPluginCollection from './components/instructions/NftVotingPlugin/ConfigureCollection'
import SwitchboardAdmitOracle from './components/instructions/Switchboard/AdmitOracle'
import SwitchboardRevokeOracle from './components/instructions/Switchboard/RevokeOracle'
import SwitchboardFundOracle from './components/instructions/Switchboard/FundOracle'
import FriktionWithdraw from './components/instructions/Friktion/FriktionWithdraw'
import FriktionClaimPendingDeposit from './components/instructions/Friktion/FriktionClaimPendingDeposit'
import FriktionClaimPendingWithdraw from './components/instructions/Friktion/FriktionClaimPendingWithdraw'
@ -325,7 +326,7 @@ const New = () => {
handleTurnOffLoaders()
}
const firstGovernancePk = instructionsData[0]?.governedAccount?.pubkey.toBase58()
const firstGovernancePk = instructionsData[0]?.governedAccount?.pubkey?.toBase58()
const previousFirstGovernancePk = usePrevious(firstGovernancePk)
useEffect(() => {
@ -438,6 +439,7 @@ const New = () => {
[Instructions.PsyFinanceExerciseOption]: PsyFinanceExerciseOption,
[Instructions.SwitchboardAdmitOracle]: SwitchboardAdmitOracle,
[Instructions.SwitchboardRevokeOracle]: SwitchboardRevokeOracle,
[Instructions.SwitchboardFundOracle]: SwitchboardFundOracle,
[Instructions.RefreshSolendObligation]: RefreshObligation,
[Instructions.RefreshSolendReserve]: RefreshReserve,
[Instructions.ForesightInitMarket]: MakeInitMarketParams,
@ -516,7 +518,7 @@ const New = () => {
[Instructions.RevokeGoverningTokens]: RevokeGoverningTokens,
[Instructions.SetMintAuthority]: SetMintAuthority,
}),
[governance?.pubkey.toBase58()]
[governance?.pubkey?.toBase58()]
)
const getCurrentInstruction = useCallback(
@ -551,7 +553,7 @@ const New = () => {
)
},
// eslint-disable-next-line react-hooks/exhaustive-deps -- TODO please fix, it can cause difficult bugs. You might wanna check out https://bobbyhadz.com/blog/react-hooks-exhaustive-deps for info. -@asktree
[governance?.pubkey.toBase58()]
[governance?.pubkey?.toBase58()]
)
const titleTooLong = form.title.length > TITLE_LENGTH_LIMIT

View File

@ -467,6 +467,7 @@ export enum Instructions {
StakeValidator,
SwitchboardAdmitOracle,
SwitchboardRevokeOracle,
SwitchboardFundOracle,
Transfer,
TransferDomainName,
UpdateTokenMetadata,

View File

@ -752,7 +752,28 @@
superstruct "^0.15.4"
toml "^3.0.0"
"@coral-xyz/borsh@0.26.0", "@coral-xyz/borsh@^0.26.0":
"@coral-xyz/anchor@^0.27.0":
version "0.27.0"
resolved "https://registry.yarnpkg.com/@coral-xyz/anchor/-/anchor-0.27.0.tgz#621e5ef123d05811b97e49973b4ed7ede27c705c"
integrity sha512-+P/vPdORawvg3A9Wj02iquxb4T0C5m4P6aZBVYysKl4Amk+r6aMPZkUhilBkD6E4Nuxnoajv3CFykUfkGE0n5g==
dependencies:
"@coral-xyz/borsh" "^0.27.0"
"@solana/web3.js" "^1.68.0"
base64-js "^1.5.1"
bn.js "^5.1.2"
bs58 "^4.0.1"
buffer-layout "^1.2.2"
camelcase "^6.3.0"
cross-fetch "^3.1.5"
crypto-hash "^1.3.0"
eventemitter3 "^4.0.7"
js-sha256 "^0.9.0"
pako "^2.0.3"
snake-case "^3.0.4"
superstruct "^0.15.4"
toml "^3.0.0"
"@coral-xyz/borsh@0.26.0", "@coral-xyz/borsh@^0.26.0", "@coral-xyz/borsh@^0.27.0":
version "0.26.0"
resolved "https://registry.yarnpkg.com/@coral-xyz/borsh/-/borsh-0.26.0.tgz#d054f64536d824634969e74138f9f7c52bbbc0d5"
integrity sha512-uCZ0xus0CszQPHYfWAqKS5swS1UxvePu83oOF+TWpUkedsNlg6p2p4azxZNSSqwXb9uXMFgxhuMBX9r3Xoi0vQ==
@ -5026,7 +5047,7 @@
"@wallet-standard/app" "^1.0.1"
"@wallet-standard/base" "^1.0.1"
"@solana/web3.js@1.42.0", "@solana/web3.js@1.56.0", "@solana/web3.js@1.73.3", "@solana/web3.js@^1.16.1", "@solana/web3.js@^1.17.0", "@solana/web3.js@^1.20.0", "@solana/web3.js@^1.21.0", "@solana/web3.js@^1.22.0", "@solana/web3.js@^1.24.1", "@solana/web3.js@^1.29.2", "@solana/web3.js@^1.30.2", "@solana/web3.js@^1.31.0", "@solana/web3.js@^1.32.0", "@solana/web3.js@^1.35.1", "@solana/web3.js@^1.36.0", "@solana/web3.js@^1.37.1", "@solana/web3.js@^1.42.0", "@solana/web3.js@^1.43.4", "@solana/web3.js@^1.44.3", "@solana/web3.js@^1.48.0", "@solana/web3.js@^1.56.2", "@solana/web3.js@^1.59.1", "@solana/web3.js@^1.63.0", "@solana/web3.js@^1.63.1", "@solana/web3.js@^1.66.2", "@solana/web3.js@^1.68.0", "@solana/web3.js@^1.73.2":
"@solana/web3.js@1.42.0", "@solana/web3.js@1.56.0", "@solana/web3.js@1.73.3", "@solana/web3.js@^1.16.1", "@solana/web3.js@^1.17.0", "@solana/web3.js@^1.20.0", "@solana/web3.js@^1.21.0", "@solana/web3.js@^1.22.0", "@solana/web3.js@^1.24.1", "@solana/web3.js@^1.29.2", "@solana/web3.js@^1.30.2", "@solana/web3.js@^1.31.0", "@solana/web3.js@^1.32.0", "@solana/web3.js@^1.35.1", "@solana/web3.js@^1.36.0", "@solana/web3.js@^1.37.1", "@solana/web3.js@^1.42.0", "@solana/web3.js@^1.43.4", "@solana/web3.js@^1.44.3", "@solana/web3.js@^1.48.0", "@solana/web3.js@^1.56.2", "@solana/web3.js@^1.59.1", "@solana/web3.js@^1.63.0", "@solana/web3.js@^1.63.1", "@solana/web3.js@^1.66.2", "@solana/web3.js@^1.68.0", "@solana/web3.js@^1.73.0", "@solana/web3.js@^1.73.2":
version "1.73.3"
resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.73.3.tgz#60e6bd68f6f364d4be360b1e0a03a0a68468a029"
integrity sha512-vHRMo589XEIpoujpE2sZZ1aMZvfA1ImKfNxobzEFyMb+H5j6mRRUXfdgWD0qJ0sm11e5BcBC7HPeRXJB+7f3Lg==
@ -5313,6 +5334,21 @@
decimal.js "^10.4.3"
protobufjs "^7.1.2"
"@switchboard-xyz/common@^2.2.3":
version "2.2.3"
resolved "https://registry.yarnpkg.com/@switchboard-xyz/common/-/common-2.2.3.tgz#f4d39cea8cea9354ad369f749462fa37152c4ec9"
integrity sha512-E4NQf9aXdOiul+sySAbFPAW9k0qz4wRTfqrU7cEa8nRIvUkg6VIZ+5JfajHv/VfK9UOD+6ZfMBxq2+dHkiz9zw==
dependencies:
"@solana/web3.js" "^1.66.2"
"@types/big.js" "^6.1.6"
"@types/bn.js" "^5.1.1"
big.js "^6.2.1"
bn.js "^5.2.1"
bs58 "^5.0.0"
decimal.js "^10.4.3"
protobufjs "^7.2.3"
yaml "^2.2.1"
"@switchboard-xyz/sbv2-lite@^0.1.6":
version "0.1.6"
resolved "https://registry.yarnpkg.com/@switchboard-xyz/sbv2-lite/-/sbv2-lite-0.1.6.tgz#dc3fbb5b3b028dbd3c688b991bcc48a670131ddb"
@ -5321,6 +5357,19 @@
"@project-serum/anchor" "^0.24.2"
big.js "^6.1.1"
"@switchboard-xyz/solana.js@2.2.0":
version "2.2.0"
resolved "https://registry.yarnpkg.com/@switchboard-xyz/solana.js/-/solana.js-2.2.0.tgz#5108cfbbf0ca6e48297ae8c6e8c11f39e04ac32a"
integrity sha512-UzAyKDY1wq1UO50PsKc/6huF6xYX/3B5kA0lmEnZMb+5L6M3YtDckbxk6mD4kG7J0curvvX6Alu9cO6uGqnI3A==
dependencies:
"@coral-xyz/anchor" "^0.27.0"
"@coral-xyz/borsh" "^0.27.0"
"@solana/spl-token" "^0.3.6"
"@solana/web3.js" "^1.73.0"
"@switchboard-xyz/common" "^2.2.3"
dotenv "^16.0.3"
lodash "^4.17.21"
"@switchboard-xyz/switchboard-api@^0.2.150":
version "0.2.201"
resolved "https://registry.yarnpkg.com/@switchboard-xyz/switchboard-api/-/switchboard-api-0.2.201.tgz#d082206d521d24dbcdeb06a77e6637a56ab883eb"
@ -14916,6 +14965,24 @@ protobufjs@^7.1.2:
"@types/node" ">=13.7.0"
long "^5.0.0"
protobufjs@^7.2.3:
version "7.2.3"
resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-7.2.3.tgz#01af019e40d9c6133c49acbb3ff9e30f4f0f70b2"
integrity sha512-TtpvOqwB5Gdz/PQmOjgsrGH1nHjAQVCN7JG4A6r1sXRWESL5rNMAiRcBQlCAdKxZcAbstExQePYG8xof/JVRgg==
dependencies:
"@protobufjs/aspromise" "^1.1.2"
"@protobufjs/base64" "^1.1.2"
"@protobufjs/codegen" "^2.0.4"
"@protobufjs/eventemitter" "^1.1.0"
"@protobufjs/fetch" "^1.1.0"
"@protobufjs/float" "^1.0.2"
"@protobufjs/inquire" "^1.1.0"
"@protobufjs/path" "^1.1.2"
"@protobufjs/pool" "^1.1.0"
"@protobufjs/utf8" "^1.1.0"
"@types/node" ">=13.7.0"
long "^5.0.0"
proxy-from-env@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
@ -17920,6 +17987,11 @@ yaml@^1.10.0, yaml@^1.10.2, yaml@^1.7.2:
resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b"
integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==
yaml@^2.2.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.3.1.tgz#02fe0975d23cd441242aa7204e09fc28ac2ac33b"
integrity sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==
yargs-parser@20.2.4:
version "20.2.4"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54"