add eslint config and fix errors

This commit is contained in:
tjs 2022-08-04 13:42:41 -04:00
parent 38a5951558
commit 21f469fe4d
13 changed files with 12196 additions and 2287 deletions

2
.eslintignore Normal file
View File

@ -0,0 +1,2 @@
ts/client/src/mango_v4.ts
ts/client/src/scripts

24
.eslintrc.json Normal file
View File

@ -0,0 +1,24 @@
{
"env": {
"browser": true,
"es2021": true,
"node": true
},
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"prettier"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 12,
"sourceType": "module"
},
"plugins": ["@typescript-eslint"],
"rules": {
"linebreak-style": ["error", "unix"],
"semi": ["error", "always"],
"@typescript-eslint/no-non-null-assertion": 0,
"@typescript-eslint/no-explicit-any": 0
}
}

9814
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -24,12 +24,12 @@
"example1-admin": "ts-node ts/client/src/scripts/example1-admin.ts", "example1-admin": "ts-node ts/client/src/scripts/example1-admin.ts",
"scratch": "ts-node ts/client/src/scripts/scratch/scratch.ts", "scratch": "ts-node ts/client/src/scripts/scratch/scratch.ts",
"format": "prettier --check .", "format": "prettier --check .",
"lint": "eslint . --ext ts --ext tsx --ext js --quiet", "lint": "eslint ./ts --ext ts --ext tsx --ext js --quiet",
"typecheck": "tsc --noEmit --pretty", "typecheck": "tsc --noEmit --pretty",
"prepare": "yarn build", "prepare": "yarn build",
"prebuild": "npm run clean", "prebuild": "npm run clean",
"prepublishOnly": "npm run validate && npm run build", "prepublishOnly": "npm run validate && npm run build",
"validate": "npm run typecheck && npm run test && npm run lint && npm run format-check" "validate": "npm run typecheck && npm run lint && npm run format-check"
}, },
"devDependencies": { "devDependencies": {
"@jup-ag/core": "^1.0.0-beta.28", "@jup-ag/core": "^1.0.0-beta.28",
@ -38,8 +38,8 @@
"@types/chai": "^4.3.0", "@types/chai": "^4.3.0",
"@types/mocha": "^9.1.0", "@types/mocha": "^9.1.0",
"@types/node": "^14.14.37", "@types/node": "^14.14.37",
"@typescript-eslint/eslint-plugin": "^4.14.2", "@typescript-eslint/eslint-plugin": "^5.32.0",
"@typescript-eslint/parser": "^4.14.2", "@typescript-eslint/parser": "^5.32.0",
"chai": "^4.3.4", "chai": "^4.3.4",
"eslint": "^7.28.0", "eslint": "^7.28.0",
"eslint-config-prettier": "^7.2.0", "eslint-config-prettier": "^7.2.0",

View File

@ -44,8 +44,8 @@ export class I80F48 {
this.data = data; this.data = data;
} }
static fromNumber(x: number): I80F48 { static fromNumber(x: number): I80F48 {
let int_part = Math.trunc(x); const int_part = Math.trunc(x);
let v = new BN(int_part).iushln(48); const v = new BN(int_part).iushln(48);
v.iadd(new BN((x - int_part) * I80F48.MULTIPLIER_NUMBER)); v.iadd(new BN((x - int_part) * I80F48.MULTIPLIER_NUMBER));
return new I80F48(v); return new I80F48(v);
} }

View File

@ -141,9 +141,9 @@ export class Bank {
maintLiabWeight: I80F48Dto, maintLiabWeight: I80F48Dto,
initLiabWeight: I80F48Dto, initLiabWeight: I80F48Dto,
liquidationFee: I80F48Dto, liquidationFee: I80F48Dto,
dust: Object, dust: I80F48Dto,
flashLoanVaultInitial: Object, flashLoanVaultInitial: BN,
flashLoanApprovedAmount: Object, flashLoanApprovedAmount: BN,
public tokenIndex: number, public tokenIndex: number,
public mintDecimals: number, public mintDecimals: number,
public bankNum: number, public bankNum: number,
@ -337,7 +337,7 @@ export class MintInfo {
} }
toString(): string { toString(): string {
let res = const res =
'mint ' + 'mint ' +
this.mint.toBase58() + this.mint.toBase58() +
'\n oracle ' + '\n oracle ' +

View File

@ -207,7 +207,7 @@ export class Group {
price.data.slice(0, 8), price.data.slice(0, 8),
) )
) { ) {
let stubOracle = coder.decode('stubOracle', price.data); const stubOracle = coder.decode('stubOracle', price.data);
banks[index].price = new I80F48(stubOracle.price.val); banks[index].price = new I80F48(stubOracle.price.val);
} else { } else {
banks[index].price = I80F48.fromNumber( banks[index].price = I80F48.fromNumber(

View File

@ -39,15 +39,18 @@ export class HealthCache {
public health(healthType: HealthType): I80F48 { public health(healthType: HealthType): I80F48 {
let health = ZERO_I80F48; let health = ZERO_I80F48;
for (const tokenInfo of this.tokenInfos) { for (const tokenInfo of this.tokenInfos) {
let contrib = tokenInfo.healthContribution(healthType); const contrib = tokenInfo.healthContribution(healthType);
health = health.add(contrib); health = health.add(contrib);
} }
for (const serum3Info of this.serum3Infos) { for (const serum3Info of this.serum3Infos) {
let contrib = serum3Info.healthContribution(healthType, this.tokenInfos); const contrib = serum3Info.healthContribution(
healthType,
this.tokenInfos,
);
health = health.add(contrib); health = health.add(contrib);
} }
for (const perpInfo of this.perpInfos) { for (const perpInfo of this.perpInfos) {
let contrib = perpInfo.healthContribution(healthType); const contrib = perpInfo.healthContribution(healthType);
health = health.add(contrib); health = health.add(contrib);
} }
return health; return health;
@ -110,9 +113,9 @@ export class Serum3Info {
quoteIndex: number; quoteIndex: number;
healthContribution(healthType: HealthType, tokenInfos: TokenInfo[]): I80F48 { healthContribution(healthType: HealthType, tokenInfos: TokenInfo[]): I80F48 {
let baseInfo = tokenInfos[this.baseIndex]; const baseInfo = tokenInfos[this.baseIndex];
let quoteInfo = tokenInfos[this.quoteIndex]; const quoteInfo = tokenInfos[this.quoteIndex];
let reserved = this.reserved; const reserved = this.reserved;
if (reserved.isZero()) { if (reserved.isZero()) {
return ZERO_I80F48; return ZERO_I80F48;
@ -120,10 +123,10 @@ export class Serum3Info {
// How much the health would increase if the reserved balance were applied to the passed // How much the health would increase if the reserved balance were applied to the passed
// token info? // token info?
let computeHealthEffect = function (tokenInfo: TokenInfo) { const computeHealthEffect = function (tokenInfo: TokenInfo) {
// This balance includes all possible reserved funds from markets that relate to the // 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`. // token, including this market itself: `reserved` is already included in `max_balance`.
let maxBalance = tokenInfo.balance.add(tokenInfo.serum3MaxReserved); const maxBalance = tokenInfo.balance.add(tokenInfo.serum3MaxReserved);
// Assuming `reserved` was added to `max_balance` last (because that gives the smallest // Assuming `reserved` was added to `max_balance` last (because that gives the smallest
// health effects): how much did health change because of it? // health effects): how much did health change because of it?
@ -139,13 +142,13 @@ export class Serum3Info {
liabPart = reserved.sub(maxBalance); liabPart = reserved.sub(maxBalance);
} }
let assetWeight = tokenInfo.assetWeight(healthType); const assetWeight = tokenInfo.assetWeight(healthType);
let liabWeight = tokenInfo.liabWeight(healthType); const liabWeight = tokenInfo.liabWeight(healthType);
return assetWeight.mul(assetPart).add(liabWeight.mul(liabPart)); return assetWeight.mul(assetPart).add(liabWeight.mul(liabPart));
}; };
let reservedAsBase = computeHealthEffect(baseInfo); const reservedAsBase = computeHealthEffect(baseInfo);
let reservedAsQuote = computeHealthEffect(quoteInfo); const reservedAsQuote = computeHealthEffect(quoteInfo);
return reservedAsBase.min(reservedAsQuote); return reservedAsBase.min(reservedAsQuote);
} }
} }

View File

@ -28,7 +28,7 @@ export class MangoAccount {
netSettled: number; netSettled: number;
headerVersion: number; headerVersion: number;
tokens: unknown; tokens: unknown;
serum3: Object; serum3: unknown;
perps: unknown; perps: unknown;
perpOpenOrders: unknown; perpOpenOrders: unknown;
}, },
@ -50,7 +50,7 @@ export class MangoAccount {
obj.serum3 as Serum3PositionDto[], obj.serum3 as Serum3PositionDto[],
obj.perps as PerpPositionDto[], obj.perps as PerpPositionDto[],
obj.perpOpenOrders as any, obj.perpOpenOrders as any,
{}, {} as any,
); );
} }
@ -71,7 +71,7 @@ export class MangoAccount {
serum3: Serum3PositionDto[], serum3: Serum3PositionDto[],
perps: PerpPositionDto[], perps: PerpPositionDto[],
perpOpenOrders: PerpPositionDto[], perpOpenOrders: PerpPositionDto[],
public accountData: {}, public accountData: MangoAccountData,
) { ) {
this.name = utf8.decode(new Uint8Array(name)).split('\x00')[0]; this.name = utf8.decode(new Uint8Array(name)).split('\x00')[0];
this.tokens = tokens.map((dto) => TokenPosition.from(dto)); this.tokens = tokens.map((dto) => TokenPosition.from(dto));
@ -172,7 +172,7 @@ export class MangoAccount {
*/ */
getEquity(): I80F48 { getEquity(): I80F48 {
const equity = (this.accountData as MangoAccountData).equity; const equity = (this.accountData as MangoAccountData).equity;
let total_equity = equity.tokens.reduce( const total_equity = equity.tokens.reduce(
(a, b) => a.add(b.value), (a, b) => a.add(b.value),
ZERO_I80F48, ZERO_I80F48,
); );
@ -191,7 +191,7 @@ export class MangoAccount {
*/ */
getAssetsVal(): I80F48 { getAssetsVal(): I80F48 {
const equity = (this.accountData as MangoAccountData).equity; const equity = (this.accountData as MangoAccountData).equity;
let total_equity = equity.tokens.reduce( const total_equity = equity.tokens.reduce(
(a, b) => (b.value.gt(ZERO_I80F48) ? a.add(b.value) : a), (a, b) => (b.value.gt(ZERO_I80F48) ? a.add(b.value) : a),
ZERO_I80F48, ZERO_I80F48,
); );
@ -203,7 +203,7 @@ export class MangoAccount {
*/ */
getLiabsVal(): I80F48 { getLiabsVal(): I80F48 {
const equity = (this.accountData as MangoAccountData).equity; const equity = (this.accountData as MangoAccountData).equity;
let total_equity = equity.tokens.reduce( const total_equity = equity.tokens.reduce(
(a, b) => (b.value.lt(ZERO_I80F48) ? a.add(b.value) : a), (a, b) => (b.value.lt(ZERO_I80F48) ? a.add(b.value) : a),
ZERO_I80F48, ZERO_I80F48,
); );
@ -374,7 +374,7 @@ export class MangoAccount {
} }
export class TokenPosition { export class TokenPosition {
static TokenIndexUnset: number = 65535; static TokenIndexUnset = 65535;
static from(dto: TokenPositionDto) { static from(dto: TokenPositionDto) {
return new TokenPosition( return new TokenPosition(
I80F48.from(dto.indexedPosition), I80F48.from(dto.indexedPosition),
@ -419,12 +419,12 @@ export class TokenPosition {
).toNumber(); ).toNumber();
} }
public toString(group?: Group): String { public toString(group?: Group): string {
let extra: string = ''; let extra = '';
if (group) { if (group) {
let bank = group.findBank(this.tokenIndex); const bank = group.findBank(this.tokenIndex);
if (bank) { if (bank) {
let native = this.native(bank); const native = this.native(bank);
extra += ', native: ' + native.toNumber(); extra += ', native: ' + native.toNumber();
extra += ', ui: ' + this.ui(bank); extra += ', ui: ' + this.ui(bank);
extra += ', tokenName: ' + bank.name; extra += ', tokenName: ' + bank.name;

View File

@ -631,7 +631,7 @@ export class MangoClient {
let wrappedSolAccount: Keypair | undefined; let wrappedSolAccount: Keypair | undefined;
let preInstructions: TransactionInstruction[] = []; let preInstructions: TransactionInstruction[] = [];
let postInstructions: TransactionInstruction[] = []; let postInstructions: TransactionInstruction[] = [];
let additionalSigners: Signer[] = []; const additionalSigners: Signer[] = [];
if (bank.mint.equals(WRAPPED_SOL_MINT)) { if (bank.mint.equals(WRAPPED_SOL_MINT)) {
wrappedSolAccount = new Keypair(); wrappedSolAccount = new Keypair();
const lamports = Math.round(amount * LAMPORTS_PER_SOL) + 1e7; const lamports = Math.round(amount * LAMPORTS_PER_SOL) + 1e7;
@ -885,7 +885,7 @@ export class MangoClient {
): Promise<TransactionSignature> { ): Promise<TransactionSignature> {
const serum3Market = group.serum3MarketsMap.get(serum3MarketName)!; const serum3Market = group.serum3MarketsMap.get(serum3MarketName)!;
let openOrders = mangoAccount.serum3.find( const openOrders = mangoAccount.serum3.find(
(account) => account.marketIndex === serum3Market.marketIndex, (account) => account.marketIndex === serum3Market.marketIndex,
)?.openOrders; )?.openOrders;
@ -1342,7 +1342,7 @@ export class MangoClient {
mangoAccount, mangoAccount,
]); ]);
let [nativePrice, nativeQuantity] = perpMarket.uiToNativePriceQuantity( const [nativePrice, nativeQuantity] = perpMarket.uiToNativePriceQuantity(
price, price,
quantity, quantity,
); );
@ -1421,7 +1421,7 @@ export class MangoClient {
/* /*
* Find or create associated token accounts * Find or create associated token accounts
*/ */
let inputTokenAccountPk = await getAssociatedTokenAddress( const inputTokenAccountPk = await getAssociatedTokenAddress(
inputBank.mint, inputBank.mint,
mangoAccount.owner, mangoAccount.owner,
); );
@ -1429,7 +1429,7 @@ export class MangoClient {
await this.program.provider.connection.getAccountInfo( await this.program.provider.connection.getAccountInfo(
inputTokenAccountPk, inputTokenAccountPk,
); );
let preInstructions = []; const preInstructions = [];
if (!inputTokenAccExists) { if (!inputTokenAccExists) {
preInstructions.push( preInstructions.push(
Token.createAssociatedTokenAccountInstruction( Token.createAssociatedTokenAccountInstruction(
@ -1443,7 +1443,7 @@ export class MangoClient {
); );
} }
let outputTokenAccountPk = await getAssociatedTokenAddress( const outputTokenAccountPk = await getAssociatedTokenAddress(
outputBank.mint, outputBank.mint,
mangoAccount.owner, mangoAccount.owner,
); );
@ -1569,8 +1569,8 @@ export class MangoClient {
liabTokenName: string, liabTokenName: string,
maxLiabTransfer: number, maxLiabTransfer: number,
) { ) {
let assetBank: Bank = group.banksMap.get(assetTokenName); const assetBank: Bank = group.banksMap.get(assetTokenName);
let liabBank: Bank = group.banksMap.get(liabTokenName); const liabBank: Bank = group.banksMap.get(liabTokenName);
const healthRemainingAccounts: PublicKey[] = const healthRemainingAccounts: PublicKey[] =
this.buildHealthRemainingAccounts( this.buildHealthRemainingAccounts(
@ -1616,7 +1616,7 @@ export class MangoClient {
// TODO: use IDL on chain or in repository? decide... // TODO: use IDL on chain or in repository? decide...
// Alternatively we could fetch IDL from chain. // Alternatively we could fetch IDL from chain.
// const idl = await Program.fetchIdl(MANGO_V4_ID, provider); // const idl = await Program.fetchIdl(MANGO_V4_ID, provider);
let idl = IDL; const idl = IDL;
return new MangoClient( return new MangoClient(
new Program<MangoV4>(idl as MangoV4, programId, provider), new Program<MangoV4>(idl as MangoV4, programId, provider),
@ -1632,7 +1632,7 @@ export class MangoClient {
// TODO: use IDL on chain or in repository? decide... // TODO: use IDL on chain or in repository? decide...
// Alternatively we could fetch IDL from chain. // Alternatively we could fetch IDL from chain.
// const idl = await Program.fetchIdl(MANGO_V4_ID, provider); // const idl = await Program.fetchIdl(MANGO_V4_ID, provider);
let idl = IDL; const idl = IDL;
const id = Id.fromIds(groupName); const id = Id.fromIds(groupName);
@ -1724,7 +1724,7 @@ export class MangoClient {
const healthRemainingAccounts: PublicKey[] = []; const healthRemainingAccounts: PublicKey[] = [];
let tokenIndices = []; let tokenIndices = [];
for (let mangoAccount of mangoAccounts) { for (const mangoAccount of mangoAccounts) {
tokenIndices.push( tokenIndices.push(
...mangoAccount.tokens ...mangoAccount.tokens
.filter((token) => token.tokenIndex !== 65535) .filter((token) => token.tokenIndex !== 65535)
@ -1747,14 +1747,14 @@ export class MangoClient {
healthRemainingAccounts.push( healthRemainingAccounts.push(
...mintInfos.map((mintInfo) => mintInfo.oracle), ...mintInfos.map((mintInfo) => mintInfo.oracle),
); );
for (let mangoAccount of mangoAccounts) { for (const mangoAccount of mangoAccounts) {
healthRemainingAccounts.push( healthRemainingAccounts.push(
...mangoAccount.serum3 ...mangoAccount.serum3
.filter((serum3Account) => serum3Account.marketIndex !== 65535) .filter((serum3Account) => serum3Account.marketIndex !== 65535)
.map((serum3Account) => serum3Account.openOrders), .map((serum3Account) => serum3Account.openOrders),
); );
} }
for (let mangoAccount of mangoAccounts) { for (const mangoAccount of mangoAccounts) {
healthRemainingAccounts.push( healthRemainingAccounts.push(
...mangoAccount.perps ...mangoAccount.perps
.filter((perp) => perp.marketIndex !== 65535) .filter((perp) => perp.marketIndex !== 65535)

View File

@ -50,7 +50,7 @@ export class Id {
} }
static fromIds(name: string): Id { static fromIds(name: string): Id {
let groupConfig = ids.groups.find((id) => id['name'] === name); const groupConfig = ids.groups.find((id) => id['name'] === name);
return new Id( return new Id(
groupConfig.cluster as Cluster, groupConfig.cluster as Cluster,
name, name,

View File

@ -23,9 +23,9 @@ export function debugAccountMetas(ams: AccountMeta[]) {
export async function findOrCreate<T>( export async function findOrCreate<T>(
entityName: string, entityName: string,
findMethod: Function, findMethod: (...x: any) => any,
findArgs: any[], findArgs: any[],
createMethod: Function, createMethod: (...x: any) => any,
createArgs: any[], createArgs: any[],
): Promise<T> { ): Promise<T> {
let many: T[] = await findMethod(...findArgs); let many: T[] = await findMethod(...findArgs);

4540
yarn.lock

File diff suppressed because it is too large Load Diff