Skip to content

Commit

Permalink
Merge pull request #254 from metaDAOproject/feat/better-spot-price-wi…
Browse files Browse the repository at this point in the history
…th-mid

feat/better spot price with mid
  • Loading branch information
LukasDeco authored Aug 21, 2024
2 parents 0a9ac7c + 9f566e6 commit 766f6b2
Show file tree
Hide file tree
Showing 12 changed files with 82 additions and 81 deletions.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

11 changes: 10 additions & 1 deletion packages/indexer/src/builders/swaps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,16 @@ export class SwapBuilder {
} catch (e: any) {
logger.errorWithChatBotAlert(
"swap peristable general error",
e.message ? e.message : e
e.message
? {
message: e.message,
stack: e.stack,
name: e.name,
cause: e.cause,
fileName: e.fileName,
lineNumber: e.lineNumber,
}
: e
);
return Err({ type: SwapPersistableError.GeneralError });
}
Expand Down
100 changes: 72 additions & 28 deletions packages/indexer/src/indexers/jupiter/jupiter-quotes-indexer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,75 +72,119 @@ const convertJupTokenPrice = (
return price;
};

const convertJupBaseOutTokenPrice = (
data: JupTokenQuoteRes,
inputTokenDecimals: number,
outputTokenDecimals: number
): number => {
const inPrice = Number(data.inAmount ?? "0") / 10 ** inputTokenDecimals;
const outPrice = Number(data.outAmount ?? "0") / 10 ** outputTokenDecimals;
return inPrice / outPrice;
};

export const fetchQuoteFromJupe = async (
acct: string
): Promise<[number, number | undefined] | null> => {
try {
const inputToken = await usingDb((db) =>
const baseToken = await usingDb((db) =>
db
.select()
.from(schema.tokens)
.where(eq(schema.tokens.mintAcct, acct))
.execute()
);
// call jup

// if it's USDC we compare to USDT
const outputMint =
// Define the output mint based on the input token
const quoteMint =
acct === "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"
? "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB"
: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";

const outputToken = await usingDb((db) =>
const quoteToken = await usingDb((db) =>
db
.select()
.from(schema.tokens)
.where(eq(schema.tokens.mintAcct, outputMint))
.where(eq(schema.tokens.mintAcct, quoteMint))
.execute()
);

const amountVal = 1 * 10 ** inputToken[0].decimals;
const amountVal = 1 * 10 ** baseToken[0].decimals;

const url =
// Fetch ASK price (original fetch)
const askUrl =
`https://public.jupiterapi.com/quote?inputMint=${acct}&` +
`outputMint=${outputMint}&` +
`outputMint=${quoteMint}&` +
`amount=${amountVal.toString()}&` +
"slippageBps=30&" +
"swapMode=ExactIn&" +
"onlyDirectRoutes=false&" +
"maxAccounts=64&" +
"experimentalDexes=Jupiter%20LO";
const tokenPriceRes = await fetch(url);
const askRes = await fetch(askUrl);

if (tokenPriceRes.status !== 200) {
if (askRes.status !== 200) {
logger.error(
"non-200 response from jupiter quotes:",
tokenPriceRes.status,
tokenPriceRes.statusText
"non-200 response from Jupiter ASK quote:",
askRes.status,
askRes.statusText
);
return null;
}

const tokenPriceJson = (await tokenPriceRes.json()) as JupTokenQuoteRes;
const askJson = (await askRes.json()) as JupTokenQuoteRes;

if (tokenPriceJson.error) {
logger.error("jupiter response error found:", tokenPriceJson);
if (askJson.error || !askJson.outAmount || !askJson.inAmount) {
logger.error("Error with ASK quote response:", askJson);
return null;
}

if (!tokenPriceJson.outAmount || !tokenPriceJson.inAmount) {
logger.error("token price output or input is 0 value");
const askPrice = convertJupTokenPrice(
askJson,
baseToken[0].decimals,
quoteToken[0].decimals
);

// Fetch BID price (swapped input/output)
const bidUrl =
`https://public.jupiterapi.com/quote?inputMint=${quoteMint}&` +
`outputMint=${acct}&` +
`amount=${(1 * 10 ** quoteToken[0].decimals).toString()}&` +
"slippageBps=30&" +
"swapMode=ExactIn&" +
"onlyDirectRoutes=false&" +
"maxAccounts=64&" +
"experimentalDexes=Jupiter%20LO";
const bidRes = await fetch(bidUrl);

if (bidRes.status !== 200) {
logger.error(
"non-200 response from Jupiter BID quote:",
bidRes.status,
bidRes.statusText
);
return null;
}

const bidJson = (await bidRes.json()) as JupTokenQuoteRes;

if (bidJson.error || !bidJson.outAmount || !bidJson.inAmount) {
logger.error("Error with BID quote response:", bidJson);
return null;
}
return [
convertJupTokenPrice(
tokenPriceJson,
inputToken[0].decimals,
outputToken[0].decimals
),
tokenPriceJson.contextSlot,
];

const bidPrice = convertJupBaseOutTokenPrice(
bidJson,
baseToken[0].decimals,
quoteToken[0].decimals
);

// Calculate the mid-price
const midPrice = (askPrice + bidPrice) / 2;

// Return the mid-price and the context slot from the ASK response
return [midPrice, askJson.contextSlot];
} catch (e) {
logger.error("error getting price number from jupiter: ", e);
logger.error("error getting price from Jupiter: ", e);
return null;
}
};

0 comments on commit 766f6b2

Please sign in to comment.