Gov instruction creation helpers
- Add one to make a proposal for all serum markets - Switch created proposals to be drafts - Add PROPOSAL_LINK env arg - Add serum3EditMarketIx()
This commit is contained in:
parent
66bb74c2fd
commit
06da4768f3
|
@ -40,6 +40,7 @@ export const createProposal = async (
|
|||
proposalIndex: number,
|
||||
proposalInstructions: TransactionInstruction[],
|
||||
client: VsrClient,
|
||||
signOff: boolean,
|
||||
) => {
|
||||
const instructions: TransactionInstruction[] = [];
|
||||
const walletPk = wallet.publicKey!;
|
||||
|
@ -95,11 +96,6 @@ export const createProposal = async (
|
|||
payer,
|
||||
);
|
||||
|
||||
const signatoryRecordAddress = await getSignatoryRecordAddress(
|
||||
MANGO_GOVERNANCE_PROGRAM,
|
||||
proposalAddress,
|
||||
signatory,
|
||||
);
|
||||
const insertInstructions: TransactionInstruction[] = [];
|
||||
for (const i in proposalInstructions) {
|
||||
const instruction = getInstructionDataFromBase64(
|
||||
|
@ -120,17 +116,24 @@ export const createProposal = async (
|
|||
payer,
|
||||
);
|
||||
}
|
||||
withSignOffProposal(
|
||||
insertInstructions, // SingOff proposal needs to be executed after inserting instructions hence we add it to insertInstructions
|
||||
MANGO_GOVERNANCE_PROGRAM,
|
||||
programVersion,
|
||||
MANGO_REALM_PK,
|
||||
governance,
|
||||
proposalAddress,
|
||||
signatory,
|
||||
signatoryRecordAddress,
|
||||
undefined,
|
||||
);
|
||||
if (signOff) {
|
||||
const signatoryRecordAddress = await getSignatoryRecordAddress(
|
||||
MANGO_GOVERNANCE_PROGRAM,
|
||||
proposalAddress,
|
||||
signatory,
|
||||
);
|
||||
withSignOffProposal(
|
||||
insertInstructions, // SingOff proposal needs to be executed after inserting instructions hence we add it to insertInstructions
|
||||
MANGO_GOVERNANCE_PROGRAM,
|
||||
programVersion,
|
||||
MANGO_REALM_PK,
|
||||
governance,
|
||||
proposalAddress,
|
||||
signatory,
|
||||
signatoryRecordAddress,
|
||||
undefined,
|
||||
);
|
||||
}
|
||||
|
||||
const txChunks = chunk([...instructions, ...insertInstructions], 2);
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ import {
|
|||
const {
|
||||
MB_CLUSTER_URL,
|
||||
PROPOSAL_TITLE,
|
||||
PROPOSAL_LINK,
|
||||
VSR_DELEGATE_KEYPAIR,
|
||||
VSR_DELEGATE_FROM_PK,
|
||||
DRY_RUN,
|
||||
|
@ -285,10 +286,11 @@ async function updateTokenParams(): Promise<void> {
|
|||
MANGO_DAO_WALLET_GOVERNANCE,
|
||||
tokenOwnerRecord,
|
||||
PROPOSAL_TITLE ? PROPOSAL_TITLE : 'Update risk parameters for tokens',
|
||||
'',
|
||||
PROPOSAL_LINK ?? '',
|
||||
Object.values(proposals).length,
|
||||
instructions,
|
||||
vsrClient!,
|
||||
false,
|
||||
);
|
||||
console.log(proposalAddress.toBase58());
|
||||
}
|
||||
|
|
|
@ -0,0 +1,153 @@
|
|||
import {
|
||||
MidPriceImpact,
|
||||
getMidPriceImpacts,
|
||||
} from '@blockworks-foundation/mango-v4-settings/lib/helpers/listingTools';
|
||||
import { AnchorProvider, Wallet } from '@coral-xyz/anchor';
|
||||
import { BN } from '@project-serum/anchor';
|
||||
import {
|
||||
getAllProposals,
|
||||
getTokenOwnerRecord,
|
||||
getTokenOwnerRecordAddress,
|
||||
} from '@solana/spl-governance';
|
||||
import {
|
||||
AccountMeta,
|
||||
Connection,
|
||||
Keypair,
|
||||
PublicKey,
|
||||
Transaction,
|
||||
TransactionInstruction,
|
||||
} from '@solana/web3.js';
|
||||
import fs from 'fs';
|
||||
import { Bank } from '../src/accounts/bank';
|
||||
import { Group } from '../src/accounts/group';
|
||||
import { MangoAccount } from '../src/accounts/mangoAccount';
|
||||
import { Builder } from '../src/builder';
|
||||
import { MangoClient } from '../src/client';
|
||||
import { NullTokenEditParams } from '../src/clientIxParamBuilder';
|
||||
import { MANGO_V4_MAIN_GROUP as MANGO_V4_PRIMARY_GROUP } from '../src/constants';
|
||||
import { getEquityForMangoAccounts } from '../src/risk';
|
||||
import { buildFetch } from '../src/utils';
|
||||
import {
|
||||
MANGO_DAO_WALLET_GOVERNANCE,
|
||||
MANGO_GOVERNANCE_PROGRAM,
|
||||
MANGO_MINT,
|
||||
MANGO_REALM_PK,
|
||||
} from './governanceInstructions/constants';
|
||||
import { createProposal } from './governanceInstructions/createProposal';
|
||||
import {
|
||||
DEFAULT_VSR_ID,
|
||||
VsrClient,
|
||||
} from './governanceInstructions/voteStakeRegistryClient';
|
||||
|
||||
const {
|
||||
MB_CLUSTER_URL,
|
||||
PROPOSAL_TITLE,
|
||||
PROPOSAL_LINK,
|
||||
VSR_DELEGATE_KEYPAIR,
|
||||
VSR_DELEGATE_FROM_PK,
|
||||
DRY_RUN,
|
||||
} = process.env;
|
||||
|
||||
async function buildClient(): Promise<MangoClient> {
|
||||
return await MangoClient.connectDefault(MB_CLUSTER_URL!);
|
||||
}
|
||||
|
||||
async function setupWallet(): Promise<Wallet> {
|
||||
const clientKeypair = Keypair.fromSecretKey(
|
||||
Buffer.from(JSON.parse(fs.readFileSync(VSR_DELEGATE_KEYPAIR!, 'utf-8'))),
|
||||
);
|
||||
const clientWallet = new Wallet(clientKeypair);
|
||||
|
||||
return clientWallet;
|
||||
}
|
||||
|
||||
async function setupVsr(
|
||||
connection: Connection,
|
||||
clientWallet: Wallet,
|
||||
): Promise<VsrClient> {
|
||||
const options = AnchorProvider.defaultOptions();
|
||||
const provider = new AnchorProvider(connection, clientWallet, options);
|
||||
const vsrClient = await VsrClient.connect(provider, DEFAULT_VSR_ID);
|
||||
return vsrClient;
|
||||
}
|
||||
|
||||
async function updateSerumMarketParams(): Promise<void> {
|
||||
const [client, wallet] = await Promise.all([buildClient(), setupWallet()]);
|
||||
const vsrClient = await setupVsr(client.connection, wallet);
|
||||
|
||||
const group = await client.getGroup(MANGO_V4_PRIMARY_GROUP);
|
||||
|
||||
const instructions: TransactionInstruction[] = [];
|
||||
|
||||
Array.from(group.serum3MarketsMapByMarketIndex.values()).forEach(
|
||||
async (sm) => {
|
||||
const ix = await client.serum3EditMarketIx(
|
||||
group,
|
||||
sm.marketIndex,
|
||||
group.admin,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
0.5,
|
||||
);
|
||||
|
||||
const tx = new Transaction({ feePayer: wallet.publicKey }).add(ix);
|
||||
const simulated = await client.connection.simulateTransaction(tx);
|
||||
|
||||
if (simulated.value.err) {
|
||||
console.log('error', simulated.value.logs);
|
||||
throw simulated.value.logs;
|
||||
}
|
||||
|
||||
instructions.push(ix);
|
||||
},
|
||||
);
|
||||
|
||||
const tokenOwnerRecordPk = await getTokenOwnerRecordAddress(
|
||||
MANGO_GOVERNANCE_PROGRAM,
|
||||
MANGO_REALM_PK,
|
||||
MANGO_MINT,
|
||||
new PublicKey(VSR_DELEGATE_FROM_PK!),
|
||||
);
|
||||
|
||||
const [tokenOwnerRecord, proposals] = await Promise.all([
|
||||
getTokenOwnerRecord(client.connection, tokenOwnerRecordPk),
|
||||
getAllProposals(
|
||||
client.connection,
|
||||
MANGO_GOVERNANCE_PROGRAM,
|
||||
MANGO_REALM_PK,
|
||||
),
|
||||
]);
|
||||
|
||||
const walletSigner = wallet as never;
|
||||
|
||||
if (!DRY_RUN) {
|
||||
const proposalAddress = await createProposal(
|
||||
client.connection,
|
||||
walletSigner,
|
||||
MANGO_DAO_WALLET_GOVERNANCE,
|
||||
tokenOwnerRecord,
|
||||
PROPOSAL_TITLE ? PROPOSAL_TITLE : 'Update risk parameters for tokens',
|
||||
PROPOSAL_LINK ?? '',
|
||||
Object.values(proposals).length,
|
||||
instructions,
|
||||
vsrClient!,
|
||||
false,
|
||||
);
|
||||
console.log(proposalAddress.toBase58());
|
||||
}
|
||||
}
|
||||
|
||||
async function main(): Promise<void> {
|
||||
try {
|
||||
await updateSerumMarketParams();
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
main();
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
import {
|
||||
AnchorProvider,
|
||||
BN,
|
||||
Instruction,
|
||||
Program,
|
||||
Provider,
|
||||
Wallet,
|
||||
|
@ -1634,6 +1635,28 @@ export class MangoClient {
|
|||
return await this.sendAndConfirmTransactionForGroup(group, [ix]);
|
||||
}
|
||||
|
||||
public async serum3EditMarketIx(
|
||||
group: Group,
|
||||
serum3MarketIndex: MarketIndex,
|
||||
admin: PublicKey,
|
||||
reduceOnly: boolean | null,
|
||||
forceClose: boolean | null,
|
||||
name: string | null,
|
||||
oraclePriceBand: number | null,
|
||||
): Promise<TransactionInstruction> {
|
||||
const serum3Market =
|
||||
group.serum3MarketsMapByMarketIndex.get(serum3MarketIndex);
|
||||
const ix = await this.program.methods
|
||||
.serum3EditMarket(reduceOnly, forceClose, name, oraclePriceBand)
|
||||
.accounts({
|
||||
group: group.publicKey,
|
||||
admin: admin,
|
||||
market: serum3Market?.publicKey,
|
||||
})
|
||||
.instruction();
|
||||
return ix;
|
||||
}
|
||||
|
||||
public async serum3EditMarket(
|
||||
group: Group,
|
||||
serum3MarketIndex: MarketIndex,
|
||||
|
@ -1642,16 +1665,16 @@ export class MangoClient {
|
|||
name: string | null,
|
||||
oraclePriceBand: number | null,
|
||||
): Promise<MangoSignatureStatus> {
|
||||
const serum3Market =
|
||||
group.serum3MarketsMapByMarketIndex.get(serum3MarketIndex);
|
||||
const ix = await this.program.methods
|
||||
.serum3EditMarket(reduceOnly, forceClose, name, oraclePriceBand)
|
||||
.accounts({
|
||||
group: group.publicKey,
|
||||
admin: (this.program.provider as AnchorProvider).wallet.publicKey,
|
||||
market: serum3Market?.publicKey,
|
||||
})
|
||||
.instruction();
|
||||
const admin = (this.program.provider as AnchorProvider).wallet.publicKey;
|
||||
const ix = await this.serum3EditMarketIx(
|
||||
group,
|
||||
serum3MarketIndex,
|
||||
admin,
|
||||
reduceOnly,
|
||||
forceClose,
|
||||
name,
|
||||
oraclePriceBand,
|
||||
);
|
||||
return await this.sendAndConfirmTransactionForGroup(group, [ix]);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue