make jup-ag/core a devdependency
This commit is contained in:
parent
1451ebc2a1
commit
1b04f924e3
|
@ -32,6 +32,7 @@
|
||||||
"validate": "npm run typecheck && npm run test && npm run lint && npm run format-check"
|
"validate": "npm run typecheck && npm run test && npm run lint && npm run format-check"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@jup-ag/core": "^1.0.0-beta.28",
|
||||||
"@tsconfig/recommended": "^1.0.1",
|
"@tsconfig/recommended": "^1.0.1",
|
||||||
"@types/bs58": "^4.0.1",
|
"@types/bs58": "^4.0.1",
|
||||||
"@types/chai": "^4.3.0",
|
"@types/chai": "^4.3.0",
|
||||||
|
|
|
@ -171,7 +171,6 @@ export class Group {
|
||||||
public async reloadBankPrices(client: MangoClient, ids?: Id): Promise<void> {
|
public async reloadBankPrices(client: MangoClient, ids?: Id): Promise<void> {
|
||||||
const banks = Array.from(this?.banksMap, ([, value]) => value);
|
const banks = Array.from(this?.banksMap, ([, value]) => value);
|
||||||
const oracles = banks.map((b) => b.oracle);
|
const oracles = banks.map((b) => b.oracle);
|
||||||
console.log(oracles.toString());
|
|
||||||
const prices =
|
const prices =
|
||||||
await client.program.provider.connection.getMultipleAccountsInfo(oracles);
|
await client.program.provider.connection.getMultipleAccountsInfo(oracles);
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ import {
|
||||||
PublicKey,
|
PublicKey,
|
||||||
Signer,
|
Signer,
|
||||||
SystemProgram,
|
SystemProgram,
|
||||||
|
SYSVAR_INSTRUCTIONS_PUBKEY,
|
||||||
SYSVAR_RENT_PUBKEY,
|
SYSVAR_RENT_PUBKEY,
|
||||||
Transaction,
|
Transaction,
|
||||||
TransactionInstruction,
|
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
|
// Stub Oracle
|
||||||
|
|
||||||
public async createStubOracle(
|
public async createStubOracle(
|
||||||
|
@ -1312,14 +1292,14 @@ export class MangoClient {
|
||||||
inputToken,
|
inputToken,
|
||||||
amountIn,
|
amountIn,
|
||||||
outputToken,
|
outputToken,
|
||||||
slippage = 0.5,
|
userDefinedInstructions,
|
||||||
}: {
|
}: {
|
||||||
group: Group;
|
group: Group;
|
||||||
mangoAccount: MangoAccount;
|
mangoAccount: MangoAccount;
|
||||||
inputToken: string;
|
inputToken: string;
|
||||||
amountIn: number;
|
amountIn: number;
|
||||||
outputToken: string;
|
outputToken: string;
|
||||||
slippage: number;
|
userDefinedInstructions: TransactionInstruction[];
|
||||||
}): Promise<TransactionSignature> {
|
}): Promise<TransactionSignature> {
|
||||||
const inputBank = group.banksMap.get(inputToken);
|
const inputBank = group.banksMap.get(inputToken);
|
||||||
const outputBank = group.banksMap.get(outputToken);
|
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,
|
* Transfer input token to users wallet, then concat the passed in instructions
|
||||||
* and finally transfer output token from users wallet back to the mango vault
|
|
||||||
*/
|
*/
|
||||||
const nativeInputAmount = toU64(
|
const nativeInputAmount = toU64(
|
||||||
amountIn,
|
amountIn,
|
||||||
|
@ -1411,57 +1390,7 @@ export class MangoClient {
|
||||||
transferIx.keys[2] = { ...inputBankKey, isWritable: true, isSigner: false };
|
transferIx.keys[2] = { ...inputBankKey, isWritable: true, isSigner: false };
|
||||||
instructions.push(transferIx);
|
instructions.push(transferIx);
|
||||||
|
|
||||||
// TODO: move out of client and into ui
|
instructions.concat(userDefinedInstructions);
|
||||||
// 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
|
|
||||||
|
|
||||||
const transferIx2 = Token.createTransferInstruction(
|
const transferIx2 = Token.createTransferInstruction(
|
||||||
TOKEN_PROGRAM_ID,
|
TOKEN_PROGRAM_ID,
|
||||||
|
@ -1469,13 +1398,12 @@ export class MangoClient {
|
||||||
outputBank.vault,
|
outputBank.vault,
|
||||||
mangoAccount.owner,
|
mangoAccount.owner,
|
||||||
[],
|
[],
|
||||||
// selectedRoute.outAmountWithSlippage,
|
0, // todo: use this for testing, this should be the amount to transfer back
|
||||||
0, // todo: use this for testing, uncomment above for use with Jup
|
|
||||||
);
|
);
|
||||||
instructions.push(transferIx2);
|
instructions.push(transferIx2);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Build data objects for margin trade instructions
|
* Create object of amounts that will be withdrawn from bank vaults
|
||||||
*/
|
*/
|
||||||
const targetRemainingAccounts = instructions
|
const targetRemainingAccounts = instructions
|
||||||
.map((ix) => [
|
.map((ix) => [
|
||||||
|
@ -1499,6 +1427,9 @@ export class MangoClient {
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Build cpi data objects for instructions
|
||||||
|
*/
|
||||||
let cpiDatas = [];
|
let cpiDatas = [];
|
||||||
for (const [index, ix] of instructions.entries()) {
|
for (const [index, ix] of instructions.entries()) {
|
||||||
if (index === 0) {
|
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) {
|
if (preInstructions.length) {
|
||||||
const tx = new Transaction();
|
const tx = new Transaction();
|
||||||
for (const ix of preInstructions) {
|
for (const ix of preInstructions) {
|
||||||
tx.add(ix);
|
tx.add(ix);
|
||||||
}
|
}
|
||||||
console.log('preInstructions', preInstructions);
|
|
||||||
|
|
||||||
await this.program.provider.sendAndConfirm(tx);
|
await this.program.provider.sendAndConfirm(tx);
|
||||||
}
|
}
|
||||||
|
@ -1559,14 +1473,14 @@ export class MangoClient {
|
||||||
inputToken,
|
inputToken,
|
||||||
amountIn,
|
amountIn,
|
||||||
outputToken,
|
outputToken,
|
||||||
slippage = 0.5,
|
userDefinedInstructions,
|
||||||
}: {
|
}: {
|
||||||
group: Group;
|
group: Group;
|
||||||
mangoAccount: MangoAccount;
|
mangoAccount: MangoAccount;
|
||||||
inputToken: string;
|
inputToken: string;
|
||||||
amountIn: number;
|
amountIn: number;
|
||||||
outputToken: string;
|
outputToken: string;
|
||||||
slippage: number;
|
userDefinedInstructions: TransactionInstruction[];
|
||||||
}): Promise<TransactionSignature> {
|
}): Promise<TransactionSignature> {
|
||||||
const inputBank = group.banksMap.get(inputToken);
|
const inputBank = group.banksMap.get(inputToken);
|
||||||
const outputBank = group.banksMap.get(outputToken);
|
const outputBank = group.banksMap.get(outputToken);
|
||||||
|
@ -1582,13 +1496,11 @@ export class MangoClient {
|
||||||
(pk) =>
|
(pk) =>
|
||||||
({
|
({
|
||||||
pubkey: pk,
|
pubkey: pk,
|
||||||
isWritable:
|
isWritable: false,
|
||||||
pk.equals(inputBank.publicKey) || pk.equals(outputBank.publicKey)
|
|
||||||
? true
|
|
||||||
: false,
|
|
||||||
isSigner: false,
|
isSigner: false,
|
||||||
} as AccountMeta),
|
} as AccountMeta),
|
||||||
);
|
);
|
||||||
|
console.log('1');
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find or create associated token accounts
|
* 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) {
|
if (preInstructions.length) {
|
||||||
const tx = new Transaction();
|
const tx = new Transaction();
|
||||||
for (const ix of preInstructions) {
|
for (const ix of preInstructions) {
|
||||||
|
@ -1700,21 +1558,37 @@ export class MangoClient {
|
||||||
|
|
||||||
await this.program.provider.sendAndConfirm(tx);
|
await this.program.provider.sendAndConfirm(tx);
|
||||||
}
|
}
|
||||||
|
console.log('3');
|
||||||
|
|
||||||
const bankAccounts = {
|
const sourceBankAccounts = {
|
||||||
isWritable: true,
|
|
||||||
pubkey: inputBank.publicKey,
|
pubkey: inputBank.publicKey,
|
||||||
|
isWritable: true,
|
||||||
isSigner: false,
|
isSigner: false,
|
||||||
};
|
};
|
||||||
const bankVaults = {
|
const targetBankAccount = {
|
||||||
|
pubkey: outputBank.publicKey,
|
||||||
isWritable: true,
|
isWritable: true,
|
||||||
|
isSigner: false,
|
||||||
|
};
|
||||||
|
const sourceBankVault = {
|
||||||
pubkey: inputBank.vault,
|
pubkey: inputBank.vault,
|
||||||
|
isWritable: true,
|
||||||
isSigner: false,
|
isSigner: false,
|
||||||
};
|
};
|
||||||
const aTokenAccounts = {
|
const targetBankVault = {
|
||||||
|
pubkey: outputBank.vault,
|
||||||
isWritable: true,
|
isWritable: true,
|
||||||
|
isSigner: false,
|
||||||
|
};
|
||||||
|
const sourceATA = {
|
||||||
pubkey: inputTokenAccountPk,
|
pubkey: inputTokenAccountPk,
|
||||||
isSigner: true,
|
isWritable: true,
|
||||||
|
isSigner: false,
|
||||||
|
};
|
||||||
|
const targetATA = {
|
||||||
|
pubkey: outputTokenAccountPk,
|
||||||
|
isWritable: false,
|
||||||
|
isSigner: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
const flashLoanEndIx = await this.program.methods
|
const flashLoanEndIx = await this.program.methods
|
||||||
|
@ -1723,17 +1597,43 @@ export class MangoClient {
|
||||||
account: mangoAccount.publicKey,
|
account: mangoAccount.publicKey,
|
||||||
owner: (this.program.provider as AnchorProvider).wallet.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();
|
.instruction();
|
||||||
|
console.log('4');
|
||||||
|
|
||||||
|
// userDefinedInstructions.push(flashLoanEndIx);
|
||||||
|
|
||||||
return await this.program.methods
|
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({
|
.accounts({
|
||||||
group: group.publicKey,
|
group: group.publicKey,
|
||||||
|
instructions: SYSVAR_INSTRUCTIONS_PUBKEY,
|
||||||
})
|
})
|
||||||
.remainingAccounts([bankAccounts, bankVaults, aTokenAccounts])
|
.remainingAccounts([
|
||||||
.postInstructions([...instructions, flashLoanEndIx])
|
sourceBankAccounts,
|
||||||
.rpc({ skipPreflight: true });
|
targetBankAccount,
|
||||||
|
sourceBankVault,
|
||||||
|
targetBankVault,
|
||||||
|
sourceATA,
|
||||||
|
targetATA,
|
||||||
|
])
|
||||||
|
.postInstructions([flashLoanEndIx])
|
||||||
|
.rpc();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// liquidations
|
/// liquidations
|
||||||
|
|
|
@ -13,6 +13,13 @@ import { QUOTE_DECIMALS } from '../accounts/bank';
|
||||||
import { MangoClient } from '../client';
|
import { MangoClient } from '../client';
|
||||||
import { getAssociatedTokenAddress } from '../utils';
|
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
|
// 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
|
// NOTE: we assume that ATA for source and target already exist for wallet
|
||||||
async function main() {
|
async function main() {
|
||||||
const options = AnchorProvider.defaultOptions();
|
const options = AnchorProvider.defaultOptions();
|
||||||
const connection = new Connection(process.env.CLUSTER_URL, options);
|
const connection = new Connection(CLUSTER_URL, options);
|
||||||
|
|
||||||
// load user key
|
// load user key
|
||||||
const user = Keypair.fromSecretKey(
|
const user = Keypair.fromSecretKey(
|
||||||
Buffer.from(
|
Buffer.from(
|
||||||
JSON.parse(
|
JSON.parse(fs.readFileSync(MANGO_MAINNET_PAYER_KEYPAIR!, 'utf-8')),
|
||||||
fs.readFileSync(process.env.MANGO_MAINNET_PAYER_KEYPAIR!, 'utf-8'),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
const userWallet = new Wallet(user);
|
const userWallet = new Wallet(user);
|
||||||
|
@ -41,9 +46,7 @@ async function main() {
|
||||||
// load admin key
|
// load admin key
|
||||||
const admin = Keypair.fromSecretKey(
|
const admin = Keypair.fromSecretKey(
|
||||||
Buffer.from(
|
Buffer.from(
|
||||||
JSON.parse(
|
JSON.parse(fs.readFileSync(MANGO_MAINNET_PAYER_KEYPAIR!, 'utf-8')),
|
||||||
fs.readFileSync(process.env.MANGO_MAINNET_PAYER_KEYPAIR!, 'utf-8'),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
console.log(`Admin ${admin.publicKey.toBase58()}`);
|
console.log(`Admin ${admin.publicKey.toBase58()}`);
|
||||||
|
|
|
@ -10,6 +10,11 @@
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"target": "es2019"
|
"target": "es2019"
|
||||||
},
|
},
|
||||||
"include": ["ts/client/src"],
|
"include": ["ts/client/src", "ts/client/scripts", "ts/client/scripts"],
|
||||||
"exclude": ["./ts/**/*.test.js", "node_modules", "**/node_modules"]
|
"exclude": [
|
||||||
|
"./ts/**/*.test.js",
|
||||||
|
"node_modules",
|
||||||
|
"**/node_modules",
|
||||||
|
"./ts/client/src/scripts"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue