Signed-off-by: microwavedcola1 <microwavedcola@gmail.com>
This commit is contained in:
microwavedcola1 2022-04-13 09:09:17 +02:00
parent b39662b804
commit e5ed7936eb
5 changed files with 36 additions and 54 deletions

View File

@ -8,33 +8,6 @@
Devnet deployment - m43thNJ58XCjL798ZSq6JGAG1BnWskhdq5or6kcnfsD Devnet deployment - m43thNJ58XCjL798ZSq6JGAG1BnWskhdq5or6kcnfsD
TS client - see ts dir, and ts/example.ts, run as `yarn ts-node ts/example.ts` TS client based examples (for details check respective scripts)
(cd ts/client && yarn example1-admin) - create a devnet group
### Module structure (cd ts/client && yarn example1-user) - run through some mangoaccount operations for a user on devnet
As and when we move to a more complete project, we should think of having multiple modules
e.g. core/shared, spot, perpetuals, etc., and then each would have its own instructions
and state sub module. Goal is that new contributors find relevant code easily and can navigate
easily.
```
programs
└── mango-v4
├── Cargo.toml
├── Xargo.toml
└── src
│ ├── error.rs
│ ├── instructions # instructions go here, each instruction gets an individual file
│ │   ├── initialiaze.rs
│ │   └── mod.rs
│ ├── lib.rs
│ └── state # state goes here, each account state gets an individual file
│ └── mod.rs
└── tests # rust tests, TODO
```
### How to open and manage pull requests
- when in doubt dont squash commits, specially when merge request is very large, specially if your branch contains unrelated commits
- use the why along with what for commit messages, code comments, makes it easy to understand the context
- add descriptions to your merge requests if they are non trivial, helps code reviewer watch out for things, understand the motivation for the merge request

View File

@ -1 +0,0 @@
See example1-user.ts and example1-admin.ts

View File

