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
TS client - see ts dir, and ts/example.ts, run as `yarn ts-node ts/example.ts`
### Module structure
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
TS client based examples (for details check respective scripts)
(cd ts/client && yarn example1-admin) - create a devnet group
(cd ts/client && yarn example1-user) - run through some mangoaccount operations for a user on devnet

View File

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

View File

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

View File

@ -1,8 +1,8 @@
import { Provider, Wallet } from '@project-serum/anchor';
import { Connection, Keypair, PublicKey } from '@solana/web3.js';
import fs from 'fs';
import { MangoClient } from './client';
import { DEVNET_SERUM3_PROGRAM_ID } from './constants';
import { MangoClient } from '../client';
import { DEVNET_SERUM3_PROGRAM_ID } from '../constants';
const DEVNET_SERUM3_MARKETS = new Map([
['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
// 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() {
const options = Provider.defaultOptions();
@ -36,15 +42,15 @@ async function main() {
const client = await MangoClient.connect(adminProvider, true);
// group
console.log(`Group...`);
console.log(`Creating Group...`);
try {
await client.createGroup();
} catch (error) {}
const group = await client.getGroupForAdmin(admin.publicKey);
console.log(`Group ${group.publicKey}`);
console.log(`...registered group ${group.publicKey}`);
// register token 0
console.log(`Token 0...`);
console.log(`Registering BTC...`);
const btcDevnetMint = new PublicKey(DEVNET_MINTS.get('BTC')!);
const btcDevnetOracle = new PublicKey(DEVNET_ORACLES.get('BTC')!);
try {
@ -69,7 +75,7 @@ async function main() {
} catch (error) {}
// stub oracle + register token 1
console.log(`Token 1...`);
console.log(`Registering USDC...`);
const usdcDevnetMint = new PublicKey(DEVNET_MINTS.get('USDC')!);
try {
await client.createStubOracle(group, usdcDevnetMint, 1.0);
@ -99,12 +105,12 @@ async function main() {
// log tokens/banks
for (const bank of await group.banksMap.values()) {
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
console.log(`Serum3 market...`);
console.log(`Registering serum3 market...`);
const serumMarketExternalPk = new PublicKey(
DEVNET_SERUM3_MARKETS.get('BTC/USDC')!,
);
@ -124,7 +130,7 @@ async function main() {
group.banksMap.get('BTC')?.tokenIndex,
group.banksMap.get('USDC')?.tokenIndex,
);
console.log(`Serum3 market ${markets[0].publicKey}`);
console.log(`...registerd serum3 market ${markets[0].publicKey}`);
process.exit();
}

View File

@ -5,12 +5,15 @@ import {
Serum3OrderType,
Serum3SelfTradeBehavior,
Serum3Side,
} from './accounts/serum3';
import { MangoClient } from './client';
import { DEVNET_SERUM3_PROGRAM_ID } from './constants';
} from '../accounts/serum3';
import { MangoClient } from '../client';
import { DEVNET_SERUM3_PROGRAM_ID } from '../constants';
//
// 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() {
const options = Provider.defaultOptions();
@ -36,16 +39,17 @@ async function main() {
),
);
const group = await client.getGroupForAdmin(admin.publicKey);
console.log(`Group ${group.publicKey.toBase58()}`);
console.log(`Found group ${group.publicKey.toBase58()}`);
// create + fetch account
console.log(`Creating mangoaccount...`);
const mangoAccount = await client.getOrCreateMangoAccount(
group,
user.publicKey,
0,
'my_mango_account',
);
console.log(`MangoAccount ${mangoAccount.publicKey}`);
console.log(`...created/found mangoAccount ${mangoAccount.publicKey}`);
// deposit and withdraw
console.log(`Depositing...5000000 USDC`);
@ -56,13 +60,13 @@ async function main() {
await client.deposit(group, mangoAccount, 'BTC', 5000000);
await mangoAccount.reload(client);
console.log(`Withdrawing...1000000`);
console.log(`Withdrawing...1000000 USDC`);
await client.withdraw(group, mangoAccount, 'USDC', 1_000000, false);
await mangoAccount.reload(client);
// serum3
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(
group,
@ -79,7 +83,7 @@ async function main() {
);
await mangoAccount.reload(client);
console.log(`Placing serum3 bid way above midprice`);
console.log(`Placing serum3 bid way above midprice...`);
await client.serum3PlaceOrder(
group,
mangoAccount,
@ -95,7 +99,7 @@ async function main() {
);
await mangoAccount.reload(client);
console.log(`Placing serum3 ask way below midprice`);
console.log(`Placing serum3 ask way below midprice...`);
await client.serum3PlaceOrder(
group,
mangoAccount,
@ -118,9 +122,9 @@ async function main() {
);
for (const order of orders) {
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(
group,
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(
group,
DEVNET_SERUM3_PROGRAM_ID,