mango-client-ts/src/instruction.ts

310 lines
10 KiB
TypeScript

import BN from 'bn.js';
import {
PublicKey,
SYSVAR_CLOCK_PUBKEY,
TransactionInstruction,
} from '@solana/web3.js';
import { Order } from '@project-serum/serum/lib/market';
import { encodeMangoInstruction, NUM_TOKENS } from './layout';
import { TOKEN_PROGRAM_ID } from '@project-serum/serum/lib/token-instructions';
import { uiToNative } from './utils';
// export function makeInitMangoGroupInstruction(
// programId: PublicKey,
// mangoGroupPk: PublicKey,
// signerKey: PublicKey,
// dexProgramId: PublicKey,
// srmVaultPk: PublicKey,
// mintPks: PublicKey[],
// vaultPks: PublicKey[],
// spotMarketPks: PublicKey[],
// oraclePks: PublicKey[],
// signerNonce: BN,
// maintCollRatio: number,
// initCollRatio: number
// ): TransactionInstruction {
//
// new BN()
// const keys = [
// { isSigner: false, isWritable: true, pubkey: mangoGroupPk},
// { isSigner: true, isWritable: false, pubkey: ownerPk },
// { isSigner: false, isWritable: true, pubkey: marginAccountPk },
// { isSigner: false, isWritable: false, pubkey: SYSVAR_CLOCK_PUBKEY },
// { isSigner: false, isWritable: false, pubkey: dexProgramId },
// { isSigner: false, isWritable: true, pubkey: spotMarketPk },
// { isSigner: false, isWritable: true, pubkey: bidsPk },
// { isSigner: false, isWritable: true, pubkey: asksPk },
// { isSigner: false, isWritable: true, pubkey: openOrdersPk },
// { isSigner: false, isWritable: false, pubkey: signerKey },
// { isSigner: false, isWritable: true, pubkey: eventQueuePk },
// ]
//
//
// }
export function makeCancelOrderInstruction(
programId: PublicKey,
mangoGroupPk: PublicKey,
ownerPk: PublicKey,
marginAccountPk: PublicKey,
dexProgramId: PublicKey,
spotMarketPk: PublicKey,
bidsPk: PublicKey,
asksPk: PublicKey,
openOrdersPk: PublicKey,
signerKey: PublicKey,
eventQueuePk: PublicKey,
order: Order,
): TransactionInstruction {
const keys = [
{ isSigner: false, isWritable: true, pubkey: mangoGroupPk },
{ isSigner: true, isWritable: false, pubkey: ownerPk },
{ isSigner: false, isWritable: true, pubkey: marginAccountPk },
{ isSigner: false, isWritable: false, pubkey: SYSVAR_CLOCK_PUBKEY },
{ isSigner: false, isWritable: false, pubkey: dexProgramId },
{ isSigner: false, isWritable: true, pubkey: spotMarketPk },
{ isSigner: false, isWritable: true, pubkey: bidsPk },
{ isSigner: false, isWritable: true, pubkey: asksPk },
{ isSigner: false, isWritable: true, pubkey: openOrdersPk },
{ isSigner: false, isWritable: false, pubkey: signerKey },
{ isSigner: false, isWritable: true, pubkey: eventQueuePk },
];
const data = encodeMangoInstruction({
CancelOrder: {
side: order.side,
orderId: order.orderId,
},
});
return new TransactionInstruction({ keys, data, programId });
}
export function makeSettleFundsInstruction(
programId: PublicKey,
mangoGroupPk: PublicKey,
ownerPk: PublicKey,
marginAccountPk: PublicKey,
dexProgramId: PublicKey,
spotMarketPk: PublicKey,
openOrdersPk: PublicKey,
signerKey: PublicKey,
spotMarketBaseVaultPk: PublicKey,
spotMarketQuoteVaultPk: PublicKey,
mangoBaseVaultPk: PublicKey,
mangoQuoteVaultPk: PublicKey,
dexSignerKey: PublicKey,
): TransactionInstruction {
const keys = [
{ isSigner: false, isWritable: true, pubkey: mangoGroupPk },
{ isSigner: true, isWritable: false, pubkey: ownerPk },
{ isSigner: false, isWritable: true, pubkey: marginAccountPk },
{ isSigner: false, isWritable: false, pubkey: SYSVAR_CLOCK_PUBKEY },
{ isSigner: false, isWritable: false, pubkey: dexProgramId },
{ isSigner: false, isWritable: true, pubkey: spotMarketPk },
{ isSigner: false, isWritable: true, pubkey: openOrdersPk },
{ isSigner: false, isWritable: false, pubkey: signerKey },
{ isSigner: false, isWritable: true, pubkey: spotMarketBaseVaultPk },
{ isSigner: false, isWritable: true, pubkey: spotMarketQuoteVaultPk },
{ isSigner: false, isWritable: true, pubkey: mangoBaseVaultPk },
{ isSigner: false, isWritable: true, pubkey: mangoQuoteVaultPk },
{ isSigner: false, isWritable: false, pubkey: dexSignerKey },
{ isSigner: false, isWritable: false, pubkey: TOKEN_PROGRAM_ID },
];
const data = encodeMangoInstruction({ SettleFunds: {} });
return new TransactionInstruction({ keys, data, programId });
}
export function makeBorrowInstruction(
programId: PublicKey,
mangoGroupPk: PublicKey,
marginAccountPk: PublicKey,
walletPk: PublicKey,
tokenIndex: number,
openOrders: PublicKey[],
oracles: PublicKey[],
nativeQuantity: BN,
): TransactionInstruction {
const borrowKeys = [
{ isSigner: false, isWritable: true, pubkey: mangoGroupPk },
{ isSigner: false, isWritable: true, pubkey: marginAccountPk },
{ isSigner: true, isWritable: false, pubkey: walletPk },
{ isSigner: false, isWritable: false, pubkey: SYSVAR_CLOCK_PUBKEY },
...openOrders.map((pubkey) => ({
isSigner: false,
isWritable: false,
pubkey,
})),
...oracles.map((pubkey) => ({
isSigner: false,
isWritable: false,
pubkey,
})),
];
const borrowData = encodeMangoInstruction({
Borrow: { tokenIndex: new BN(tokenIndex), quantity: nativeQuantity },
});
return new TransactionInstruction({
keys: borrowKeys,
data: borrowData,
programId,
});
}
export function makeWithdrawInstruction(
programId: PublicKey,
mangoGroupPk: PublicKey,
marginAccountPk: PublicKey,
walletPk: PublicKey,
signerKey: PublicKey,
tokenAccPk: PublicKey,
vaultPk: PublicKey,
openOrders: PublicKey[],
oracles: PublicKey[],
nativeQuantity: BN,
): TransactionInstruction {
const withdrawKeys = [
{ isSigner: false, isWritable: true, pubkey: mangoGroupPk },
{ isSigner: false, isWritable: true, pubkey: marginAccountPk },
{ isSigner: true, isWritable: false, pubkey: walletPk },
{ isSigner: false, isWritable: true, pubkey: tokenAccPk },
{ isSigner: false, isWritable: true, pubkey: vaultPk },
{ isSigner: false, isWritable: false, pubkey: signerKey },
{ isSigner: false, isWritable: false, pubkey: TOKEN_PROGRAM_ID },
{ isSigner: false, isWritable: false, pubkey: SYSVAR_CLOCK_PUBKEY },
...openOrders.map((pubkey) => ({
isSigner: false,
isWritable: false,
pubkey,
})),
...oracles.map((pubkey) => ({
isSigner: false,
isWritable: false,
pubkey,
})),
];
const withdrawData = encodeMangoInstruction({
Withdraw: { quantity: nativeQuantity },
});
return new TransactionInstruction({
keys: withdrawKeys,
data: withdrawData,
programId,
});
}
export function makeSettleBorrowInstruction(
programId: PublicKey,
mangoGroupPk: PublicKey,
marginAccountPk: PublicKey,
walletPk: PublicKey,
tokenIndex: number,
nativeQuantity: BN,
): TransactionInstruction {
const keys = [
{ isSigner: false, isWritable: true, pubkey: mangoGroupPk },
{ isSigner: false, isWritable: true, pubkey: marginAccountPk },
{ isSigner: true, isWritable: false, pubkey: walletPk },
{ isSigner: false, isWritable: false, pubkey: SYSVAR_CLOCK_PUBKEY },
];
const data = encodeMangoInstruction({
SettleBorrow: { tokenIndex: new BN(tokenIndex), quantity: nativeQuantity },
});
return new TransactionInstruction({ keys, data, programId });
}
export function makeForceCancelOrdersInstruction(
programId: PublicKey,
mangoGroup: PublicKey,
liqor: PublicKey,
liqeeMarginAccount: PublicKey,
baseVault: PublicKey,
quoteVault: PublicKey,
spotMarket: PublicKey,
bids: PublicKey,
asks: PublicKey,
signerKey: PublicKey,
dexEventQueue: PublicKey,
dexBaseVault: PublicKey,
dexQuoteVault: PublicKey,
dexSigner: PublicKey,
dexProgramId: PublicKey,
openOrders: PublicKey[],
oracles: PublicKey[],
limit: BN,
): TransactionInstruction {
const keys = [
{ isSigner: false, isWritable: true, pubkey: mangoGroup },
{ isSigner: true, isWritable: false, pubkey: liqor },
{ isSigner: false, isWritable: true, pubkey: liqeeMarginAccount },
{ isSigner: false, isWritable: true, pubkey: baseVault },
{ isSigner: false, isWritable: true, pubkey: quoteVault },
{ isSigner: false, isWritable: true, pubkey: spotMarket },
{ isSigner: false, isWritable: true, pubkey: bids },
{ isSigner: false, isWritable: true, pubkey: asks },
{ isSigner: false, isWritable: false, pubkey: signerKey },
{ isSigner: false, isWritable: true, pubkey: dexEventQueue },
{ isSigner: false, isWritable: true, pubkey: dexBaseVault },
{ isSigner: false, isWritable: true, pubkey: dexQuoteVault },
{ isSigner: false, isWritable: false, pubkey: dexSigner },
{ isSigner: false, isWritable: false, pubkey: TOKEN_PROGRAM_ID },
{ isSigner: false, isWritable: false, pubkey: dexProgramId },
{ isSigner: false, isWritable: false, pubkey: SYSVAR_CLOCK_PUBKEY },
...openOrders.map((pubkey) => ({
isSigner: false,
isWritable: true,
pubkey,
})),
...oracles.map((pubkey) => ({
isSigner: false,
isWritable: false,
pubkey,
})),
];
const data = encodeMangoInstruction({ ForceCancelOrders: { limit } });
return new TransactionInstruction({ keys, data, programId });
}
export function makePartialLiquidateInstruction(
programId: PublicKey,
mangoGroup: PublicKey,
liqor: PublicKey,
liqorInTokenWallet: PublicKey,
liqorOutTokenWallet: PublicKey,
liqeeMarginAccount: PublicKey,
inTokenVault: PublicKey,
outTokenVault: PublicKey,
signerKey: PublicKey,
openOrders: PublicKey[],
oracles: PublicKey[],
maxDeposit: BN,
): TransactionInstruction {
const keys = [
{ isSigner: false, isWritable: true, pubkey: mangoGroup },
{ isSigner: true, isWritable: false, pubkey: liqor },
{ isSigner: false, isWritable: true, pubkey: liqorInTokenWallet },
{ isSigner: false, isWritable: true, pubkey: liqorOutTokenWallet },
{ isSigner: false, isWritable: true, pubkey: liqeeMarginAccount },
{ isSigner: false, isWritable: true, pubkey: inTokenVault },
{ isSigner: false, isWritable: true, pubkey: outTokenVault },
{ isSigner: false, isWritable: false, pubkey: signerKey },
{ isSigner: false, isWritable: false, pubkey: TOKEN_PROGRAM_ID },
{ isSigner: false, isWritable: false, pubkey: SYSVAR_CLOCK_PUBKEY },
...openOrders.map((pubkey) => ({
isSigner: false,
isWritable: false,
pubkey,
})),
...oracles.map((pubkey) => ({
isSigner: false,
isWritable: false,
pubkey,
})),
];
const data = encodeMangoInstruction({ PartialLiquidate: { maxDeposit } });
return new TransactionInstruction({ keys, data, programId });
}