@ -8,8 +8,8 @@
"scripts": { "scripts": {
"build": "tsc", "build": "tsc",
"clean": "rm -rf dist", "clean": "rm -rf dist",
"example1-user": "ts-node src/example1-user.ts", "example1-user": "ts-node src/scripts/example1-user.ts",
"example1-admin": "ts-node src/example1-admin.ts", "example1-admin": "ts-node src/scripts/example1-admin.ts",
"format": "prettier --check .", "format": "prettier --check .",
"lint": "eslint . --ext ts --ext tsx --ext js --quiet", "lint": "eslint . --ext ts --ext tsx --ext js --quiet",
"type-check": "tsc --pretty --noEmit" "type-check": "tsc --pretty --noEmit"

View File

@ -1,8 +1,8 @@
import { Provider, Wallet } from '@project-serum/anchor'; import { Provider, Wallet } from '@project-serum/anchor';
import { Connection, Keypair, PublicKey } from '@solana/web3.js'; import { Connection, Keypair, PublicKey } from '@solana/web3.js';
import fs from 'fs'; import fs from 'fs';
import { MangoClient } from './client'; import { MangoClient } from '../client';
import { DEVNET_SERUM3_PROGRAM_ID } from './constants'; import { DEVNET_SERUM3_PROGRAM_ID } from '../constants';
const DEVNET_SERUM3_MARKETS = new Map([ const DEVNET_SERUM3_MARKETS = new Map([
['BTC/USDC', 'DW83EpHFywBxCHmyARxwj3nzxJd7MUdSeznmrdzZKNZB'], ['BTC/USDC', 'DW83EpHFywBxCHmyARxwj3nzxJd7MUdSeznmrdzZKNZB'],
@ -17,6 +17,12 @@ const DEVNET_ORACLES = new Map([
// //
// An example for admins based on high level api i.e. the client // An example for admins based on high level api i.e. the client
// Depoys a new mango group to devnet, registers 2 tokens, and 1 serum3 spot market
//
// process.env.ADMIN_KEYPAIR - group admin keypair path
// to create a new admin keypair:
// * solana-keygen new --outfile ~/.config/solana/admin.json
// * solana airdrop 1 -k ~/.config/solana/admin.json
// //
async function main() { async function main() {
const options = Provider.defaultOptions(); const options = Provider.defaultOptions();
@ -36,15 +42,15 @@ async function main() {
const client = await MangoClient.connect(adminProvider, true); const client = await MangoClient.connect(adminProvider, true);
// group // group
console.log(`Group...`); console.log(`Creating Group...`);
try { try {
await client.createGroup(); await client.createGroup();
} catch (error) {} } catch (error) {}
const group = await client.getGroupForAdmin(admin.publicKey); const group = await client.getGroupForAdmin(admin.publicKey);
console.log(`Group ${group.publicKey}`); console.log(`...registered group ${group.publicKey}`);
// register token 0 // register token 0
console.log(`Token 0...`); console.log(`Registering BTC...`);
const btcDevnetMint = new PublicKey(DEVNET_MINTS.get('BTC')!); const btcDevnetMint = new PublicKey(DEVNET_MINTS.get('BTC')!);
const btcDevnetOracle = new PublicKey(DEVNET_ORACLES.get('BTC')!); const btcDevnetOracle = new PublicKey(DEVNET_ORACLES.get('BTC')!);
try { try {
@ -69,7 +75,7 @@ async function main() {
} catch (error) {} } catch (error) {}
// stub oracle + register token 1 // stub oracle + register token 1
console.log(`Token 1...`); console.log(`Registering USDC...`);
const usdcDevnetMint = new PublicKey(DEVNET_MINTS.get('USDC')!); const usdcDevnetMint = new PublicKey(DEVNET_MINTS.get('USDC')!);
try { try {
await client.createStubOracle(group, usdcDevnetMint, 1.0); await client.createStubOracle(group, usdcDevnetMint, 1.0);
@ -99,12 +105,12 @@ async function main() {
// log tokens/banks // log tokens/banks
for (const bank of await group.banksMap.values()) { for (const bank of await group.banksMap.values()) {
console.log( console.log(
`Bank ${bank.tokenIndex} ${bank.publicKey}, mint ${bank.mint}, oracle ${bank.oracle}`, `...registered Bank ${bank.tokenIndex} ${bank.publicKey}, mint ${bank.mint}, oracle ${bank.oracle}`,
); );
} }
// register serum market // register serum market
console.log(`Serum3 market...`); console.log(`Registering serum3 market...`);
const serumMarketExternalPk = new PublicKey( const serumMarketExternalPk = new PublicKey(
DEVNET_SERUM3_MARKETS.get('BTC/USDC')!, DEVNET_SERUM3_MARKETS.get('BTC/USDC')!,
); );
@ -124,7 +130,7 @@ async function main() {
group.banksMap.get('BTC')?.tokenIndex, group.banksMap.get('BTC')?.tokenIndex,
group.banksMap.get('USDC')?.tokenIndex, group.banksMap.get('USDC')?.tokenIndex,
); );
console.log(`Serum3 market ${markets[0].publicKey}`); console.log(`...registerd serum3 market ${markets[0].publicKey}`);
process.exit(); process.exit();
} }

View File

@ -5,12 +5,15 @@ import {
Serum3OrderType, Serum3OrderType,
Serum3SelfTradeBehavior, Serum3SelfTradeBehavior,
Serum3Side, Serum3Side,
} from './accounts/serum3'; } from '../accounts/serum3';
import { MangoClient } from './client'; import { MangoClient } from '../client';
import { DEVNET_SERUM3_PROGRAM_ID } from './constants'; import { DEVNET_SERUM3_PROGRAM_ID } from '../constants';
// //
// An example for users based on high level api i.e. the client // An example for users based on high level api i.e. the client
// Create
// process.env.USER_KEYPAIR - mango account owner keypair path
// process.env.ADMIN_KEYPAIR - group admin keypair path (useful for automatically finding the group)
// //
async function main() { async function main() {
const options = Provider.defaultOptions(); const options = Provider.defaultOptions();
@ -36,16 +39,17 @@ async function main() {
), ),
); );
const group = await client.getGroupForAdmin(admin.publicKey); const group = await client.getGroupForAdmin(admin.publicKey);
console.log(`Group ${group.publicKey.toBase58()}`); console.log(`Found group ${group.publicKey.toBase58()}`);
// create + fetch account // create + fetch account
console.log(`Creating mangoaccount...`);
const mangoAccount = await client.getOrCreateMangoAccount( const mangoAccount = await client.getOrCreateMangoAccount(
group, group,
user.publicKey, user.publicKey,
0, 0,
'my_mango_account', 'my_mango_account',
); );
console.log(`MangoAccount ${mangoAccount.publicKey}`); console.log(`...created/found mangoAccount ${mangoAccount.publicKey}`);
// deposit and withdraw // deposit and withdraw
console.log(`Depositing...5000000 USDC`); console.log(`Depositing...5000000 USDC`);
@ -56,13 +60,13 @@ async function main() {
await client.deposit(group, mangoAccount, 'BTC', 5000000); await client.deposit(group, mangoAccount, 'BTC', 5000000);
await mangoAccount.reload(client); await mangoAccount.reload(client);
console.log(`Withdrawing...1000000`); console.log(`Withdrawing...1000000 USDC`);
await client.withdraw(group, mangoAccount, 'USDC', 1_000000, false); await client.withdraw(group, mangoAccount, 'USDC', 1_000000, false);
await mangoAccount.reload(client); await mangoAccount.reload(client);
// serum3 // serum3
console.log( console.log(
`Placing serum3 bid which would not be settled since its relatively low then midprice`, `Placing serum3 bid which would not be settled since its relatively low then midprice...`,
); );
await client.serum3PlaceOrder( await client.serum3PlaceOrder(
group, group,
@ -79,7 +83,7 @@ async function main() {
); );
await mangoAccount.reload(client); await mangoAccount.reload(client);
console.log(`Placing serum3 bid way above midprice`); console.log(`Placing serum3 bid way above midprice...`);
await client.serum3PlaceOrder( await client.serum3PlaceOrder(
group, group,
mangoAccount, mangoAccount,
@ -95,7 +99,7 @@ async function main() {
); );
await mangoAccount.reload(client); await mangoAccount.reload(client);
console.log(`Placing serum3 ask way below midprice`); console.log(`Placing serum3 ask way below midprice...`);
await client.serum3PlaceOrder( await client.serum3PlaceOrder(
group, group,
mangoAccount, mangoAccount,
@ -118,9 +122,9 @@ async function main() {
); );
for (const order of orders) { for (const order of orders) {
console.log( console.log(
`Order orderId ${order.orderId}, ${order.side}, ${order.price}, ${order.size}`, ` - Order orderId ${order.orderId}, ${order.side}, ${order.price}, ${order.size}`,
); );
console.log(`Cancelling order with ${order.orderId}`); console.log(` - Cancelling order with ${order.orderId}`);
await client.serum3CancelOrder( await client.serum3CancelOrder(
group, group,
mangoAccount, mangoAccount,
@ -131,7 +135,7 @@ async function main() {
); );
} }
console.log(`Current own orders on OB...`); console.log(` - Current own orders on OB...`);
orders = await client.getSerum3Orders( orders = await client.getSerum3Orders(
group, group,
DEVNET_SERUM3_PROGRAM_ID, DEVNET_SERUM3_PROGRAM_ID,