more reorg
Signed-off-by: microwavedcola1 <microwavedcola@gmail.com>
This commit is contained in:
parent
2cc8bfbeeb
commit
06a4bb90ba
|
@ -0,0 +1,175 @@
|
|||
import { I80F48, I80F48Dto } from './I80F48';
|
||||
import {
|
||||
Keypair,
|
||||
PublicKey,
|
||||
SYSVAR_RENT_PUBKEY,
|
||||
Transaction,
|
||||
TransactionInstruction,
|
||||
} from '@solana/web3.js';
|
||||
import { MangoClient } from '../../client';
|
||||
|
||||
export class Bank {
|
||||
public depositIndex: I80F48;
|
||||
public borrowIndex: I80F48;
|
||||
|
||||
static from(
|
||||
publicKey: PublicKey,
|
||||
obj: {
|
||||
group: PublicKey;
|
||||
mint: PublicKey;
|
||||
vault: PublicKey;
|
||||
oracle: PublicKey;
|
||||
depositIndex: I80F48Dto;
|
||||
borrowIndex: I80F48Dto;
|
||||
indexedTotalDeposits: I80F48Dto;
|
||||
indexedTotalBorrows: I80F48Dto;
|
||||
maintAssetWeight: I80F48Dto;
|
||||
initAssetWeight: I80F48Dto;
|
||||
maintLiabWeight: I80F48Dto;
|
||||
initLiabWeight: I80F48Dto;
|
||||
liquidationFee: I80F48Dto;
|
||||
dust: Object;
|
||||
tokenIndex: number;
|
||||
},
|
||||
) {
|
||||
return new Bank(
|
||||
publicKey,
|
||||
obj.group,
|
||||
obj.mint,
|
||||
obj.vault,
|
||||
obj.oracle,
|
||||
obj.depositIndex,
|
||||
obj.borrowIndex,
|
||||
obj.indexedTotalDeposits,
|
||||
obj.indexedTotalBorrows,
|
||||
obj.maintAssetWeight,
|
||||
obj.initAssetWeight,
|
||||
obj.maintLiabWeight,
|
||||
obj.initLiabWeight,
|
||||
obj.liquidationFee,
|
||||
obj.dust,
|
||||
obj.tokenIndex,
|
||||
);
|
||||
}
|
||||
|
||||
constructor(
|
||||
public publicKey: PublicKey,
|
||||
group: PublicKey,
|
||||
mint: PublicKey,
|
||||
public vault: PublicKey,
|
||||
oracle: PublicKey,
|
||||
depositIndex: I80F48Dto,
|
||||
borrowIndex: I80F48Dto,
|
||||
indexedTotalDeposits: I80F48Dto,
|
||||
indexedTotalBorrows: I80F48Dto,
|
||||
maintAssetWeight: I80F48Dto,
|
||||
initAssetWeight: I80F48Dto,
|
||||
maintLiabWeight: I80F48Dto,
|
||||
initLiabWeight: I80F48Dto,
|
||||
liquidationFee: I80F48Dto,
|
||||
dust: Object,
|
||||
public tokenIndex: number,
|
||||
) {
|
||||
this.depositIndex = I80F48.from(depositIndex);
|
||||
this.borrowIndex = I80F48.from(borrowIndex);
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return `Bank ${
|
||||
this.tokenIndex
|
||||
} deposit index - ${this.depositIndex.toNumber()}, borrow index - ${this.borrowIndex.toNumber()}`;
|
||||
}
|
||||
}
|
||||
|
||||
export async function registerToken(
|
||||
client: MangoClient,
|
||||
groupPk: PublicKey,
|
||||
adminPk: PublicKey,
|
||||
mintPk: PublicKey,
|
||||
oraclePk: PublicKey,
|
||||
payer: Keypair,
|
||||
tokenIndex: number,
|
||||
): Promise<void> {
|
||||
const tx = new Transaction();
|
||||
const signers = [payer];
|
||||
const ix = await registerTokenIx(
|
||||
client,
|
||||
groupPk,
|
||||
adminPk,
|
||||
mintPk,
|
||||
oraclePk,
|
||||
payer,
|
||||
tokenIndex,
|
||||
);
|
||||
tx.add(ix);
|
||||
await client.program.provider.send(tx, signers);
|
||||
}
|
||||
|
||||
export async function registerTokenIx(
|
||||
client: MangoClient,
|
||||
groupPk: PublicKey,
|
||||
adminPk: PublicKey,
|
||||
mintPk: PublicKey,
|
||||
oraclePk: PublicKey,
|
||||
payer: Keypair,
|
||||
tokenIndex: number,
|
||||
): Promise<TransactionInstruction> {
|
||||
return await client.program.methods
|
||||
.registerToken(tokenIndex, 0.8, 0.6, 1.2, 1.4, 0.02)
|
||||
.accounts({
|
||||
group: groupPk,
|
||||
admin: adminPk,
|
||||
mint: mintPk,
|
||||
oracle: oraclePk,
|
||||
payer: payer.publicKey,
|
||||
rent: SYSVAR_RENT_PUBKEY,
|
||||
})
|
||||
.signers([payer])
|
||||
.instruction();
|
||||
}
|
||||
|
||||
export async function getBank(
|
||||
client: MangoClient,
|
||||
address: PublicKey,
|
||||
): Promise<Bank> {
|
||||
return Bank.from(address, await client.program.account.bank.fetch(address));
|
||||
}
|
||||
|
||||
export async function getBanksForGroup(
|
||||
client: MangoClient,
|
||||
groupPk: PublicKey,
|
||||
): Promise<Bank[]> {
|
||||
return (
|
||||
await client.program.account.bank.all([
|
||||
{
|
||||
memcmp: {
|
||||
bytes: groupPk.toBase58(),
|
||||
offset: 8,
|
||||
},
|
||||
},
|
||||
])
|
||||
).map((tuple) => Bank.from(tuple.publicKey, tuple.account));
|
||||
}
|
||||
|
||||
export async function getBankForGroupAndMint(
|
||||
client: MangoClient,
|
||||
groupPk: PublicKey,
|
||||
mintPk: PublicKey,
|
||||
): Promise<Bank[]> {
|
||||
return (
|
||||
await client.program.account.bank.all([
|
||||
{
|
||||
memcmp: {
|
||||
bytes: groupPk.toBase58(),
|
||||
offset: 8,
|
||||
},
|
||||
},
|
||||
{
|
||||
memcmp: {
|
||||
bytes: mintPk.toBase58(),
|
||||
offset: 40,
|
||||
},
|
||||
},
|
||||
])
|
||||
).map((tuple) => Bank.from(tuple.publicKey, tuple.account));
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
import {
|
||||
Keypair,
|
||||
PublicKey,
|
||||
Transaction,
|
||||
TransactionInstruction,
|
||||
} from '@solana/web3.js';
|
||||
import { MangoClient } from '../../client';
|
||||
|
||||
export class Group {
|
||||
static from(publicKey: PublicKey, obj: { admin: PublicKey }): Group {
|
||||
return new Group(publicKey, obj.admin);
|
||||
}
|
||||
|
||||
constructor(public publicKey: PublicKey, public admin: PublicKey) {}
|
||||
}
|
||||
|
||||
export async function createGroup(
|
||||
client: MangoClient,
|
||||
adminPk: PublicKey,
|
||||
payer: Keypair,
|
||||
): Promise<void> {
|
||||
const tx = new Transaction();
|
||||
const signers = [payer];
|
||||
const ix = await createGroupIx(client, adminPk, payer);
|
||||
tx.add(ix);
|
||||
await client.program.provider.send(tx, signers);
|
||||
}
|
||||
|
||||
export async function createGroupIx(
|
||||
client: MangoClient,
|
||||
adminPk: PublicKey,
|
||||
payer: Keypair,
|
||||
): Promise<TransactionInstruction> {
|
||||
return await client.program.methods
|
||||
.createGroup()
|
||||
.accounts({
|
||||
admin: adminPk,
|
||||
payer: payer.publicKey,
|
||||
})
|
||||
.signers([payer])
|
||||
.instruction();
|
||||
}
|
||||
|
||||
export async function getGroupForAdmin(
|
||||
client: MangoClient,
|
||||
adminPk: PublicKey,
|
||||
): Promise<Group[]> {
|
||||
return (
|
||||
await client.program.account.group.all([
|
||||
{
|
||||
memcmp: {
|
||||
bytes: adminPk.toBase58(),
|
||||
offset: 8,
|
||||
},
|
||||
},
|
||||
])
|
||||
).map((tuple) => Group.from(tuple.publicKey, tuple.account));
|
||||
}
|
|
@ -0,0 +1,320 @@
|
|||
import {
|
||||
Keypair,
|
||||
PublicKey,
|
||||
Transaction,
|
||||
TransactionInstruction,
|
||||
} from '@solana/web3.js';
|
||||
import { Bank } from './bank';
|
||||
import { I80F48, I80F48Dto } from './I80F48';
|
||||
import { MangoClient } from '../../client';
|
||||
import { BN } from '@project-serum/anchor';
|
||||
|
||||
export class MangoAccount {
|
||||
public tokens: TokenAccount[];
|
||||
|
||||
static from(
|
||||
publicKey: PublicKey,
|
||||
obj: {
|
||||
group: PublicKey;
|
||||
owner: PublicKey;
|
||||
delegate: PublicKey;
|
||||
tokens: unknown;
|
||||
serum3: Object;
|
||||
perps: unknown;
|
||||
beingLiquidated: number;
|
||||
isBankrupt: number;
|
||||
accountNum: number;
|
||||
bump: number;
|
||||
reserved: number[];
|
||||
},
|
||||
) {
|
||||
return new MangoAccount(
|
||||
publicKey,
|
||||
obj.group,
|
||||
obj.owner,
|
||||
obj.delegate,
|
||||
obj.tokens as { values: TokenAccountDto[] },
|
||||
obj.serum3,
|
||||
obj.perps,
|
||||
obj.beingLiquidated,
|
||||
obj.isBankrupt,
|
||||
obj.accountNum,
|
||||
obj.bump,
|
||||
obj.reserved,
|
||||
);
|
||||
}
|
||||
|
||||
constructor(
|
||||
public publicKey: PublicKey,
|
||||
group: PublicKey,
|
||||
owner: PublicKey,
|
||||
delegate: PublicKey,
|
||||
tokens: { values: TokenAccountDto[] },
|
||||
serum3: Object,
|
||||
perps: unknown,
|
||||
beingLiquidated: number,
|
||||
isBankrupt: number,
|
||||
accountNum: number,
|
||||
bump: number,
|
||||
reserved: number[],
|
||||
) {
|
||||
this.tokens = tokens.values.map((dto) => TokenAccount.from(dto));
|
||||
}
|
||||
|
||||
find(tokenIndex: number): TokenAccount | undefined {
|
||||
return this.tokens.find((ta) => ta.tokenIndex == tokenIndex);
|
||||
}
|
||||
|
||||
getNativeDeposit(bank: Bank): I80F48 {
|
||||
const ta = this.find(bank.tokenIndex);
|
||||
return bank.depositIndex.mul(ta?.indexedValue!);
|
||||
}
|
||||
|
||||
getNativeBorrow(bank: Bank): I80F48 {
|
||||
const ta = this.find(bank.tokenIndex);
|
||||
return bank.borrowIndex.mul(ta?.indexedValue!);
|
||||
}
|
||||
}
|
||||
|
||||
export class TokenAccount {
|
||||
static from(dto: TokenAccountDto) {
|
||||
return new TokenAccount(
|
||||
I80F48.from(dto.indexedValue),
|
||||
dto.tokenIndex,
|
||||
dto.inUseCount,
|
||||
);
|
||||
}
|
||||
|
||||
constructor(
|
||||
public indexedValue: I80F48,
|
||||
public tokenIndex: number,
|
||||
public inUseCount: number,
|
||||
) {}
|
||||
}
|
||||
|
||||
export class TokenAccountDto {
|
||||
constructor(
|
||||
public indexedValue: I80F48Dto,
|
||||
public tokenIndex: number,
|
||||
public inUseCount: number,
|
||||
public reserved: number[],
|
||||
) {}
|
||||
}
|
||||
|
||||
export async function createMangoAccount(
|
||||
client: MangoClient,
|
||||
groupPk: PublicKey,
|
||||
ownerPk: PublicKey,
|
||||
payer: Keypair,
|
||||
): Promise<void> {
|
||||
const tx = new Transaction();
|
||||
const signers = [payer];
|
||||
const ix = await createMangoAccountIx(client, groupPk, ownerPk, payer);
|
||||
tx.add(ix);
|
||||
await client.program.provider.send(tx, signers);
|
||||
}
|
||||
|
||||
export async function createMangoAccountIx(
|
||||
client: MangoClient,
|
||||
groupPk: PublicKey,
|
||||
ownerPk: PublicKey,
|
||||
payer: Keypair,
|
||||
): Promise<TransactionInstruction> {
|
||||
return await client.program.methods
|
||||
.createAccount(11)
|
||||
.accounts({
|
||||
group: groupPk,
|
||||
owner: ownerPk,
|
||||
payer: payer.publicKey,
|
||||
})
|
||||
.signers([payer])
|
||||
.instruction();
|
||||
}
|
||||
|
||||
export async function closeMangoAccount(
|
||||
client: MangoClient,
|
||||
accountPk: PublicKey,
|
||||
ownerPk: PublicKey,
|
||||
) {
|
||||
const tx = new Transaction();
|
||||
const ix = await closeMangoAccountIx(client, accountPk, ownerPk);
|
||||
tx.add(ix);
|
||||
await client.program.provider.send(tx);
|
||||
}
|
||||
|
||||
export async function closeMangoAccountIx(
|
||||
client: MangoClient,
|
||||
accountPk: PublicKey,
|
||||
ownerPk: PublicKey,
|
||||
): Promise<TransactionInstruction> {
|
||||
return await client.program.methods
|
||||
.closeAccount()
|
||||
.accounts({
|
||||
account: accountPk,
|
||||
owner: ownerPk,
|
||||
solDestination: ownerPk,
|
||||
})
|
||||
.instruction();
|
||||
}
|
||||
|
||||
export async function getMangoAccount(
|
||||
client: MangoClient,
|
||||
address: PublicKey,
|
||||
): Promise<MangoAccount> {
|
||||
return MangoAccount.from(
|
||||
address,
|
||||
await client.program.account.mangoAccount.fetch(address),
|
||||
);
|
||||
}
|
||||
|
||||
export async function getMangoAccountsForGroup(
|
||||
client: MangoClient,
|
||||
groupPk: PublicKey,
|
||||
): Promise<MangoAccount[]> {
|
||||
return (
|
||||
await client.program.account.mangoAccount.all([
|
||||
{
|
||||
memcmp: {
|
||||
bytes: groupPk.toBase58(),
|
||||
offset: 8,
|
||||
},
|
||||
},
|
||||
])
|
||||
).map((pa) => MangoAccount.from(pa.publicKey, pa.account));
|
||||
}
|
||||
|
||||
export async function getMangoAccountsForGroupAndOwner(
|
||||
client: MangoClient,
|
||||
groupPk: PublicKey,
|
||||
ownerPk: PublicKey,
|
||||
): Promise<MangoAccount[]> {
|
||||
return (
|
||||
await client.program.account.mangoAccount.all([
|
||||
{
|
||||
memcmp: {
|
||||
bytes: groupPk.toBase58(),
|
||||
offset: 8,
|
||||
},
|
||||
},
|
||||
{
|
||||
memcmp: {
|
||||
bytes: ownerPk.toBase58(),
|
||||
offset: 40,
|
||||
},
|
||||
},
|
||||
])
|
||||
).map((pa) => MangoAccount.from(pa.publicKey, pa.account));
|
||||
}
|
||||
|
||||
export async function deposit(
|
||||
client: MangoClient,
|
||||
groupPk: PublicKey,
|
||||
mangoAccountPk: PublicKey,
|
||||
bankPk: PublicKey,
|
||||
vaultPk: PublicKey,
|
||||
tokenAccountPk: PublicKey,
|
||||
oraclePk: PublicKey,
|
||||
ownerPk: PublicKey,
|
||||
amount: number,
|
||||
): Promise<void> {
|
||||
const tx = new Transaction();
|
||||
const ix = await depositIx(
|
||||
client,
|
||||
groupPk,
|
||||
mangoAccountPk,
|
||||
bankPk,
|
||||
vaultPk,
|
||||
tokenAccountPk,
|
||||
oraclePk,
|
||||
ownerPk,
|
||||
amount,
|
||||
);
|
||||
tx.add(ix);
|
||||
await client.program.provider.send(tx);
|
||||
}
|
||||
|
||||
export async function depositIx(
|
||||
client: MangoClient,
|
||||
groupPk: PublicKey,
|
||||
mangoAccountPk: PublicKey,
|
||||
bankPk: PublicKey,
|
||||
vaultPk: PublicKey,
|
||||
tokenAccountPk: PublicKey,
|
||||
oraclePk: PublicKey,
|
||||
ownerPk: PublicKey,
|
||||
amount: number,
|
||||
): Promise<TransactionInstruction> {
|
||||
return await client.program.methods
|
||||
.deposit(new BN(amount))
|
||||
.accounts({
|
||||
group: groupPk,
|
||||
account: mangoAccountPk,
|
||||
bank: bankPk,
|
||||
vault: vaultPk,
|
||||
tokenAccount: tokenAccountPk,
|
||||
tokenAuthority: ownerPk,
|
||||
})
|
||||
.remainingAccounts([
|
||||
{ pubkey: bankPk, isWritable: false, isSigner: false },
|
||||
{ pubkey: oraclePk, isWritable: false, isSigner: false },
|
||||
])
|
||||
.instruction();
|
||||
}
|
||||
|
||||
export async function withdraw(
|
||||
client: MangoClient,
|
||||
groupPk: PublicKey,
|
||||
mangoAccountPk: PublicKey,
|
||||
bankPk: PublicKey,
|
||||
vaultPk: PublicKey,
|
||||
tokenAccountPk: PublicKey,
|
||||
oraclePk: PublicKey,
|
||||
ownerPk: PublicKey,
|
||||
amount: number,
|
||||
allowBorrow: boolean,
|
||||
): Promise<void> {
|
||||
const tx = new Transaction();
|
||||
const ix = await withdrawIx(
|
||||
client,
|
||||
groupPk,
|
||||
mangoAccountPk,
|
||||
bankPk,
|
||||
vaultPk,
|
||||
tokenAccountPk,
|
||||
oraclePk,
|
||||
ownerPk,
|
||||
amount,
|
||||
allowBorrow,
|
||||
);
|
||||
tx.add(ix);
|
||||
await client.program.provider.send(tx);
|
||||
}
|
||||
|
||||
export async function withdrawIx(
|
||||
client: MangoClient,
|
||||
groupPk: PublicKey,
|
||||
mangoAccountPk: PublicKey,
|
||||
bankPk: PublicKey,
|
||||
vaultPk: PublicKey,
|
||||
tokenAccountPk: PublicKey,
|
||||
oraclePk: PublicKey,
|
||||
ownerPk: PublicKey,
|
||||
amount: number,
|
||||
allowBorrow: boolean,
|
||||
): Promise<TransactionInstruction> {
|
||||
return await client.program.methods
|
||||
.withdraw(new BN(amount), allowBorrow)
|
||||
.accounts({
|
||||
group: groupPk,
|
||||
account: mangoAccountPk,
|
||||
bank: bankPk,
|
||||
vault: vaultPk,
|
||||
tokenAccount: tokenAccountPk,
|
||||
tokenAuthority: ownerPk,
|
||||
})
|
||||
.remainingAccounts([
|
||||
{ pubkey: bankPk, isWritable: false, isSigner: false },
|
||||
{ pubkey: oraclePk, isWritable: false, isSigner: false },
|
||||
])
|
||||
.instruction();
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
import { I80F48, I80F48Dto } from './I80F48';
|
||||
import { Keypair, PublicKey } from '@solana/web3.js';
|
||||
import BN from 'bn.js';
|
||||
import { MangoClient } from '../../client';
|
||||
|
||||
export class StubOracle {
|
||||
public price: I80F48;
|
||||
public lastUpdated: number;
|
||||
|
||||
static from(
|
||||
publicKey: PublicKey,
|
||||
obj: {
|
||||
group: PublicKey;
|
||||
mint: PublicKey;
|
||||
price: I80F48Dto;
|
||||
lastUpdated: BN;
|
||||
reserved: unknown;
|
||||
},
|
||||
): StubOracle {
|
||||
return new StubOracle(
|
||||
publicKey,
|
||||
obj.group,
|
||||
obj.mint,
|
||||
obj.price,
|
||||
obj.lastUpdated,
|
||||
);
|
||||
}
|
||||
|
||||
constructor(
|
||||
public publicKey: PublicKey,
|
||||
public group: PublicKey,
|
||||
public mint: PublicKey,
|
||||
price: I80F48Dto,
|
||||
lastUpdated: BN,
|
||||
) {
|
||||
this.price = I80F48.from(price);
|
||||
this.lastUpdated = lastUpdated.toNumber();
|
||||
}
|
||||
}
|
||||
|
||||
export async function createStubOracle(
|
||||
client: MangoClient,
|
||||
groupPk: PublicKey,
|
||||
adminPk: PublicKey,
|
||||
tokenMintPk: PublicKey,
|
||||
payer: Keypair,
|
||||
staticPrice: number,
|
||||
): Promise<void> {
|
||||
return await client.program.methods
|
||||
.createStubOracle({ val: I80F48.fromNumber(staticPrice).getData() })
|
||||
.accounts({
|
||||
group: groupPk,
|
||||
admin: adminPk,
|
||||
tokenMint: tokenMintPk,
|
||||
payer: payer.publicKey,
|
||||
})
|
||||
.signers([payer])
|
||||
.rpc();
|
||||
}
|
||||
|
||||
export async function setStubOracle(
|
||||
client: MangoClient,
|
||||
groupPk: PublicKey,
|
||||
adminPk: PublicKey,
|
||||
tokenMintPk: PublicKey,
|
||||
payer: Keypair,
|
||||
staticPrice: number,
|
||||
): Promise<void> {
|
||||
return await client.program.methods
|
||||
.setStubOracle({ val: new BN(staticPrice) })
|
||||
.accounts({
|
||||
group: groupPk,
|
||||
admin: adminPk,
|
||||
tokenMint: tokenMintPk,
|
||||
payer: payer.publicKey,
|
||||
})
|
||||
.signers([payer])
|
||||
.rpc();
|
||||
}
|
||||
|
||||
export async function getStubOracleForGroupAndMint(
|
||||
client: MangoClient,
|
||||
groupPk: PublicKey,
|
||||
mintPk: PublicKey,
|
||||
): Promise<StubOracle[]> {
|
||||
return (
|
||||
await client.program.account.stubOracle.all([
|
||||
{
|
||||
memcmp: {
|
||||
bytes: groupPk.toBase58(),
|
||||
offset: 8,
|
||||
},
|
||||
},
|
||||
{
|
||||
memcmp: {
|
||||
bytes: mintPk.toBase58(),
|
||||
offset: 40,
|
||||
},
|
||||
},
|
||||
])
|
||||
).map((pa) => StubOracle.from(pa.publicKey, pa.account));
|
||||
}
|
|
@ -0,0 +1,135 @@
|
|||
import {
|
||||
Keypair,
|
||||
PublicKey,
|
||||
Transaction,
|
||||
TransactionInstruction,
|
||||
} from '@solana/web3.js';
|
||||
import { MangoClient } from '../../client';
|
||||
import * as bs58 from 'bs58';
|
||||
|
||||
export class Serum3Market {
|
||||
static from(
|
||||
publicKey: PublicKey,
|
||||
obj: {
|
||||
group: PublicKey;
|
||||
serumProgram: PublicKey;
|
||||
serumMarketExternal: PublicKey;
|
||||
marketIndex: number;
|
||||
baseTokenIndex: number;
|
||||
quoteTokenIndex: number;
|
||||
bump: number;
|
||||
reserved: unknown;
|
||||
},
|
||||
): Serum3Market {
|
||||
return new Serum3Market(
|
||||
publicKey,
|
||||
obj.group,
|
||||
obj.serumProgram,
|
||||
obj.serumMarketExternal,
|
||||
obj.marketIndex,
|
||||
obj.baseTokenIndex,
|
||||
obj.quoteTokenIndex,
|
||||
);
|
||||
}
|
||||
|
||||
constructor(
|
||||
public publicKey: PublicKey,
|
||||
public group: PublicKey,
|
||||
public serumProgram: PublicKey,
|
||||
public serumMarketExternal: PublicKey,
|
||||
public marketIndex: number,
|
||||
public baseTokenIndex: number,
|
||||
public quoteTokenIndex: number,
|
||||
) {}
|
||||
}
|
||||
|
||||
export async function serum3RegisterMarket(
|
||||
client: MangoClient,
|
||||
groupPk: PublicKey,
|
||||
adminPk: PublicKey,
|
||||
serumProgramPk: PublicKey,
|
||||
serumMarketExternalPk: PublicKey,
|
||||
quoteBankPk: PublicKey,
|
||||
baseBankPk: PublicKey,
|
||||
payer: Keypair,
|
||||
marketIndex: number,
|
||||
): Promise<void> {
|
||||
const tx = new Transaction();
|
||||
const ix = await serum3RegisterMarketIx(
|
||||
client,
|
||||
groupPk,
|
||||
adminPk,
|
||||
serumProgramPk,
|
||||
serumMarketExternalPk,
|
||||
quoteBankPk,
|
||||
baseBankPk,
|
||||
payer,
|
||||
marketIndex,
|
||||
);
|
||||
tx.add(ix);
|
||||
await client.program.provider.send(tx, [payer]);
|
||||
}
|
||||
|
||||
export async function serum3RegisterMarketIx(
|
||||
client: MangoClient,
|
||||
groupPk: PublicKey,
|
||||
adminPk: PublicKey,
|
||||
serumProgramPk: PublicKey,
|
||||
serumMarketExternalPk: PublicKey,
|
||||
quoteBankPk: PublicKey,
|
||||
baseBankPk: PublicKey,
|
||||
payer: Keypair,
|
||||
marketIndex: number,
|
||||
): Promise<TransactionInstruction> {
|
||||
return await client.program.methods
|
||||
.serum3RegisterMarket(marketIndex)
|
||||
.accounts({
|
||||
group: groupPk,
|
||||
admin: adminPk,
|
||||
serumProgram: serumProgramPk,
|
||||
serumMarketExternal: serumMarketExternalPk,
|
||||
quoteBank: quoteBankPk,
|
||||
baseBank: baseBankPk,
|
||||
payer: payer.publicKey,
|
||||
})
|
||||
.instruction();
|
||||
}
|
||||
|
||||
export async function getSerum3MarketForBaseAndQuote(
|
||||
client: MangoClient,
|
||||
groupPk: PublicKey,
|
||||
baseTokenIndex: number,
|
||||
quoteTokenIndex: number,
|
||||
): Promise<Serum3Market[]> {
|
||||
const bbuf = Buffer.alloc(2);
|
||||
bbuf.writeUInt16LE(baseTokenIndex);
|
||||
|
||||
const qbuf = Buffer.alloc(2);
|
||||
qbuf.writeUInt16LE(quoteTokenIndex);
|
||||
|
||||
const bumpfbuf = Buffer.alloc(1);
|
||||
bumpfbuf.writeUInt8(255);
|
||||
|
||||
return (
|
||||
await client.program.account.serum3Market.all([
|
||||
{
|
||||
memcmp: {
|
||||
bytes: groupPk.toBase58(),
|
||||
offset: 8,
|
||||
},
|
||||
},
|
||||
{
|
||||
memcmp: {
|
||||
bytes: bs58.encode(bbuf),
|
||||
offset: 106,
|
||||
},
|
||||
},
|
||||
{
|
||||
memcmp: {
|
||||
bytes: bs58.encode(qbuf),
|
||||
offset: 108,
|
||||
},
|
||||
},
|
||||
])
|
||||
).map((tuple) => Serum3Market.from(tuple.publicKey, tuple.account));
|
||||
}
|
|
@ -3,27 +3,31 @@ import { Connection, Keypair, PublicKey } from '@solana/web3.js';
|
|||
import * as spl from '@solana/spl-token';
|
||||
import fs from 'fs';
|
||||
import { MangoClient } from './client';
|
||||
import { findOrCreate } from './utils';
|
||||
import {
|
||||
createGroup,
|
||||
createMangoAccount,
|
||||
createStubOracle,
|
||||
deposit,
|
||||
Bank,
|
||||
getBank,
|
||||
getBankForGroupAndMint,
|
||||
getGroupForAdmin,
|
||||
registerToken,
|
||||
} from './accounts/types/bank';
|
||||
import {
|
||||
createMangoAccount,
|
||||
deposit,
|
||||
getMangoAccount,
|
||||
getMangoAccountsForGroupAndOwner,
|
||||
getSerum3MarketForBaseAndQuote,
|
||||
getStubOracleForGroupAndMint,
|
||||
registerToken,
|
||||
serum3RegisterMarket,
|
||||
MangoAccount,
|
||||
withdraw,
|
||||
} from './instructions';
|
||||
import { findOrCreate } from './utils';
|
||||
import { Bank } from './types/bank';
|
||||
import { MangoAccount } from './types/mangoAccount';
|
||||
import { Group } from './types/group';
|
||||
import { Serum3Market } from './types/serum3';
|
||||
} from './accounts/types/mangoAccount';
|
||||
import { createGroup, getGroupForAdmin, Group } from './accounts/types/group';
|
||||
import {
|
||||
getSerum3MarketForBaseAndQuote,
|
||||
Serum3Market,
|
||||
serum3RegisterMarket,
|
||||
} from './accounts/types/serum3';
|
||||
import {
|
||||
createStubOracle,
|
||||
getStubOracleForGroupAndMint,
|
||||
} from './accounts/types/oracle';
|
||||
|
||||
async function main() {
|
||||
//
|
||||
|
|
43
ts/index.ts
43
ts/index.ts
|
@ -1,11 +1,36 @@
|
|||
export * from './client';
|
||||
export * from './instructions';
|
||||
export * from './types/types';
|
||||
export * from './types/I80F48';
|
||||
export { Bank } from './types/bank';
|
||||
export { MangoAccount } from './types/mangoAccount';
|
||||
export { Group } from './types/group';
|
||||
export { TokenAccountDto } from './types/mangoAccount';
|
||||
export { TokenAccount } from './types/mangoAccount';
|
||||
export { Serum3Market } from './types/serum3';
|
||||
export { StubOracle } from './types/oracle';
|
||||
export * from './accounts/types/types';
|
||||
export * from './accounts/types/I80F48';
|
||||
export { Bank } from './accounts/types/bank';
|
||||
export { MangoAccount } from './accounts/types/mangoAccount';
|
||||
export { Group } from './accounts/types/group';
|
||||
export { TokenAccountDto } from './accounts/types/mangoAccount';
|
||||
export { TokenAccount } from './accounts/types/mangoAccount';
|
||||
export { Serum3Market } from './accounts/types/serum3';
|
||||
export { StubOracle } from './accounts/types/oracle';
|
||||
export { getGroupForAdmin } from './accounts/types/group';
|
||||
export { createGroupIx } from './accounts/types/group';
|
||||
export { createGroup } from './accounts/types/group';
|
||||
export { registerTokenIx } from './accounts/types/bank';
|
||||
export { registerToken } from './accounts/types/bank';
|
||||
export { getBankForGroupAndMint } from './accounts/types/bank';
|
||||
export { getBanksForGroup } from './accounts/types/bank';
|
||||
export { getBank } from './accounts/types/bank';
|
||||
export { getMangoAccountsForGroupAndOwner } from './accounts/types/mangoAccount';
|
||||
export { getMangoAccountsForGroup } from './accounts/types/mangoAccount';
|
||||
export { getMangoAccount } from './accounts/types/mangoAccount';
|
||||
export { createMangoAccountIx } from './accounts/types/mangoAccount';
|
||||
export { createMangoAccount } from './accounts/types/mangoAccount';
|
||||
export { closeMangoAccountIx } from './accounts/types/mangoAccount';
|
||||
export { closeMangoAccount } from './accounts/types/mangoAccount';
|
||||
export { withdrawIx } from './accounts/types/mangoAccount';
|
||||
export { withdraw } from './accounts/types/mangoAccount';
|
||||
export { depositIx } from './accounts/types/mangoAccount';
|
||||
export { deposit } from './accounts/types/mangoAccount';
|
||||
export { getSerum3MarketForBaseAndQuote } from './accounts/types/serum3';
|
||||
export { serum3RegisterMarketIx } from './accounts/types/serum3';
|
||||
export { serum3RegisterMarket } from './accounts/types/serum3';
|
||||
export { getStubOracleForGroupAndMint } from './accounts/types/oracle';
|
||||
export { setStubOracle } from './accounts/types/oracle';
|
||||
export { createStubOracle } from './accounts/types/oracle';
|
||||
|
|
|
@ -1,389 +1,19 @@
|
|||
import { BN } from '@project-serum/anchor';
|
||||
import {
|
||||
Keypair,
|
||||
PublicKey,
|
||||
SYSVAR_RENT_PUBKEY,
|
||||
Transaction,
|
||||
TransactionInstruction,
|
||||
} from '@solana/web3.js';
|
||||
import * as bs58 from 'bs58';
|
||||
import { MangoClient } from './client';
|
||||
import { I80F48 } from './types/I80F48';
|
||||
import { Bank } from './types/bank';
|
||||
import { MangoAccount } from './types/mangoAccount';
|
||||
import { Group } from './types/group';
|
||||
import { Serum3Market } from './types/serum3';
|
||||
import { StubOracle } from './types/oracle';
|
||||
|
||||
//
|
||||
// group
|
||||
//
|
||||
|
||||
export async function createGroup(
|
||||
client: MangoClient,
|
||||
adminPk: PublicKey,
|
||||
payer: Keypair,
|
||||
): Promise<void> {
|
||||
const tx = new Transaction();
|
||||
const signers = [payer];
|
||||
const ix = await createGroupIx(client, adminPk, payer);
|
||||
tx.add(ix);
|
||||
await client.program.provider.send(tx, signers);
|
||||
}
|
||||
|
||||
export async function createGroupIx(
|
||||
client: MangoClient,
|
||||
adminPk: PublicKey,
|
||||
payer: Keypair,
|
||||
): Promise<TransactionInstruction> {
|
||||
return await client.program.methods
|
||||
.createGroup()
|
||||
.accounts({
|
||||
admin: adminPk,
|
||||
payer: payer.publicKey,
|
||||
})
|
||||
.signers([payer])
|
||||
.instruction();
|
||||
}
|
||||
|
||||
export async function getGroupForAdmin(
|
||||
client: MangoClient,
|
||||
adminPk: PublicKey,
|
||||
): Promise<Group[]> {
|
||||
return (
|
||||
await client.program.account.group.all([
|
||||
{
|
||||
memcmp: {
|
||||
bytes: adminPk.toBase58(),
|
||||
offset: 8,
|
||||
},
|
||||
},
|
||||
])
|
||||
).map((tuple) => Group.from(tuple.publicKey, tuple.account));
|
||||
}
|
||||
|
||||
//
|
||||
// token / bank
|
||||
//
|
||||
|
||||
export async function registerToken(
|
||||
client: MangoClient,
|
||||
groupPk: PublicKey,
|
||||
adminPk: PublicKey,
|
||||
mintPk: PublicKey,
|
||||
oraclePk: PublicKey,
|
||||
payer: Keypair,
|
||||
tokenIndex: number,
|
||||
): Promise<void> {
|
||||
const tx = new Transaction();
|
||||
const signers = [payer];
|
||||
const ix = await registerTokenIx(
|
||||
client,
|
||||
groupPk,
|
||||
adminPk,
|
||||
mintPk,
|
||||
oraclePk,
|
||||
payer,
|
||||
tokenIndex,
|
||||
);
|
||||
tx.add(ix);
|
||||
await client.program.provider.send(tx, signers);
|
||||
}
|
||||
|
||||
export async function registerTokenIx(
|
||||
client: MangoClient,
|
||||
groupPk: PublicKey,
|
||||
adminPk: PublicKey,
|
||||
mintPk: PublicKey,
|
||||
oraclePk: PublicKey,
|
||||
payer: Keypair,
|
||||
tokenIndex: number,
|
||||
): Promise<TransactionInstruction> {
|
||||
return await client.program.methods
|
||||
.registerToken(tokenIndex, 0.8, 0.6, 1.2, 1.4, 0.02)
|
||||
.accounts({
|
||||
group: groupPk,
|
||||
admin: adminPk,
|
||||
mint: mintPk,
|
||||
oracle: oraclePk,
|
||||
payer: payer.publicKey,
|
||||
rent: SYSVAR_RENT_PUBKEY,
|
||||
})
|
||||
.signers([payer])
|
||||
.instruction();
|
||||
}
|
||||
|
||||
export async function getBank(
|
||||
client: MangoClient,
|
||||
address: PublicKey,
|
||||
): Promise<Bank> {
|
||||
return Bank.from(address, await client.program.account.bank.fetch(address));
|
||||
}
|
||||
|
||||
export async function getBanksForGroup(
|
||||
client: MangoClient,
|
||||
groupPk: PublicKey,
|
||||
): Promise<Bank[]> {
|
||||
return (
|
||||
await client.program.account.bank.all([
|
||||
{
|
||||
memcmp: {
|
||||
bytes: groupPk.toBase58(),
|
||||
offset: 8,
|
||||
},
|
||||
},
|
||||
])
|
||||
).map((tuple) => Bank.from(tuple.publicKey, tuple.account));
|
||||
}
|
||||
|
||||
export async function getBankForGroupAndMint(
|
||||
client: MangoClient,
|
||||
groupPk: PublicKey,
|
||||
mintPk: PublicKey,
|
||||
): Promise<Bank[]> {
|
||||
return (
|
||||
await client.program.account.bank.all([
|
||||
{
|
||||
memcmp: {
|
||||
bytes: groupPk.toBase58(),
|
||||
offset: 8,
|
||||
},
|
||||
},
|
||||
{
|
||||
memcmp: {
|
||||
bytes: mintPk.toBase58(),
|
||||
offset: 40,
|
||||
},
|
||||
},
|
||||
])
|
||||
).map((tuple) => Bank.from(tuple.publicKey, tuple.account));
|
||||
}
|
||||
|
||||
//
|
||||
// mango account
|
||||
//
|
||||
|
||||
export async function closeMangoAccount(
|
||||
client: MangoClient,
|
||||
accountPk: PublicKey,
|
||||
ownerPk: PublicKey,
|
||||
) {
|
||||
const tx = new Transaction();
|
||||
const ix = await closeMangoAccountIx(client, accountPk, ownerPk);
|
||||
tx.add(ix);
|
||||
await client.program.provider.send(tx);
|
||||
}
|
||||
|
||||
export async function closeMangoAccountIx(
|
||||
client: MangoClient,
|
||||
accountPk: PublicKey,
|
||||
ownerPk: PublicKey,
|
||||
): Promise<TransactionInstruction> {
|
||||
return await client.program.methods
|
||||
.closeAccount()
|
||||
.accounts({
|
||||
account: accountPk,
|
||||
owner: ownerPk,
|
||||
solDestination: ownerPk,
|
||||
})
|
||||
.instruction();
|
||||
}
|
||||
|
||||
export async function createMangoAccount(
|
||||
client: MangoClient,
|
||||
groupPk: PublicKey,
|
||||
ownerPk: PublicKey,
|
||||
payer: Keypair,
|
||||
): Promise<void> {
|
||||
const tx = new Transaction();
|
||||
const signers = [payer];
|
||||
const ix = await createMangoAccountIx(client, groupPk, ownerPk, payer);
|
||||
tx.add(ix);
|
||||
await client.program.provider.send(tx, signers);
|
||||
}
|
||||
|
||||
export async function createMangoAccountIx(
|
||||
client: MangoClient,
|
||||
groupPk: PublicKey,
|
||||
ownerPk: PublicKey,
|
||||
payer: Keypair,
|
||||
): Promise<TransactionInstruction> {
|
||||
return await client.program.methods
|
||||
.createAccount(11)
|
||||
.accounts({
|
||||
group: groupPk,
|
||||
owner: ownerPk,
|
||||
payer: payer.publicKey,
|
||||
})
|
||||
.signers([payer])
|
||||
.instruction();
|
||||
}
|
||||
|
||||
export async function getMangoAccount(
|
||||
client: MangoClient,
|
||||
address: PublicKey,
|
||||
): Promise<MangoAccount> {
|
||||
return MangoAccount.from(
|
||||
address,
|
||||
await client.program.account.mangoAccount.fetch(address),
|
||||
);
|
||||
}
|
||||
export async function getMangoAccountsForGroup(
|
||||
client: MangoClient,
|
||||
groupPk: PublicKey,
|
||||
): Promise<MangoAccount[]> {
|
||||
return (
|
||||
await client.program.account.mangoAccount.all([
|
||||
{
|
||||
memcmp: {
|
||||
bytes: groupPk.toBase58(),
|
||||
offset: 8,
|
||||
},
|
||||
},
|
||||
])
|
||||
).map((pa) => MangoAccount.from(pa.publicKey, pa.account));
|
||||
}
|
||||
|
||||
export async function getMangoAccountsForGroupAndOwner(
|
||||
client: MangoClient,
|
||||
groupPk: PublicKey,
|
||||
ownerPk: PublicKey,
|
||||
): Promise<MangoAccount[]> {
|
||||
return (
|
||||
await client.program.account.mangoAccount.all([
|
||||
{
|
||||
memcmp: {
|
||||
bytes: groupPk.toBase58(),
|
||||
offset: 8,
|
||||
},
|
||||
},
|
||||
{
|
||||
memcmp: {
|
||||
bytes: ownerPk.toBase58(),
|
||||
offset: 40,
|
||||
},
|
||||
},
|
||||
])
|
||||
).map((pa) => MangoAccount.from(pa.publicKey, pa.account));
|
||||
}
|
||||
|
||||
//
|
||||
// deposit & withdraw
|
||||
//
|
||||
|
||||
export async function deposit(
|
||||
client: MangoClient,
|
||||
groupPk: PublicKey,
|
||||
mangoAccountPk: PublicKey,
|
||||
bankPk: PublicKey,
|
||||
vaultPk: PublicKey,
|
||||
tokenAccountPk: PublicKey,
|
||||
oraclePk: PublicKey,
|
||||
ownerPk: PublicKey,
|
||||
amount: number,
|
||||
): Promise<void> {
|
||||
const tx = new Transaction();
|
||||
const ix = await depositIx(
|
||||
client,
|
||||
groupPk,
|
||||
mangoAccountPk,
|
||||
bankPk,
|
||||
vaultPk,
|
||||
tokenAccountPk,
|
||||
oraclePk,
|
||||
ownerPk,
|
||||
amount,
|
||||
);
|
||||
tx.add(ix);
|
||||
await client.program.provider.send(tx);
|
||||
}
|
||||
|
||||
export async function depositIx(
|
||||
client: MangoClient,
|
||||
groupPk: PublicKey,
|
||||
mangoAccountPk: PublicKey,
|
||||
bankPk: PublicKey,
|
||||
vaultPk: PublicKey,
|
||||
tokenAccountPk: PublicKey,
|
||||
oraclePk: PublicKey,
|
||||
ownerPk: PublicKey,
|
||||
amount: number,
|
||||
): Promise<TransactionInstruction> {
|
||||
return await client.program.methods
|
||||
.deposit(new BN(amount))
|
||||
.accounts({
|
||||
group: groupPk,
|
||||
account: mangoAccountPk,
|
||||
bank: bankPk,
|
||||
vault: vaultPk,
|
||||
tokenAccount: tokenAccountPk,
|
||||
tokenAuthority: ownerPk,
|
||||
})
|
||||
.remainingAccounts([
|
||||
{ pubkey: bankPk, isWritable: false, isSigner: false },
|
||||
{ pubkey: oraclePk, isWritable: false, isSigner: false },
|
||||
])
|
||||
.instruction();
|
||||
}
|
||||
|
||||
export async function withdraw(
|
||||
client: MangoClient,
|
||||
groupPk: PublicKey,
|
||||
mangoAccountPk: PublicKey,
|
||||
bankPk: PublicKey,
|
||||
vaultPk: PublicKey,
|
||||
tokenAccountPk: PublicKey,
|
||||
oraclePk: PublicKey,
|
||||
ownerPk: PublicKey,
|
||||
amount: number,
|
||||
allowBorrow: boolean,
|
||||
): Promise<void> {
|
||||
const tx = new Transaction();
|
||||
const ix = await withdrawIx(
|
||||
client,
|
||||
groupPk,
|
||||
mangoAccountPk,
|
||||
bankPk,
|
||||
vaultPk,
|
||||
tokenAccountPk,
|
||||
oraclePk,
|
||||
ownerPk,
|
||||
amount,
|
||||
allowBorrow,
|
||||
);
|
||||
tx.add(ix);
|
||||
await client.program.provider.send(tx);
|
||||
}
|
||||
|
||||
export async function withdrawIx(
|
||||
client: MangoClient,
|
||||
groupPk: PublicKey,
|
||||
mangoAccountPk: PublicKey,
|
||||
bankPk: PublicKey,
|
||||
vaultPk: PublicKey,
|
||||
tokenAccountPk: PublicKey,
|
||||
oraclePk: PublicKey,
|
||||
ownerPk: PublicKey,
|
||||
amount: number,
|
||||
allowBorrow: boolean,
|
||||
): Promise<TransactionInstruction> {
|
||||
return await client.program.methods
|
||||
.withdraw(new BN(amount), allowBorrow)
|
||||
.accounts({
|
||||
group: groupPk,
|
||||
account: mangoAccountPk,
|
||||
bank: bankPk,
|
||||
vault: vaultPk,
|
||||
tokenAccount: tokenAccountPk,
|
||||
tokenAuthority: ownerPk,
|
||||
})
|
||||
.remainingAccounts([
|
||||
{ pubkey: bankPk, isWritable: false, isSigner: false },
|
||||
{ pubkey: oraclePk, isWritable: false, isSigner: false },
|
||||
])
|
||||
.instruction();
|
||||
}
|
||||
|
||||
//
|
||||
// Serum3 instructions
|
||||
//
|
||||
|
@ -422,160 +52,6 @@ export async function withdrawIx(
|
|||
// .rpc();
|
||||
// }
|
||||
|
||||
export async function serum3RegisterMarket(
|
||||
client: MangoClient,
|
||||
groupPk: PublicKey,
|
||||
adminPk: PublicKey,
|
||||
serumProgramPk: PublicKey,
|
||||
serumMarketExternalPk: PublicKey,
|
||||
quoteBankPk: PublicKey,
|
||||
baseBankPk: PublicKey,
|
||||
payer: Keypair,
|
||||
marketIndex: number,
|
||||
): Promise<void> {
|
||||
const tx = new Transaction();
|
||||
const ix = await serum3RegisterMarketIx(
|
||||
client,
|
||||
groupPk,
|
||||
adminPk,
|
||||
serumProgramPk,
|
||||
serumMarketExternalPk,
|
||||
quoteBankPk,
|
||||
baseBankPk,
|
||||
payer,
|
||||
marketIndex,
|
||||
);
|
||||
tx.add(ix);
|
||||
await client.program.provider.send(tx, [payer]);
|
||||
}
|
||||
|
||||
export async function serum3RegisterMarketIx(
|
||||
client: MangoClient,
|
||||
groupPk: PublicKey,
|
||||
adminPk: PublicKey,
|
||||
serumProgramPk: PublicKey,
|
||||
serumMarketExternalPk: PublicKey,
|
||||
quoteBankPk: PublicKey,
|
||||
baseBankPk: PublicKey,
|
||||
payer: Keypair,
|
||||
marketIndex: number,
|
||||
): Promise<TransactionInstruction> {
|
||||
return await client.program.methods
|
||||
.serum3RegisterMarket(marketIndex)
|
||||
.accounts({
|
||||
group: groupPk,
|
||||
admin: adminPk,
|
||||
serumProgram: serumProgramPk,
|
||||
serumMarketExternal: serumMarketExternalPk,
|
||||
quoteBank: quoteBankPk,
|
||||
baseBank: baseBankPk,
|
||||
payer: payer.publicKey,
|
||||
})
|
||||
.instruction();
|
||||
}
|
||||
|
||||
export async function getSerum3MarketForBaseAndQuote(
|
||||
client: MangoClient,
|
||||
groupPk: PublicKey,
|
||||
baseTokenIndex: number,
|
||||
quoteTokenIndex: number,
|
||||
): Promise<Serum3Market[]> {
|
||||
const bbuf = Buffer.alloc(2);
|
||||
bbuf.writeUInt16LE(baseTokenIndex);
|
||||
|
||||
const qbuf = Buffer.alloc(2);
|
||||
qbuf.writeUInt16LE(quoteTokenIndex);
|
||||
|
||||
const bumpfbuf = Buffer.alloc(1);
|
||||
bumpfbuf.writeUInt8(255);
|
||||
|
||||
return (
|
||||
await client.program.account.serum3Market.all([
|
||||
{
|
||||
memcmp: {
|
||||
bytes: groupPk.toBase58(),
|
||||
offset: 8,
|
||||
},
|
||||
},
|
||||
{
|
||||
memcmp: {
|
||||
bytes: bs58.encode(bbuf),
|
||||
offset: 106,
|
||||
},
|
||||
},
|
||||
{
|
||||
memcmp: {
|
||||
bytes: bs58.encode(qbuf),
|
||||
offset: 108,
|
||||
},
|
||||
},
|
||||
])
|
||||
).map((tuple) => Serum3Market.from(tuple.publicKey, tuple.account));
|
||||
}
|
||||
|
||||
//
|
||||
// Oracle
|
||||
//
|
||||
|
||||
export async function createStubOracle(
|
||||
client: MangoClient,
|
||||
groupPk: PublicKey,
|
||||
adminPk: PublicKey,
|
||||
tokenMintPk: PublicKey,
|
||||
payer: Keypair,
|
||||
staticPrice: number,
|
||||
): Promise<void> {
|
||||
return await client.program.methods
|
||||
.createStubOracle({ val: I80F48.fromNumber(staticPrice).getData() })
|
||||
.accounts({
|
||||
group: groupPk,
|
||||
admin: adminPk,
|
||||
tokenMint: tokenMintPk,
|
||||
payer: payer.publicKey,
|
||||
})
|
||||
.signers([payer])
|
||||
.rpc();
|
||||
}
|
||||
|
||||
export async function setStubOracle(
|
||||
client: MangoClient,
|
||||
groupPk: PublicKey,
|
||||
adminPk: PublicKey,
|
||||
tokenMintPk: PublicKey,
|
||||
payer: Keypair,
|
||||
staticPrice: number,
|
||||
): Promise<void> {
|
||||
return await client.program.methods
|
||||
.setStubOracle({ val: new BN(staticPrice) })
|
||||
.accounts({
|
||||
group: groupPk,
|
||||
admin: adminPk,
|
||||
tokenMint: tokenMintPk,
|
||||
payer: payer.publicKey,
|
||||
})
|
||||
.signers([payer])
|
||||
.rpc();
|
||||
}
|
||||
|
||||
export async function getStubOracleForGroupAndMint(
|
||||
client: MangoClient,
|
||||
groupPk: PublicKey,
|
||||
mintPk: PublicKey,
|
||||
): Promise<StubOracle[]> {
|
||||
return (
|
||||
await client.program.account.stubOracle.all([
|
||||
{
|
||||
memcmp: {
|
||||
bytes: groupPk.toBase58(),
|
||||
offset: 8,
|
||||
},
|
||||
},
|
||||
{
|
||||
memcmp: {
|
||||
bytes: mintPk.toBase58(),
|
||||
offset: 40,
|
||||
},
|
||||
},
|
||||
])
|
||||
).map((pa) => StubOracle.from(pa.publicKey, pa.account));
|
||||
}
|
||||
|
|
6144
ts/mango_v4.ts
6144
ts/mango_v4.ts
File diff suppressed because it is too large
Load Diff
|
@ -1,75 +0,0 @@
|
|||
import { I80F48, I80F48Dto } from './I80F48';
|
||||
import { PublicKey } from '@solana/web3.js';
|
||||
|
||||
export class Bank {
|
||||
public depositIndex: I80F48;
|
||||
public borrowIndex: I80F48;
|
||||
|
||||
static from(
|
||||
publicKey: PublicKey,
|
||||
obj: {
|
||||
group: PublicKey;
|
||||
mint: PublicKey;
|
||||
vault: PublicKey;
|
||||
oracle: PublicKey;
|
||||
depositIndex: I80F48Dto;
|
||||
borrowIndex: I80F48Dto;
|
||||
indexedTotalDeposits: I80F48Dto;
|
||||
indexedTotalBorrows: I80F48Dto;
|
||||
maintAssetWeight: I80F48Dto;
|
||||
initAssetWeight: I80F48Dto;
|
||||
maintLiabWeight: I80F48Dto;
|
||||
initLiabWeight: I80F48Dto;
|
||||
liquidationFee: I80F48Dto;
|
||||
dust: Object;
|
||||
tokenIndex: number;
|
||||
},
|
||||
) {
|
||||
return new Bank(
|
||||
publicKey,
|
||||
obj.group,
|
||||
obj.mint,
|
||||
obj.vault,
|
||||
obj.oracle,
|
||||
obj.depositIndex,
|
||||
obj.borrowIndex,
|
||||
obj.indexedTotalDeposits,
|
||||
obj.indexedTotalBorrows,
|
||||
obj.maintAssetWeight,
|
||||
obj.initAssetWeight,
|
||||
obj.maintLiabWeight,
|
||||
obj.initLiabWeight,
|
||||
obj.liquidationFee,
|
||||
obj.dust,
|
||||
obj.tokenIndex,
|
||||
);
|
||||
}
|
||||
|
||||
constructor(
|
||||
public publicKey: PublicKey,
|
||||
group: PublicKey,
|
||||
mint: PublicKey,
|
||||
public vault: PublicKey,
|
||||
oracle: PublicKey,
|
||||
depositIndex: I80F48Dto,
|
||||
borrowIndex: I80F48Dto,
|
||||
indexedTotalDeposits: I80F48Dto,
|
||||
indexedTotalBorrows: I80F48Dto,
|
||||
maintAssetWeight: I80F48Dto,
|
||||
initAssetWeight: I80F48Dto,
|
||||
maintLiabWeight: I80F48Dto,
|
||||
initLiabWeight: I80F48Dto,
|
||||
liquidationFee: I80F48Dto,
|
||||
dust: Object,
|
||||
public tokenIndex: number,
|
||||
) {
|
||||
this.depositIndex = I80F48.from(depositIndex);
|
||||
this.borrowIndex = I80F48.from(borrowIndex);
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return `Bank ${
|
||||
this.tokenIndex
|
||||
} deposit index - ${this.depositIndex.toNumber()}, borrow index - ${this.borrowIndex.toNumber()}`;
|
||||
}
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
import { PublicKey } from '@solana/web3.js';
|
||||
|
||||
export class Group {
|
||||
static from(publicKey: PublicKey, obj: { admin: PublicKey }): Group {
|
||||
return new Group(publicKey, obj.admin);
|
||||
}
|
||||
|
||||
constructor(public publicKey: PublicKey, public admin: PublicKey) {}
|
||||
}
|
|
@ -1,95 +0,0 @@
|
|||
import { PublicKey } from '@solana/web3.js';
|
||||
import { Bank } from './bank';
|
||||
import { I80F48, I80F48Dto } from './I80F48';
|
||||
|
||||
export class TokenAccount {
|
||||
static from(dto: TokenAccountDto) {
|
||||
return new TokenAccount(
|
||||
I80F48.from(dto.indexedValue),
|
||||
dto.tokenIndex,
|
||||
dto.inUseCount,
|
||||
);
|
||||
}
|
||||
|
||||
constructor(
|
||||
public indexedValue: I80F48,
|
||||
public tokenIndex: number,
|
||||
public inUseCount: number,
|
||||
) {}
|
||||
}
|
||||
|
||||
export class TokenAccountDto {
|
||||
constructor(
|
||||
public indexedValue: I80F48Dto,
|
||||
public tokenIndex: number,
|
||||
public inUseCount: number,
|
||||
public reserved: number[],
|
||||
) {}
|
||||
}
|
||||
|
||||
export class MangoAccount {
|
||||
public tokens: TokenAccount[];
|
||||
|
||||
static from(
|
||||
publicKey: PublicKey,
|
||||
obj: {
|
||||
group: PublicKey;
|
||||
owner: PublicKey;
|
||||
delegate: PublicKey;
|
||||
tokens: unknown;
|
||||
serum3: Object;
|
||||
perps: unknown;
|
||||
beingLiquidated: number;
|
||||
isBankrupt: number;
|
||||
accountNum: number;
|
||||
bump: number;
|
||||
reserved: number[];
|
||||
},
|
||||
) {
|
||||
return new MangoAccount(
|
||||
publicKey,
|
||||
obj.group,
|
||||
obj.owner,
|
||||
obj.delegate,
|
||||
obj.tokens as { values: TokenAccountDto[] },
|
||||
obj.serum3,
|
||||
obj.perps,
|
||||
obj.beingLiquidated,
|
||||
obj.isBankrupt,
|
||||
obj.accountNum,
|
||||
obj.bump,
|
||||
obj.reserved,
|
||||
);
|
||||
}
|
||||
|
||||
constructor(
|
||||
public publicKey: PublicKey,
|
||||
group: PublicKey,
|
||||
owner: PublicKey,
|
||||
delegate: PublicKey,
|
||||
tokens: { values: TokenAccountDto[] },
|
||||
serum3: Object,
|
||||
perps: unknown,
|
||||
beingLiquidated: number,
|
||||
isBankrupt: number,
|
||||
accountNum: number,
|
||||
bump: number,
|
||||
reserved: number[],
|
||||
) {
|
||||
this.tokens = tokens.values.map((dto) => TokenAccount.from(dto));
|
||||
}
|
||||
|
||||
find(tokenIndex: number): TokenAccount | undefined {
|
||||
return this.tokens.find((ta) => ta.tokenIndex == tokenIndex);
|
||||
}
|
||||
|
||||
getNativeDeposit(bank: Bank): I80F48 {
|
||||
const ta = this.find(bank.tokenIndex);
|
||||
return bank.depositIndex.mul(ta?.indexedValue!);
|
||||
}
|
||||
|
||||
getNativeBorrow(bank: Bank): I80F48 {
|
||||
const ta = this.find(bank.tokenIndex);
|
||||
return bank.borrowIndex.mul(ta?.indexedValue!);
|
||||
}
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
import { I80F48, I80F48Dto } from './I80F48';
|
||||
import { PublicKey } from '@solana/web3.js';
|
||||
import BN from 'bn.js';
|
||||
|
||||
export class StubOracle {
|
||||
public price: I80F48;
|
||||
public lastUpdated: number;
|
||||
|
||||
static from(
|
||||
publicKey: PublicKey,
|
||||
obj: {
|
||||
group: PublicKey;
|
||||
mint: PublicKey;
|
||||
price: I80F48Dto;
|
||||
lastUpdated: BN;
|
||||
reserved: unknown;
|
||||
},
|
||||
): StubOracle {
|
||||
return new StubOracle(
|
||||
publicKey,
|
||||
obj.group,
|
||||
obj.mint,
|
||||
obj.price,
|
||||
obj.lastUpdated,
|
||||
);
|
||||
}
|
||||
|
||||
constructor(
|
||||
public publicKey: PublicKey,
|
||||
public group: PublicKey,
|
||||
public mint: PublicKey,
|
||||
price: I80F48Dto,
|
||||
lastUpdated: BN,
|
||||
) {
|
||||
this.price = I80F48.from(price);
|
||||
this.lastUpdated = lastUpdated.toNumber();
|
||||
}
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
import { PublicKey } from '@solana/web3.js';
|
||||
|
||||
export class Serum3Market {
|
||||
static from(
|
||||
publicKey: PublicKey,
|
||||
obj: {
|
||||
group: PublicKey;
|
||||
serumProgram: PublicKey;
|
||||
serumMarketExternal: PublicKey;
|
||||
marketIndex: number;
|
||||
baseTokenIndex: number;
|
||||
quoteTokenIndex: number;
|
||||
bump: number;
|
||||
reserved: unknown;
|
||||
},
|
||||
): Serum3Market {
|
||||
return new Serum3Market(
|
||||
publicKey,
|
||||
obj.group,
|
||||
obj.serumProgram,
|
||||
obj.serumMarketExternal,
|
||||
obj.marketIndex,
|
||||
obj.baseTokenIndex,
|
||||
obj.quoteTokenIndex,
|
||||
);
|
||||
}
|
||||
|
||||
constructor(
|
||||
public publicKey: PublicKey,
|
||||
public group: PublicKey,
|
||||
public serumProgram: PublicKey,
|
||||
public serumMarketExternal: PublicKey,
|
||||
public marketIndex: number,
|
||||
public baseTokenIndex: number,
|
||||
public quoteTokenIndex: number,
|
||||
) {}
|
||||
}
|
Loading…
Reference in New Issue