Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EpicentralDAO - Treasury Metadata + Removed Bugged Proposal #71

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions components/instructions/tools.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,10 @@ export const ACCOUNT_NAMES = {
'9zUzsav4JcUHnmzsT9YFkbk2YvjxEf9MosVTKYDDnnnW': 'Rewards Treasury',
'6yuntQAS5gSwhhKaXG3QYbcwXPxhsbULu9Tzv9mizUUm': 'SOL Rewards Reserve',
'6PPtCuNPxipkwATrXorGNMFsEiJK2WNwNRVdgzTJZfU8': 'LABS DeFi Rewards Vault',

'7fGPDUx91yTASVAyt3DTUEnxMN1ghL1oQ69BVv8q8z3z': 'Admin Treasury',
'GpbTR5zgfgM6tJt1epcXFvNELusiacc7qKr845FRnzZv': 'SOL Admin Reserve',
'Auecwis4vTxvHHkqKvPiut3GzuSN85ZWM6z2WDhZtrxh': 'LABS Admin Vault',

// Physis DAO
'29epeLvAMyRXtpA1HaoKB1hGcAnrc1NvMCbaZ8AVRwEi': 'Physis DAO Treasury',
Expand Down Expand Up @@ -387,6 +391,7 @@ export const HIDDEN_PROPOSALS = new Map<string, string>([
['CRmUPr8CbfPQ4MAoo2yxSf5qL2nPsddL69kowMfp1JYP', ''],
['8msNFq5VBectsGAv66zYx5QRve1p3m6ZEz49xaWX3tbd', ''],
['3jU2YuKXKBw4cWx9taPDfhQZ8RFLmFUx3HLxMrh7w749', ''],
['8eiBtZ7ZgAZEK747z1mXKPktQg3gdbgB9ew78t9LXwyL', ''],
])

export const DEFAULT_NATIVE_SOL_MINT =
Expand Down
37 changes: 37 additions & 0 deletions hooks/useMeteoraClient.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { useState, useEffect } from 'react'
import { useConnection } from '@solana/wallet-adapter-react'
// ⚠ Replace this import with the actual Meteora package import or client creation logic
// import { createMeteoraClient } from 'meteora-sdk'

/**
* Example hook that sets up a Meteora client instance:
*/
export function useMeteoraClient() {
const { connection } = useConnection()
const [meteoraClient, setMeteoraClient] = useState<any | null>(null)

useEffect(() => {
// If you have an official Meteora client creation method, call it here:
// const client = createMeteoraClient({ connection })
// setMeteoraClient(client)

// For now, we’ll just mock it to demonstrate usage.
const mockClient = {
createPool: async ({ tokenAMint, tokenBMint, authority, fee }) => {
// Placeholder logic for demonstration.
// In a real use case, this would build and return a TransactionInstruction.
console.log('Creating pool with:', {
tokenAMint,
tokenBMint,
authority,
fee,
})
return {} // Return a valid TransactionInstruction object
},
}

setMeteoraClient(mockClient)
}, [connection])

return { meteoraClient }
}
11 changes: 7 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
"@carbon/icons-react": "11.7.0",
"@civic/profile": "^0.5.0-beta.1",
"@civic/solana-gateway-react": "^0.16.10",
"@coral-xyz/anchor": "0.29.0",
"@coral-xyz/anchor": "0.30.1",
"@coral-xyz/borsh": "0.27.0",
"@dialectlabs/react-sdk-blockchain-solana": "^2.0.3",
"@dialectlabs/react-ui": "^2.0.7",
Expand All @@ -60,6 +60,7 @@
"@mean-dao/payment-streaming": "4.0.3",
"@metaplex-foundation/js": "0.19.4",
"@metaplex-foundation/mpl-token-metadata": "2.10.0",
"@meteora-ag/m3m3": "1.0.5",
"@multifarm/solana-realms": "1.0.6",
"@next/bundle-analyzer": "12.1.5",
"@nivo/bar": "0.79.1",
Expand Down Expand Up @@ -96,8 +97,9 @@
"@solana/spl-account-compression": "~0.2.0",
"@solana/spl-governance": "0.3.28",
"@solana/spl-stake-pool": "1.1.5",
"@solana/spl-token": "0.1.8",
"@solana/spl-token": "0.4.9",
"@solana/spl-token-new": "npm:@solana/[email protected]",
"@solana/spl-token-registry": "0.2.4574",
"@solana/wallet-adapter-backpack": "0.1.13",
"@solana/wallet-adapter-base": "0.9.22",
"@solana/wallet-adapter-exodus": "0.1.17",
Expand All @@ -109,7 +111,7 @@
"@solana/wallet-adapter-torus": "0.11.27",
"@solana/wallet-adapter-walletconnect": "0.1.16",
"@solana/wallet-adapter-wallets": "0.19.16",
"@solana/web3.js": "1.78.8",
"@solana/web3.js": "1.98.0",
"@solendprotocol/solend-sdk": "0.5.5",
"@sqds/iframe-adapter": "1.0.16",
"@sqds/mesh": "1.0.6",
Expand Down Expand Up @@ -290,5 +292,6 @@
"volta": {
"node": "18.19.0",
"yarn": "1.22.19"
}
},
"packageManager": "[email protected]+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
import { useContext, useEffect, useState } from 'react'
import * as yup from 'yup'
import {
Governance,
ProgramAccount,
serializeInstructionToBase64,
} from '@solana/spl-governance'
import { validateInstruction } from '@utils/instructionTools'
import { UiInstruction } from '@utils/uiTypes/proposalCreationTypes'
import { PublicKey } from '@solana/web3.js'

