make jup-ag/core a devdependency

This commit is contained in:
tjs 2022-07-05 23:38:53 -04:00
parent 1451ebc2a1
commit 1b04f924e3
6 changed files with 755 additions and 190 deletions

View File

@ -32,6 +32,7 @@
"validate": "npm run typecheck && npm run test && npm run lint && npm run format-check"
},
"devDependencies": {
"@jup-ag/core": "^1.0.0-beta.28",
"@tsconfig/recommended": "^1.0.1",
"@types/bs58": "^4.0.1",
"@types/chai": "^4.3.0",

View File

@ -171,7 +171,6 @@ export class Group {
public async reloadBankPrices(client: MangoClient, ids?: Id): Promise<void> {
const banks = Array.from(this?.banksMap, ([, value]) => value);
const oracles = banks.map((b) => b.oracle);
console.log(oracles.toString());
const prices =
await client.program.provider.connection.getMultipleAccountsInfo(oracles);

View File

@ -20,6 +20,7 @@ import {
PublicKey,
Signer,
SystemProgram,
SYSVAR_INSTRUCTIONS_PUBKEY,
SYSVAR_RENT_PUBKEY,
Transaction,
TransactionInstruction,
@ -333,27 +334,6 @@ export class MangoClient {
});
}
public async getPricesForGroup(group: Group): Promise<void> {
if (group.banksMap.size === 0) {
await this.getBanksForGroup(group);
}
const banks = Array.from(group?.banksMap, ([, value]) => value);
const oracles = banks.map((b) => b.oracle);
const prices =
await this.program.provider.connection.getMultipleAccountsInfo(oracles);
for (const [index, price] of prices.entries()) {
if (banks[index].name === 'USDC') {
banks[index].price = 1;
} else {
const parsedPriceData = parsePriceData(price.data);
banks[index].price =
parsedPriceData.price || parsedPriceData.previousPrice;
}
}
}
// Stub Oracle
public async createStubOracle(
@ -1312,14 +1292,14 @@ export class MangoClient {
inputToken,
amountIn,
outputToken,
slippage = 0.5,
userDefinedInstructions,
}: {
group: Group;
mangoAccount: MangoAccount;
inputToken: string;
amountIn: number;
outputToken: string;
slippage: number;
userDefinedInstructions: TransactionInstruction[];
}): Promise<TransactionSignature> {
const inputBank = group.banksMap.get(inputToken);
const outputBank = group.banksMap.get(outputToken);
@ -1390,8 +1370,7 @@ export class MangoClient {
}
/*
* Transfer input token to users wallet, then swap with the Jupiter route,
* and finally transfer output token from users wallet back to the mango vault
* Transfer input token to users wallet, then concat the passed in instructions
*/
const nativeInputAmount = toU64(
amountIn,
@ -1411,57 +1390,7 @@ export class MangoClient {
transferIx.keys[2] = { ...inputBankKey, isWritable: true, isSigner: false };
instructions.push(transferIx);
// TODO: move out of client and into ui
// Start Jupiter
// const jupiter = await Jupiter.load({
// connection: this.program.provider.connection,
// cluster: 'mainnet-beta',
// user: mangoAccount.owner, // or public key
// // platformFeeAndAccounts: NO_PLATFORM_FEE,
// routeCacheDuration: 10_000, // Will not refetch data on computeRoutes for up to 10 seconds
// });
// const routes = await jupiter.computeRoutes({
// inputMint: inputBank.mint, // Mint address of the input token
// outputMint: outputBank.mint, // Mint address of the output token
// inputAmount: nativeInputAmount, // raw input amount of tokens
// slippage, // The slippage in % terms
// forceFetch: false, // false is the default value => will use cache if not older than routeCacheDuration
// });
// const routesInfosWithoutRaydium = routes.routesInfos.filter((r) => {
// if (r.marketInfos.length > 1) {
// for (const mkt of r.marketInfos) {
// if (mkt.amm.label === 'Raydium' || mkt.amm.label === 'Serum')
// return false;
// }
// }
// return true;
// });
// const selectedRoute = routesInfosWithoutRaydium[0];
// console.log(
// `route found: ${selectedRoute.marketInfos[0].amm.label}. generating jup transaction`,
// );
// const { transactions } = await jupiter.exchange({
// routeInfo: selectedRoute,
// });
// console.log('Jupiter Transactions:', transactions);
// const { setupTransaction, swapTransaction } = transactions;
// for (const ix of swapTransaction.instructions) {
// if (
// ix.programId.toBase58() ===
// 'JUP2jxvXaqu7NQY1GmNF4m1vodw12LVXYxbFL2uJvfo'
// ) {
// instructions.push(ix);
// }
// }
// End Jupiter
instructions.concat(userDefinedInstructions);
const transferIx2 = Token.createTransferInstruction(
TOKEN_PROGRAM_ID,
@ -1469,13 +1398,12 @@ export class MangoClient {
outputBank.vault,
mangoAccount.owner,
[],
// selectedRoute.outAmountWithSlippage,
0, // todo: use this for testing, uncomment above for use with Jup
0, // todo: use this for testing, this should be the amount to transfer back
);
instructions.push(transferIx2);
/*
* Build data objects for margin trade instructions
* Create object of amounts that will be withdrawn from bank vaults
*/
const targetRemainingAccounts = instructions
.map((ix) => [
@ -1499,6 +1427,9 @@ export class MangoClient {
},
];
/*
* Build cpi data objects for instructions
*/
let cpiDatas = [];
for (const [index, ix] of instructions.entries()) {
if (index === 0) {
@ -1516,28 +1447,11 @@ export class MangoClient {
}
}
console.log(
'instructions',
instructions.map((i) => ({ ...i, programId: i.programId.toString() })),
);
console.log('cpiDatas', cpiDatas);
console.log(
'targetRemainingAccounts',
targetRemainingAccounts.map((t) => ({
...t,
pubkey: t.pubkey.toString(),
})),
);
// if (setupTransaction) {
// await this.program.provider.sendAndConfirm(setupTransaction);
// } else
if (preInstructions.length) {
const tx = new Transaction();
for (const ix of preInstructions) {
tx.add(ix);
}
console.log('preInstructions', preInstructions);
await this.program.provider.sendAndConfirm(tx);
}
@ -1559,14 +1473,14 @@ export class MangoClient {
inputToken,
amountIn,
outputToken,
slippage = 0.5,
userDefinedInstructions,
}: {
group: Group;
mangoAccount: MangoAccount;
inputToken: string;
amountIn: number;
outputToken: string;
slippage: number;
userDefinedInstructions: TransactionInstruction[];
}): Promise<TransactionSignature> {
const inputBank = group.banksMap.get(inputToken);
const outputBank = group.banksMap.get(outputToken);
@ -1582,13 +1496,11 @@ export class MangoClient {
(pk) =>
({
pubkey: pk,
isWritable:
pk.equals(inputBank.publicKey) || pk.equals(outputBank.publicKey)
? true
: false,
isWritable: false,
isSigner: false,
} as AccountMeta),
);
console.log('1');
/*
* Find or create associated token accounts
@ -1635,62 +1547,8 @@ export class MangoClient {
),
);
}
console.log('2');
const nativeInputAmount = toU64(
amountIn,
inputBank.mintDecimals,
).toNumber();
const instructions: TransactionInstruction[] = [];
// TODO: move out of client and into ui
// Start Jupiter
// const jupiter = await Jupiter.load({
// connection: this.program.provider.connection,
// cluster: 'mainnet-beta',
// user: mangoAccount.owner, // or public key
// // platformFeeAndAccounts: NO_PLATFORM_FEE,
// routeCacheDuration: 10_000, // Will not refetch data on computeRoutes for up to 10 seconds
// });
// const routes = await jupiter.computeRoutes({
// inputMint: inputBank.mint, // Mint address of the input token
// outputMint: outputBank.mint, // Mint address of the output token
// inputAmount: nativeInputAmount, // raw input amount of tokens
// slippage, // The slippage in % terms
// forceFetch: false, // false is the default value => will use cache if not older than routeCacheDuration
// });
// const routesInfosWithoutRaydium = routes.routesInfos.filter((r) => {
// if (r.marketInfos.length > 1) {
// for (const mkt of r.marketInfos) {
// if (mkt.amm.label === 'Raydium' || mkt.amm.label === 'Serum')
// return false;
// }
// }
// return true;
// });
// const selectedRoute = routesInfosWithoutRaydium[0];
// const { transactions } = await jupiter.exchange({
// routeInfo: selectedRoute,
// });
// const { setupTransaction, swapTransaction } = transactions;
// for (const ix of swapTransaction.instructions) {
// if (
// ix.programId.toBase58() ===
// 'JUP2jxvXaqu7NQY1GmNF4m1vodw12LVXYxbFL2uJvfo'
// ) {
// instructions.push(ix);
// }
// }
// End Jupiter
// if (setupTransaction) {
// await this.program.provider.sendAndConfirm(setupTransaction);
// } else
if (preInstructions.length) {
const tx = new Transaction();
for (const ix of preInstructions) {
@ -1700,21 +1558,37 @@ export class MangoClient {
await this.program.provider.sendAndConfirm(tx);
}
console.log('3');
const bankAccounts = {
isWritable: true,
const sourceBankAccounts = {
pubkey: inputBank.publicKey,
isWritable: true,
isSigner: false,
};
const bankVaults = {
const targetBankAccount = {
pubkey: outputBank.publicKey,
isWritable: true,
isSigner: false,
};
const sourceBankVault = {
pubkey: inputBank.vault,
isWritable: true,
isSigner: false,
};
const aTokenAccounts = {
const targetBankVault = {
pubkey: outputBank.vault,
isWritable: true,
isSigner: false,
};
const sourceATA = {
pubkey: inputTokenAccountPk,
isSigner: true,
isWritable: true,
isSigner: false,
};
const targetATA = {
pubkey: outputTokenAccountPk,
isWritable: false,
isSigner: false,
};
const flashLoanEndIx = await this.program.methods
@ -1723,17 +1597,43 @@ export class MangoClient {
account: mangoAccount.publicKey,
owner: (this.program.provider as AnchorProvider).wallet.publicKey,
})
.remainingAccounts([...parsedHealthAccounts, bankVaults, aTokenAccounts])
.remainingAccounts([
...parsedHealthAccounts,
sourceBankVault,
targetBankVault,
sourceATA,
{
isWritable: true,
pubkey: outputTokenAccountPk,
isSigner: false,
},
])
.instruction();
console.log('4');
// userDefinedInstructions.push(flashLoanEndIx);
return await this.program.methods
.flashLoan3Begin([toU64(amountIn, inputBank.mintDecimals)])
.flashLoan3Begin([
toNativeDecimals(amountIn, inputBank.mintDecimals),
new BN(
0,
) /* we don't care about borrowing the target amount, this is just a dummy */,
])
.accounts({
group: group.publicKey,
instructions: SYSVAR_INSTRUCTIONS_PUBKEY,
})
.remainingAccounts([bankAccounts, bankVaults, aTokenAccounts])
.postInstructions([...instructions, flashLoanEndIx])
.rpc({ skipPreflight: true });
.remainingAccounts([
sourceBankAccounts,
targetBankAccount,
sourceBankVault,
targetBankVault,
sourceATA,
targetATA,
])
.postInstructions([flashLoanEndIx])
.rpc();
}
/// liquidations

View File

@ -13,6 +13,13 @@ import { QUOTE_DECIMALS } from '../accounts/bank';
import { MangoClient } from '../client';
import { getAssociatedTokenAddress } from '../utils';
const CLUSTER_URL =
process.env.CLUSTER_URL ||
'https://mango.rpcpool.com/946ef7337da3f5b8d3e4a34e7f88';
const MANGO_MAINNET_PAYER_KEYPAIR =
process.env.MANGO_MAINNET_PAYER_KEYPAIR ||
'/Users/tylershipe/.config/solana/deploy.json';
//
// example script which shows usage of flash loan 3 ix using a jupiter swap
//
@ -20,14 +27,12 @@ import { getAssociatedTokenAddress } from '../utils';
// NOTE: we assume that ATA for source and target already exist for wallet
async function main() {
const options = AnchorProvider.defaultOptions();
const connection = new Connection(process.env.CLUSTER_URL, options);
const connection = new Connection(CLUSTER_URL, options);
// load user key
const user = Keypair.fromSecretKey(
Buffer.from(
JSON.parse(
fs.readFileSync(process.env.MANGO_MAINNET_PAYER_KEYPAIR!, 'utf-8'),
),
JSON.parse(fs.readFileSync(MANGO_MAINNET_PAYER_KEYPAIR!, 'utf-8')),
),
);
const userWallet = new Wallet(user);
@ -41,9 +46,7 @@ async function main() {
// load admin key
const admin = Keypair.fromSecretKey(
Buffer.from(
JSON.parse(
fs.readFileSync(process.env.MANGO_MAINNET_PAYER_KEYPAIR!, 'utf-8'),
),
JSON.parse(fs.readFileSync(MANGO_MAINNET_PAYER_KEYPAIR!, 'utf-8')),
),
);
console.log(`Admin ${admin.publicKey.toBase58()}`);

View File

@ -10,6 +10,11 @@
"skipLibCheck": true,
"target": "es2019"
},
"include": ["ts/client/src"],
"exclude": ["./ts/**/*.test.js", "node_modules", "**/node_modules"]
"include": ["ts/client/src", "ts/client/scripts", "ts/client/scripts"],
"exclude": [
"./ts/**/*.test.js",
"node_modules",
"**/node_modules",
"./ts/client/src/scripts"
]
}

683
yarn.lock

File diff suppressed because it is too large Load Diff