mango-client-ts/src/tests.ts

177 lines
6.6 KiB
TypeScript

import { Market, OpenOrders } from '@project-serum/serum';
import { Account, Commitment, Connection, PublicKey } from '@solana/web3.js';
import * as os from 'os';
import * as fs from 'fs';
import { MangoClient, MangoGroup } from './client';
import IDS from './ids.json';
import {
decodeRecentEvents,
findLargestTokenAccountForOwner,
getMultipleAccounts,
nativeToUi,
parseTokenAccountData,
sleep
} from './utils'
async function tests() {
const cluster = "mainnet-beta";
const client = new MangoClient();
const clusterIds = IDS[cluster]
const connection = new Connection(IDS.cluster_urls[cluster], 'processed' as Commitment)
const mangoGroupPk = new PublicKey(clusterIds.mango_groups['BTC_ETH_USDT'].mango_group_pk);
const mangoProgramId = new PublicKey(clusterIds.mango_program_id);
const keyPairPath = process.env.KEYPAIR || os.homedir() + '/.config/solana/id.json'
const payer = new Account(JSON.parse(fs.readFileSync(keyPairPath, 'utf-8')))
/*
async function testSolink() {
const oraclePk = new PublicKey(IDS[cluster].oracles['ETH/USDT'])
const agg = await Aggregator.loadWithConnection(oraclePk, connection)
// const agg = await Aggregator.loadWithConnection(oraclePk, connection)
console.log(agg.answer.median.toNumber(), agg.answer.updatedAt.toNumber(), agg.round.id.toNumber())
}
*/
/*
async function testDepositSrm() {
const srmVaultPk = new PublicKey(clusterIds['mango_groups']['BTC_ETH_USDT']['srm_vault_pk'])
const mangoGroup = await client.getMangoGroup(connection, mangoGroupPk, srmVaultPk)
const srmAccountPk = new PublicKey("6utvndL8EEjpwK5QVtguErncQEPVbkuyABmXu6FeygeV")
const mangoSrmAccountPk = await client.depositSrm(connection, mangoProgramId, mangoGroup, payer, srmAccountPk, 100)
console.log(mangoSrmAccountPk.toBase58())
await sleep(2000)
const mangoSrmAccount = await client.getMangoSrmAccount(connection, mangoSrmAccountPk)
const txid = await client.withdrawSrm(connection, mangoProgramId, mangoGroup, mangoSrmAccount, payer, srmAccountPk, 50)
console.log('success', txid)
}
*/
/*
async function getMarginAccountDetails() {
const mangoGroup = await client.getMangoGroup(connection, mangoGroupPk);
const marginAccountPk = new PublicKey("6vAry8oHVvWqPJV6SMzzJ9EcQr5kkQYHef6ui2ewaagQ")
const marginAccount = await client.getMarginAccount(connection, marginAccountPk, mangoGroup.dexProgramId)
const prices = await mangoGroup.getPrices(connection)
console.log(marginAccount.toPrettyString(mangoGroup, prices))
console.log(marginAccount.beingLiquidated)
console.log(marginAccount.getUiDeposit(mangoGroup, 0), marginAccount.getUiBorrow(mangoGroup, 0))
console.log(marginAccount.getUiDeposit(mangoGroup, 1), marginAccount.getUiBorrow(mangoGroup, 1))
console.log(marginAccount.getUiDeposit(mangoGroup, 2), marginAccount.getUiBorrow(mangoGroup, 2))
console.log(marginAccount.getCollateralRatio(mangoGroup, prices))
// for (let i = 0; i < NUM_MARKETS; i++) {
// let openOrdersAccount = marginAccount.openOrdersAccounts[i]
// if (openOrdersAccount === undefined) {
// continue
// }
//
// for (const oid of openOrdersAccount.orders) {
// console.log(oid.toString())
// }
// console.log(i,
// nativeToUi(openOrdersAccount.quoteTokenTotal.toNumber(), mangoGroup.mintDecimals[NUM_MARKETS]),
// nativeToUi(openOrdersAccount.quoteTokenFree.toNumber(), mangoGroup.mintDecimals[NUM_MARKETS]),
//
// nativeToUi(openOrdersAccount.baseTokenTotal.toNumber(), mangoGroup.mintDecimals[i]),
// nativeToUi(openOrdersAccount.baseTokenFree.toNumber(), mangoGroup.mintDecimals[i])
//
// )
// }
}
*/
async function testMarketOrderDex() {
const NUM_MARKETS = 2;
const dexProgramId = new PublicKey(clusterIds.dex_program_id);
const mangoGroup = await client.getMangoGroup(connection, mangoGroupPk)
// load largest wallet account for each token
const tokenWallets = (await Promise.all(
mangoGroup.tokens.map(
(mint) => findLargestTokenAccountForOwner(connection, payer.publicKey, mint).then(
(response) => response.publicKey
)
)
))
console.log({tokenWallets: tokenWallets.map(w => w.toString())})
// load all markets
const markets = await Promise.all(mangoGroup.spotMarkets.map(
(pk) => Market.load(connection, pk, {skipPreflight: true, commitment: 'singleGossip'}, dexProgramId)
))
console.log({markets})
// load open orders
const liqorOpenOrdersKeys: PublicKey[] = []
for (let i = 0; i < NUM_MARKETS; i++) {
let openOrdersAccounts: OpenOrders[] = await markets[i].findOpenOrdersAccountsForOwner(connection, payer.publicKey)
if(openOrdersAccounts.length) {
liqorOpenOrdersKeys.push(openOrdersAccounts[0].publicKey)
} else {
console.log(`No OpenOrders account found for market ${markets[i].publicKey.toBase58()}`)
}
}
console.log({liqorOpenOrdersKeys: liqorOpenOrdersKeys.map(k => k.toString())})
const marketIndex = 1;
const market = markets[marketIndex]; // ETH/USDT
const price = 4000;
const size = 0.001;
const txid = await market.placeOrder(
connection,
{
owner: payer,
payer: tokenWallets[marketIndex],
side: 'sell',
price,
size,
orderType: 'ioc',
openOrdersAddressKey: liqorOpenOrdersKeys[marketIndex],
feeDiscountPubkey: null // TODO find liqor's SRM fee account
}
)
console.log({txid})
var lastSeenSeqNum = undefined
for (let i = 0; i < 50; ++i) {
const status = await connection.getSignatureStatus(txid);
console.log({status: status!.value!.confirmations})
let orders = await market.loadOrdersForOwner(connection, payer.publicKey);
console.log({orders});
const info = await connection.getAccountInfo(market['_decoded'].eventQueue)
const { header, nodes } = decodeRecentEvents(info!.data, lastSeenSeqNum)
console.log({ header, nodes: nodes.map(n => [n.nativeQuantityPaid.toNumber(),
n.nativeQuantityReleased.toNumber()]) })
lastSeenSeqNum = header.seqNum
const liqorWalletAccounts = await getMultipleAccounts(connection, tokenWallets, 'processed' as Commitment)
const liqorValuesUi = liqorWalletAccounts.map(
(a, i) => nativeToUi(parseTokenAccountData(a.accountInfo.data).amount, mangoGroup.mintDecimals[i])
)
console.log({liqorValuesUi})
await sleep(500)
}
}
/*
await getMarginAccountDetails()
await testSolink()
await testDepositSrm()
*/
await testMarketOrderDex()
}
tests()