Merge pull request #8 from blockworks-foundation/partial_liq
Partial liq
This commit is contained in:
commit
5f4db748eb
|
@ -39,7 +39,11 @@ import { getFeeRates, getFeeTier, Market, OpenOrders, Orderbook } from '@project
|
|||
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 { makeCancelOrderInstruction, makeSettleFundsInstruction } from './instruction';
|
||||
import {
|
||||
makeCancelOrderInstruction,
|
||||
makeForceCancelOrdersInstruction, makePartialLiquidateInstruction,
|
||||
makeSettleFundsInstruction,
|
||||
} from './instruction';
|
||||
import { Aggregator } from './schema';
|
||||
import { TOKEN_PROGRAM_ID } from '@solana/spl-token';
|
||||
|
||||
|
@ -164,6 +168,8 @@ export class MarginAccount {
|
|||
owner!: PublicKey;
|
||||
deposits!: number[];
|
||||
borrows!: number[];
|
||||
beingLiquidated!: boolean;
|
||||
|
||||
openOrders!: PublicKey[];
|
||||
openOrdersAccounts: (OpenOrders | undefined)[] // undefined if an openOrdersAccount not yet initialized and has zeroKey
|
||||
// TODO keep updated with websocket
|
||||
|
@ -188,8 +194,6 @@ export class MarginAccount {
|
|||
return nativeToUi(this.getNativeBorrow(mangoGroup, tokenIndex), mangoGroup.mintDecimals[tokenIndex])
|
||||
}
|
||||
|
||||
|
||||
|
||||
async loadOpenOrders(
|
||||
connection: Connection,
|
||||
dexProgramId: PublicKey
|
||||
|
@ -399,6 +403,7 @@ export class MangoClient {
|
|||
const signers = [payer].concat(additionalSigners)
|
||||
transaction.sign(...signers)
|
||||
const rawTransaction = transaction.serialize()
|
||||
console.log('Transaction size:', rawTransaction.length)
|
||||
const startTime = getUnixTs();
|
||||
|
||||
const txid: TransactionSignature = await connection.sendRawTransaction(
|
||||
|
@ -772,10 +777,88 @@ export class MangoClient {
|
|||
...tokenAccs.map( (pubkey) => ( { isSigner: false, isWritable: true, pubkey })),
|
||||
]
|
||||
const data = encodeMangoInstruction({Liquidate: {depositQuantities: depositsBN}})
|
||||
|
||||
|
||||
const instruction = new TransactionInstruction( { keys, data, programId })
|
||||
const transaction = new Transaction()
|
||||
transaction.add(instruction)
|
||||
const additionalSigners = []
|
||||
|
||||
return await this.sendTransaction(connection, transaction, liqor, additionalSigners)
|
||||
}
|
||||
|
||||
async forceCancelOrders(
|
||||
connection: Connection,
|
||||
programId: PublicKey,
|
||||
mangoGroup: MangoGroup,
|
||||
liqeeMarginAccount: MarginAccount,
|
||||
liqor: Account,
|
||||
spotMarket: Market,
|
||||
limit: number
|
||||
): Promise<TransactionSignature> {
|
||||
|
||||
const limitBn = new BN(limit)
|
||||
const marketIndex = mangoGroup.getMarketIndex(spotMarket)
|
||||
const dexSigner = await PublicKey.createProgramAddress(
|
||||
[
|
||||
spotMarket.publicKey.toBuffer(),
|
||||
spotMarket['_decoded'].vaultSignerNonce.toArrayLike(Buffer, 'le', 8)
|
||||
],
|
||||
spotMarket.programId
|
||||
)
|
||||
|
||||
const instruction = makeForceCancelOrdersInstruction(
|
||||
programId,
|
||||
mangoGroup.publicKey,
|
||||
liqor.publicKey,
|
||||
liqeeMarginAccount.publicKey,
|
||||
mangoGroup.vaults[marketIndex],
|
||||
mangoGroup.vaults[NUM_TOKENS-1],
|
||||
spotMarket.publicKey,
|
||||
spotMarket.bidsAddress,
|
||||
spotMarket.asksAddress,
|
||||
mangoGroup.signerKey,
|
||||
spotMarket['_decoded'].eventQueue,
|
||||
spotMarket['_decoded'].baseVault,
|
||||
spotMarket['_decoded'].quoteVault,
|
||||
dexSigner,
|
||||
mangoGroup.dexProgramId,
|
||||
liqeeMarginAccount.openOrders,
|
||||
mangoGroup.oracles,
|
||||
limitBn
|
||||
)
|
||||
|
||||
const transaction = new Transaction()
|
||||
transaction.add(instruction)
|
||||
const additionalSigners = []
|
||||
return await this.sendTransaction(connection, transaction, liqor, additionalSigners)
|
||||
}
|
||||
|
||||
async partialLiquidate(
|
||||
connection: Connection,
|
||||
programId: PublicKey,
|
||||
mangoGroup: MangoGroup,
|
||||
liqeeMarginAccount: MarginAccount,
|
||||
liqor: Account,
|
||||
liqorInTokenWallet: PublicKey,
|
||||
liqorOutTokenWallet: PublicKey,
|
||||
inTokenIndex: number,
|
||||
outTokenIndex: number,
|
||||
maxDeposit: number
|
||||
): Promise<TransactionSignature> {
|
||||
const maxDepositBn: BN = uiToNative(maxDeposit, mangoGroup.mintDecimals[inTokenIndex])
|
||||
const instruction = makePartialLiquidateInstruction(
|
||||
programId,
|
||||
mangoGroup.publicKey,
|
||||
liqor.publicKey,
|
||||
liqorInTokenWallet,
|
||||
liqorOutTokenWallet,
|
||||
liqeeMarginAccount.publicKey,
|
||||
mangoGroup.vaults[inTokenIndex],
|
||||
mangoGroup.vaults[outTokenIndex],
|
||||
mangoGroup.signerKey,
|
||||
liqeeMarginAccount.openOrders,
|
||||
mangoGroup.oracles,
|
||||
maxDepositBn
|
||||
)
|
||||
const transaction = new Transaction()
|
||||
transaction.add(instruction)
|
||||
const additionalSigners = []
|
||||
|
|
204
src/index.ts
204
src/index.ts
|
@ -1,141 +1,87 @@
|
|||
import fs from 'fs';
|
||||
import { homedir } from 'os';
|
||||
import { MangoClient, MangoGroup } from './client';
|
||||
import IDS from './ids.json';
|
||||
import { Connection, PublicKey, Account } from '@solana/web3.js';
|
||||
import { nativeToUi } from './utils';
|
||||
import { Account, Connection, PublicKey } from '@solana/web3.js';
|
||||
|
||||
export { MangoClient, MangoGroup, MarginAccount, tokenToDecimals } from './client';
|
||||
export { MangoIndexLayout, MarginAccountLayout, MangoGroupLayout } from './layout';
|
||||
export * from './layout';
|
||||
export * from './utils'
|
||||
|
||||
export { IDS }
|
||||
|
||||
import { homedir } from 'os'
|
||||
import * as fs from 'fs';
|
||||
import { Aggregator } from './schema';
|
||||
import { nativeToUi, sleep, uiToNative } from './utils';
|
||||
import { NUM_MARKETS, NUM_TOKENS } from './layout';
|
||||
|
||||
export {
|
||||
MangoClient,
|
||||
MangoGroup,
|
||||
MarginAccount,
|
||||
tokenToDecimals,
|
||||
} from './client';
|
||||
export {
|
||||
MangoIndexLayout,
|
||||
MarginAccountLayout,
|
||||
MangoGroupLayout,
|
||||
} from './layout';
|
||||
export * from './layout';
|
||||
export * from './utils';
|
||||
|
||||
export { IDS };
|
||||
|
||||
// async function tests() {
|
||||
// const cluster = 'devnet';
|
||||
// const cluster = "mainnet-beta";
|
||||
// const client = new MangoClient();
|
||||
// const clusterIds = IDS[cluster];
|
||||
|
||||
// const connection = new Connection(IDS.cluster_urls[cluster], 'singleGossip');
|
||||
// const mangoGroupPk = new PublicKey(
|
||||
// clusterIds.mango_groups['BTC_ETH_USDT'].mango_group_pk,
|
||||
// );
|
||||
// const clusterIds = IDS[cluster]
|
||||
//
|
||||
// const connection = new Connection(IDS.cluster_urls[cluster], 'singleGossip')
|
||||
// const mangoGroupPk = new PublicKey(clusterIds.mango_groups['BTC_ETH_USDT'].mango_group_pk);
|
||||
// const mangoProgramId = new PublicKey(clusterIds.mango_program_id);
|
||||
|
||||
// const keyPairPath =
|
||||
// process.env.KEYPAIR || homedir() + '/.config/solana/id.json';
|
||||
// const payer = new Account(JSON.parse(fs.readFileSync(keyPairPath, 'utf-8')));
|
||||
|
||||
// async function testSolink() {
|
||||
|
||||
// const oraclePk = new PublicKey(IDS[cluster].oracles['ETH/USDT'])
|
||||
// const agg = await Aggregator.loadWithConnection(oraclePk, connection)
|
||||
|
||||
// // const agg = await Aggregator.loadWithConnection(oraclePk, connection)
|
||||
// console.log(agg.answer.median.toNumber(), agg.answer.updatedAt.toNumber(), agg.round.id.toNumber())
|
||||
|
||||
// }
|
||||
|
||||
// async function testDepositSrm() {
|
||||
// const srmVaultPk = new PublicKey(clusterIds['mango_groups']['BTC_ETH_USDT']['srm_vault_pk'])
|
||||
// const mangoGroup = await client.getMangoGroup(connection, mangoGroupPk, srmVaultPk)
|
||||
// const srmAccountPk = new PublicKey("6utvndL8EEjpwK5QVtguErncQEPVbkuyABmXu6FeygeV")
|
||||
// const mangoSrmAccountPk = await client.depositSrm(connection, mangoProgramId, mangoGroup, payer, srmAccountPk, 100)
|
||||
// console.log(mangoSrmAccountPk.toBase58())
|
||||
// await sleep(2000)
|
||||
// const mangoSrmAccount = await client.getMangoSrmAccount(connection, mangoSrmAccountPk)
|
||||
// const txid = await client.withdrawSrm(connection, mangoProgramId, mangoGroup, mangoSrmAccount, payer, srmAccountPk, 50)
|
||||
// console.log('success', txid)
|
||||
// }
|
||||
|
||||
// async function getMarginAccountDetails() {
|
||||
// const mangoGroup = await client.getMangoGroup(connection, mangoGroupPk);
|
||||
// const marginAccountPk = new PublicKey(
|
||||
// '5pmKq6D67vdUam6KMoMNa1euaqDCScqCehtcTyhC4Koh',
|
||||
// );
|
||||
|
||||
// console.log('ma:', mangoGroup.dexProgramId.toString());
|
||||
// const marginAccount = await client.getMarginAccount(
|
||||
// connection,
|
||||
// marginAccountPk,
|
||||
// mangoGroup.dexProgramId,
|
||||
// );
|
||||
// const prices = await mangoGroup.getPrices(connection);
|
||||
|
||||
// console.log(marginAccount.toPrettyString(mangoGroup, prices));
|
||||
|
||||
// for (let i = 0; i < NUM_TOKENS; i++) {
|
||||
// console.log(
|
||||
// i,
|
||||
// marginAccount.getUiDeposit(mangoGroup, i),
|
||||
// marginAccount.getUiBorrow(mangoGroup, i),
|
||||
// );
|
||||
//
|
||||
// const keyPairPath = process.env.KEYPAIR || homedir() + '/.config/solana/id.json'
|
||||
// const payer = new Account(JSON.parse(fs.readFileSync(keyPairPath, 'utf-8')))
|
||||
//
|
||||
//
|
||||
// async function testSolink() {
|
||||
//
|
||||
// const oraclePk = new PublicKey(IDS[cluster].oracles['ETH/USDT'])
|
||||
// const agg = await Aggregator.loadWithConnection(oraclePk, connection)
|
||||
//
|
||||
// // const agg = await Aggregator.loadWithConnection(oraclePk, connection)
|
||||
// console.log(agg.answer.median.toNumber(), agg.answer.updatedAt.toNumber(), agg.round.id.toNumber())
|
||||
//
|
||||
// }
|
||||
// for (let i = 0; i < NUM_MARKETS; i++) {
|
||||
// let openOrdersAccount = marginAccount.openOrdersAccounts[i];
|
||||
// if (openOrdersAccount === undefined) {
|
||||
// continue;
|
||||
//
|
||||
// async function testDepositSrm() {
|
||||
// const srmVaultPk = new PublicKey(clusterIds['mango_groups']['BTC_ETH_USDT']['srm_vault_pk'])
|
||||
// const mangoGroup = await client.getMangoGroup(connection, mangoGroupPk, srmVaultPk)
|
||||
// const srmAccountPk = new PublicKey("6utvndL8EEjpwK5QVtguErncQEPVbkuyABmXu6FeygeV")
|
||||
// const mangoSrmAccountPk = await client.depositSrm(connection, mangoProgramId, mangoGroup, payer, srmAccountPk, 100)
|
||||
// console.log(mangoSrmAccountPk.toBase58())
|
||||
// await sleep(2000)
|
||||
// const mangoSrmAccount = await client.getMangoSrmAccount(connection, mangoSrmAccountPk)
|
||||
// const txid = await client.withdrawSrm(connection, mangoProgramId, mangoGroup, mangoSrmAccount, payer, srmAccountPk, 50)
|
||||
// console.log('success', txid)
|
||||
// }
|
||||
//
|
||||
// async function getMarginAccountDetails() {
|
||||
// const mangoGroup = await client.getMangoGroup(connection, mangoGroupPk);
|
||||
// const marginAccountPk = new PublicKey("BSFaizvArm1dpVGwJvrsqbWTpT8nh3xD7ERrdHuaY1C1")
|
||||
// const marginAccount = await client.getMarginAccount(connection, marginAccountPk, mangoGroup.dexProgramId)
|
||||
// const prices = await mangoGroup.getPrices(connection)
|
||||
//
|
||||
// console.log(marginAccount.toPrettyString(mangoGroup, prices))
|
||||
//
|
||||
// for (let i = 0; i < NUM_MARKETS; i++) {
|
||||
// let openOrdersAccount = marginAccount.openOrdersAccounts[i]
|
||||
// if (openOrdersAccount === undefined) {
|
||||
// continue
|
||||
// }
|
||||
//
|
||||
// for (const oid of openOrdersAccount.orders) {
|
||||
// console.log(oid.toString())
|
||||
// }
|
||||
// console.log(i,
|
||||
// nativeToUi(openOrdersAccount.quoteTokenTotal.toNumber(), mangoGroup.mintDecimals[NUM_MARKETS]),
|
||||
// nativeToUi(openOrdersAccount.quoteTokenFree.toNumber(), mangoGroup.mintDecimals[NUM_MARKETS]),
|
||||
//
|
||||
// nativeToUi(openOrdersAccount.baseTokenTotal.toNumber(), mangoGroup.mintDecimals[i]),
|
||||
// nativeToUi(openOrdersAccount.baseTokenFree.toNumber(), mangoGroup.mintDecimals[i])
|
||||
//
|
||||
// )
|
||||
// }
|
||||
|
||||
// console.log(
|
||||
// i,
|
||||
// nativeToUi(
|
||||
// openOrdersAccount.quoteTokenTotal.toNumber(),
|
||||
// mangoGroup.mintDecimals[NUM_MARKETS],
|
||||
// ),
|
||||
// nativeToUi(
|
||||
// openOrdersAccount.baseTokenTotal.toNumber(),
|
||||
// mangoGroup.mintDecimals[i],
|
||||
// ),
|
||||
// );
|
||||
//
|
||||
// }
|
||||
// await getMarginAccountDetails()
|
||||
// // await testSolink()
|
||||
// // testDepositSrm()
|
||||
// }
|
||||
|
||||
// async function testDeposit() {
|
||||
// const mangoGroup = await client.getMangoGroup(connection, mangoGroupPk);
|
||||
// const marginAccountPk = new PublicKey(
|
||||
// '5pmKq6D67vdUam6KMoMNa1euaqDCScqCehtcTyhC4Koh',
|
||||
// );
|
||||
|
||||
// const marginAccount = await client.getMarginAccount(
|
||||
// connection,
|
||||
// marginAccountPk,
|
||||
// mangoGroup.dexProgramId,
|
||||
// );
|
||||
|
||||
// console.log('starting deposit');
|
||||
// try {
|
||||
// await client.deposit(
|
||||
// connection,
|
||||
// mangoProgramId,
|
||||
// mangoGroup,
|
||||
// marginAccount,
|
||||
// payer,
|
||||
// new PublicKey('7KBVenLz5WNH4PA5MdGkJNpDDyNKnBQTwnz1UqJv9GUm'),
|
||||
// new PublicKey('FNYRWcdcJn1YjWstQ7SGmSizgmERECfoknwk2cf1sQMe'),
|
||||
// 1000,
|
||||
// );
|
||||
// } catch (e) {
|
||||
// console.log('deposit error:', e);
|
||||
// }
|
||||
// console.log('deposit complete');
|
||||
// }
|
||||
|
||||
// await testDeposit();
|
||||
// await getMarginAccountDetails();
|
||||
// await testSolink()
|
||||
// testDepositSrm()
|
||||
// }
|
||||
|
||||
// tests();
|
||||
//
|
||||
// tests()
|
|
@ -5,7 +5,7 @@ import {
|
|||
TransactionInstruction,
|
||||
} from '@solana/web3.js';
|
||||
import { Order } from '@project-serum/serum/lib/market';
|
||||
import { encodeMangoInstruction } from './layout';
|
||||
import { encodeMangoInstruction, NUM_TOKENS } from './layout';
|
||||
import { TOKEN_PROGRAM_ID } from '@project-serum/serum/lib/token-instructions';
|
||||
import { uiToNative } from './utils';
|
||||
|
||||
|
@ -134,3 +134,82 @@ export function makeSettleBorrowInstruction(
|
|||
});
|
||||
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 })
|
||||
}
|
|
@ -155,7 +155,8 @@ export const MarginAccountLayout = struct([
|
|||
seq(U64F64(), NUM_TOKENS, 'deposits'),
|
||||
seq(U64F64(), NUM_TOKENS, 'borrows'),
|
||||
seq(publicKeyLayout(), NUM_MARKETS, 'openOrders'),
|
||||
seq(u8(), 8, 'padding')
|
||||
u8('beingLiquidated'),
|
||||
seq(u8(), 7, 'padding')
|
||||
]);
|
||||
|
||||
export const MangoSrmAccountLayout = struct([
|
||||
|
@ -165,6 +166,19 @@ export const MangoSrmAccountLayout = struct([
|
|||
u64('amount')
|
||||
]);
|
||||
|
||||
export const AccountLayout = struct([
|
||||
publicKeyLayout('mint'),
|
||||
publicKeyLayout('owner'),
|
||||
u64('amount'),
|
||||
u32('delegateOption'),
|
||||
publicKeyLayout('delegate'),
|
||||
u8('state'),
|
||||
u32('isNativeOption'),
|
||||
u64('isNative'),
|
||||
u64('delegatedAmount'),
|
||||
u32('closeAuthorityOption'),
|
||||
publicKeyLayout('closeAuthority')
|
||||
]);
|
||||
|
||||
class EnumLayout extends UInt {
|
||||
values: any;
|
||||
|
@ -260,6 +274,8 @@ MangoInstructionLayout.addVariant(14,
|
|||
),
|
||||
'PlaceAndSettle'
|
||||
)
|
||||
MangoInstructionLayout.addVariant(15, struct([u8('limit')]), 'ForceCancelOrders')
|
||||
MangoInstructionLayout.addVariant(16, struct([u64('maxDeposit')]), 'PartialLiquidate')
|
||||
|
||||
// @ts-ignore
|
||||
const instructionMaxSpan = Math.max(...Object.values(MangoInstructionLayout.registry).map((r) => r.span));
|
||||
|
@ -268,3 +284,5 @@ export function encodeMangoInstruction(data) {
|
|||
const span = MangoInstructionLayout.encode(data, b);
|
||||
return b.slice(0, span);
|
||||
}
|
||||
|
||||
|
||||
|
|
13
src/utils.ts
13
src/utils.ts
|
@ -11,6 +11,7 @@ import BN from 'bn.js';
|
|||
import { WRAPPED_SOL_MINT } from '@project-serum/serum/lib/token-instructions';
|
||||
import { blob, struct, u8, nu64 } from 'buffer-layout';
|
||||
import { TOKEN_PROGRAM_ID } from '@solana/spl-token';
|
||||
import { AccountLayout } from './layout';
|
||||
|
||||
export const zeroKey = new PublicKey(new Uint8Array(32))
|
||||
|
||||
|
@ -230,6 +231,18 @@ export function parseTokenAccountData(
|
|||
};
|
||||
}
|
||||
|
||||
export function parseTokenAccount(
|
||||
data: Buffer
|
||||
): { mint: PublicKey; owner: PublicKey; amount: BN } {
|
||||
|
||||
const decoded = AccountLayout.decode(data)
|
||||
return {
|
||||
mint: decoded.mint,
|
||||
owner: decoded.owner,
|
||||
amount: decoded.amount
|
||||
}
|
||||
}
|
||||
|
||||
export async function getMultipleAccounts(
|
||||
connection: Connection,
|
||||
publicKeys: PublicKey[]
|
||||
|
|
Loading…
Reference in New Issue