import { NewProposalContext } from '../../../new'
import InstructionForm, { InstructionInput } from '../FormCreator'
import { InstructionInputType } from '../inputInstructionType'
import { AssetAccount } from '@utils/uiTypes/assets'
import useWalletOnePointOh from '@hooks/useWalletOnePointOh'
import { useRealmQuery } from '@hooks/queries/realm'
import useGovernanceAssets from '@hooks/useGovernanceAssets'
import { useMeteoraClient } from '@hooks/useMeteoraClient'
interface CreatePoolForm {
governedAccount: AssetAccount | undefined
tokenAMint: string
tokenBMint: string
fee: number
}

const CreateMeteoraPool = ({
index,
governance,
}: {
index: number
governance: ProgramAccount<Governance> | null
}) => {
const realm = useRealmQuery().data?.result
const { assetAccounts } = useGovernanceAssets()
const wallet = useWalletOnePointOh()
const { meteoraClient } = useMeteoraClient()
const shouldBeGoverned = !!(index !== 0 && governance)
const [form, setForm] = useState<CreatePoolForm>()
const [formErrors, setFormErrors] = useState({})
const { handleSetInstructions } = useContext(NewProposalContext)

const schema = yup.object().shape({
governedAccount: yup
.object()
.nullable()
.required('Governed account is required'),
tokenAMint: yup.string().required('Token A mint is required'),
tokenBMint: yup.string().required('Token B mint is required'),
fee: yup
.number()
.min(0, 'Fee must be positive')
.max(100, 'Fee must be less than 100')
.required('Fee is required'),
})

async function getInstruction(): Promise<UiInstruction> {
const isValid = await validateInstruction({ schema, form, setFormErrors })
let serializedInstruction = ''

if (
isValid &&
form?.governedAccount?.governance?.account &&
wallet?.publicKey &&
meteoraClient
) {
const createPoolIx = await meteoraClient.createPool({
tokenAMint: new PublicKey(form.tokenAMint),
tokenBMint: new PublicKey(form.tokenBMint),
authority: wallet.publicKey,
fee: form.fee,
})

serializedInstruction = serializeInstructionToBase64(createPoolIx)
}

return {
serializedInstruction,
isValid,
governance: form?.governedAccount?.governance,
}
}

const inputs: InstructionInput[] = [
{
label: 'Governance',
initialValue: null,
name: 'governedAccount',
type: InstructionInputType.GOVERNED_ACCOUNT,
shouldBeGoverned,
governance,
options: assetAccounts,
},
{
label: 'Token A Mint',
initialValue: '',
name: 'tokenAMint',
type: InstructionInputType.INPUT,
inputType: 'text',
},
{
label: 'Token B Mint',
initialValue: '',
name: 'tokenBMint',
type: InstructionInputType.INPUT,
inputType: 'text',
},
{
label: 'Fee (%)',
initialValue: 0,
name: 'fee',
type: InstructionInputType.INPUT,
inputType: 'number',
min: 0,
max: 100,
},
]

useEffect(() => {
handleSetInstructions(
{
governedAccount: form?.governedAccount?.governance,
getInstruction,
},
index
)
}, [form, handleSetInstructions, index])

return (
<InstructionForm
outerForm={form}
setForm={setForm}
inputs={inputs}
setFormErrors={setFormErrors}
formErrors={formErrors}
/>
)
}

export default CreateMeteoraPool
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/**
* The following code fixes the errors by retrieving the mint info for each token
* and passing it to getMintDecimalAmountFromNatural instead of a PublicKey.
*/

