mainnet scripts (#80)

Signed-off-by: microwavedcola1 <microwavedcola@gmail.com>
This commit is contained in:
microwavedcola1 2022-06-23 15:22:59 +02:00 committed by GitHub
parent 54c0306ae7
commit c1dea82a55
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 488 additions and 11 deletions

34
release-to-mainnet.sh Executable file
View File

@ -0,0 +1,34 @@
#!/usr/bin/env bash
set -e pipefail
WALLET_WITH_FUNDS=~/.config/solana/mango-mainnet.json
PROGRAM_ID=m43thNJ58XCjL798ZSq6JGAG1BnWskhdq5or6kcnfsD
# TODO fix need for --skip-lint
# build program,
anchor build --skip-lint
# patch types, which we want in rust, but anchor client doesn't support
./idl-fixup.sh
# update types in ts client package
cp -v ./target/types/mango_v4.ts ./ts/client/src/mango_v4.ts
(cd ./ts/client && tsc)
if [[ -z "${NO_DEPLOY}" ]]; then
# publish program
solana --url $CLUSTER_URL program deploy --program-id $PROGRAM_ID \
-k $WALLET_WITH_FUNDS target/deploy/mango_v4.so
# publish idl
anchor idl upgrade --provider.cluster $CLUSTER_URL --provider.wallet $WALLET_WITH_FUNDS \
--filepath target/idl/mango_v4.json $PROGRAM_ID
else
echo "Skipping deployment..."
fi
# build npm package
(cd ./ts/client && tsc)

View File

@ -61,6 +61,49 @@
"publicKey": "5ZwVhP5PYkKtx2H4WL2JxSvWL6AALFzwubwM5dsR5XHF"
}
]
},
{
"cluster": "mainnet-beta",
"name": "mainnet-beta.microwavedcola",
"publicKey": "A9XhGqUUjV992cD36qWDY8wDiZnGuCaUWtSE3NGXjDCb",
"serum3ProgramId": "9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin",
"mangoProgramId": "m43thNJ58XCjL798ZSq6JGAG1BnWskhdq5or6kcnfsD",
"banks": [
{
"name": "USDC",
"publicKey": "BYq994HWWuXC1UC7ByTiDLQBsnBQQAzJaLvMCQU3priu"
},
{
"name": "BTC",
"publicKey": "96e336hgaPWbbHqPbpPcmr1pbTY1CALtFWkNk2tD4ZmK"
},
{
"name": "SOL",
"publicKey": "J3dxEFhJG1maNva8W9u4XzxCR1DQm6qfkgrkY29Ujrh3"
}
],
"stubOracles": [
{
"name": "USDC",
"publicKey": "DcCuQDbDqHj7G5pBe7epuPQSwwvysm8GfJSa51MYqFXk"
}
],
"mintInfos": [
{
"name": "USDC",
"publicKey": "42bXYX5sidUkrijuArv4D11g1aAm9947ht6qUB8Me5Q3"
},
{
"name": "BTC",
"publicKey": "4KZkrJQRvrVy8BWmbUKk7YWezMAsSb97ZMHFLUtj6Q5u"
},
{
"name": "SOL",
"publicKey": "EvjoLBh7ej78C1yA7jaLcHQfoGx3KkDBnZbrztSZFGmC"
}
],
"serum3Markets": [],
"perpMarkets": []
}
]
}

View File

