added srm vault pk to ids.json; added nativeSrm to MangoGroup; fixed settleAll function

This commit is contained in:
dd 2021-02-25 15:09:06 -05:00
parent b3d4e240f9
commit 8f51b00efb
6 changed files with 131 additions and 35 deletions

View File

@ -57,6 +57,8 @@
"dependencies": {
"@project-serum/serum": "^0.13.20",
"@project-serum/sol-wallet-adapter": "^0.1.4",
"@solana/spl-token": "0.0.13",
"@solana/web3.js": "^0.90.0",
"bn.js": "^5.1.2",
"buffer-layout": "^1.2.0",

View File

@ -22,17 +22,18 @@ import BN from 'bn.js';
import {
createAccountInstruction,
getFilteredProgramAccounts, getUnixTs,
nativeToUi,
nativeToUi, parseTokenAccountData,
promiseUndef,
uiToNative,
zeroKey,
} from './utils';
import { Market, OpenOrders, Orderbook } from '@project-serum/serum';
import { SRM_DECIMALS, TOKEN_PROGRAM_ID } from '@project-serum/serum/lib/token-instructions';
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 { Aggregator } from './schema'
import { AccountLayout, TOKEN_PROGRAM_ID } from '@solana/spl-token';
export class MangoGroup {
@ -57,9 +58,15 @@ export class MangoGroup {
mintDecimals!: number[];
oracleDecimals!: number[];
constructor(publicKey: PublicKey, decoded: any) {
this.publicKey = publicKey;
Object.assign(this, decoded);
nativeSrm: number | null;
constructor(publicKey: PublicKey, decoded: any, nativeSrm?: number) {
this.publicKey = publicKey
Object.assign(this, decoded)
if (nativeSrm) {
this.nativeSrm = nativeSrm
} else {
this.nativeSrm = null
}
}
async getPrices(
@ -251,6 +258,16 @@ export class MarginAccount {
return this.computeValue(mangoGroup, prices)
}
getDeposits(mangoGroup: MangoGroup): number[] {
const deposits = new Array<number>(NUM_TOKENS)
for (let i = 0; i < NUM_TOKENS; i++) {
deposits[i] = this.getUiDeposit(mangoGroup, i)
}
return deposits
}
getAssets(mangoGroup: MangoGroup): number[] {
const assets = new Array<number>(NUM_TOKENS)
@ -366,9 +383,7 @@ export class MangoClient {
connection: Connection,
programId: PublicKey,
payer: PublicKey,
) {
throw new Error("Not Implemented");
}
@ -564,10 +579,20 @@ export class MangoClient {
): Promise<TransactionSignature> {
const transaction = new Transaction()
const assetGains: number[] = new Array(NUM_TOKENS).fill(0)
for (let i = 0; i < NUM_MARKETS; i++) {
if (marginAccount.openOrdersAccounts[i] == undefined) {
const openOrdersAccount = marginAccount.openOrdersAccounts[i]
if (openOrdersAccount === undefined) {
continue
} else if (openOrdersAccount.quoteTokenFree.toNumber() === 0 && openOrdersAccount.baseTokenFree.toNumber() === 0) {
continue
}
assetGains[i] += openOrdersAccount.baseTokenFree.toNumber()
assetGains[NUM_TOKENS-1] += openOrdersAccount.quoteTokenFree.toNumber()
const spotMarket = markets[i]
const dexSigner = await PublicKey.createProgramAddress(
[
@ -577,6 +602,8 @@ export class MangoClient {
spotMarket.programId
)
const keys = [
{ isSigner: false, isWritable: true, pubkey: mangoGroup.publicKey},
{ isSigner: true, isWritable: false, pubkey: owner.publicKey },
@ -599,10 +626,15 @@ export class MangoClient {
transaction.add(instruction)
}
const assets = marginAccount.getAssets(mangoGroup)
const deposits = marginAccount.getDeposits(mangoGroup)
const liabs = marginAccount.getLiabs(mangoGroup)
for (let i = 0; i < NUM_TOKENS; i++) { // TODO test this. maybe it hits transaction size limit
const deposit = deposits[i] + assetGains[i]
if (deposit === 0 || liabs[i] === 0) {
continue
}
const keys = [
{ isSigner: false, isWritable: true, pubkey: mangoGroup.publicKey},
{ isSigner: false, isWritable: true, pubkey: marginAccount.publicKey },
@ -900,11 +932,23 @@ export class MangoClient {
async getMangoGroup(
connection: Connection,
mangoGroupPk: PublicKey
mangoGroupPk: PublicKey,
srmVaultPk?: PublicKey
): Promise<MangoGroup> {
const acc = await connection.getAccountInfo(mangoGroupPk);
const decoded = MangoGroupLayout.decode(acc == null ? undefined : acc.data);
return new MangoGroup(mangoGroupPk, decoded);
if (srmVaultPk) {
const [acc, srmVaultAcc] = await Promise.all(
[connection.getAccountInfo(mangoGroupPk), connection.getAccountInfo(srmVaultPk)]
)
const decoded = MangoGroupLayout.decode(acc == null ? undefined : acc.data);
if (!srmVaultAcc) { return new MangoGroup(mangoGroupPk, decoded) }
const srmVault = parseTokenAccountData(srmVaultAcc.data)
return new MangoGroup(mangoGroupPk, decoded, srmVault.amount)
} else {
const acc = await connection.getAccountInfo(mangoGroupPk);
const decoded = MangoGroupLayout.decode(acc == null ? undefined : acc.data);
return new MangoGroup(mangoGroupPk, decoded);
}
}
async getMarginAccount(

View File

@ -33,7 +33,8 @@
"BUgSeSxAyKdXc9VUqadCsS4ZuZZhdGjUr8JkRrxoZXV9",
"DcfCtZrmHwEi1J3ksU2hYKGDR4n8Pbwi1fxURzNC6xEe",
"HfiDTJ4V6KN7o4dtDfZgYxWLTipGJUPVCQxk6ajFkNEc"
]
],
"srm_vault_pk": "Fxoyr3u1oxzcY8NdYUwW6Mbi5mBW6KLx44J6zKiix43r"
}
},
"mango_program_id": "AHKufSeSqvjehJcW1uTy1RKhV4BafbpQxVGXGHn7G3hX",

View File

@ -1,5 +1,7 @@
import { MangoClient, MangoGroup } from './client';
import IDS from './ids.json';
import { Connection, PublicKey } from '@solana/web3.js';
import { getUnixTs } from './utils';
export { MangoClient, MangoGroup, MarginAccount } from './client';
export { MangoIndexLayout, MarginAccountLayout, MangoGroupLayout } from './layout';
@ -9,25 +11,6 @@ export * from './utils'
export { IDS }
// async function testMangoGroup() {
// const cluster = "devnet";
// 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_USDC.mango_group_pk);
// const mangoProgramId = new PublicKey(clusterIds.mango_program_id);
//
// const mangoGroup = await client.getMangoGroup(connection, mangoGroupPk)
//
// for (let i = 0; i < NUM_TOKENS; i++) {
// console.log(nativeToUi(mangoGroup.borrowLimits[i], mangoGroup.mintDecimals[i]))
// }
//
// }
// testMangoGroup()
// async function testSolink() {
// const cluster = "devnet";
// const client = new MangoClient();

View File

@ -2,7 +2,7 @@ import { Account, AccountInfo, Connection, PublicKey, SystemProgram, Transaction
import { publicKeyLayout, u64 } from './layout';
import BN from 'bn.js';
import { WRAPPED_SOL_MINT } from '@project-serum/serum/lib/token-instructions';
import { blob, struct, u8 } from 'buffer-layout';
import { blob, struct, u8, nu64 } from 'buffer-layout';
export const zeroKey = new PublicKey(new Uint8Array(32))
@ -171,4 +171,23 @@ export async function promiseUndef(): Promise<undefined> {
export const getUnixTs = () => {
return new Date().getTime() / 1000;
}
export const ACCOUNT_LAYOUT = struct([
blob(32, 'mint'),
blob(32, 'owner'),
nu64('amount'),
blob(93)
]);
export function parseTokenAccountData(
data: Buffer,
): { mint: PublicKey; owner: PublicKey; amount: number } {
let { mint, owner, amount } = ACCOUNT_LAYOUT.decode(data);
return {
mint: new PublicKey(mint),
owner: new PublicKey(owner),
amount,
};
}

View File

@ -269,6 +269,13 @@
dependencies:
"@babel/helper-plugin-utils" "^7.12.13"
"@babel/runtime@^7.10.5":
version "7.13.7"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.13.7.tgz#d494e39d198ee9ca04f4dcb76d25d9d7a1dc961a"
integrity sha512-h+ilqoX998mRVM5FtB5ijRuHUDVt5l3yfoOi2uh18Z/O3hvyaHQ39NpxVkCIG5yFs+mLq/ewFp8Bss6zmWv6ZA==
dependencies:
regenerator-runtime "^0.13.4"
"@babel/runtime@^7.11.2", "@babel/runtime@^7.3.1":
version "7.13.0"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.13.0.tgz#7f2cd0e2086626eea186a5a062e21e77ec0e45d0"
@ -577,6 +584,18 @@
dependencies:
"@sinonjs/commons" "^1.7.0"
"@solana/spl-token@0.0.13":
version "0.0.13"
resolved "https://registry.yarnpkg.com/@solana/spl-token/-/spl-token-0.0.13.tgz#5e0b235b1f8b34643280401dbfddeb34d13d1acd"
integrity sha512-WT8M9V/hxURR5jLbhr3zgwVsgcY6m8UhHtK045w7o+jx8FJ9MKARkj387WBFU7mKiFq0k8jw/8YL7XmnIUuH8Q==
dependencies:
"@babel/runtime" "^7.10.5"
"@solana/web3.js" "^0.86.1"
bn.js "^5.0.0"
buffer-layout "^1.2.0"
dotenv "8.2.0"
mkdirp "1.0.4"
"@solana/web3.js@0.86.1":
version "0.86.1"
resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-0.86.1.tgz#034a2cef742569f74dfc9960dfbcabc92e674b08"
@ -600,6 +619,29 @@
tweetnacl "^1.0.0"
ws "^7.0.0"
"@solana/web3.js@^0.86.1":
version "0.86.4"
resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-0.86.4.tgz#69216d3928ca4727c25a1ea96c405e897156ac3b"
integrity sha512-FpabDmdyxBN5aHIVUWc9Q6pXJFWiLRm/xeyxFg9O9ICHjiUkd38omds7G0CAmykIccG7zaMziwtkXp+0KvQOhA==
dependencies:
"@babel/runtime" "^7.3.1"
bn.js "^5.0.0"
bs58 "^4.0.1"
buffer "^5.4.3"
buffer-layout "^1.2.0"
crypto-hash "^1.2.2"
esdoc-inject-style-plugin "^1.0.0"
jayson "^3.0.1"
keccak "^3.0.1"
mz "^2.7.0"
node-fetch "^2.2.0"
npm-run-all "^4.1.5"
rpc-websockets "^7.4.2"
secp256k1 "^4.0.2"
superstruct "^0.8.3"
tweetnacl "^1.0.0"
ws "^7.0.0"
"@solana/web3.js@^0.90.0":
version "0.90.5"
resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-0.90.5.tgz#5be7d78a19f0b5e01bf82c52e3cbf0bb72a38cfd"
@ -1802,6 +1844,11 @@ domutils@^1.5.1:
dom-serializer "0"
domelementtype "1"
dotenv@8.2.0:
version "8.2.0"
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a"
integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==
ecc-jsbn@~0.1.1:
version "0.1.2"
resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9"
@ -3694,7 +3741,7 @@ mixin-deep@^1.2.0:
for-in "^1.0.2"
is-extendable "^1.0.1"
mkdirp@1.x:
mkdirp@1.0.4, mkdirp@1.x:
version "1.0.4"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==