diff --git a/ts/client/scripts/archive/account-shrink/admin.ts b/ts/client/scripts/archive/account-shrink/admin.ts new file mode 100644 index 000000000..917ee6ade --- /dev/null +++ b/ts/client/scripts/archive/account-shrink/admin.ts @@ -0,0 +1,230 @@ +import { AnchorProvider, Wallet } from '@coral-xyz/anchor'; +import { Connection, Keypair, PublicKey } from '@solana/web3.js'; +import fs from 'fs'; +import { PerpMarketIndex } from '../../../src/accounts/perp'; +import { MangoClient } from '../../../src/client'; +import { DefaultTokenRegisterParams } from '../../../src/clientIxParamBuilder'; +import { MANGO_V4_ID } from '../../../src/constants'; + +const DEVNET_SERUM3_MARKETS = new Map([ + ['SOL/USDC', '6xYbSQyhajUqyatJDdkonpj7v41bKeEBWpf7kwRh5X7A'], +]); +const DEVNET_MINTS = new Map([ + ['USDC', '8FRFC6MoGGkMFQwngccyu69VnYbzykGeez7ignHVAFSN'], + ['USDT', 'DAwBSXe6w9g37wdE2tCrFbho3QHKZi4PjuBytQCULap2'], + ['SOL', 'So11111111111111111111111111111111111111112'], +]); +const DEVNET_ORACLES = new Map([ + ['SOL', 'J83w4HKfqxwcq3BEMMkPFSppX3gqekLyLJBexebFVkix'], +]); + +const GROUP_NUM = 2814; + +async function main(): Promise { + let sig; + + const options = AnchorProvider.defaultOptions(); + const connection = new Connection( + 'https://mango.devnet.rpcpool.com', + options, + ); + + const admin = Keypair.fromSecretKey( + Buffer.from( + JSON.parse(fs.readFileSync(process.env.ADMIN_KEYPAIR!, 'utf-8')), + ), + ); + const adminWallet = new Wallet(admin); + console.log(`Admin ${adminWallet.publicKey.toBase58()}`); + const adminProvider = new AnchorProvider(connection, adminWallet, options); + const client = await MangoClient.connect( + adminProvider, + 'devnet', + MANGO_V4_ID['devnet'], + { + idsSource: 'get-program-accounts', + }, + ); + + // group + console.log(`Creating Group...`); + const insuranceMint = new PublicKey(DEVNET_MINTS.get('USDC')!); + try { + await client.groupCreate(GROUP_NUM, true, 0, insuranceMint); + } catch (error) { + console.log(error); + } + const group = await client.getGroupForCreator(admin.publicKey, GROUP_NUM); + console.log(`...registered group ${group.publicKey}`); + + // stub usdc oracle + register token 0 + console.log(`Registering USDC...`); + const usdcDevnetMint = new PublicKey(DEVNET_MINTS.get('USDC')!); + try { + sig = await client.stubOracleCreate(group, insuranceMint, 1.0); + const usdcDevnetOracle = ( + await client.getStubOracle(group, insuranceMint) + )[0]; + console.log( + `...registered stub oracle ${usdcDevnetOracle}, https://explorer.solana.com/tx/${sig}?cluster=devnet`, + ); + + sig = await client.tokenRegister( + group, + usdcDevnetMint, + usdcDevnetOracle.publicKey, + 0, // tokenIndex + 'USDC', + { + ...DefaultTokenRegisterParams, + oracleConfig: { + confFilter: 10000, + maxStalenessSlots: null, + }, + }, + ); + await group.reloadAll(client); + const bank = group.getFirstBankByMint(usdcDevnetMint); + console.log( + `...registered token bank ${bank.publicKey}, https://explorer.solana.com/tx/${sig}?cluster=devnet`, + ); + await group.reloadAll(client); + // eslint-disable-next-line + } catch (error) {} + + // register token 4 + console.log(`Registering SOL...`); + const solDevnetMint = new PublicKey(DEVNET_MINTS.get('SOL')!); + const solDevnetOracle = new PublicKey(DEVNET_ORACLES.get('SOL')!); + try { + sig = await client.tokenRegister( + group, + solDevnetMint, + solDevnetOracle, + 4, // tokenIndex + 'SOL', + { + ...DefaultTokenRegisterParams, + oracleConfig: { + confFilter: 10000, + maxStalenessSlots: null, + }, + }, + ); + await group.reloadAll(client); + const bank = group.getFirstBankByMint(solDevnetMint); + console.log( + `...registered token bank ${bank.publicKey}, https://explorer.solana.com/tx/${sig}?cluster=devnet`, + ); + } catch (error) { + console.log(error); + } + + console.log(`Registering USDT...`); + const usdtDevnetMint = new PublicKey(DEVNET_MINTS.get('USDT')!); + const usdcDevnetOracle = ( + await client.getStubOracle(group, insuranceMint) + )[0]; + try { + sig = await client.tokenRegister( + group, + usdtDevnetMint, + usdcDevnetOracle.publicKey, + 5, // tokenIndex + 'USDT', + { + ...DefaultTokenRegisterParams, + oracleConfig: { + confFilter: 10000, + maxStalenessSlots: null, + }, + }, + ); + await group.reloadAll(client); + const bank = group.getFirstBankByMint(solDevnetMint); + console.log( + `...registered token bank ${bank.publicKey}, https://explorer.solana.com/tx/${sig}?cluster=devnet`, + ); + } catch (error) { + console.log(error); + } + + // register serum market + console.log(`Registering serum3 markets...`); + + const serumMarketExternalPk = new PublicKey( + DEVNET_SERUM3_MARKETS.get('SOL/USDC')!, + ); + try { + sig = await client.serum3RegisterMarket( + group, + serumMarketExternalPk, + group.getFirstBankByMint(solDevnetMint), + group.getFirstBankByMint(insuranceMint), + 0, + 'SOL/USDC', + ); + await group.reloadAll(client); + const serum3Market = group.getSerum3MarketByExternalMarket( + serumMarketExternalPk, + ); + console.log( + `...registered serum market ${serum3Market.publicKey}, https://explorer.solana.com/tx/${sig}?cluster=devnet`, + ); + } catch (error) { + console.log(error); + } + + // register perp market + let count = 0; + console.log(`Registering perp market...`); + for (const market of ['SOL-PERP1', 'SOL-PERP2', 'SOL-PERP3']) { + count = count + 1; + try { + sig = await client.perpCreateMarket( + group, + new PublicKey(DEVNET_ORACLES.get('SOL')!), + count, + market, + { confFilter: 10000, maxStalenessSlots: null }, + 6, + 10, + 100, + 0.975, + 0.95, + 1.025, + 1.05, + 0.95, + 0.9, + 0.012, + 0.0002, + 0.0, + 0, + 0.05, + 0.05, + 100, + true, + 1000, + 1000000, + 0.05, + 0, + 1.0, + 2 * 60 * 60, + 0.025, + ); + await group.reloadAll(client); + const perpMarket = group.getPerpMarketByMarketIndex( + count as PerpMarketIndex, + ); + console.log( + `...registered perp market ${perpMarket.publicKey}, https://explorer.solana.com/tx/${sig}?cluster=devnet`, + ); + } catch (error) { + console.log(error); + } + } + + process.exit(); +} + +main(); diff --git a/ts/client/scripts/archive/account-shrink/user.ts b/ts/client/scripts/archive/account-shrink/user.ts new file mode 100644 index 000000000..966e91482 --- /dev/null +++ b/ts/client/scripts/archive/account-shrink/user.ts @@ -0,0 +1,226 @@ +import { AnchorProvider, Wallet } from '@coral-xyz/anchor'; +import { Connection, Keypair } from '@solana/web3.js'; +import fs from 'fs'; +import { MangoAccount } from '../../../src/accounts/mangoAccount'; +import { MangoClient } from '../../../src/client'; +import { MANGO_V4_ID } from '../../../src/constants'; + +/* eslint-disable */ + +const GROUP_NUM = 2814; + +async function main(): Promise { + const options = AnchorProvider.defaultOptions(); + const connection = new Connection( + 'https://mango.devnet.rpcpool.com', + options, + ); + + const user = Keypair.fromSecretKey( + Buffer.from( + JSON.parse(fs.readFileSync(process.env.USER_KEYPAIR!, 'utf-8')), + ), + ); + const userWallet = new Wallet(user); + const userProvider = new AnchorProvider(connection, userWallet, options); + const client = await MangoClient.connect( + userProvider, + 'devnet', + MANGO_V4_ID['devnet'], + { + idsSource: 'get-program-accounts', + }, + ); + console.log(`User ${userWallet.publicKey.toBase58()}`); + + // fetch group + const admin = Keypair.fromSecretKey( + Buffer.from( + JSON.parse(fs.readFileSync(process.env.ADMIN_KEYPAIR!, 'utf-8')), + ), + ); + const group = await client.getGroupForCreator(admin.publicKey, GROUP_NUM); + const serumMarketExternal = Array.from( + group.serum3MarketsMapByMarketIndex.values(), + )[0]!.serumMarketExternal; + const perpMarket1 = Array.from(group.perpMarketsMapByName.values())[0]!; + const perpMarket2 = Array.from(group.perpMarketsMapByName.values())[1]!; + const perpMarket3 = Array.from(group.perpMarketsMapByName.values())[2]!; + + // create + fetch account + console.log(`Creating mangoaccount...`); + let mangoAccount = await client.getMangoAccountForOwner( + group, + user.publicKey, + 0, + ); + if (!mangoAccount) { + await client.createMangoAccount(group, 0, 'some', 2, 1, 1, 1); + mangoAccount = (await client.getMangoAccountForOwner( + group, + user.publicKey, + 0, + true, + )) as MangoAccount; + } + await mangoAccount!.reload(client); + console.log(`...created/found mangoAccount ${mangoAccount.publicKey}`); + + let sig; + + console.log(`Expanding mangoaccount...`); + sig = await client.expandMangoAccount(group, mangoAccount, 2, 1, 3, 3); + console.log(`...expanded mangoAccount ${sig.signature}`); + + // tokens + { + sig = await client.tokenDeposit( + group, + mangoAccount, + group.banksMapByName.get('USDC')![0].mint, + 50, + ); + console.log(`...deposited usdc ${sig.signature}`); + // await mangoAccount.reload(client); + // // deposit SOL + // sig = await client.tokenDeposit( + // group, + // mangoAccount, + // group.banksMapByName.get('SOL')![0].mint, + // 1, + // ); + // console.log(`...deposited sol ${sig.signature}`); + // await mangoAccount.reload(client); + } + + // serum3 + { + // sig = await client.serum3PlaceOrder( + // group, + // mangoAccount, + // serumMarketExternal, + // Serum3Side.bid, + // 1, + // 1, + // Serum3SelfTradeBehavior.decrementTake, + // Serum3OrderType.limit, + // Date.now(), + // 10, + // ); + // console.log(`...placed serum3 order ${sig.signature}`); + // await mangoAccount.reload(client); + // sig = await client.serum3ConsumeEvents(group, serumMarketExternal); + // console.log(`...consumed events ${sig.signature}`); + // for (const _ of range(0, 10)) { + // sig = await client.serum3CancelAllOrders( + // group, + // mangoAccount, + // serumMarketExternal, + // 100, + // ); + // console.log(`...cancelled all serum3 oo ${sig.signature}`); + // sig = await client.serum3SettleFunds( + // group, + // mangoAccount, + // serumMarketExternal, + // ); + // console.log(`...settled serum3 ${sig.signature}`); + // await mangoAccount.reload(client); + // if ( + // mangoAccount + // .getSerum3OoAccount( + // group.getSerum3MarketByExternalMarket(serumMarketExternal) + // .marketIndex, + // ) + // .freeSlotBits.zeroBits() === 0 + // ) { + // break; + // } + // } + // sig = await client.serum3CloseOpenOrders( + // group, + // mangoAccount, + // serumMarketExternal, + // ); + // console.log(`...closed serum3 oo ${sig.signature}`); + // sig = await client.expandMangoAccount(group, mangoAccount, 2, 0, 3, 3); + // console.log(`...resized mangoAccount ${sig.signature}`); + } + + // perps + { + // sig = await client.perpCancelAllOrders( + // group, + // mangoAccount, + // perpMarket1.perpMarketIndex, + // 10, + // ); + // sig = await client.perpCancelAllOrders( + // group, + // mangoAccount, + // perpMarket2.perpMarketIndex, + // 10, + // ); + // sig = await client.perpCancelAllOrders( + // group, + // mangoAccount, + // perpMarket3.perpMarketIndex, + // 10, + // ); + // sig = await client.perpPlaceOrder( + // group, + // mangoAccount, + // perpMarket1.perpMarketIndex, + // PerpOrderSide.bid, + // 1, + // 1, + // ); + // console.log(`...placed perp order ${sig.signature}`); + // await mangoAccount.reload(client); + // sig = await client.perpPlaceOrder( + // group, + // mangoAccount, + // perpMarket2.perpMarketIndex, + // PerpOrderSide.bid, + // 1, + // 1, + // ); + // console.log(`...placed perp order ${sig.signature}`); + // await mangoAccount.reload(client); + // sig = await client.perpPlaceOrder( + // group, + // mangoAccount, + // perpMarket3.perpMarketIndex, + // PerpOrderSide.bid, + // 1, + // 1, + // ); + // console.log(`...placed perp order ${sig.signature}`); + // await mangoAccount.reload(client); + // sig = await client.perpCancelAllOrders( + // group, + // mangoAccount, + // perpMarket1.perpMarketIndex, + // 10, + // ); + // console.log(`...perp cancel orders ${sig.signature}`); + // sig = await client.perpDeactivatePosition( + // group, + // mangoAccount, + // perpMarket1.perpMarketIndex, + // ); + // console.log(`...perp deactivate position ${sig.signature}`); + // await mangoAccount.reload(client); + // console.log(mangoAccount.toString(group)); + // console.log(`Resizing mangoaccount...`); + // sig = await client.expandMangoAccount(group, mangoAccount, 2, 1, 2, 3); + // console.log(`...resized mangoAccount ${sig.signature}`); + } + + await mangoAccount.reload(client); + console.log(mangoAccount.toString(group)); + + process.exit(); +} + +main(); diff --git a/ts/client/src/client.ts b/ts/client/src/client.ts index bbca557df..358b43aed 100644 --- a/ts/client/src/client.ts +++ b/ts/client/src/client.ts @@ -6,7 +6,7 @@ import { Wallet, } from '@coral-xyz/anchor'; import * as borsh from '@coral-xyz/borsh'; -import { OpenOrders } from '@project-serum/serum'; +import { OpenOrders, decodeEventQueue } from '@project-serum/serum'; import { createCloseAccountInstruction, createInitializeAccount3Instruction, @@ -1584,6 +1584,28 @@ export class MangoClient { return await this.sendAndConfirmTransactionForGroup(group, [ix]); } + public async serum3ConsumeEvents( + group: Group, + serum3MarketExternalPk: PublicKey, + ): Promise { + const serum3MarketExternal = group.serum3ExternalMarketsMap.get( + serum3MarketExternalPk.toBase58(), + )!; + const ai = await this.program.provider.connection.getAccountInfo( + serum3MarketExternal.decoded.eventQueue, + ); + const eq = decodeEventQueue(ai!.data); + const orderedAccounts: PublicKey[] = eq + .map((e) => e.openOrders) + .sort((a, b) => a.toBuffer().swap64().compare(b.toBuffer().swap64())); + if (orderedAccounts.length == 0) { + throw new Error(`Event queue is empty!`); + } + return this.sendAndConfirmTransactionForGroup(group, [ + serum3MarketExternal.makeConsumeEventsInstruction(orderedAccounts, 65535), + ]); + } + public async serum3EditMarket( group: Group, serum3MarketIndex: MarketIndex,