@ -6,7 +6,7 @@ import {
initializeAccount,
WRAPPED_SOL_MINT,
} from '@project-serum/serum/lib/token-instructions';
import { parsePriceData, PriceData } from '@pythnetwork/client';
import { parsePriceData } from '@pythnetwork/client';
import { TOKEN_PROGRAM_ID } from '@solana/spl-token';
import {
AccountMeta,
@ -122,6 +122,7 @@ export class MangoClient {
const groups = (await this.program.account.group.all(filters)).map(
(tuple) => Group.from(tuple.publicKey, tuple.account),
);
console.log(groups);
await groups[0].reloadAll(this);
return groups[0];
}
@ -1221,10 +1222,10 @@ export class MangoClient {
return new MangoClient(
new Program<MangoV4>(
idl as MangoV4,
new PublicKey(id.publicKey),
new PublicKey(id.mangoProgramId),
provider,
),
new PublicKey(id.publicKey),
new PublicKey(id.mangoProgramId),
id.cluster,
groupName,
);

View File

@ -1,13 +1,13 @@
import { PublicKey } from '@solana/web3.js';
export const SERUM3_PROGRAM_ID = {
testnet: new PublicKey('DESVgJVGajEgKGXhb6XmqDHGz3VjdgP7rEVESBgxmroY'), // todo: fix
testnet: new PublicKey('DESVgJVGajEgKGXhb6XmqDHGz3VjdgP7rEVESBgxmroY'),
devnet: new PublicKey('DESVgJVGajEgKGXhb6XmqDHGz3VjdgP7rEVESBgxmroY'),
mainnet: new PublicKey('9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin'),
'mainnet-beta': new PublicKey('9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin'),
};
export const MANGO_V4_ID = {
testnet: new PublicKey('m43thNJ58XCjL798ZSq6JGAG1BnWskhdq5or6kcnfsD'), // todo: fix
testnet: new PublicKey('m43thNJ58XCjL798ZSq6JGAG1BnWskhdq5or6kcnfsD'),
devnet: new PublicKey('m43thNJ58XCjL798ZSq6JGAG1BnWskhdq5or6kcnfsD'),
mainnet: new PublicKey('m43thNJ58XCjL798ZSq6JGAG1BnWskhdq5or6kcnfsD'), // note: never deployed so far
'mainnet-beta': new PublicKey('m43thNJ58XCjL798ZSq6JGAG1BnWskhdq5or6kcnfsD'),
};

View File

@ -76,7 +76,7 @@ async function main() {
0.07,
0.8,
0.9,
0.0005,
0.88,
0.0005,
1.5,
0.8,
@ -114,7 +114,7 @@ async function main() {
0.07,
0.8,
0.9,
0.0005,
1.5,
0.0005,
1.5,
0.8,
@ -142,7 +142,7 @@ async function main() {
0.07,
0.8,
0.9,
0.0005,
0.63,
0.0005,
1.5,
0.8,
@ -172,7 +172,7 @@ async function main() {
0.07,
0.8,
0.9,
0.0005,
0.63,
0.0005,
1.5,
0.8,

View File

@ -0,0 +1,105 @@
import { AnchorProvider, Wallet } from '@project-serum/anchor';
import { Connection, Keypair } from '@solana/web3.js';
import fs from 'fs';
import idsJson from '../../ids.json';
import { MangoClient } from '../client';
import { MANGO_V4_ID, SERUM3_PROGRAM_ID } from '../constants';
import { Id } from '../ids';
function replacer(key, value) {
if (value instanceof Map) {
return Object.fromEntries(value);
} else {
return value;
}
}
async function main() {
const groupName = 'mainnet-beta.microwavedcola';
const cluster = 'mainnet-beta';
// build client and fetch group for admin
const options = AnchorProvider.defaultOptions();
const connection = new Connection(process.env.CLUSTER_URL, 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,
cluster,
MANGO_V4_ID[cluster],
);
const admin = Keypair.fromSecretKey(
Buffer.from(
JSON.parse(
fs.readFileSync(process.env.MANGO_MAINNET_PAYER_KEYPAIR!, 'utf-8'),
),
),
);
console.log(`Admin ${admin.publicKey.toBase58()}`);
const group = await client.getGroupForAdmin(admin.publicKey, 0);
// collect mappings &
// collect pubkeys
const banks = await client.getBanksForGroup(group);
const banksMapByMint = new Map(
banks.map((tuple) => [tuple.mint.toBase58(), tuple]),
);
const stubOracles = await client.getStubOracle(group);
const mintInfos = await client.getMintInfosForGroup(group);
const serum3Markets = await client.serum3GetMarkets(group);
const perpMarkets = await client.perpGetMarkets(group);
// build ids
const toDump = new Id(
cluster,
groupName,
group.publicKey.toBase58(),
SERUM3_PROGRAM_ID[cluster].toBase58(),
MANGO_V4_ID[cluster].toBase58(),
banks.map((tuple) => ({
name: tuple.name,
publicKey: tuple.publicKey.toBase58(),
})),
stubOracles.map((tuple) => ({
name: banksMapByMint.get(tuple.mint.toBase58())!.name,
publicKey: tuple.publicKey.toBase58(),
})),
mintInfos.map((tuple) => ({
name: banksMapByMint.get(tuple.mint.toBase58())!.name,
publicKey: tuple.publicKey.toBase58(),
})),
serum3Markets.map((tuple) => ({
name: tuple.name,
publicKey: tuple.publicKey.toBase58(),
marketExternal: tuple.serumMarketExternal.toBase58(),
})),
perpMarkets.map((tuple) => ({
name: tuple.name,
publicKey: tuple.publicKey.toBase58(),
})),
);
// adds ids for group in existing ids.json
const existingGroup = idsJson.groups.find((group) => group.name == groupName);
if (existingGroup) {
console.log('Updating existing group with latest state...');
} else {
console.log('Group does not exist yet...');
}
idsJson.groups = idsJson.groups.filter((group) => group.name !== groupName);
idsJson.groups.push(toDump);
// dump
const file = `${process.cwd()}/ts/client/ids.json`;
await fs.writeFileSync(file, JSON.stringify(idsJson, replacer, 2));
process.exit();
}
main();

View File

@ -0,0 +1,100 @@
import { AnchorProvider, Wallet } from '@project-serum/anchor';
import { Connection, Keypair, PublicKey } from '@solana/web3.js';
import fs from 'fs';
import { MangoClient } from '../client';
import { MANGO_V4_ID } from '../constants';
const MAINNET_MINTS = new Map([
['USDC', 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'],
['BTC', '9n4nbM75f5Ui33ZbPYXn59EwSgE8CGsHtAeTH5YFeJ9E'],
['SOL', 'So11111111111111111111111111111111111111112'],
]);
async function main() {
const options = AnchorProvider.defaultOptions();
const connection = new Connection(process.env.CLUSTER_URL, options);
const admin = Keypair.fromSecretKey(
Buffer.from(
JSON.parse(
fs.readFileSync(process.env.MANGO_MAINNET_PAYER_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,
'mainnet-beta',
MANGO_V4_ID['mainnet-beta'],
);
const group = await client.getGroupForAdmin(admin.publicKey);
console.log(`Group ${group.publicKey}`);
let sig;
// close stub oracle
const usdcDevnetMint = new PublicKey(MAINNET_MINTS.get('USDC')!);
try {
const usdcDevnetOracle = await client.getStubOracle(
group,
usdcDevnetMint,
)[0];
let sig = await client.closeStubOracle(group, usdcDevnetOracle.publicKey);
console.log(
`Closed USDC stub oracle, sig https://explorer.solana.com/address/${sig}`,
);
} catch (error) {
console.error(error);
}
// close all bank
for (const bank of group.banksMap.values()) {
try {
sig = await client.tokenDeregister(group, bank.name);
console.log(
`Removed token ${bank.name}, sig https://explorer.solana.com/address/${sig}`,
);
} catch (error) {
console.error(error);
}
}
// deregister all serum markets
for (const market of group.serum3MarketsMap.values()) {
try {
sig = await client.serum3deregisterMarket(group, market.name);
console.log(
`Deregistered serum market ${market.name}, sig https://explorer.solana.com/address/${sig}`,
);
} catch (error) {
console.error(error);
}
}
// close all perp markets
for (const market of group.perpMarketsMap.values()) {
try {
sig = await client.perpCloseMarket(group, market.name);
console.log(
`Closed perp market ${market.name}, sig https://explorer.solana.com/address/${sig}`,
);
} catch (error) {
console.error(error);
}
}
// finally, close the group
try {
sig = await client.closeGroup(group);
console.log(`Closed group, sig https://explorer.solana.com/address/${sig}`);
} catch (error) {
console.error(error);
}
process.exit();
}
main();

View File

@ -0,0 +1,157 @@
import { AnchorProvider, Wallet } from '@project-serum/anchor';
import { Connection, Keypair, PublicKey } from '@solana/web3.js';
import fs from 'fs';
import { MangoClient } from '../client';
import { MANGO_V4_ID } from '../constants';
const MAINNET_MINTS = new Map([
['USDC', 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'],
['BTC', '9n4nbM75f5Ui33ZbPYXn59EwSgE8CGsHtAeTH5YFeJ9E'],
['SOL', 'So11111111111111111111111111111111111111112'],
]);
const MAINNET_ORACLES = new Map([
['BTC', 'GVXRSBjFk6e6J3NbVPXohDJetcTjaeeuykUpbQF8UoMU'],
['SOL', 'H6ARHf6YXhGYeQfUzQNGk6rDNnLBQKrenN712K4AQJEG'],
]);
async function main() {
const options = AnchorProvider.defaultOptions();
const connection = new Connection(process.env.CLUSTER_URL, options);
const admin = Keypair.fromSecretKey(
Buffer.from(
JSON.parse(
fs.readFileSync(process.env.MANGO_MAINNET_PAYER_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,
'mainnet-beta',
MANGO_V4_ID['mainnet-beta'],
);
// group
console.log(`Creating Group...`);
try {
await client.createGroup(0, true);
} catch (error) {
console.log(error);
}
const group = await client.getGroupForAdmin(admin.publicKey);
console.log(`...registered group ${group.publicKey}`);
// register token 0
console.log(`Registering BTC...`);
const btcMainnetMint = new PublicKey(MAINNET_MINTS.get('BTC')!);
const btcMainnetOracle = new PublicKey(MAINNET_ORACLES.get('BTC')!);
try {
await client.tokenRegister(
group,
btcMainnetMint,
btcMainnetOracle,
0.1,
0,
'BTC',
0.4,
0.07,
0.8,
0.9,
0.88,
0.0005,
1.5,
0.8,
0.6,
1.2,
1.4,
0.02,
);
await group.reloadAll(client);
} catch (error) {
console.log(error);
}
// stub oracle + register token 1
console.log(`Creating USDC stub oracle...`);
const usdcMainnetMint = new PublicKey(MAINNET_MINTS.get('USDC')!);
try {
await client.createStubOracle(group, usdcMainnetMint, 1.0);
} catch (error) {
console.log(error);
}
const usdcMainnetOracle = (
await client.getStubOracle(group, usdcMainnetMint)
)[0];
console.log(`...created stub oracle ${usdcMainnetOracle.publicKey}`);
console.log(`Registering USDC...`);
try {
await client.tokenRegister(
group,
usdcMainnetMint,
usdcMainnetOracle.publicKey,
0.1,
1,
'USDC',
0.4,
0.07,
0.8,
0.9,
1.5,
0.0005,
1.5,
0.8,
0.6,
1.2,
1.4,
0.02,
);
await group.reloadAll(client);
} catch (error) {
console.log(error);
}
// register token 2
console.log(`Registering SOL...`);
const solMainnetMint = new PublicKey(MAINNET_MINTS.get('SOL')!);
const solMainnetOracle = new PublicKey(MAINNET_ORACLES.get('SOL')!);
try {
await client.tokenRegister(
group,
solMainnetMint,
solMainnetOracle,
0.1,
2, // tokenIndex
'SOL',
0.4,
0.07,
0.8,
0.9,
0.63,
0.0005,
1.5,
0.8,
0.6,
1.2,
1.4,
0.02,
);
await group.reloadAll(client);
} catch (error) {
console.log(error);
}
// log tokens/banks
for (const bank of await group.banksMap.values()) {
console.log(
`...registered Bank ${bank.name} ${bank.tokenIndex} ${bank.publicKey}, mint ${bank.mint}, oracle ${bank.oracle}`,
);
}
process.exit();
}
main();

View File

@ -0,0 +1,37 @@
import { AnchorProvider, Wallet } from '@project-serum/anchor';
import { Connection, Keypair } from '@solana/web3.js';
import fs from 'fs';
import { MangoClient } from '../client';
async function main() {
const options = AnchorProvider.defaultOptions();
const connection = new Connection(process.env.CLUSTER_URL, 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.connectForGroupName(
userProvider,
'mainnet-beta.microwavedcola' /* Use ids json instead of getProgramAccounts */,
);
console.log(`User ${userWallet.publicKey.toBase58()}`);
const admin = Keypair.fromSecretKey(
Buffer.from(
JSON.parse(
fs.readFileSync(process.env.MANGO_MAINNET_PAYER_KEYPAIR!, 'utf-8'),
),
),
);
console.log(`Admin ${admin.publicKey.toBase58()}`);
const group = await client.getGroupForAdmin(admin.publicKey, 0);
console.log(`Found group ${group.publicKey.toBase58()}`);
process.exit();
}
main();