add borrowAndWithdraw function
This commit is contained in:
parent
9c539e7945
commit
a203b31eab
111
src/client.ts
111
src/client.ts
|
@ -40,9 +40,11 @@ import { SRM_DECIMALS } from '@project-serum/serum/lib/token-instructions';
|
|||
import { Order } from '@project-serum/serum/lib/market';
|
||||
import Wallet from '@project-serum/sol-wallet-adapter';
|
||||
import {
|
||||
makeBorrowInstruction,
|
||||
makeCancelOrderInstruction,
|
||||
makeForceCancelOrdersInstruction, makePartialLiquidateInstruction,
|
||||
makeSettleFundsInstruction,
|
||||
makeWithdrawInstruction,
|
||||
} from './instruction';
|
||||
import { Aggregator } from './schema';
|
||||
import { TOKEN_PROGRAM_ID } from '@solana/spl-token';
|
||||
|
@ -574,22 +576,18 @@ export class MangoClient {
|
|||
const tokenIndex = mangoGroup.getTokenIndex(token)
|
||||
const nativeQuantity = uiToNative(quantity, mangoGroup.mintDecimals[tokenIndex])
|
||||
|
||||
const keys = [
|
||||
{ isSigner: false, isWritable: true, pubkey: mangoGroup.publicKey},
|
||||
{ isSigner: false, isWritable: true, pubkey: marginAccount.publicKey },
|
||||
{ isSigner: true, isWritable: false, pubkey: owner.publicKey },
|
||||
{ isSigner: false, isWritable: true, pubkey: tokenAcc },
|
||||
{ isSigner: false, isWritable: true, pubkey: mangoGroup.vaults[tokenIndex] },
|
||||
{ isSigner: false, isWritable: false, pubkey: mangoGroup.signerKey },
|
||||
{ isSigner: false, isWritable: false, pubkey: TOKEN_PROGRAM_ID },
|
||||
{ isSigner: false, isWritable: false, pubkey: SYSVAR_CLOCK_PUBKEY },
|
||||
...marginAccount.openOrders.map( (pubkey) => ( { isSigner: false, isWritable: false, pubkey })),
|
||||
...mangoGroup.oracles.map( (pubkey) => ( { isSigner: false, isWritable: false, pubkey }))
|
||||
]
|
||||
const data = encodeMangoInstruction({Withdraw: {quantity: nativeQuantity}})
|
||||
|
||||
|
||||
const instruction = new TransactionInstruction( { keys, data, programId })
|
||||
const instruction = makeWithdrawInstruction(
|
||||
programId,
|
||||
mangoGroup.publicKey,
|
||||
marginAccount.publicKey,
|
||||
owner.publicKey,
|
||||
mangoGroup.signerKey,
|
||||
tokenAcc,
|
||||
mangoGroup.vaults[tokenIndex],
|
||||
marginAccount.openOrders,
|
||||
mangoGroup.oracles,
|
||||
nativeQuantity,
|
||||
);
|
||||
|
||||
const transaction = new Transaction()
|
||||
transaction.add(instruction)
|
||||
|
@ -611,18 +609,16 @@ export class MangoClient {
|
|||
const tokenIndex = mangoGroup.getTokenIndex(token)
|
||||
const nativeQuantity = uiToNative(quantity, mangoGroup.mintDecimals[tokenIndex])
|
||||
|
||||
const keys = [
|
||||
{ isSigner: false, isWritable: true, pubkey: mangoGroup.publicKey},
|
||||
{ isSigner: false, isWritable: true, pubkey: marginAccount.publicKey },
|
||||
{ isSigner: true, isWritable: false, pubkey: owner.publicKey },
|
||||
{ isSigner: false, isWritable: false, pubkey: SYSVAR_CLOCK_PUBKEY },
|
||||
...marginAccount.openOrders.map( (pubkey) => ( { isSigner: false, isWritable: false, pubkey })),
|
||||
...mangoGroup.oracles.map( (pubkey) => ( { isSigner: false, isWritable: false, pubkey })),
|
||||
]
|
||||
const data = encodeMangoInstruction({Borrow: {tokenIndex: new BN(tokenIndex), quantity: nativeQuantity}})
|
||||
|
||||
|
||||
const instruction = new TransactionInstruction( { keys, data, programId })
|
||||
const instruction = makeBorrowInstruction(
|
||||
programId,
|
||||
mangoGroup.publicKey,
|
||||
marginAccount.publicKey,
|
||||
owner.publicKey,
|
||||
tokenIndex,
|
||||
marginAccount.openOrders,
|
||||
mangoGroup.oracles,
|
||||
nativeQuantity,
|
||||
);
|
||||
|
||||
const transaction = new Transaction()
|
||||
transaction.add(instruction)
|
||||
|
@ -631,6 +627,65 @@ export class MangoClient {
|
|||
return await this.sendTransaction(connection, transaction, owner, additionalSigners)
|
||||
}
|
||||
|
||||
async borrowAndWithdraw(
|
||||
connection: Connection,
|
||||
programId: PublicKey,
|
||||
mangoGroup: MangoGroup,
|
||||
marginAccount: MarginAccount,
|
||||
wallet: Wallet | Account,
|
||||
token: PublicKey,
|
||||
tokenAcc: PublicKey,
|
||||
|
||||
withdrawQuantity: number
|
||||
): Promise<TransactionSignature> {
|
||||
const transaction = new Transaction()
|
||||
const tokenIndex = mangoGroup.getTokenIndex(token)
|
||||
const tokenBalance = marginAccount.getUiDeposit(mangoGroup, tokenIndex)
|
||||
const borrowQuantity = withdrawQuantity - tokenBalance
|
||||
|
||||
const nativeBorrowQuantity = uiToNative(
|
||||
borrowQuantity,
|
||||
mangoGroup.mintDecimals[tokenIndex]
|
||||
)
|
||||
|
||||
const borrowInstruction = makeBorrowInstruction(
|
||||
programId,
|
||||
mangoGroup.publicKey,
|
||||
marginAccount.publicKey,
|
||||
wallet.publicKey,
|
||||
tokenIndex,
|
||||
marginAccount.openOrders,
|
||||
mangoGroup.oracles,
|
||||
nativeBorrowQuantity,
|
||||
);
|
||||
transaction.add(borrowInstruction);
|
||||
|
||||
// uiToNative() uses Math.round resulting in rounding
|
||||
// errors, so we use Math.floor here instead
|
||||
const nativeWithdrawQuantity = new BN(
|
||||
Math.floor(
|
||||
withdrawQuantity * Math.pow(10, mangoGroup.mintDecimals[tokenIndex]),
|
||||
) * 0.98,
|
||||
);
|
||||
|
||||
const withdrawInstruction = makeWithdrawInstruction(
|
||||
programId,
|
||||
mangoGroup.publicKey,
|
||||
marginAccount.publicKey,
|
||||
wallet.publicKey,
|
||||
mangoGroup.signerKey,
|
||||
tokenAcc,
|
||||
mangoGroup.vaults[tokenIndex],
|
||||
marginAccount.openOrders,
|
||||
mangoGroup.oracles,
|
||||
nativeWithdrawQuantity,
|
||||
);
|
||||
transaction.add(withdrawInstruction);
|
||||
|
||||
const signers = []
|
||||
return await this.sendTransaction(connection, transaction, wallet, signers)
|
||||
}
|
||||
|
||||
async settleBorrow(
|
||||
connection: Connection,
|
||||
programId: PublicKey,
|
||||
|
|
|
@ -115,6 +115,85 @@ export function makeSettleFundsInstruction(
|
|||
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,
|
||||
|
@ -153,9 +232,8 @@ export function makeForceCancelOrdersInstruction(
|
|||
dexProgramId: PublicKey,
|
||||
openOrders: PublicKey[],
|
||||
oracles: PublicKey[],
|
||||
limit: BN
|
||||
limit: BN,
|
||||
): TransactionInstruction {
|
||||
|
||||
const keys = [
|
||||
{ isSigner: false, isWritable: true, pubkey: mangoGroup },
|
||||
{ isSigner: true, isWritable: false, pubkey: liqor },
|
||||
|
@ -173,12 +251,20 @@ export function makeForceCancelOrdersInstruction(
|
|||
{ 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 })),
|
||||
]
|
||||
...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 })
|
||||
const data = encodeMangoInstruction({ ForceCancelOrders: { limit } });
|
||||
return new TransactionInstruction({ keys, data, programId });
|
||||
}
|
||||
|
||||
export function makePartialLiquidateInstruction(
|
||||
|
@ -193,7 +279,7 @@ export function makePartialLiquidateInstruction(
|
|||
signerKey: PublicKey,
|
||||
openOrders: PublicKey[],
|
||||
oracles: PublicKey[],
|
||||
maxDeposit: BN
|
||||
maxDeposit: BN,
|
||||
): TransactionInstruction {
|
||||
const keys = [
|
||||
{ isSigner: false, isWritable: true, pubkey: mangoGroup },
|
||||
|
@ -206,10 +292,18 @@ export function makePartialLiquidateInstruction(
|
|||
{ 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 }})
|
||||
...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 })
|
||||
return new TransactionInstruction({ keys, data, programId });
|
||||
}
|
Loading…
Reference in New Issue