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