commit
d9cbc9239f
|
@ -1,6 +1,7 @@
|
|||
CLUSTER=devnet
|
||||
DEX_PROGRAM_ID=9MVDeYQnJmN2Dt7H44Z8cob4bET2ysdNu2uFJcatDJno
|
||||
KEYPAIR=~/.config/solana/id.json
|
||||
BTCUSD=6pZpjgfwKJhQ93ZYNjbJFtWEaB8kZjErsiGAEXn9WNjn
|
||||
BTC_WALLET=HLoPtihB8oETm1kkTpx17FEnXm7afQdS4hojTNvbg3Rg
|
||||
USDC_WALLET=GBBtcVE7WA8qdrHyhWTZkYDaz71EVHsg7wVaca9iq9xs
|
||||
BTC=C6kYXcaRUMqeBF5fhg165RWU7AnpT9z92fvKNoMqjmz6
|
||||
ETH=8p968u9m7jZzKSsqxFDqki69MjqdFkwPM9FN4AN8hvHR
|
||||
USDC=Fq939Y5hycK62ZGwBjftLY2VyxqAQ8f1MxRqBMdAaBS7
|
|
@ -7,7 +7,7 @@
|
|||
"name": "Blockworks Foundation",
|
||||
"email": "hello@blockworks.foundation",
|
||||
"url": "https://blockworks.foundation"
|
||||
},
|
||||
},
|
||||
"main": "lib/index.js",
|
||||
"source": "src/index.js",
|
||||
"types": "lib/index.d.ts",
|
||||
|
@ -56,10 +56,10 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@project-serum/serum": "^0.13.20",
|
||||
"@project-serum/sol-wallet-adapter": "^0.1.4",
|
||||
"@solana/web3.js": "^0.90.0",
|
||||
"bn.js": "^5.1.2",
|
||||
"buffer-layout": "^1.2.0",
|
||||
"@project-serum/sol-wallet-adapter": "^0.1.4"
|
||||
"buffer-layout": "^1.2.0"
|
||||
},
|
||||
"browserslist": [
|
||||
">0.2%",
|
||||
|
|
187
src/client.ts
187
src/client.ts
|
@ -28,14 +28,13 @@ import {
|
|||
zeroKey,
|
||||
} from './utils';
|
||||
import { Market, OpenOrders, Orderbook } from '@project-serum/serum';
|
||||
import { TOKEN_PROGRAM_ID } from '@project-serum/serum/lib/token-instructions';
|
||||
import { SRM_DECIMALS, TOKEN_PROGRAM_ID } from '@project-serum/serum/lib/token-instructions';
|
||||
import { Order } from '@project-serum/serum/lib/market';
|
||||
import Wallet from '@project-serum/sol-wallet-adapter';
|
||||
|
||||
|
||||
export class MangoGroup {
|
||||
publicKey: PublicKey;
|
||||
mintDecimals: number[];
|
||||
|
||||
accountFlags!: WideBits;
|
||||
tokens!: PublicKey[];
|
||||
|
@ -50,10 +49,12 @@ export class MangoGroup {
|
|||
totalBorrows!: number[];
|
||||
maintCollRatio!: number;
|
||||
initCollRatio!: number;
|
||||
srmVault!: PublicKey;
|
||||
mintDecimals!: number[];
|
||||
oracleDecimals!: number[];
|
||||
|
||||
constructor(publicKey: PublicKey, mintDecimals: number[], decoded: any) {
|
||||
constructor(publicKey: PublicKey, decoded: any) {
|
||||
this.publicKey = publicKey;
|
||||
this.mintDecimals = mintDecimals;
|
||||
Object.assign(this, decoded);
|
||||
}
|
||||
|
||||
|
@ -108,13 +109,14 @@ export class MarginAccount {
|
|||
deposits!: number[];
|
||||
borrows!: number[];
|
||||
openOrders!: PublicKey[];
|
||||
|
||||
openOrdersAccounts: undefined | (OpenOrders | undefined)[] // undefined if an openOrdersAccount not yet initialized and has zeroKey
|
||||
srmBalance!: number;
|
||||
openOrdersAccounts: (OpenOrders | undefined)[] // undefined if an openOrdersAccount not yet initialized and has zeroKey
|
||||
// TODO keep updated with websocket
|
||||
|
||||
constructor(publicKey: PublicKey, decoded: any) {
|
||||
this.publicKey = publicKey
|
||||
this.createTime = getUnixTs()
|
||||
this.openOrdersAccounts = new Array(NUM_MARKETS).fill(undefined)
|
||||
Object.assign(this, decoded)
|
||||
}
|
||||
|
||||
|
@ -131,6 +133,10 @@ export class MarginAccount {
|
|||
return nativeToUi(this.getNativeBorrow(mangoGroup, tokenIndex), mangoGroup.mintDecimals[tokenIndex])
|
||||
}
|
||||
|
||||
getUiSrmBalance() {
|
||||
return nativeToUi(this.srmBalance, SRM_DECIMALS)
|
||||
}
|
||||
|
||||
async loadOpenOrders(
|
||||
connection: Connection,
|
||||
dexProgramId: PublicKey
|
||||
|
@ -147,6 +153,7 @@ export class MarginAccount {
|
|||
this.openOrdersAccounts = await Promise.all(promises)
|
||||
return this.openOrdersAccounts
|
||||
}
|
||||
|
||||
toPrettyString(
|
||||
mangoGroup: MangoGroup
|
||||
): string {
|
||||
|
@ -176,10 +183,6 @@ export class MarginAccount {
|
|||
value += (this.getUiDeposit(mangoGroup, i) - this.getUiBorrow(mangoGroup, i)) * prices[i]
|
||||
}
|
||||
|
||||
if (this.openOrdersAccounts == undefined) {
|
||||
return value
|
||||
}
|
||||
|
||||
for (let i = 0; i < this.openOrdersAccounts.length; i++) {
|
||||
const oos = this.openOrdersAccounts[i]
|
||||
if (oos != undefined) {
|
||||
|
@ -192,10 +195,6 @@ export class MarginAccount {
|
|||
}
|
||||
|
||||
getAssets(mangoGroup: MangoGroup): number[] {
|
||||
if (this.openOrdersAccounts == undefined) {
|
||||
throw new Error("openOrdersAccounts not yet loaded")
|
||||
}
|
||||
|
||||
const assets = new Array<number>(NUM_TOKENS)
|
||||
|
||||
for (let i = 0; i < NUM_TOKENS; i++) {
|
||||
|
@ -229,9 +228,6 @@ export class MarginAccount {
|
|||
for (let i = 0; i < NUM_TOKENS; i++) {
|
||||
assetsVal += this.getUiDeposit(mangoGroup, i) * prices[i]
|
||||
}
|
||||
if (this.openOrdersAccounts == undefined) {
|
||||
return assetsVal
|
||||
}
|
||||
|
||||
for (let i = 0; i < NUM_MARKETS; i++) {
|
||||
const openOrdersAccount = this.openOrdersAccounts[i]
|
||||
|
@ -271,13 +267,10 @@ export class MarginAccount {
|
|||
asks: Orderbook,
|
||||
owner: Account
|
||||
): Promise<TransactionSignature[]> {
|
||||
if (this.openOrdersAccounts == undefined) {
|
||||
throw new Error("Must load open orders accounts first")
|
||||
}
|
||||
|
||||
const marketIndex = mangoGroup.getMarketIndex(market)
|
||||
const openOrdersAccount = this.openOrdersAccounts[marketIndex]
|
||||
if (!openOrdersAccount) { // no open orders for this market
|
||||
if (openOrdersAccount == undefined) { // no open orders for this market
|
||||
return []
|
||||
}
|
||||
|
||||
|
@ -290,16 +283,6 @@ export class MarginAccount {
|
|||
|
||||
}
|
||||
|
||||
async cancelAllOrders(
|
||||
connection: Connection
|
||||
|
||||
): Promise<boolean> {
|
||||
|
||||
// fetch all orders using order id
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class MangoClient {
|
||||
|
@ -380,7 +363,6 @@ export class MangoClient {
|
|||
{ isSigner: false, isWritable: true, pubkey: mangoGroup.publicKey},
|
||||
{ isSigner: false, isWritable: true, pubkey: marginAccount.publicKey },
|
||||
{ isSigner: true, isWritable: false, pubkey: owner.publicKey },
|
||||
{ isSigner: false, isWritable: false, pubkey: token },
|
||||
{ isSigner: false, isWritable: true, pubkey: tokenAcc },
|
||||
{ isSigner: false, isWritable: true, pubkey: mangoGroup.vaults[tokenIndex] },
|
||||
{ isSigner: false, isWritable: false, pubkey: TOKEN_PROGRAM_ID },
|
||||
|
@ -422,10 +404,9 @@ export class MangoClient {
|
|||
{ isSigner: false, isWritable: false, pubkey: TOKEN_PROGRAM_ID },
|
||||
{ isSigner: false, isWritable: false, pubkey: SYSVAR_CLOCK_PUBKEY },
|
||||
...marginAccount.openOrders.map( (pubkey) => ( { isSigner: false, isWritable: false, pubkey })),
|
||||
...mangoGroup.oracles.map( (pubkey) => ( { isSigner: false, isWritable: false, pubkey })),
|
||||
...mangoGroup.tokens.map( (pubkey) => ( { isSigner: false, isWritable: false, pubkey })),
|
||||
...mangoGroup.oracles.map( (pubkey) => ( { isSigner: false, isWritable: false, pubkey }))
|
||||
]
|
||||
const data = encodeMangoInstruction({Withdraw: {tokenIndex, quantity: nativeQuantity}})
|
||||
const data = encodeMangoInstruction({Withdraw: {quantity: nativeQuantity}})
|
||||
|
||||
|
||||
const instruction = new TransactionInstruction( { keys, data, programId })
|
||||
|
@ -457,9 +438,8 @@ export class MangoClient {
|
|||
{ isSigner: false, isWritable: false, pubkey: SYSVAR_CLOCK_PUBKEY },
|
||||
...marginAccount.openOrders.map( (pubkey) => ( { isSigner: false, isWritable: false, pubkey })),
|
||||
...mangoGroup.oracles.map( (pubkey) => ( { isSigner: false, isWritable: false, pubkey })),
|
||||
...mangoGroup.tokens.map( (pubkey) => ( { isSigner: false, isWritable: false, pubkey })),
|
||||
]
|
||||
const data = encodeMangoInstruction({Borrow: {tokenIndex, quantity: nativeQuantity}})
|
||||
const data = encodeMangoInstruction({Borrow: {tokenIndex: new BN(tokenIndex), quantity: nativeQuantity}})
|
||||
|
||||
|
||||
const instruction = new TransactionInstruction( { keys, data, programId })
|
||||
|
@ -519,10 +499,6 @@ export class MangoClient {
|
|||
owner: Account
|
||||
): Promise<TransactionSignature> {
|
||||
|
||||
if (!marginAccount.openOrdersAccounts) {
|
||||
throw new Error("openOrderesAccounts must be initialized")
|
||||
}
|
||||
|
||||
const transaction = new Transaction()
|
||||
for (let i = 0; i < NUM_MARKETS; i++) {
|
||||
if (marginAccount.openOrdersAccounts[i] == undefined) {
|
||||
|
@ -604,7 +580,6 @@ export class MangoClient {
|
|||
...mangoGroup.oracles.map( (pubkey) => ( { isSigner: false, isWritable: false, pubkey })),
|
||||
...mangoGroup.vaults.map( (pubkey) => ( { isSigner: false, isWritable: true, pubkey })),
|
||||
...tokenAccs.map( (pubkey) => ( { isSigner: false, isWritable: true, pubkey })),
|
||||
...mangoGroup.tokens.map( (pubkey) => ( { isSigner: false, isWritable: false, pubkey })),
|
||||
]
|
||||
const data = encodeMangoInstruction({Liquidate: {depositQuantities: depositsBN}})
|
||||
|
||||
|
@ -618,6 +593,71 @@ export class MangoClient {
|
|||
return await this.sendTransaction(connection, transaction, liqor, additionalSigners)
|
||||
}
|
||||
|
||||
async depositSrm(
|
||||
connection: Connection,
|
||||
programId: PublicKey,
|
||||
mangoGroup: MangoGroup,
|
||||
marginAccount: MarginAccount,
|
||||
owner: Account,
|
||||
srmAccount: PublicKey,
|
||||
|
||||
quantity: number
|
||||
): Promise<TransactionSignature> {
|
||||
const nativeQuantity = uiToNative(quantity, SRM_DECIMALS)
|
||||
|
||||
const keys = [
|
||||
{ isSigner: false, isWritable: true, pubkey: mangoGroup.publicKey },
|
||||
{ isSigner: false, isWritable: true, pubkey: marginAccount.publicKey },
|
||||
{ isSigner: true, isWritable: false, pubkey: owner.publicKey },
|
||||
{ isSigner: false, isWritable: true, pubkey: srmAccount },
|
||||
{ isSigner: false, isWritable: true, pubkey: mangoGroup.srmVault },
|
||||
{ isSigner: false, isWritable: false, pubkey: TOKEN_PROGRAM_ID },
|
||||
{ isSigner: false, isWritable: false, pubkey: SYSVAR_CLOCK_PUBKEY }
|
||||
]
|
||||
const data = encodeMangoInstruction({DepositSrm: {quantity: nativeQuantity}})
|
||||
|
||||
const instruction = new TransactionInstruction( { keys, data, programId })
|
||||
|
||||
const transaction = new Transaction()
|
||||
transaction.add(instruction)
|
||||
const additionalSigners = []
|
||||
|
||||
return await this.sendTransaction(connection, transaction, owner, additionalSigners)
|
||||
}
|
||||
|
||||
async withdrawSrm(
|
||||
connection: Connection,
|
||||
programId: PublicKey,
|
||||
mangoGroup: MangoGroup,
|
||||
marginAccount: MarginAccount,
|
||||
owner: Account,
|
||||
srmAccount: PublicKey,
|
||||
|
||||
quantity: number
|
||||
): Promise<TransactionSignature> {
|
||||
const nativeQuantity = uiToNative(quantity, SRM_DECIMALS)
|
||||
|
||||
const keys = [
|
||||
{ isSigner: false, isWritable: true, pubkey: mangoGroup.publicKey },
|
||||
{ isSigner: false, isWritable: true, pubkey: marginAccount.publicKey },
|
||||
{ isSigner: true, isWritable: false, pubkey: owner.publicKey },
|
||||
{ isSigner: false, isWritable: true, pubkey: srmAccount },
|
||||
{ isSigner: false, isWritable: true, pubkey: mangoGroup.srmVault },
|
||||
{ isSigner: false, isWritable: false, pubkey: mangoGroup.signerKey },
|
||||
{ isSigner: false, isWritable: false, pubkey: TOKEN_PROGRAM_ID },
|
||||
{ isSigner: false, isWritable: false, pubkey: SYSVAR_CLOCK_PUBKEY }
|
||||
]
|
||||
const data = encodeMangoInstruction({WithdrawSrm: {quantity: nativeQuantity}})
|
||||
|
||||
const instruction = new TransactionInstruction( { keys, data, programId })
|
||||
|
||||
const transaction = new Transaction()
|
||||
transaction.add(instruction)
|
||||
const additionalSigners = []
|
||||
|
||||
return await this.sendTransaction(connection, transaction, owner, additionalSigners)
|
||||
}
|
||||
|
||||
async placeOrder(
|
||||
connection: Connection,
|
||||
programId: PublicKey,
|
||||
|
@ -639,8 +679,14 @@ export class MangoClient {
|
|||
orderType = orderType == undefined ? 'limit' : orderType
|
||||
// orderType = orderType ?? 'limit'
|
||||
const limitPrice = spotMarket.priceNumberToLots(price)
|
||||
const maxQuantity = spotMarket.baseSizeNumberToLots(size)
|
||||
if (maxQuantity.lte(new BN(0))) {
|
||||
const maxBaseQuantity = spotMarket.baseSizeNumberToLots(size)
|
||||
|
||||
// TODO verify if multiplying by highest fee tier is appropriate
|
||||
const maxQuoteQuantity = new BN(spotMarket['_decoded'].quoteLotSize.toNumber()).mul(
|
||||
maxBaseQuantity.mul(limitPrice),
|
||||
)
|
||||
|
||||
if (maxBaseQuantity.lte(new BN(0))) {
|
||||
throw new Error('size too small')
|
||||
}
|
||||
if (limitPrice.lte(new BN(0))) {
|
||||
|
@ -683,23 +729,26 @@ export class MangoClient {
|
|||
{ isSigner: false, isWritable: false, pubkey: spotMarket.programId },
|
||||
{ isSigner: false, isWritable: true, pubkey: spotMarket.publicKey },
|
||||
{ isSigner: false, isWritable: true, pubkey: spotMarket['_decoded'].requestQueue },
|
||||
{ isSigner: false, isWritable: true, pubkey: spotMarket['_decoded'].eventQueue },
|
||||
{ isSigner: false, isWritable: true, pubkey: spotMarket['_decoded'].bids },
|
||||
{ isSigner: false, isWritable: true, pubkey: spotMarket['_decoded'].asks },
|
||||
{ isSigner: false, isWritable: true, pubkey: mangoGroup.vaults[vaultIndex] },
|
||||
{ isSigner: false, isWritable: false, pubkey: mangoGroup.signerKey },
|
||||
{ isSigner: false, isWritable: true, pubkey: spotMarket['_decoded'].baseVault },
|
||||
{ isSigner: false, isWritable: true, pubkey: spotMarket['_decoded'].quoteVault },
|
||||
{ isSigner: false, isWritable: false, pubkey: TOKEN_PROGRAM_ID },
|
||||
{ isSigner: false, isWritable: false, pubkey: SYSVAR_RENT_PUBKEY },
|
||||
{ isSigner: false, isWritable: true, pubkey: mangoGroup.srmVault },
|
||||
...openOrdersKeys.map( (pubkey) => ( { isSigner: false, isWritable: true, pubkey })),
|
||||
...mangoGroup.oracles.map( (pubkey) => ( { isSigner: false, isWritable: false, pubkey })),
|
||||
...mangoGroup.tokens.map( (pubkey) => ( { isSigner: false, isWritable: false, pubkey })),
|
||||
]
|
||||
|
||||
const data = encodeMangoInstruction(
|
||||
{
|
||||
PlaceOrder:
|
||||
clientId
|
||||
? { side, limitPrice, maxQuantity, orderType, clientId, selfTradeBehavior }
|
||||
: { side, limitPrice, maxQuantity, orderType, selfTradeBehavior }
|
||||
? { side, limitPrice, maxBaseQuantity, maxQuoteQuantity, selfTradeBehavior, orderType, clientId, limit: 65535}
|
||||
: { side, limitPrice, maxBaseQuantity, maxQuoteQuantity, selfTradeBehavior, orderType, limit: 65535}
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -752,7 +801,7 @@ export class MangoClient {
|
|||
const transaction = new Transaction()
|
||||
transaction.add(instruction)
|
||||
|
||||
// Specify signers in addition to the wallet
|
||||
// Specify signers in addition to the owner account
|
||||
const additionalSigners = []
|
||||
|
||||
// sign, send and confirm transaction
|
||||
|
@ -775,17 +824,17 @@ export class MangoClient {
|
|||
{ isSigner: false, isWritable: false, pubkey: SYSVAR_CLOCK_PUBKEY },
|
||||
{ isSigner: false, isWritable: false, pubkey: mangoGroup.dexProgramId },
|
||||
{ isSigner: false, isWritable: true, pubkey: spotMarket.publicKey },
|
||||
{ isSigner: false, isWritable: true, pubkey: spotMarket['_decoded'].bids },
|
||||
{ isSigner: false, isWritable: true, pubkey: spotMarket['_decoded'].asks },
|
||||
{ isSigner: false, isWritable: true, pubkey: order.openOrdersAddress },
|
||||
{ isSigner: false, isWritable: true, pubkey: spotMarket['_decoded'].requestQueue },
|
||||
{ isSigner: false, isWritable: false, pubkey: mangoGroup.signerKey },
|
||||
{ isSigner: false, isWritable: true, pubkey: spotMarket['_decoded'].eventQueue },
|
||||
]
|
||||
|
||||
const data = encodeMangoInstruction({
|
||||
CancelOrder: {
|
||||
side: order.side,
|
||||
orderId: order.orderId,
|
||||
openOrders: order.openOrdersAddress,
|
||||
openOrdersSlot: order.openOrdersSlot
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -799,31 +848,22 @@ export class MangoClient {
|
|||
return await this.sendTransaction(connection, transaction, owner, additionalSigners)
|
||||
}
|
||||
|
||||
|
||||
async getMangoGroup(
|
||||
connection: Connection,
|
||||
mangoGroupPk: PublicKey
|
||||
): Promise<MangoGroup> {
|
||||
const acc = await connection.getAccountInfo(mangoGroupPk);
|
||||
const decoded = MangoGroupLayout.decode(acc == null ? undefined : acc.data);
|
||||
const mintDecimals: number[] = await Promise.all(decoded.tokens.map( (pk) => getMintDecimals(connection, pk) ))
|
||||
return new MangoGroup(mangoGroupPk, mintDecimals, decoded);
|
||||
return new MangoGroup(mangoGroupPk, decoded);
|
||||
}
|
||||
|
||||
async getMarginAccount(
|
||||
connection: Connection,
|
||||
marginAccountPk: PublicKey
|
||||
): Promise<MarginAccount> {
|
||||
const acc = await connection.getAccountInfo(marginAccountPk, 'singleGossip')
|
||||
return new MarginAccount(marginAccountPk, MarginAccountLayout.decode(acc == null ? undefined : acc.data))
|
||||
}
|
||||
|
||||
|
||||
async getCompleteMarginAccount(
|
||||
connection: Connection,
|
||||
marginAccountPk: PublicKey,
|
||||
dexProgramId: PublicKey
|
||||
): Promise<MarginAccount> {
|
||||
const ma = await this.getMarginAccount(connection, marginAccountPk)
|
||||
const acc = await connection.getAccountInfo(marginAccountPk, 'singleGossip')
|
||||
const ma = new MarginAccount(marginAccountPk, MarginAccountLayout.decode(acc == null ? undefined : acc.data))
|
||||
await ma.loadOpenOrders(connection, dexProgramId)
|
||||
return ma
|
||||
}
|
||||
|
@ -831,13 +871,13 @@ export class MangoClient {
|
|||
async getAllMarginAccounts(
|
||||
connection: Connection,
|
||||
programId: PublicKey,
|
||||
mangoGroupPk: PublicKey
|
||||
mangoGroup: MangoGroup
|
||||
): Promise<MarginAccount[]>{
|
||||
const filters = [
|
||||
{
|
||||
memcmp: {
|
||||
offset: MarginAccountLayout.offsetOf('mangoGroup'),
|
||||
bytes: mangoGroupPk.toBase58(),
|
||||
bytes: mangoGroup.publicKey.toBase58(),
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -847,10 +887,14 @@ export class MangoClient {
|
|||
];
|
||||
|
||||
const accounts = await getFilteredProgramAccounts(connection, programId, filters);
|
||||
return accounts.map(
|
||||
const marginAccounts = accounts.map(
|
||||
({ publicKey, accountInfo }) =>
|
||||
new MarginAccount(publicKey, MarginAccountLayout.decode(accountInfo == null ? undefined : accountInfo.data))
|
||||
);
|
||||
)
|
||||
|
||||
await Promise.all(marginAccounts.map((ma) => ma.loadOpenOrders(connection, mangoGroup.dexProgramId)))
|
||||
return marginAccounts
|
||||
|
||||
}
|
||||
|
||||
async getMarginAccountsForOwner(
|
||||
|
@ -880,11 +924,14 @@ export class MangoClient {
|
|||
];
|
||||
|
||||
const accounts = await getFilteredProgramAccounts(connection, programId, filters);
|
||||
return accounts.map(
|
||||
const marginAccounts = accounts.map(
|
||||
({ publicKey, accountInfo }) =>
|
||||
new MarginAccount(publicKey, MarginAccountLayout.decode(accountInfo == null ? undefined : accountInfo.data))
|
||||
);
|
||||
)
|
||||
await Promise.all(marginAccounts.map((ma) => ma.loadOpenOrders(connection, mangoGroup.dexProgramId)))
|
||||
return marginAccounts
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async function getMultipleAccounts(
|
||||
|
|
29
src/ids.json
29
src/ids.json
|
@ -6,10 +6,11 @@
|
|||
"testnet": "https://testnet.solana.com"
|
||||
},
|
||||
"devnet": {
|
||||
"dex_program_id": "9MVDeYQnJmN2Dt7H44Z8cob4bET2ysdNu2uFJcatDJno",
|
||||
"dex_program_id": "6XffKSLZRxmQcRinmb4K32AegYnmkoTm6TLR2Ezp9FBR",
|
||||
"fee_symbol": "SRM",
|
||||
"mango_groups": {
|
||||
"BTC_ETH_USDC": {
|
||||
"mango_group_pk": "FK6o45mYRDNvgSqcZ4xd5wjyuSbxxM3LQhFz3n9eMr3x",
|
||||
"mango_group_pk": "6hcULrp3j5JZS7PDK3XYehzdbXZoqaiKPNNGC2sF4oz2",
|
||||
"mint_pks": [
|
||||
"C6kYXcaRUMqeBF5fhg165RWU7AnpT9z92fvKNoMqjmz6",
|
||||
"8p968u9m7jZzKSsqxFDqki69MjqdFkwPM9FN4AN8hvHR",
|
||||
|
@ -20,8 +21,8 @@
|
|||
"DBiZZ6riT6QVoGVBMBnSsYFwkie1GAxWdac3NCpyrDR1"
|
||||
],
|
||||
"spot_market_pks": [
|
||||
"6pZpjgfwKJhQ93ZYNjbJFtWEaB8kZjErsiGAEXn9WNjn",
|
||||
"GAZmMjiABoZimoePnrA2BiPx7BTDByskopZ7coBDnKFQ"
|
||||
"DY6X83vWk5VdHQEtVxFdecmEsGXHyLskkeQeo8BHn75s",
|
||||
"CQwr1dHHPeoUpzGcQHLtEYE1LdXkszxha8oG6Y7v5KWZ"
|
||||
],
|
||||
"symbols": {
|
||||
"BTC": "C6kYXcaRUMqeBF5fhg165RWU7AnpT9z92fvKNoMqjmz6",
|
||||
|
@ -29,9 +30,9 @@
|
|||
"USDC": "Fq939Y5hycK62ZGwBjftLY2VyxqAQ8f1MxRqBMdAaBS7"
|
||||
},
|
||||
"vault_pks": [
|
||||
"9vUVVAXPZHVKV2vo8uv1jFtg2uR6iHQR3AvpzEnJejdR",
|
||||
"MhtHbYG65N6e4dwhCbHJFzyRX9KndxQ3mGmmLmunHoS",
|
||||
"5ygigzB3ngRXzuaiz7MQdh94ZH2SAR7wNbYe4GXHZbZ2"
|
||||
"HHZCZBqkNrJp51g6T5Gu4eCVrCNfSJekCMgx4cjMDBJC",
|
||||
"GCa1SdEaod5VucgJoCvc9wFSiX4G7i5GpDbtPbhBFCHY",
|
||||
"134B3occRaHiiMxo1M5GXavW7ocWgwR6951951LU5Vub"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
@ -41,13 +42,16 @@
|
|||
"ETH/USDC": "DBiZZ6riT6QVoGVBMBnSsYFwkie1GAxWdac3NCpyrDR1"
|
||||
},
|
||||
"spot_markets": {
|
||||
"BTC/USDC": "6pZpjgfwKJhQ93ZYNjbJFtWEaB8kZjErsiGAEXn9WNjn",
|
||||
"ETH/USDC": "GAZmMjiABoZimoePnrA2BiPx7BTDByskopZ7coBDnKFQ"
|
||||
"BTC/USDC": "DY6X83vWk5VdHQEtVxFdecmEsGXHyLskkeQeo8BHn75s",
|
||||
"ETH/USDC": "CQwr1dHHPeoUpzGcQHLtEYE1LdXkszxha8oG6Y7v5KWZ"
|
||||
},
|
||||
"symbols": {
|
||||
"BTC": "C6kYXcaRUMqeBF5fhg165RWU7AnpT9z92fvKNoMqjmz6",
|
||||
"ETH": "8p968u9m7jZzKSsqxFDqki69MjqdFkwPM9FN4AN8hvHR",
|
||||
"USDC": "Fq939Y5hycK62ZGwBjftLY2VyxqAQ8f1MxRqBMdAaBS7"
|
||||
"MSRM": "934bNdNw9QfE8dXD4mKQiKajYURfSkPhxfYZzpvmygca",
|
||||
"SRM": "9FbAMDvXqNjPqZSYt4EWTguJuDrGkfvwr3gSFpiSbX9S",
|
||||
"USDC": "Fq939Y5hycK62ZGwBjftLY2VyxqAQ8f1MxRqBMdAaBS7",
|
||||
"USDT": "7tSPGVhneTBWZjLGJGZb9V2UntC7T98cwtSLtgcXjeSs"
|
||||
}
|
||||
},
|
||||
"localnet": {
|
||||
|
@ -68,6 +72,7 @@
|
|||
},
|
||||
"mainnet-beta": {
|
||||
"dex_program_id": "EUqojwWA2rd19FZrzeBncJsm38Jm1hEhE3zsmX3bRc2o",
|
||||
"fee_token": "SRM",
|
||||
"spot_markets": {
|
||||
"BTC/USDC": "CVfYa8RGXnuDBeGmniCcdkBwoLqVxh92xB1JqgRQx3F",
|
||||
"BTC/USDT": "EXnGBBSamqzd3uxEdRLUiYzjJkTwQyorAaFXdfteuGXe",
|
||||
|
@ -75,6 +80,10 @@
|
|||
"ETH/USDT": "5abZGhrELnUnfM9ZUnvK6XJPoBU5eShZwfFPkdhAC7o",
|
||||
"SOL/USDT": "7xLk17EQQ5KLDLDe44wCmupJKJjTGd8hs3eSVVhCx932",
|
||||
"SRM/USDC": "CDdR97S8y96v3To93aKvi3nCnjUrbuVSuumw8FLvbVeg"
|
||||
},
|
||||
"symbols": {
|
||||
"MSRM": "MSRMcoVyrFxnSgo5uXwone5SKcGhT1KEJMFEkMEWf9L",
|
||||
"SRM": "SRMuApVNdxXokk5GT7XD5cUUgXMBCoAz2LHeuAoKWRt"
|
||||
}
|
||||
},
|
||||
"testnet": {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { bits, BitStructure, Blob, Layout, seq, struct, u32, u8, UInt, union } from 'buffer-layout';
|
||||
import { bits, BitStructure, Blob, Layout, seq, struct, u32, u8, u16, UInt, union } from 'buffer-layout';
|
||||
import { PublicKey } from '@solana/web3.js';
|
||||
import BN from 'bn.js';
|
||||
|
||||
|
@ -134,6 +134,7 @@ export const MangoGroupLayout = struct([
|
|||
seq(U64F64(), NUM_TOKENS, 'totalBorrows'),
|
||||
U64F64('maintCollRatio'),
|
||||
U64F64('initCollRatio'),
|
||||
publicKeyLayout('srmVault'),
|
||||
seq(u8(), NUM_TOKENS, 'mintDecimals'),
|
||||
seq(u8(), NUM_MARKETS, 'oracleDecimals'),
|
||||
seq(u8(), MANGO_GROUP_PADDING, 'padding')
|
||||
|
@ -147,8 +148,8 @@ export const MarginAccountLayout = struct([
|
|||
|
||||
seq(U64F64(), NUM_TOKENS, 'deposits'),
|
||||
seq(U64F64(), NUM_TOKENS, 'borrows'),
|
||||
// seq(u64(), NUM_TOKENS, 'positions'),
|
||||
seq(publicKeyLayout(), NUM_MARKETS, 'openOrders')
|
||||
seq(publicKeyLayout(), NUM_MARKETS, 'openOrders'),
|
||||
u64('srmBalance')
|
||||
]);
|
||||
|
||||
|
||||
|
@ -186,7 +187,7 @@ export function orderTypeLayout(property) {
|
|||
}
|
||||
|
||||
export function selfTradeBehaviorLayout(property) {
|
||||
return new EnumLayout({ decrementTake: 0, cancelProvide: 1 }, 4, property);
|
||||
return new EnumLayout({ decrementTake: 0, cancelProvide: 1, abortTransaction: 2 }, 4, property);
|
||||
}
|
||||
|
||||
export const MangoInstructionLayout = union(u32('instruction'))
|
||||
|
@ -194,39 +195,41 @@ export const MangoInstructionLayout = union(u32('instruction'))
|
|||
MangoInstructionLayout.addVariant(0, struct([]), 'InitMangoGroup')
|
||||
MangoInstructionLayout.addVariant(1, struct([]), 'InitMarginAccount')
|
||||
MangoInstructionLayout.addVariant(2, struct([u64('quantity')]), 'Deposit')
|
||||
MangoInstructionLayout.addVariant(3, struct([u64('tokenIndex'), u64('quantity')]), 'Withdraw')
|
||||
MangoInstructionLayout.addVariant(3, struct([u64('quantity')]), 'Withdraw')
|
||||
MangoInstructionLayout.addVariant(4, struct([u64('tokenIndex'), u64('quantity')]), 'Borrow')
|
||||
MangoInstructionLayout.addVariant(5, struct([u64('tokenIndex'), u64('quantity')]), 'SettleBorrow')
|
||||
MangoInstructionLayout.addVariant(6, struct([seq(u64(), NUM_TOKENS, 'depositQuantities')]), 'Liquidate')
|
||||
MangoInstructionLayout.addVariant(7, struct([u64('quantity')]), 'DepositSrm')
|
||||
MangoInstructionLayout.addVariant(8, struct([u64('quantity')]), 'WithdrawSrm')
|
||||
|
||||
MangoInstructionLayout.addVariant(7,
|
||||
MangoInstructionLayout.addVariant(9,
|
||||
struct(
|
||||
[
|
||||
sideLayout('side'),
|
||||
u64('limitPrice'),
|
||||
u64('maxQuantity'),
|
||||
u64('maxBaseQuantity'),
|
||||
u64('maxQuoteQuantity'),
|
||||
selfTradeBehaviorLayout('selfTradeBehavior'),
|
||||
orderTypeLayout('orderType'),
|
||||
u64('clientId'),
|
||||
selfTradeBehaviorLayout('selfTradeBehavior')
|
||||
u16('limit'),
|
||||
]
|
||||
),
|
||||
'PlaceOrder'
|
||||
)
|
||||
|
||||
MangoInstructionLayout.addVariant(8, struct([]), 'SettleFunds')
|
||||
MangoInstructionLayout.addVariant(9,
|
||||
MangoInstructionLayout.addVariant(10, struct([]), 'SettleFunds')
|
||||
MangoInstructionLayout.addVariant(11,
|
||||
struct(
|
||||
[
|
||||
sideLayout('side'),
|
||||
u128('orderId'),
|
||||
publicKeyLayout('openOrders'),
|
||||
u8('openOrdersSlot')
|
||||
u128('orderId')
|
||||
]
|
||||
),
|
||||
'CancelOrder'
|
||||
)
|
||||
|
||||
MangoInstructionLayout.addVariant(10, struct([u64('clientId')]), 'CancelOrderByClientId')
|
||||
MangoInstructionLayout.addVariant(12, struct([u64('clientId')]), 'CancelOrderByClientId')
|
||||
|
||||
// @ts-ignore
|
||||
const instructionMaxSpan = Math.max(...Object.values(MangoInstructionLayout.registry).map((r) => r.span));
|
||||
|
|
Loading…
Reference in New Issue