Skip to content

Commit

Permalink
jto (#385)
Browse files Browse the repository at this point in the history
  • Loading branch information
kelvinlau20100 authored Apr 17, 2024
1 parent d1e0d82 commit 9b107ce
Show file tree
Hide file tree
Showing 5 changed files with 176 additions and 21 deletions.
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@zetamarkets/sdk",
"repository": "https://github.com/zetamarkets/sdk/",
"version": "1.26.4",
"version": "1.27.3",
"description": "Zeta SDK",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand All @@ -17,12 +17,13 @@
"@solana/spl-token": "0.1.6",
"@solana/web3.js": "1.87.6",
"@zetamarkets/anchor": "0.26.1-versioned",
"axios": "^1.6.8",
"bs58": "^4.0.1",
"cross-fetch": "^3.1.6",
"lodash": "^4.17.21",
"lodash.clonedeep": "^4.5.0",
"zeta-solana-web3": "1.87.7",
"obscenity": "0.2.0"
"obscenity": "0.2.0",
"zeta-solana-web3": "1.87.7"
},
"devDependencies": {
"@types/mocha": "^9.0.0",
Expand Down
20 changes: 20 additions & 0 deletions src/exchange.ts
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,18 @@ export class Exchange {
}
private _priorityFee: number = 0;

// toggle to use jito bundles
public get useJitoBundle(): boolean {
return this._useJitoBundle;
}
private _useJitoBundle: boolean = false;

// jito tip
public get jitoTip(): number {
return this._jitoTip;
}
private _jitoTip: number = 0;

public get useAutoPriorityFee(): boolean {
return this._useAutoPriorityFee;
}
Expand Down Expand Up @@ -355,6 +367,14 @@ export class Exchange {
this._priorityFee = microLamportsPerCU;
}

public setUseJitoBundle(option: boolean) {
this._useJitoBundle = option;
}

public updateJitoTip(tipAmountInLamports: number) {
this._jitoTip = tipAmountInLamports;
}

public updateAutoPriorityFeeUpperLimit(microLamportsPerCU: number) {
this._autoPriorityFeeUpperLimit = microLamportsPerCU;
}
Expand Down
8 changes: 4 additions & 4 deletions src/idl/zeta.json
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,7 @@
{
"name": "authority",
"isMut": true,
"isSigner": true
"isSigner": false
}
],
"args": []
Expand All @@ -465,7 +465,7 @@
{
"name": "authority",
"isMut": true,
"isSigner": true
"isSigner": false
}
],
"args": [
Expand Down Expand Up @@ -2763,7 +2763,7 @@
{
"name": "authority",
"isMut": true,
"isSigner": true
"isSigner": false
},
{
"name": "market",
Expand Down Expand Up @@ -9721,7 +9721,7 @@
"name": "STRK"
},
{
"name": "W"
"name": "TNSR"
},
{
"name": "UNDEFINED"
Expand Down
16 changes: 8 additions & 8 deletions src/types/zeta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,7 @@ export type Zeta = {
{
"name": "authority",
"isMut": true,
"isSigner": true
"isSigner": false
}
],
"args": []
Expand All @@ -465,7 +465,7 @@ export type Zeta = {
{
"name": "authority",
"isMut": true,
"isSigner": true
"isSigner": false
}
],
"args": [
Expand Down Expand Up @@ -2763,7 +2763,7 @@ export type Zeta = {
{
"name": "authority",
"isMut": true,
"isSigner": true
"isSigner": false
},
{
"name": "market",
Expand Down Expand Up @@ -9721,7 +9721,7 @@ export type Zeta = {
"name": "STRK"
},
{
"name": "W"
"name": "TNSR"
},
{
"name": "UNDEFINED"
Expand Down Expand Up @@ -11705,7 +11705,7 @@ export const IDL: Zeta = {
{
"name": "authority",
"isMut": true,
"isSigner": true
"isSigner": false
}
],
"args": []
Expand All @@ -11726,7 +11726,7 @@ export const IDL: Zeta = {
{
"name": "authority",
"isMut": true,
"isSigner": true
"isSigner": false
}
],
"args": [
Expand Down Expand Up @@ -14024,7 +14024,7 @@ export const IDL: Zeta = {
{
"name": "authority",
"isMut": true,
"isSigner": true
"isSigner": false
},
{
"name": "market",
Expand Down Expand Up @@ -20982,7 +20982,7 @@ export const IDL: Zeta = {
"name": "STRK"
},
{
"name": "W"
"name": "TNSR"
},
{
"name": "UNDEFINED"
Expand Down
146 changes: 140 additions & 6 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import { Network } from "./network";
import cloneDeep from "lodash.clonedeep";
import * as os from "os";
import { OpenOrders, _OPEN_ORDERS_LAYOUT_V2 } from "./serum/market";
import axios from "axios";

export function getNativeTickSize(asset: Asset): number {
return Exchange.state.tickSizes[assets.assetToIndex(asset)];
Expand Down Expand Up @@ -950,6 +951,122 @@ function txConfirmationCheck(expectedLevel: string, currentLevel: string) {
return false;
}

export async function processTransactionJito(
provider: anchor.AnchorProvider,
tx: Transaction,
signers?: Array<Signer>,
opts?: ConfirmOptions,
lutAccs?: AddressLookupTableAccount[],
blockhash?: { blockhash: string; lastValidBlockHeight: number }
): Promise<TransactionSignature> {
if (Exchange.jitoTip == 0) {
throw Error("Jito bundle tip has not been set.");
}

if (Exchange.priorityFee != 0) {
tx.instructions.unshift(
ComputeBudgetProgram.setComputeUnitPrice({
microLamports: Math.round(Exchange.priorityFee),
})
);
}

tx.instructions.push(
SystemProgram.transfer({
fromPubkey: Exchange.provider.publicKey,
toPubkey: new PublicKey(
"DttWaMuVvTiduZRnguLF7jNxTgiMBZ1hyAumKUiL2KRL" // Jito tip account
),
lamports: Exchange.jitoTip, // tip
})
);

let recentBlockhash =
blockhash ??
(await provider.connection.getLatestBlockhash(
Exchange.blockhashCommitment
));

let vTx: VersionedTransaction = new VersionedTransaction(
new TransactionMessage({
payerKey: provider.wallet.publicKey,
recentBlockhash: recentBlockhash.blockhash,
instructions: tx.instructions,
}).compileToV0Message(lutAccs)
);

vTx.sign(
(signers ?? [])
.filter((s) => s !== undefined)
.map((kp) => {
return kp;
})
);
vTx = (await provider.wallet.signTransaction(vTx)) as VersionedTransaction;

let rawTx = vTx.serialize();

const encodedTx = bs58.encode(rawTx);
const jitoURL = "https://mainnet.block-engine.jito.wtf/api/v1/transactions";
const payload = {
jsonrpc: "2.0",
id: 1,
method: "sendTransaction",
params: [encodedTx],
};

let txOpts = opts || commitmentConfig(provider.connection.commitment);
let txSig: string;
try {
const response = await axios.post(jitoURL, payload, {
headers: { "Content-Type": "application/json" },
});
txSig = response.data.result;
} catch (error) {
console.error("Error:", error);
throw new Error("Jito Bundle Error: cannot send.");
}

if (Exchange.skipRpcConfirmation) {
return txSig;
}

let currentBlockHeight = await provider.connection.getBlockHeight(
provider.connection.commitment
);

while (currentBlockHeight < recentBlockhash.lastValidBlockHeight) {
// Keep resending to maximise the chance of confirmation
await provider.connection.sendRawTransaction(rawTx, {
skipPreflight: true,
preflightCommitment: provider.connection.commitment,
});

let status = await provider.connection.getSignatureStatus(txSig);
currentBlockHeight = await provider.connection.getBlockHeight(
provider.connection.commitment
);
if (status.value != null) {
if (status.value.err != null) {
// Gets caught and parsed in the later catch
let err = parseInt(status.value.err["InstructionError"][1]["Custom"]);
let parsedErr = parseError(err);
throw parsedErr;
}
if (
txConfirmationCheck(
txOpts.commitment ? txOpts.commitment.toString() : "confirmed",
status.value.confirmationStatus.toString()
)
) {
return txSig;
}
}
await sleep(500); // Don't spam the RPC
}
throw Error(`Transaction ${txSig} was not confirmed`);
}

export async function processTransaction(
provider: anchor.AnchorProvider,
tx: Transaction,
Expand All @@ -960,6 +1077,17 @@ export async function processTransaction(
blockhash?: { blockhash: string; lastValidBlockHeight: number },
retries?: number
): Promise<TransactionSignature> {
if (Exchange.useJitoBundle) {
return processTransactionJito(
provider,
tx,
signers,
opts,
lutAccs,
blockhash
);
}

let failures = 0;
while (true) {
let rawTx: Buffer | Uint8Array;
Expand Down Expand Up @@ -1322,7 +1450,7 @@ export async function cleanZetaMarketHalted(asset: Asset) {
*/
export async function crankMarket(
asset: Asset,
openOrdersToMargin?: Map<PublicKey, PublicKey>,
openOrdersToMargin?: Map<string, PublicKey>,
crankLimit?: number
): Promise<boolean> {
let ix = await createCrankMarketIx(asset, openOrdersToMargin, crankLimit);
Expand All @@ -1340,7 +1468,7 @@ export async function crankMarket(

export async function createCrankMarketIx(
asset: Asset,
openOrdersToMargin?: Map<PublicKey, PublicKey>,
openOrdersToMargin?: Map<string, PublicKey>,
crankLimit?: number
): Promise<TransactionInstruction | null> {
let market = Exchange.getPerpMarket(asset);
Expand Down Expand Up @@ -1373,11 +1501,17 @@ export async function createCrankMarketIx(
await Promise.all(
uniqueOpenOrders.map(async (openOrders, index) => {
let marginAccount: PublicKey;
if (openOrdersToMargin && !openOrdersToMargin.has(openOrders)) {
if (
openOrdersToMargin &&
!openOrdersToMargin.has(openOrders.toBase58())
) {
marginAccount = await getAccountFromOpenOrders(openOrders, asset);
openOrdersToMargin.set(openOrders, marginAccount);
} else if (openOrdersToMargin && openOrdersToMargin.has(openOrders)) {
marginAccount = openOrdersToMargin.get(openOrders);
openOrdersToMargin.set(openOrders.toBase58(), marginAccount);
} else if (
openOrdersToMargin &&
openOrdersToMargin.has(openOrders.toBase58())
) {
marginAccount = openOrdersToMargin.get(openOrders.toBase58());
} else {
marginAccount = await getAccountFromOpenOrders(openOrders, asset);
}
Expand Down

0 comments on commit 9b107ce

Please sign in to comment.