2021-02-22 14:36:45 -08:00
|
|
|
import BN from 'bn.js';
|
2021-02-22 19:36:17 -08:00
|
|
|
import {
|
|
|
|
PublicKey,
|
|
|
|
SYSVAR_CLOCK_PUBKEY,
|
|
|
|
TransactionInstruction,
|
|
|
|
} from '@solana/web3.js';
|
2021-02-19 06:33:11 -08:00
|
|
|
import { Order } from '@project-serum/serum/lib/market';
|
2021-04-06 13:43:00 -07:00
|
|
|
import { encodeMangoInstruction, NUM_TOKENS } from './layout';
|
2021-02-19 06:56:16 -08:00
|
|
|
import { TOKEN_PROGRAM_ID } from '@project-serum/serum/lib/token-instructions';
|
2021-02-22 19:36:17 -08:00
|
|
|
import { uiToNative } from './utils';
|
2021-02-21 15:27:48 -08:00
|
|
|
|
|
|
|
// 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 },
|
|
|
|
// ]
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// }
|
2021-02-19 06:33:11 -08:00
|
|
|
|
|
|
|
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,
|
2021-02-22 14:30:08 -08:00
|
|
|
order: Order,
|
2021-02-19 06:33:11 -08:00
|
|
|
): TransactionInstruction {
|
|
|
|
const keys = [
|
2021-02-22 14:30:08 -08:00
|
|
|
{ isSigner: false, isWritable: true, pubkey: mangoGroupPk },
|
|
|
|
{ isSigner: true, isWritable: false, pubkey: ownerPk },
|
|
|
|
{ isSigner: false, isWritable: true, pubkey: marginAccountPk },
|
2021-02-19 06:33:11 -08:00
|
|
|
{ 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 },
|
2021-02-22 14:30:08 -08:00
|
|
|
];
|
2021-02-19 06:33:11 -08:00
|
|
|
|
|
|
|
const data = encodeMangoInstruction({
|
|
|
|
CancelOrder: {
|
|
|
|
side: order.side,
|
|
|
|
orderId: order.orderId,
|
2021-02-22 14:30:08 -08:00
|
|
|
},
|
|
|
|
});
|
|
|
|
return new TransactionInstruction({ keys, data, programId });
|
2021-02-19 06:56:16 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
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 = [
|
2021-02-22 14:30:08 -08:00
|
|
|
{ isSigner: false, isWritable: true, pubkey: mangoGroupPk },
|
|
|
|
{ isSigner: true, isWritable: false, pubkey: ownerPk },
|
|
|
|
{ isSigner: false, isWritable: true, pubkey: marginAccountPk },
|
2021-02-19 06:56:16 -08:00
|
|
|
{ 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 },
|
2021-02-22 14:30:08 -08:00
|
|
|
];
|
|
|
|
const data = encodeMangoInstruction({ SettleFunds: {} });
|
|
|
|
|
|
|
|
return new TransactionInstruction({ keys, data, programId });
|
|
|
|
}
|
2021-02-19 06:56:16 -08:00
|
|
|
|
2021-04-20 11:10:16 -07:00
|
|
|
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,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2021-02-22 14:30:08 -08:00
|
|
|
export function makeSettleBorrowInstruction(
|
|
|
|
programId: PublicKey,
|
|
|
|
mangoGroupPk: PublicKey,
|
|
|
|
marginAccountPk: PublicKey,
|
|
|
|
walletPk: PublicKey,
|
|
|
|
tokenIndex: number,
|
2021-02-22 19:36:17 -08:00
|
|
|
nativeQuantity: BN,
|
2021-02-22 14:30:08 -08:00
|
|
|
): 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({
|
2021-02-24 18:14:23 -08:00
|
|
|
SettleBorrow: { tokenIndex: new BN(tokenIndex), quantity: nativeQuantity },
|
2021-02-22 14:30:08 -08:00
|
|
|
});
|
|
|
|
return new TransactionInstruction({ keys, data, programId });
|
|
|
|
}
|
2021-04-06 13:43:00 -07:00
|
|
|
|
|
|
|
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[],
|
2021-04-08 07:15:52 -07:00
|
|
|
oracles: PublicKey[],
|
2021-04-20 11:10:16 -07:00
|
|
|
limit: BN,
|
2021-04-06 13:43:00 -07:00
|
|
|
): TransactionInstruction {
|
|
|
|
const keys = [
|
2021-04-20 11:10:16 -07:00
|
|
|
{ isSigner: false, isWritable: true, pubkey: mangoGroup },
|
2021-04-06 13:43:00 -07:00
|
|
|
{ isSigner: true, isWritable: false, pubkey: liqor },
|
2021-04-20 11:10:16 -07:00
|
|
|
{ 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 },
|
2021-04-06 13:43:00 -07:00
|
|
|
{ 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 },
|
2021-04-20 11:10:16 -07:00
|
|
|
...openOrders.map((pubkey) => ({
|
|
|
|
isSigner: false,
|
|
|
|
isWritable: true,
|
|
|
|
pubkey,
|
|
|
|
})),
|
|
|
|
...oracles.map((pubkey) => ({
|
|
|
|
isSigner: false,
|
|
|
|
isWritable: false,
|
|
|
|
pubkey,
|
|
|
|
})),
|
|
|
|
];
|
2021-04-06 13:43:00 -07:00
|
|
|
|
2021-04-20 11:10:16 -07:00
|
|
|
const data = encodeMangoInstruction({ ForceCancelOrders: { limit } });
|
|
|
|
return new TransactionInstruction({ keys, data, programId });
|
2021-04-06 13:43:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
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[],
|
2021-04-20 11:10:16 -07:00
|
|
|
maxDeposit: BN,
|
2021-04-06 13:43:00 -07:00
|
|
|
): 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 },
|
2021-04-20 11:10:16 -07:00
|
|
|
{ isSigner: false, isWritable: true, pubkey: liqeeMarginAccount },
|
2021-04-06 13:43:00 -07:00
|
|
|
{ isSigner: false, isWritable: true, pubkey: inTokenVault },
|
|
|
|
{ isSigner: false, isWritable: true, pubkey: outTokenVault },
|
|
|
|
{ isSigner: false, isWritable: false, pubkey: signerKey },
|
2021-04-06 15:57:25 -07:00
|
|
|
{ isSigner: false, isWritable: false, pubkey: TOKEN_PROGRAM_ID },
|
2021-04-06 13:43:00 -07:00
|
|
|
{ isSigner: false, isWritable: false, pubkey: SYSVAR_CLOCK_PUBKEY },
|
2021-04-20 11:10:16 -07:00
|
|
|
...openOrders.map((pubkey) => ({
|
|
|
|
isSigner: false,
|
|
|
|
isWritable: false,
|
|
|
|
pubkey,
|
|
|
|
})),
|
|
|
|
...oracles.map((pubkey) => ({
|
|
|
|
isSigner: false,
|
|
|
|
isWritable: false,
|
|
|
|
pubkey,
|
|
|
|
})),
|
|
|
|
];
|
|
|
|
const data = encodeMangoInstruction({ PartialLiquidate: { maxDeposit } });
|
2021-04-06 13:43:00 -07:00
|
|
|
|
2021-04-20 11:10:16 -07:00
|
|
|
return new TransactionInstruction({ keys, data, programId });
|
|
|
|
}
|