mainnet setup script for vanity address (#324)

* mainnet setup script for vanity address

Signed-off-by: microwavedcola1 <microwavedcola@gmail.com>

* rename

Signed-off-by: microwavedcola1 <microwavedcola@gmail.com>

* update

Signed-off-by: microwavedcola1 <microwavedcola@gmail.com>

* update

Signed-off-by: microwavedcola1 <microwavedcola@gmail.com>

* update

Signed-off-by: microwavedcola1 <microwavedcola@gmail.com>

Signed-off-by: microwavedcola1 <microwavedcola@gmail.com>
This commit is contained in:
microwavedcola1 2022-12-08 16:04:58 +01:00 committed by GitHub
parent b66dc7ae80
commit 5cc88b0d97
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 209 additions and 365 deletions

View File

@ -231,7 +231,7 @@ export class MangoClient {
liquidationFee: number,
minVaultToDepositsRatio: number,
netBorrowLimitWindowSizeTs: number,
netBorrowsLimitNative: number,
netBorrowLimitPerWindowQuote: number,
): Promise<TransactionSignature> {
return await this.program.methods
.tokenRegister(
@ -248,7 +248,7 @@ export class MangoClient {
liquidationFee,
minVaultToDepositsRatio,
new BN(netBorrowLimitWindowSizeTs),
new BN(netBorrowsLimitNative),
new BN(netBorrowLimitPerWindowQuote),
)
.accounts({
group: group.publicKey,
@ -559,8 +559,8 @@ export class MangoClient {
accountNumber ?? 0,
tokenCount ?? 8,
serum3Count ?? 8,
perpCount ?? 0,
perpOoCount ?? 0,
perpCount ?? 8,
perpOoCount ?? 8,
name ?? '',
)
.accounts({

View File

@ -1,19 +1,19 @@
import * as dotenv from 'dotenv';
dotenv.config();
import { AnchorProvider, Wallet } from '@project-serum/anchor';
import { coder } from '@project-serum/anchor/dist/cjs/spl/token';
import { Cluster, Connection, Keypair } from '@solana/web3.js';
import * as dotenv from 'dotenv';
import fs from 'fs';
import { MangoClient } from '../client';
import { MANGO_V4_ID } from '../constants';
import { I80F48, ZERO_I80F48 } from '../numbers/I80F48';
import { toUiDecimals } from '../utils';
dotenv.config();
const CLUSTER_URL =
process.env.CLUSTER_URL_OVERRIDE || process.env.MB_CLUSTER_URL;
const PAYER_KEYPAIR =
process.env.PAYER_KEYPAIR_OVERRIDE || process.env.MB_PAYER_KEYPAIR;
const GROUP_NUM = Number(process.env.GROUP_NUM || 2);
const GROUP_NUM = Number(process.env.GROUP_NUM || 0);
const CLUSTER: Cluster =
(process.env.CLUSTER_OVERRIDE as Cluster) || 'mainnet-beta';

View File

@ -3855,17 +3855,6 @@ export type MangoV4 = {
},
{
"name": "beingLiquidated",
"docs": [
"Tracks that this account should be liquidated until init_health >= 0.",
"",
"Normally accounts can not be liquidated while maint_health >= 0. But when an account",
"reaches maint_health < 0, liquidators will call a liquidation instruction and thereby",
"set this flag. Now the account may be liquidated until init_health >= 0.",
"",
"Many actions should be disabled while the account is being liquidated, even if",
"its maint health has recovered to positive. Creating new open orders would, for example,",
"confuse liquidators."
],
"type": "u8"
},
{
@ -5775,19 +5764,6 @@ export type MangoV4 = {
},
{
"name": "StablePriceModel",
"docs": [
"Maintains a \"stable_price\" based on the oracle price.",
"",
"The stable price follows the oracle price, but its relative rate of",
"change is limited (to `stable_growth_limit`) and futher reduced if",
"the oracle price is far from the `delay_price`.",
"",
"Conceptually the `delay_price` is itself a time delayed",
"(`24 * delay_interval_seconds`, assume 24h) and relative rate of change limited",
"function of the oracle price. It is implemented as averaging the oracle",
"price over every `delay_interval_seconds` (assume 1h) and then applying the",
"`delay_growth_limit` between intervals."
],
"type": {
"kind": "struct",
"fields": [
@ -5804,13 +5780,6 @@ export type MangoV4 = {
},
{
"name": "delayPrices",
"docs": [
"Stored delay_price for each delay_interval.",
"If we want the delay_price to be 24h delayed, we would store one for each hour.",
"This is used in a cyclical way: We use the maximally-delayed value at delay_interval_index",
"and once enough time passes to move to the next delay interval, that gets overwritten and",
"we use the next one."
],
"type": {
"array": [
"f64",
@ -5820,46 +5789,26 @@ export type MangoV4 = {
},
{
"name": "delayAccumulatorPrice",
"docs": [
"The delay price is based on an average over each delay_interval. The contributions",
"to the average are summed up here."
],
"type": "f64"
},
{
"name": "delayAccumulatorTime",
"docs": [
"Accumulating the total time for the above average."
],
"type": "u32"
},
{
"name": "delayIntervalSeconds",
"docs": [
"Length of a delay_interval"
],
"type": "u32"
},
{
"name": "delayGrowthLimit",
"docs": [
"Maximal relative difference between two delay_price in consecutive intervals."
],
"type": "f32"
},
{
"name": "stableGrowthLimit",
"docs": [
"Maximal per-second relative difference of the stable price.",
"It gets further reduced if stable and delay price disagree."
],
"type": "f32"
},
{
"name": "lastDelayIntervalIndex",
"docs": [
"The delay_interval_index that update() was last called on."
],
"type": "u8"
},
{
@ -6031,14 +5980,6 @@ export type MangoV4 = {
},
{
"name": "HealthType",
"docs": [
"There are two types of health, initial health used for opening new positions and maintenance",
"health used for liquidations. They are both calculated as a weighted sum of the assets",
"minus the liabilities but the maint. health uses slightly larger weights for assets and",
"slightly smaller weights for the liabilities. Zero is used as the bright line for both",
"i.e. if your init health falls below zero, you cannot open new positions and if your maint. health",
"falls below zero you will be liquidated."
],
"type": {
"kind": "enum",
"variants": [
@ -11271,17 +11212,6 @@ export const IDL: MangoV4 = {
},
{
"name": "beingLiquidated",
"docs": [
"Tracks that this account should be liquidated until init_health >= 0.",
"",
"Normally accounts can not be liquidated while maint_health >= 0. But when an account",
"reaches maint_health < 0, liquidators will call a liquidation instruction and thereby",
"set this flag. Now the account may be liquidated until init_health >= 0.",
"",
"Many actions should be disabled while the account is being liquidated, even if",
"its maint health has recovered to positive. Creating new open orders would, for example,",
"confuse liquidators."
],
"type": "u8"
},
{
@ -13191,19 +13121,6 @@ export const IDL: MangoV4 = {
},
{
"name": "StablePriceModel",
"docs": [
"Maintains a \"stable_price\" based on the oracle price.",
"",
"The stable price follows the oracle price, but its relative rate of",
"change is limited (to `stable_growth_limit`) and futher reduced if",
"the oracle price is far from the `delay_price`.",
"",
"Conceptually the `delay_price` is itself a time delayed",
"(`24 * delay_interval_seconds`, assume 24h) and relative rate of change limited",
"function of the oracle price. It is implemented as averaging the oracle",
"price over every `delay_interval_seconds` (assume 1h) and then applying the",
"`delay_growth_limit` between intervals."
],
"type": {
"kind": "struct",
"fields": [
@ -13220,13 +13137,6 @@ export const IDL: MangoV4 = {
},
{
"name": "delayPrices",
"docs": [
"Stored delay_price for each delay_interval.",
"If we want the delay_price to be 24h delayed, we would store one for each hour.",
"This is used in a cyclical way: We use the maximally-delayed value at delay_interval_index",
"and once enough time passes to move to the next delay interval, that gets overwritten and",
"we use the next one."
],
"type": {
"array": [
"f64",
@ -13236,46 +13146,26 @@ export const IDL: MangoV4 = {
},
{
"name": "delayAccumulatorPrice",
"docs": [
"The delay price is based on an average over each delay_interval. The contributions",
"to the average are summed up here."
],
"type": "f64"
},
{
"name": "delayAccumulatorTime",
"docs": [
"Accumulating the total time for the above average."
],
"type": "u32"
},
{
"name": "delayIntervalSeconds",
"docs": [
"Length of a delay_interval"
],
"type": "u32"
},
{
"name": "delayGrowthLimit",
"docs": [
"Maximal relative difference between two delay_price in consecutive intervals."
],
"type": "f32"
},
{
"name": "stableGrowthLimit",
"docs": [
"Maximal per-second relative difference of the stable price.",
"It gets further reduced if stable and delay price disagree."
],
"type": "f32"
},
{
"name": "lastDelayIntervalIndex",
"docs": [
"The delay_interval_index that update() was last called on."
],
"type": "u8"
},
{
@ -13447,14 +13337,6 @@ export const IDL: MangoV4 = {
},
{
"name": "HealthType",
"docs": [
"There are two types of health, initial health used for opening new positions and maintenance",
"health used for liquidations. They are both calculated as a weighted sum of the assets",
"minus the liabilities but the maint. health uses slightly larger weights for assets and",
"slightly smaller weights for the liabilities. Zero is used as the bright line for both",
"i.e. if your init health falls below zero, you cannot open new positions and if your maint. health",
"falls below zero you will be liquidated."
],
"type": {
"kind": "enum",
"variants": [

View File

@ -15,39 +15,40 @@ import {
} from '../accounts/serum3';
import { MangoClient } from '../client';
import { MANGO_V4_ID } from '../constants';
import { buildVersionedTx } from '../utils';
import { buildVersionedTx, toNative } from '../utils';
const GROUP_NUM = Number(process.env.GROUP_NUM || 0);
const MAINNET_MINTS = new Map([
['USDC', 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'],
['USDT', 'Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB'],
['ETH', '7vfCXTUXx5WJV5JADk17DUJ4ksgau7utNKj4b963voxs'], // Ether (Portal)
['SOL', 'So11111111111111111111111111111111111111112'], // Wrapped SOL
['MSOL', 'mSoLzYCxHdYgdzU16g5QSh3i5K3z3KZK7ytfqcJm7So'],
['MNGO', 'MangoCzJ36AjZyKwVj3VnYU4GTonjfVEnJmvvWaxLac'],
['RAY', '4k3Dyjzvzp8eMZWUXbBCjEvwSkkk59S5iCNLY3QrkX6R'],
['DUST', 'DUSTawucrTsGU8hcqRdHDCbuYhCPADMLM2VcCb8VnFnQ'],
['USDC', 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'], // 0
['USDT', 'Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB'], // 1
['DAI', 'EjmyN6qEC1Tf1JxiG1ae7UTJhUxSwk1TCWNWqxWV4J6o'], // 2
['ETH', '7vfCXTUXx5WJV5JADk17DUJ4ksgau7utNKj4b963voxs'], // 3 Ether (Portal)
['SOL', 'So11111111111111111111111111111111111111112'], // 4 Wrapped SOL
['MSOL', 'mSoLzYCxHdYgdzU16g5QSh3i5K3z3KZK7ytfqcJm7So'], // 5
['MNGO', 'MangoCzJ36AjZyKwVj3VnYU4GTonjfVEnJmvvWaxLac'], // 6
]);
const MAINNET_ORACLES = new Map([
// USDC - stub oracle
['USDT', '3vxLXJqLqF3JG5TCbYycbKWRBbCJQLxQmBGCkyqEEefL'],
['BTC', 'GVXRSBjFk6e6J3NbVPXohDJetcTjaeeuykUpbQF8UoMU'],
['DAI', 'CtJ8EkqLmeYyGB8s4jevpeNsvmD4dxVR2krfsDLcvV8Y'],
['ETH', 'JBu1AL4obBcCMqKBBxhpWCNUt136ijcuMZLFvTP7iWdB'],
['SOL', 'H6ARHf6YXhGYeQfUzQNGk6rDNnLBQKrenN712K4AQJEG'],
['MSOL', 'E4v1BBgoso9s64TQvmyownAVJbhbEPGyzA3qn4n46qj9'],
['MNGO', '79wm3jjcPr6RaNQ4DGvP5KxG1mNd3gEBsg6FsNVFezK4'],
['RAY', 'AnLf8tVYCM816gmBjiy8n53eXKKEDydT5piYjjQDPgTB'],
['DUST', 'C5tuUPi7xJHBHZGZX6wWYf1Svm6jtTVwYrYrBCiEVejK'],
['BTC', 'GVXRSBjFk6e6J3NbVPXohDJetcTjaeeuykUpbQF8UoMU'],
]);
// External markets are matched with those in https://github.com/openbook-dex/openbook-ts/blob/master/packages/serum/src/markets.json
const MAINNET_SERUM3_MARKETS = new Map([
['SOL/USDC', '9wFFyRfZBsuAha4YcuxcXLKwMxJR43S7fPfQLusDBzvT'],
['SOL/USDC', '8BnEgHoWFysVcuFFX7QztDmzuH8r5ZFvyP3sYwn1XTh6'],
]);
const MIN_VAULT_TO_DEPOSITS_RATIO = 0.2;
const NET_BORROWS_WINDOW_SIZE_TS = 24 * 60 * 60;
const NET_BORROWS_LIMIT_NATIVE = 1 * Math.pow(10, 7) * Math.pow(10, 6);
const NET_BORROW_LIMIT_PER_WINDOW_QUOTE = toNative(1000000, 6).toNumber();
const { MB_CLUSTER_URL, MB_PAYER_KEYPAIR, MB_USER_KEYPAIR, MB_USER2_KEYPAIR } =
const { MB_CLUSTER_URL, MB_PAYER_KEYPAIR, MB_USER_KEYPAIR, MB_USER4_KEYPAIR } =
process.env;
async function buildAdminClient(): Promise<[MangoClient, Keypair]> {
@ -96,7 +97,7 @@ async function buildUserClient(
Buffer.from(JSON.parse(fs.readFileSync(MB_PAYER_KEYPAIR!, 'utf-8'))),
);
console.log(`Admin ${admin.publicKey.toBase58()}`);
const group = await client.getGroupForCreator(admin.publicKey, 2);
const group = await client.getGroupForCreator(admin.publicKey, GROUP_NUM);
return [client, group, user];
}
@ -107,8 +108,8 @@ async function createGroup() {
console.log(`Creating Group...`);
const insuranceMint = new PublicKey(MAINNET_MINTS.get('USDC')!);
await client.groupCreate(2, true, 0, insuranceMint);
const group = await client.getGroupForCreator(admin.publicKey, 2);
await client.groupCreate(GROUP_NUM, true, 2, insuranceMint);
const group = await client.getGroupForCreator(admin.publicKey, GROUP_NUM);
console.log(`...registered group ${group.publicKey}`);
}
@ -117,7 +118,7 @@ async function registerTokens() {
const client = result[0];
const admin = result[1];
const group = await client.getGroupForCreator(admin.publicKey, 2);
const group = await client.getGroupForCreator(admin.publicKey, GROUP_NUM);
const defaultOracleConfig = {
confFilter: 0.1,
@ -159,7 +160,7 @@ async function registerTokens() {
0,
MIN_VAULT_TO_DEPOSITS_RATIO,
NET_BORROWS_WINDOW_SIZE_TS,
NET_BORROWS_LIMIT_NATIVE,
NET_BORROW_LIMIT_PER_WINDOW_QUOTE,
);
console.log(`Registering USDT...`);
@ -182,7 +183,30 @@ async function registerTokens() {
0.025,
MIN_VAULT_TO_DEPOSITS_RATIO,
NET_BORROWS_WINDOW_SIZE_TS,
NET_BORROWS_LIMIT_NATIVE,
NET_BORROW_LIMIT_PER_WINDOW_QUOTE,
);
console.log(`Registering DAI...`);
const daiMainnetMint = new PublicKey(MAINNET_MINTS.get('DAI')!);
const daiMainnetOracle = new PublicKey(MAINNET_ORACLES.get('DAI')!);
await client.tokenRegister(
group,
daiMainnetMint,
daiMainnetOracle,
defaultOracleConfig,
2,
'DAI',
defaultInterestRate,
0.005,
0.0005,
0.95,
0.9,
1.05,
1.1,
0.025,
MIN_VAULT_TO_DEPOSITS_RATIO,
NET_BORROWS_WINDOW_SIZE_TS,
NET_BORROW_LIMIT_PER_WINDOW_QUOTE,
);
console.log(`Registering ETH...`);
@ -205,7 +229,7 @@ async function registerTokens() {
0.05,
MIN_VAULT_TO_DEPOSITS_RATIO,
NET_BORROWS_WINDOW_SIZE_TS,
NET_BORROWS_LIMIT_NATIVE,
NET_BORROW_LIMIT_PER_WINDOW_QUOTE,
);
console.log(`Registering SOL...`);
@ -216,7 +240,7 @@ async function registerTokens() {
solMainnetMint,
solMainnetOracle,
defaultOracleConfig,
5,
4,
'SOL',
defaultInterestRate,
0.005,
@ -228,7 +252,7 @@ async function registerTokens() {
0.05,
MIN_VAULT_TO_DEPOSITS_RATIO,
NET_BORROWS_WINDOW_SIZE_TS,
NET_BORROWS_LIMIT_NATIVE,
NET_BORROW_LIMIT_PER_WINDOW_QUOTE,
);
console.log(`Registering MSOL...`);
@ -239,7 +263,7 @@ async function registerTokens() {
msolMainnetMint,
msolMainnetOracle,
defaultOracleConfig,
6,
5,
'MSOL',
defaultInterestRate,
0.005,
@ -251,143 +275,47 @@ async function registerTokens() {
0.05,
MIN_VAULT_TO_DEPOSITS_RATIO,
NET_BORROWS_WINDOW_SIZE_TS,
NET_BORROWS_LIMIT_NATIVE,
);
console.log(`Registering RAY...`);
const rayMainnetMint = new PublicKey(MAINNET_MINTS.get('RAY')!);
const rayMainnetOracle = new PublicKey(MAINNET_ORACLES.get('RAY')!);
await client.tokenRegister(
group,
rayMainnetMint,
rayMainnetOracle,
defaultOracleConfig,
7,
'RAY',
{
adjustmentFactor: 0.004,
util0: 0.7,
rate0: 0.2,
util1: 0.85,
rate1: 0.4,
maxRate: 4.0,
},
0.005,
0.0005,
7 / 8,
3 / 4,
8 / 7,
4 / 3,
1 / 16,
MIN_VAULT_TO_DEPOSITS_RATIO,
NET_BORROWS_WINDOW_SIZE_TS,
NET_BORROWS_LIMIT_NATIVE,
NET_BORROW_LIMIT_PER_WINDOW_QUOTE,
);
console.log(`Registering DUST...`);
const dustMainnetMint = new PublicKey(MAINNET_MINTS.get('DUST')!);
const dustMainnetOracle = new PublicKey(MAINNET_ORACLES.get('DUST')!);
await client.tokenRegister(
console.log(`Registering MNGO...`);
await client.groupEdit(group, group.admin, group.admin);
const mngoMainnetMint = new PublicKey(MAINNET_MINTS.get('MNGO')!);
const mngoMainnetOracle = new PublicKey(MAINNET_ORACLES.get('MNGO')!);
await client.tokenRegisterTrustless(
group,
dustMainnetMint,
dustMainnetOracle,
defaultOracleConfig,
8,
'DUST',
{
adjustmentFactor: 0.004,
util0: 0.7,
rate0: 0.3,
util1: 0.85,
rate1: 0.6,
maxRate: 6.0,
},
0.005,
0.0005,
0, // no asset weight for isolation
0,
81 / 80,
41 / 40, // 40x leverage so we can test something
1 / 160, // no liquidation fee
MIN_VAULT_TO_DEPOSITS_RATIO,
NET_BORROWS_WINDOW_SIZE_TS,
NET_BORROWS_LIMIT_NATIVE,
mngoMainnetMint,
mngoMainnetOracle,
6,
'MNGO',
);
// log tokens/banks
await group.reloadAll(client);
for (const bank of await Array.from(group.banksMapByMint.values()).flat()) {
for (const bank of await Array.from(group.banksMapByMint.values())
.flat()
.sort((a, b) => a.tokenIndex - b.tokenIndex)) {
console.log(`${bank.toString()}`);
}
}
async function unregisterTokens() {
const result = await buildAdminClient();
const client = result[0];
const admin = result[1];
const group = await client.getGroupForCreator(admin.publicKey, 2);
let bank = group.getFirstBankByTokenIndex(8 as TokenIndex);
let sig = await client.tokenDeregister(group, bank.mint);
console.log(
`Removed token ${bank.name}, sig https://explorer.solana.com/tx/${sig}`,
);
}
async function registerSerum3Markets() {
const result = await buildAdminClient();
const client = result[0];
const admin = result[1];
const group = await client.getGroupForCreator(admin.publicKey, 2);
// Bump version to 1 to unlock serum3 feature
await client.groupEdit(
group,
group.admin,
group.fastListingAdmin,
undefined,
1,
);
const group = await client.getGroupForCreator(admin.publicKey, GROUP_NUM);
// Register SOL serum market
await client.serum3RegisterMarket(
group,
new PublicKey(MAINNET_SERUM3_MARKETS.get('SOL/USDC')!),
group.getFirstBankByMint(new PublicKey(MAINNET_MINTS.get('SOL')!)),
group.getFirstBankByMint(new PublicKey(MAINNET_MINTS.get('USDC')!)),
1,
0,
'SOL/USDC',
);
}
async function unregisterSerum3Markets() {
const result = await buildAdminClient();
const client = result[0];
const admin = result[1];
const group = await client.getGroupForCreator(admin.publicKey, 2);
let serum3Market = group.getSerum3MarketByName('RAY/SOL');
let sig = await client.serum3deregisterMarket(
group,
serum3Market.serumMarketExternal,
);
console.log(
`Deregistered serum market ${serum3Market.name}, sig https://explorer.solana.com/tx/${sig}`,
);
serum3Market = group.getSerum3MarketByName('DUST/SOL');
sig = await client.serum3deregisterMarket(
group,
serum3Market.serumMarketExternal,
);
console.log(
`Deregistered serum market ${serum3Market.name}, sig https://explorer.solana.com/tx/${sig}`,
);
}
async function createUser(userKeypair: string) {
const result = await buildUserClient(userKeypair);
const client = result[0];
@ -421,89 +349,49 @@ async function createUser(userKeypair: string) {
console.log(`...deposited 1 SOL`);
}
async function expandMangoAccount(userKeypair: string) {
const result = await buildUserClient(userKeypair);
const client = result[0];
const group = result[1];
const user = result[2];
const mangoAccounts = await client.getMangoAccountsForOwner(
group,
user.publicKey,
);
if (!mangoAccounts) {
throw new Error(`MangoAccounts not found for user ${user.publicKey}`);
async function main() {
try {
// await createGroup();
} catch (error) {
console.log(error);
}
try {
// await registerTokens();
} catch (error) {
console.log(error);
}
try {
// await registerSerum3Markets();
} catch (error) {
console.log(error);
}
try {
await createUser(MB_USER_KEYPAIR!);
await createUser(MB_USER4_KEYPAIR!);
} catch (error) {
console.log(error);
}
for (const mangoAccount of mangoAccounts) {
console.log(`...found MangoAccount ${mangoAccount.publicKey.toBase58()}`);
await client.expandMangoAccount(group, mangoAccount, 8, 2, 0, 0);
}
try {
} catch (error) {}
}
async function placeSerum3TradeAndCancelIt(userKeypair: string) {
const result = await buildUserClient(userKeypair);
const client = result[0];
const group = result[1];
const user = result[2];
const mangoAccounts = await client.getMangoAccountsForOwner(
group,
user.publicKey,
);
if (!mangoAccounts) {
throw new Error(`MangoAccounts not found for user ${user.publicKey}`);
}
for (const mangoAccount of mangoAccounts) {
console.log(`...found MangoAccount ${mangoAccount.publicKey.toBase58()}`);
console.log(`...placing serum3 order`);
await client.serum3PlaceOrder(
group,
mangoAccount,
new PublicKey(MAINNET_SERUM3_MARKETS.get('SOL/USDC')!),
Serum3Side.bid,
1,
1,
Serum3SelfTradeBehavior.decrementTake,
Serum3OrderType.limit,
Date.now(),
10,
);
console.log(`...current own orders on OB`);
let orders = await mangoAccount.loadSerum3OpenOrdersForMarket(
client,
group,
new PublicKey(MAINNET_SERUM3_MARKETS.get('SOL/USDC')!),
);
for (const order of orders) {
console.log(order);
}
console.log(`...cancelling serum3 orders`);
await client.serum3CancelAllOrders(
group,
mangoAccount,
new PublicKey(MAINNET_SERUM3_MARKETS.get('SOL/USDC')!),
10,
);
console.log(`...current own orders on OB`);
orders = await mangoAccount.loadSerum3OpenOrdersForMarket(
client,
group,
new PublicKey(MAINNET_SERUM3_MARKETS.get('SOL/USDC')!),
);
for (const order of orders) {
console.log(order);
}
}
try {
main();
} catch (error) {
console.log(error);
}
////////////////////////////////////////////////////////////
/// UNUSED /////////////////////////////////////////////////
////////////////////////////////////////////////////////////
async function createAndPopulateAlt() {
const result = await buildAdminClient();
const client = result[0];
const admin = result[1];
const group = await client.getGroupForCreator(admin.publicKey, 2);
const group = await client.getGroupForCreator(admin.publicKey, GROUP_NUM);
const connection = client.program.provider.connection;
@ -618,40 +506,114 @@ async function createAndPopulateAlt() {
}
}
async function main() {
try {
// await createGroup();
} catch (error) {
console.log(error);
}
try {
// await registerTokens();
// await unregisterTokens();
} catch (error) {
console.log(error);
}
try {
// await registerSerum3Markets();
// await unregisterSerum3Markets();
} catch (error) {
console.log(error);
}
try {
// await createUser(MB_USER_KEYPAIR!);
// await createUser(MB_USER2_KEYPAIR!);
// await expandMangoAccount(MB_USER_KEYPAIR!);
// await placeSerum3TradeAndCancelIt(MB_USER_KEYPAIR!);
} catch (error) {
console.log(error);
async function expandMangoAccount(userKeypair: string) {
const result = await buildUserClient(userKeypair);
const client = result[0];
const group = result[1];
const user = result[2];
const mangoAccounts = await client.getMangoAccountsForOwner(
group,
user.publicKey,
);
if (!mangoAccounts) {
throw new Error(`MangoAccounts not found for user ${user.publicKey}`);
}
try {
// await createAndPopulateAlt();
} catch (error) {}
for (const mangoAccount of mangoAccounts) {
console.log(
`...expanding MangoAccount ${mangoAccount.publicKey.toBase58()}`,
);
await client.expandMangoAccount(group, mangoAccount, 8, 8, 8, 8);
}
}
try {
main();
} catch (error) {
console.log(error);
async function placeSerum3TradeAndCancelIt(userKeypair: string) {
const result = await buildUserClient(userKeypair);
const client = result[0];
const group = result[1];
const user = result[2];
const mangoAccounts = await client.getMangoAccountsForOwner(
group,
user.publicKey,
);
if (!mangoAccounts) {
throw new Error(`MangoAccounts not found for user ${user.publicKey}`);
}
for (const mangoAccount of mangoAccounts) {
console.log(`...found MangoAccount ${mangoAccount.publicKey.toBase58()}`);
console.log(`...placing serum3 order`);
await client.serum3PlaceOrder(
group,
mangoAccount,
new PublicKey(MAINNET_SERUM3_MARKETS.get('SOL/USDC')!),
Serum3Side.bid,
1,
1,
Serum3SelfTradeBehavior.decrementTake,
Serum3OrderType.limit,
Date.now(),
10,
);
console.log(`...current own orders on OB`);
let orders = await mangoAccount.loadSerum3OpenOrdersForMarket(
client,
group,
new PublicKey(MAINNET_SERUM3_MARKETS.get('SOL/USDC')!),
);
for (const order of orders) {
console.log(order);
}
console.log(`...cancelling serum3 orders`);
await client.serum3CancelAllOrders(
group,
mangoAccount,
new PublicKey(MAINNET_SERUM3_MARKETS.get('SOL/USDC')!),
10,
);
console.log(`...current own orders on OB`);
orders = await mangoAccount.loadSerum3OpenOrdersForMarket(
client,
group,
new PublicKey(MAINNET_SERUM3_MARKETS.get('SOL/USDC')!),
);
for (const order of orders) {
console.log(order);
}
}
}
async function deregisterSerum3Markets() {
const result = await buildAdminClient();
const client = result[0];
const admin = result[1];
const group = await client.getGroupForCreator(admin.publicKey, GROUP_NUM);
// change xxx/xxx to market of choice
let serum3Market = group.getSerum3MarketByName('XXX/XXX');
let sig = await client.serum3deregisterMarket(
group,
serum3Market.serumMarketExternal,
);
console.log(
`...deregistered serum market ${serum3Market.name}, sig https://explorer.solana.com/tx/${sig}`,
);
}
async function deregisterTokens() {
const result = await buildAdminClient();
const client = result[0];
const admin = result[1];
const group = await client.getGroupForCreator(admin.publicKey, GROUP_NUM);
// change -1 to tokenIndex of choice
let bank = group.getFirstBankByTokenIndex(-1 as TokenIndex);
let sig = await client.tokenDeregister(group, bank.mint);
console.log(
`...removed token ${bank.name}, sig https://explorer.solana.com/tx/${sig}`,
);
}