// Start of Selection
import { Connection } from '@solana/web3.js'
import { AccountMetaData } from '@solana/spl-governance'
import { tryGetTokenAccount, tryGetMint } from '@utils/tokens'
import { getMintDecimalAmountFromNatural } from '@tools/sdk/units'

export const METEORA_INSTRUCTIONS = {
'M3mxk5W2tt27WGZWpZR7hUpV7c5Hqm8GfwUtbyLJGrj1': {
// Create Pool instruction
1: {
name: 'Create Liquidity Pool',
accounts: [
{ name: 'Token A Mint' },
{ name: 'Token B Mint' },
{ name: 'Pool Authority' },
{ name: 'Fee Account' },
{ name: 'Pool State' },
{ name: 'Token Program' },
],
getDataUI: async (
connection: Connection,
data: Uint8Array,
accounts: AccountMetaData[]
) => {
const tokenAAccount = await tryGetTokenAccount(
connection,
accounts[0].pubkey
)
const tokenBAccount = await tryGetTokenAccount(
connection,
accounts[1].pubkey
)

const tokenAMintInfo = tokenAAccount?.account.mint
? await tryGetMint(connection, tokenAAccount.account.mint)
: null

const tokenBMintInfo = tokenBAccount?.account.mint
? await tryGetMint(connection, tokenBAccount.account.mint)
: null

return (
<div className="space-y-3">
<div>
<div className="font-bold">Token A:</div>
<div>
{tokenAAccount &&
tokenAMintInfo &&
getMintDecimalAmountFromNatural(
tokenAMintInfo.account,
tokenAAccount.account.amount
).toFormat()}
</div>
</div>
<div>
<div className="font-bold">Token B:</div>
<div>
{tokenBAccount &&
tokenBMintInfo &&
getMintDecimalAmountFromNatural(
tokenBMintInfo.account,
tokenBAccount.account.amount
).toFormat()}
</div>
</div>
</div>
)
},
},
},
}
2 changes: 2 additions & 0 deletions pages/dao/[symbol]/proposal/new.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ import SymmetryEditBasket from './components/instructions/Symmetry/SymmetryEditB
import SymmetryDeposit from './components/instructions/Symmetry/SymmetryDeposit'
import SymmetryWithdraw from './components/instructions/Symmetry/SymmetryWithdraw'
import PythUpdatePoolAuthority from './components/instructions/Pyth/PythUpdatePoolAuthority'
import CreateMeteoraPool from './components/instructions/Meteora/CreatePool'

const TITLE_LENGTH_LIMIT = 130
// the true length limit is either at the tx size level, and maybe also the total account size level (I can't remember)
Expand Down Expand Up @@ -608,6 +609,7 @@ const New = () => {
[Instructions.SymmetryEditBasket]: SymmetryEditBasket,
[Instructions.SymmetryDeposit]: SymmetryDeposit,
[Instructions.SymmetryWithdraw]: SymmetryWithdraw,
[Instructions.CreateMeteoraPool]: CreateMeteoraPool,
}),
[governance?.pubkey?.toBase58()]
)
Expand Down
Binary file removed public/realms/EpicentralDAO/EpicentralDAOBanner.png
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion public/realms/mainnet-beta.json
Original file line number Diff line number Diff line change
Expand Up @@ -3630,7 +3630,7 @@
{
"symbol": "LABS",
"category": "defi",
"bannerImage": "/realms/EpicentralDAO/EpicentralDAOBanner.png",
"bannerImage": "/realms/EpicentralDAO/EpicentralDAO_Banner_v2.png",
"displayName": "EpicentralDAO",
"programId": "GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw",
"realmId": "5PP7vKjJyLw1MR55LoexRsCj3CpZj9MdD6aNXRrvxG42",
Expand Down
9 changes: 8 additions & 1 deletion utils/uiTypes/proposalCreationTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export enum PackageEnum {
Squads,
Switchboard,
VsrPlugin,
Meteora,
}

export interface UiInstruction {
Expand Down Expand Up @@ -397,7 +398,8 @@ export enum Instructions {
SymmetryCreateBasket,
SymmetryEditBasket,
SymmetryDeposit,
SymmetryWithdraw
SymmetryWithdraw,
CreateMeteoraPool,
}

export interface ComponentInstructionData {
Expand Down Expand Up @@ -610,3 +612,8 @@ export interface SymmetryWithdrawForm {
withdrawAmount: number,
withdrawType: number
}

export interface CreateMeteoraPoolForm {
governedAccount?: AssetAccount
// Add other required fields for Meteora pool creation
}
Loading
Loading