Health from health components in ts/client (#104)
This commit is contained in:
parent
03882e6dd3
commit
bc4c57911a
|
@ -1,11 +1,11 @@
|
|||
use anchor_lang::prelude::*;
|
||||
use fixed::types::I80F48;
|
||||
|
||||
use crate::state::{PerpMarketIndex, TokenIndex};
|
||||
use crate::state::{HealthCache, PerpMarketIndex, TokenIndex};
|
||||
|
||||
#[event]
|
||||
#[derive(Debug)]
|
||||
pub struct MangoAccountData {
|
||||
pub health_cache: HealthCache,
|
||||
pub init_health: I80F48,
|
||||
pub maint_health: I80F48,
|
||||
pub equity: Equity,
|
||||
|
|
|
@ -24,9 +24,10 @@ pub fn compute_account_data(ctx: Context<ComputeAccountData>) -> Result<()> {
|
|||
let equity = compute_equity(&account, &account_retriever)?;
|
||||
|
||||
emit!(MangoAccountData {
|
||||
health_cache,
|
||||
init_health,
|
||||
maint_health,
|
||||
equity
|
||||
equity,
|
||||
});
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -410,7 +410,8 @@ pub fn compute_health(
|
|||
Ok(new_health_cache(account, retriever)?.health(health_type))
|
||||
}
|
||||
|
||||
struct TokenInfo {
|
||||
#[derive(AnchorDeserialize, AnchorSerialize)]
|
||||
pub struct TokenInfo {
|
||||
token_index: TokenIndex,
|
||||
maint_asset_weight: I80F48,
|
||||
init_asset_weight: I80F48,
|
||||
|
@ -451,7 +452,8 @@ impl TokenInfo {
|
|||
}
|
||||
}
|
||||
|
||||
struct Serum3Info {
|
||||
#[derive(AnchorSerialize, AnchorDeserialize)]
|
||||
pub struct Serum3Info {
|
||||
reserved: I80F48,
|
||||
base_index: usize,
|
||||
quote_index: usize,
|
||||
|
@ -496,7 +498,8 @@ impl Serum3Info {
|
|||
}
|
||||
}
|
||||
|
||||
struct PerpInfo {
|
||||
#[derive(AnchorSerialize, AnchorDeserialize)]
|
||||
pub struct PerpInfo {
|
||||
maint_asset_weight: I80F48,
|
||||
init_asset_weight: I80F48,
|
||||
maint_liab_weight: I80F48,
|
||||
|
@ -535,6 +538,7 @@ impl PerpInfo {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(AnchorSerialize, AnchorDeserialize)]
|
||||
pub struct HealthCache {
|
||||
token_infos: Vec<TokenInfo>,
|
||||
serum3_infos: Vec<Serum3Info>,
|
||||
|
|
|
@ -0,0 +1,224 @@
|
|||
import { I80F48, I80F48Dto, ZERO_I80F48 } from './I80F48';
|
||||
import { HealthType } from './mangoAccount';
|
||||
|
||||
// ░░░░
|
||||
//
|
||||
// ██
|
||||
// ██░░██
|
||||
// ░░ ░░ ██░░░░░░██ ░░░░
|
||||
// ██░░░░░░░░░░██
|
||||
// ██░░░░░░░░░░██
|
||||
// ██░░░░░░░░░░░░░░██
|
||||
// ██░░░░░░██████░░░░░░██
|
||||
// ██░░░░░░██████░░░░░░██
|
||||
// ██░░░░░░░░██████░░░░░░░░██
|
||||
// ██░░░░░░░░██████░░░░░░░░██
|
||||
// ██░░░░░░░░░░██████░░░░░░░░░░██
|
||||
// ██░░░░░░░░░░░░██████░░░░░░░░░░░░██
|
||||
// ██░░░░░░░░░░░░██████░░░░░░░░░░░░██
|
||||
// ██░░░░░░░░░░░░░░██████░░░░░░░░░░░░░░██
|
||||
// ██░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░██
|
||||
// ██░░░░░░░░░░░░░░░░██████░░░░░░░░░░░░░░░░██
|
||||
// ██░░░░░░░░░░░░░░░░██████░░░░░░░░░░░░░░░░██
|
||||
// ██░░░░░░░░░░░░░░░░░░██████░░░░░░░░░░░░░░░░░░██
|
||||
// ░░ ██░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░██
|
||||
// ██████████████████████████████████████████
|
||||
// warning: this code is copy pasta from rust, keep in sync with health.rs
|
||||
|
||||
export class HealthCache {
|
||||
tokenInfos: TokenInfo[];
|
||||
serum3Infos: Serum3Info[];
|
||||
perpInfos: PerpInfo[];
|
||||
|
||||
constructor(dto: HealthCacheDto) {
|
||||
this.tokenInfos = dto.tokenInfos.map((dto) => new TokenInfo(dto));
|
||||
this.serum3Infos = dto.serum3Infos.map((dto) => new Serum3Info(dto));
|
||||
this.perpInfos = dto.perpInfos.map((dto) => new PerpInfo(dto));
|
||||
}
|
||||
|
||||
public health(healthType: HealthType): I80F48 {
|
||||
let health = ZERO_I80F48;
|
||||
for (const tokenInfo of this.tokenInfos) {
|
||||
let contrib = tokenInfo.healthContribution(healthType);
|
||||
health = health.add(contrib);
|
||||
}
|
||||
for (const serum3Info of this.serum3Infos) {
|
||||
let contrib = serum3Info.healthContribution(healthType, this.tokenInfos);
|
||||
health = health.add(contrib);
|
||||
}
|
||||
for (const perpInfo of this.perpInfos) {
|
||||
let contrib = perpInfo.healthContribution(healthType);
|
||||
health = health.add(contrib);
|
||||
}
|
||||
return health;
|
||||
}
|
||||
}
|
||||
|
||||
export class TokenInfo {
|
||||
constructor(dto: TokenInfoDto) {
|
||||
this.tokenIndex = dto.tokenIndex;
|
||||
this.maintAssetWeight = I80F48.from(dto.maintAssetWeight);
|
||||
this.initAssetWeight = I80F48.from(dto.initAssetWeight);
|
||||
this.maintLiabWeight = I80F48.from(dto.maintLiabWeight);
|
||||
this.initLiabWeight = I80F48.from(dto.initLiabWeight);
|
||||
this.oraclePrice = I80F48.from(dto.oraclePrice);
|
||||
this.balance = I80F48.from(dto.balance);
|
||||
this.serum3MaxReserved = I80F48.from(dto.serum3MaxReserved);
|
||||
}
|
||||
|
||||
tokenIndex: number;
|
||||
maintAssetWeight: I80F48;
|
||||
initAssetWeight: I80F48;
|
||||
maintLiabWeight: I80F48;
|
||||
initLiabWeight: I80F48;
|
||||
oraclePrice: I80F48; // native/native
|
||||
// in health-reference-token native units
|
||||
balance: I80F48;
|
||||
// in health-reference-token native units
|
||||
serum3MaxReserved: I80F48;
|
||||
|
||||
assetWeight(healthType: HealthType): I80F48 {
|
||||
return healthType == HealthType.init
|
||||
? this.initAssetWeight
|
||||
: this.maintAssetWeight;
|
||||
}
|
||||
|
||||
liabWeight(healthType: HealthType): I80F48 {
|
||||
return healthType == HealthType.init
|
||||
? this.initLiabWeight
|
||||
: this.maintLiabWeight;
|
||||
}
|
||||
|
||||
healthContribution(healthType: HealthType): I80F48 {
|
||||
return (
|
||||
this.balance.isNeg()
|
||||
? this.liabWeight(healthType)
|
||||
: this.assetWeight(healthType)
|
||||
).mul(this.balance);
|
||||
}
|
||||
}
|
||||
|
||||
export class Serum3Info {
|
||||
constructor(dto: Serum3InfoDto) {
|
||||
this.reserved = I80F48.from(dto.reserved);
|
||||
this.baseIndex = dto.baseIndex;
|
||||
this.quoteIndex = dto.quoteIndex;
|
||||
}
|
||||
|
||||
reserved: I80F48;
|
||||
baseIndex: number;
|
||||
quoteIndex: number;
|
||||
|
||||
healthContribution(healthType: HealthType, tokenInfos: TokenInfo[]): I80F48 {
|
||||
let baseInfo = tokenInfos[this.baseIndex];
|
||||
let quoteInfo = tokenInfos[this.quoteIndex];
|
||||
let reserved = this.reserved;
|
||||
|
||||
if (reserved.isZero()) {
|
||||
return ZERO_I80F48;
|
||||
}
|
||||
|
||||
// How much the health would increase if the reserved balance were applied to the passed
|
||||
// token info?
|
||||
let computeHealthEffect = function (tokenInfo: TokenInfo) {
|
||||
// This balance includes all possible reserved funds from markets that relate to the
|
||||
// token, including this market itself: `reserved` is already included in `max_balance`.
|
||||
let maxBalance = tokenInfo.balance.add(tokenInfo.serum3MaxReserved);
|
||||
|
||||
// Assuming `reserved` was added to `max_balance` last (because that gives the smallest
|
||||
// health effects): how much did health change because of it?
|
||||
let assetPart, liabPart;
|
||||
if (maxBalance.gte(reserved)) {
|
||||
assetPart = reserved;
|
||||
liabPart = ZERO_I80F48;
|
||||
} else if (maxBalance.isNeg()) {
|
||||
assetPart = ZERO_I80F48;
|
||||
liabPart = reserved;
|
||||
} else {
|
||||
assetPart = maxBalance;
|
||||
liabPart = reserved.sub(maxBalance);
|
||||
}
|
||||
|
||||
let assetWeight = tokenInfo.assetWeight(healthType);
|
||||
let liabWeight = tokenInfo.liabWeight(healthType);
|
||||
return assetWeight.mul(assetPart).add(liabWeight.mul(liabPart));
|
||||
};
|
||||
|
||||
let reservedAsBase = computeHealthEffect(baseInfo);
|
||||
let reservedAsQuote = computeHealthEffect(quoteInfo);
|
||||
return reservedAsBase.min(reservedAsQuote);
|
||||
}
|
||||
}
|
||||
|
||||
export class PerpInfo {
|
||||
constructor(dto: PerpInfoDto) {
|
||||
this.maintAssetWeight = I80F48.from(dto.maintAssetWeight);
|
||||
this.initAssetWeight = I80F48.from(dto.initAssetWeight);
|
||||
this.maintLiabWeight = I80F48.from(dto.maintLiabWeight);
|
||||
this.initLiabWeight = I80F48.from(dto.initLiabWeight);
|
||||
this.base = I80F48.from(dto.base);
|
||||
this.quote = I80F48.from(dto.quote);
|
||||
}
|
||||
maintAssetWeight: I80F48;
|
||||
initAssetWeight: I80F48;
|
||||
maintLiabWeight: I80F48;
|
||||
initLiabWeight: I80F48;
|
||||
// in health-reference-token native units, needs scaling by asset/liab
|
||||
base: I80F48;
|
||||
// in health-reference-token native units, no asset/liab factor needed
|
||||
quote: I80F48;
|
||||
|
||||
healthContribution(healthType: HealthType): I80F48 {
|
||||
let weight;
|
||||
if (healthType == HealthType.init && this.base.isNeg()) {
|
||||
weight = this.initLiabWeight;
|
||||
} else if (healthType == HealthType.init && !this.base.isNeg()) {
|
||||
weight = this.initAssetWeight;
|
||||
}
|
||||
if (healthType == HealthType.maint && this.base.isNeg()) {
|
||||
weight = this.maintLiabWeight;
|
||||
}
|
||||
if (healthType == HealthType.maint && !this.base.isNeg()) {
|
||||
weight = this.maintAssetWeight;
|
||||
}
|
||||
|
||||
// FUTURE: Allow v3-style "reliable" markets where we can return
|
||||
// `self.quote + weight * self.base` here
|
||||
return this.quote.add(weight.mul(this.base)).min(ZERO_I80F48);
|
||||
}
|
||||
}
|
||||
|
||||
export class HealthCacheDto {
|
||||
tokenInfos: TokenInfoDto[];
|
||||
serum3Infos: Serum3InfoDto[];
|
||||
perpInfos: PerpInfoDto[];
|
||||
}
|
||||
export class TokenInfoDto {
|
||||
tokenIndex: number;
|
||||
maintAssetWeight: I80F48Dto;
|
||||
initAssetWeight: I80F48Dto;
|
||||
maintLiabWeight: I80F48Dto;
|
||||
initLiabWeight: I80F48Dto;
|
||||
oraclePrice: I80F48Dto; // native/native
|
||||
// in health-reference-token native units
|
||||
balance: I80F48Dto;
|
||||
// in health-reference-token native units
|
||||
serum3MaxReserved: I80F48Dto;
|
||||
}
|
||||
|
||||
export class Serum3InfoDto {
|
||||
reserved: I80F48Dto;
|
||||
baseIndex: number;
|
||||
quoteIndex: number;
|
||||
}
|
||||
|
||||
export class PerpInfoDto {
|
||||
maintAssetWeight: I80F48Dto;
|
||||
initAssetWeight: I80F48Dto;
|
||||
maintLiabWeight: I80F48Dto;
|
||||
initLiabWeight: I80F48Dto;
|
||||
// in health-reference-token native units, needs scaling by asset/liab
|
||||
base: I80F48Dto;
|
||||
// in health-reference-token native units, no asset/liab factor needed
|
||||
quote: I80F48Dto;
|
||||
}
|
|
@ -5,6 +5,7 @@ import { MangoClient } from '../client';
|
|||
import { nativeI80F48ToUi } from '../utils';
|
||||
import { Bank, QUOTE_DECIMALS } from './bank';
|
||||
import { Group } from './group';
|
||||
import { HealthCache, HealthCacheDto } from './healthCache';
|
||||
import { I80F48, I80F48Dto, ONE_I80F48, ZERO_I80F48 } from './I80F48';
|
||||
export class MangoAccount {
|
||||
public tokens: TokenPosition[];
|
||||
|
@ -422,12 +423,14 @@ export class HealthType {
|
|||
|
||||
export class MangoAccountData {
|
||||
constructor(
|
||||
public healthCache: HealthCache,
|
||||
public initHealth: I80F48,
|
||||
public maintHealth: I80F48,
|
||||
public equity: Equity,
|
||||
) {}
|
||||
|
||||
static from(event: {
|
||||
healthCache: HealthCacheDto;
|
||||
initHealth: I80F48Dto;
|
||||
maintHealth: I80F48Dto;
|
||||
equity: {
|
||||
|
@ -438,6 +441,7 @@ export class MangoAccountData {
|
|||
tokenAssets: any;
|
||||
}) {
|
||||
return new MangoAccountData(
|
||||
new HealthCache(event.healthCache),
|
||||
I80F48.from(event.initHealth),
|
||||
I80F48.from(event.maintHealth),
|
||||
Equity.from(event.equity),
|
||||
|
|
|
@ -3427,6 +3427,158 @@ export type MangoV4 = {
|
|||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "TokenInfo",
|
||||
"type": {
|
||||
"kind": "struct",
|
||||
"fields": [
|
||||
{
|
||||
"name": "tokenIndex",
|
||||
"type": "u16"
|
||||
},
|
||||
{
|
||||
"name": "maintAssetWeight",
|
||||
"type": {
|
||||
"defined": "I80F48"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "initAssetWeight",
|
||||
"type": {
|
||||
"defined": "I80F48"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "maintLiabWeight",
|
||||
"type": {
|
||||
"defined": "I80F48"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "initLiabWeight",
|
||||
"type": {
|
||||
"defined": "I80F48"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "oraclePrice",
|
||||
"type": {
|
||||
"defined": "I80F48"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "balance",
|
||||
"type": {
|
||||
"defined": "I80F48"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "serum3MaxReserved",
|
||||
"type": {
|
||||
"defined": "I80F48"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Serum3Info",
|
||||
"type": {
|
||||
"kind": "struct",
|
||||
"fields": [
|
||||
{
|
||||
"name": "reserved",
|
||||
"type": {
|
||||
"defined": "I80F48"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "baseIndex",
|
||||
"type": "u64"
|
||||
},
|
||||
{
|
||||
"name": "quoteIndex",
|
||||
"type": "u64"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "PerpInfo",
|
||||
"type": {
|
||||
"kind": "struct",
|
||||
"fields": [
|
||||
{
|
||||
"name": "maintAssetWeight",
|
||||
"type": {
|
||||
"defined": "I80F48"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "initAssetWeight",
|
||||
"type": {
|
||||
"defined": "I80F48"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "maintLiabWeight",
|
||||
"type": {
|
||||
"defined": "I80F48"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "initLiabWeight",
|
||||
"type": {
|
||||
"defined": "I80F48"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "base",
|
||||
"type": {
|
||||
"defined": "I80F48"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "quote",
|
||||
"type": {
|
||||
"defined": "I80F48"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "HealthCache",
|
||||
"type": {
|
||||
"kind": "struct",
|
||||
"fields": [
|
||||
{
|
||||
"name": "tokenInfos",
|
||||
"type": {
|
||||
"vec": {
|
||||
"defined": "TokenInfo"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "serum3Infos",
|
||||
"type": {
|
||||
"vec": {
|
||||
"defined": "Serum3Info"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "perpInfos",
|
||||
"type": {
|
||||
"vec": {
|
||||
"defined": "PerpInfo"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "TokenPosition",
|
||||
"type": {
|
||||
|
@ -4046,6 +4198,13 @@ export type MangoV4 = {
|
|||
{
|
||||
"name": "MangoAccountData",
|
||||
"fields": [
|
||||
{
|
||||
"name": "healthCache",
|
||||
"type": {
|
||||
"defined": "HealthCache"
|
||||
},
|
||||
"index": false
|
||||
},
|
||||
{
|
||||
"name": "initHealth",
|
||||
"type": {
|
||||
|
@ -8048,6 +8207,158 @@ export const IDL: MangoV4 = {
|
|||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "TokenInfo",
|
||||
"type": {
|
||||
"kind": "struct",
|
||||
"fields": [
|
||||
{
|
||||
"name": "tokenIndex",
|
||||
"type": "u16"
|
||||
},
|
||||
{
|
||||
"name": "maintAssetWeight",
|
||||
"type": {
|
||||
"defined": "I80F48"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "initAssetWeight",
|
||||
"type": {
|
||||
"defined": "I80F48"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "maintLiabWeight",
|
||||
"type": {
|
||||
"defined": "I80F48"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "initLiabWeight",
|
||||
"type": {
|
||||
"defined": "I80F48"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "oraclePrice",
|
||||
"type": {
|
||||
"defined": "I80F48"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "balance",
|
||||
"type": {
|
||||
"defined": "I80F48"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "serum3MaxReserved",
|
||||
"type": {
|
||||
"defined": "I80F48"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Serum3Info",
|
||||
"type": {
|
||||
"kind": "struct",
|
||||
"fields": [
|
||||
{
|
||||
"name": "reserved",
|
||||
"type": {
|
||||
"defined": "I80F48"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "baseIndex",
|
||||
"type": "u64"
|
||||
},
|
||||
{
|
||||
"name": "quoteIndex",
|
||||
"type": "u64"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "PerpInfo",
|
||||
"type": {
|
||||
"kind": "struct",
|
||||
"fields": [
|
||||
{
|
||||
"name": "maintAssetWeight",
|
||||
"type": {
|
||||
"defined": "I80F48"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "initAssetWeight",
|
||||
"type": {
|
||||
"defined": "I80F48"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "maintLiabWeight",
|
||||
"type": {
|
||||
"defined": "I80F48"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "initLiabWeight",
|
||||
"type": {
|
||||
"defined": "I80F48"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "base",
|
||||
"type": {
|
||||
"defined": "I80F48"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "quote",
|
||||
"type": {
|
||||
"defined": "I80F48"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "HealthCache",
|
||||
"type": {
|
||||
"kind": "struct",
|
||||
"fields": [
|
||||
{
|
||||
"name": "tokenInfos",
|
||||
"type": {
|
||||
"vec": {
|
||||
"defined": "TokenInfo"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "serum3Infos",
|
||||
"type": {
|
||||
"vec": {
|
||||
"defined": "Serum3Info"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "perpInfos",
|
||||
"type": {
|
||||
"vec": {
|
||||
"defined": "PerpInfo"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "TokenPosition",
|
||||
"type": {
|
||||
|
@ -8667,6 +8978,13 @@ export const IDL: MangoV4 = {
|
|||
{
|
||||
"name": "MangoAccountData",
|
||||
"fields": [
|
||||
{
|
||||
"name": "healthCache",
|
||||
"type": {
|
||||
"defined": "HealthCache"
|
||||
},
|
||||
"index": false
|
||||
},
|
||||
{
|
||||
"name": "initHealth",
|
||||
"type": {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { AnchorProvider, Wallet } from '@project-serum/anchor';
|
||||
import { Connection, Keypair, PublicKey } from '@solana/web3.js';
|
||||
import fs from 'fs';
|
||||
import { HealthType } from '../accounts/mangoAccount';
|
||||
import { OrderType, Side } from '../accounts/perp';
|
||||
import {
|
||||
Serum3OrderType,
|
||||
|
@ -67,12 +68,22 @@ async function main() {
|
|||
const randomKey = new PublicKey(
|
||||
'4ZkS7ZZkxfsC3GtvvsHP3DFcUeByU9zzZELS4r8HCELo',
|
||||
);
|
||||
await client.editMangoAccount(group, mangoAccount, 'my_changed_name', randomKey);
|
||||
await client.editMangoAccount(
|
||||
group,
|
||||
mangoAccount,
|
||||
'my_changed_name',
|
||||
randomKey,
|
||||
);
|
||||
await mangoAccount.reload(client, group);
|
||||
console.log(mangoAccount.toString());
|
||||
|
||||
console.log(`...resetting mango account name, and re-setting a delegate`);
|
||||
await client.editMangoAccount(group, mangoAccount, 'my_mango_account', PublicKey.default);
|
||||
await client.editMangoAccount(
|
||||
group,
|
||||
mangoAccount,
|
||||
'my_mango_account',
|
||||
PublicKey.default,
|
||||
);
|
||||
await mangoAccount.reload(client, group);
|
||||
console.log(mangoAccount.toString());
|
||||
}
|
||||
|
@ -199,6 +210,14 @@ async function main() {
|
|||
'...mangoAccount.getCollateralValue() ' +
|
||||
toUiDecimals(mangoAccount.getCollateralValue().toNumber()),
|
||||
);
|
||||
console.log(
|
||||
'...mangoAccount.accountData["healthCache"].health(HealthType.init) ' +
|
||||
toUiDecimals(
|
||||
mangoAccount.accountData['healthCache']
|
||||
.health(HealthType.init)
|
||||
.toNumber(),
|
||||
),
|
||||
);
|
||||
console.log(
|
||||
'...mangoAccount.getAssetsVal() ' +
|
||||
toUiDecimals(mangoAccount.getAssetsVal().toNumber()),
|
||||
|
|
Loading…
Reference in New Issue