@solana-mev-sdk/jito-client 0.2.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,75 @@
1
+ # jito-client
2
+
3
+ **Jito Block Engine client** for Solana: send bundles (up to 5 txs), optional tip transaction, and wait for confirmation.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install jito-client @solana/web3.js
9
+ ```
10
+
11
+ `@solana/web3.js` is a peer dependency.
12
+
13
+ ## Usage
14
+
15
+ ### Basic
16
+
17
+ ```ts
18
+ import { Connection, Keypair } from "@solana/web3.js";
19
+ import { JitoClient } from "jito-client";
20
+
21
+ const connection = new Connection("https://api.mainnet-beta.solana.com");
22
+ const client = new JitoClient(connection);
23
+
24
+ // Send bundle with tip (tipPayer pays tip; tip tx is appended)
25
+ const ok = await client.sendBundleAndConfirm([signedTx1, signedTx2], tipPayer);
26
+ ```
27
+
28
+ ### With options
29
+
30
+ ```ts
31
+ await client.sendBundleAndConfirm(txs, tipPayer, {
32
+ commitment: "finalized", // blockhash commitment for tip tx
33
+ simulate: true, // simulate each tx before sending
34
+ uuid: "your-jito-uuid", // optional API uuid
35
+ confirmationCommitment: "finalized", // wait until last tx is finalized
36
+ });
37
+ ```
38
+
39
+ ### Send without waiting
40
+
41
+ ```ts
42
+ const result = await client.sendBundle(txs, tipPayer, { simulate: true });
43
+ if (result) {
44
+ console.log("Bundle ID:", result.bundleId);
45
+ const landed = await client.waitForBundleConfirmation(result.lastTx, "finalized");
46
+ }
47
+ ```
48
+
49
+ ### Custom tip account / amount and logger
50
+
51
+ ```ts
52
+ const client = new JitoClient(connection, {
53
+ tipAccount: "96gYZGLnJYVFmbjzopPSU6QiEV5fGqZNyN9nmNhvrZU5",
54
+ tipSol: 0.00001,
55
+ logger: {
56
+ logError: (msg) => console.error(msg),
57
+ logWarning: (msg) => console.warn(msg),
58
+ },
59
+ });
60
+ ```
61
+
62
+ ## API
63
+
64
+ - **`JitoClient`** – Main class. Constructor: `new JitoClient(connection, config?)`.
65
+ - **`sendBundle(txs, tipPayer, options?)`** – Send bundle; returns `{ bundleId, lastTx }` or `null`.
66
+ - **`sendBundleAndConfirm(txs, tipPayer, options?)`** – Send and wait for last tx to reach `confirmationCommitment`; returns `boolean`.
67
+ - **`waitForBundleConfirmation(lastTx, commitment?)`** – Poll until last tx reaches `finalized` or `confirmed`.
68
+
69
+ - **`BundleOptions`** – `commitment`, `simulate`, `uuid`, `confirmationCommitment`.
70
+ - **`JitoClientConfig`** – `tipAccount`, `tipSol`, `logger`.
71
+ - **Constants** – `JITO_BLOCK_ENGINE_HOSTS`, `JITO_TIP_ACCOUNT_DEFAULT`, `JITO_TIP_SOL_DEFAULT`.
72
+
73
+ ## License
74
+
75
+ MIT
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Jito Block Engine client. Send bundles, optional tip tx, wait for confirmation.
3
+ */
4
+ import { Connection, Keypair, VersionedTransaction } from "@solana/web3.js";
5
+ import type { BundleOptions, JitoClientConfig, SendBundleResult } from "./types";
6
+ export declare class JitoClient {
7
+ readonly connection: Connection;
8
+ readonly tipSol: number;
9
+ private readonly log;
10
+ constructor(connection: Connection, config?: JitoClientConfig);
11
+ /**
12
+ * Send a bundle via Jito Block Engine HTTP API.
13
+ * @param signedTransactions - Up to 5 signed VersionedTransactions (serialized to base58).
14
+ * @param tipPayer - Optional keypair to pay Jito tip (adds tip tx to bundle).
15
+ * @param options - commitment, simulate, uuid, confirmationCommitment.
16
+ * @returns { bundleId, lastTx } or null on failure.
17
+ */
18
+ sendBundle(signedTransactions: VersionedTransaction[], tipPayer: Keypair | null, options?: BundleOptions): Promise<SendBundleResult>;
19
+ /**
20
+ * Wait for the last transaction in a bundle to reach the given commitment on-chain.
21
+ */
22
+ waitForBundleConfirmation(lastSignedTx: VersionedTransaction, commitment?: "finalized" | "confirmed"): Promise<boolean>;
23
+ /**
24
+ * Send a bundle and wait for the last tx to reach the requested commitment.
25
+ * @returns true if bundle was sent and the last tx reached confirmationCommitment on-chain.
26
+ */
27
+ sendBundleAndConfirm(signedTransactions: VersionedTransaction[], tipPayer: Keypair | null, options?: BundleOptions): Promise<boolean>;
28
+ }
29
+ //# sourceMappingURL=JitoClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JitoClient.d.ts","sourceRoot":"","sources":["../src/JitoClient.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,oBAAoB,EAAoB,MAAM,iBAAiB,CAAC;AAK9F,OAAO,KAAK,EACV,aAAa,EACb,gBAAgB,EAEhB,gBAAgB,EACjB,MAAM,SAAS,CAAC;AAqCjB,qBAAa,UAAU;IACrB,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAkC;gBAE1C,UAAU,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE,gBAAgB;IAM7D;;;;;;OAMG;IACG,UAAU,CACd,kBAAkB,EAAE,oBAAoB,EAAE,EAC1C,QAAQ,EAAE,OAAO,GAAG,IAAI,EACxB,OAAO,CAAC,EAAE,aAAa,GACtB,OAAO,CAAC,gBAAgB,CAAC;IA4G5B;;OAEG;IACG,yBAAyB,CAC7B,YAAY,EAAE,oBAAoB,EAClC,UAAU,GAAE,WAAW,GAAG,WAAyB,GAClD,OAAO,CAAC,OAAO,CAAC;IAoBnB;;;OAGG;IACG,oBAAoB,CACxB,kBAAkB,EAAE,oBAAoB,EAAE,EAC1C,QAAQ,EAAE,OAAO,GAAG,IAAI,EACxB,OAAO,CAAC,EAAE,aAAa,GACtB,OAAO,CAAC,OAAO,CAAC;CAYpB"}
@@ -0,0 +1,190 @@
1
+ "use strict";
2
+ /**
3
+ * Jito Block Engine client. Send bundles, optional tip tx, wait for confirmation.
4
+ */
5
+ var __importDefault = (this && this.__importDefault) || function (mod) {
6
+ return (mod && mod.__esModule) ? mod : { "default": mod };
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.JitoClient = void 0;
10
+ const axios_1 = __importDefault(require("axios"));
11
+ const bs58_1 = __importDefault(require("bs58"));
12
+ const jito_tip_tx_1 = require("@solana-mev-sdk/jito-tip-tx");
13
+ const constants_1 = require("./constants");
14
+ const constants_2 = require("./constants");
15
+ const logger_1 = require("./logger");
16
+ const BUNDLE_FINALIZE_TIMEOUT_MS = 50000;
17
+ const BUNDLE_POLL_INTERVAL_MS = 500;
18
+ const JITO_429_RETRY_MS = 4000;
19
+ const JITO_429_MAX_RETRIES = 3;
20
+ const DEFAULT_BUNDLE_OPTIONS = {
21
+ commitment: "finalized",
22
+ simulate: true,
23
+ uuid: null,
24
+ confirmationCommitment: "finalized",
25
+ };
26
+ function resolveBundleOptions(options) {
27
+ if (!options)
28
+ return DEFAULT_BUNDLE_OPTIONS;
29
+ return {
30
+ commitment: options.commitment ?? DEFAULT_BUNDLE_OPTIONS.commitment,
31
+ simulate: options.simulate ?? DEFAULT_BUNDLE_OPTIONS.simulate,
32
+ uuid: options.uuid ?? DEFAULT_BUNDLE_OPTIONS.uuid,
33
+ confirmationCommitment: options.confirmationCommitment ?? DEFAULT_BUNDLE_OPTIONS.confirmationCommitment,
34
+ };
35
+ }
36
+ function shortMessage(err) {
37
+ if (axios_1.default.isAxiosError(err)) {
38
+ const status = err.response?.status;
39
+ const msg = err.response?.data?.error?.message ?? err.message;
40
+ return status ? `HTTP ${status}: ${msg}` : msg;
41
+ }
42
+ if (err && typeof err === "object" && "message" in err) {
43
+ return String(err.message);
44
+ }
45
+ return err instanceof Error ? err.message : String(err);
46
+ }
47
+ class JitoClient {
48
+ constructor(connection, config) {
49
+ this.connection = connection;
50
+ this.tipSol = config?.tipSol ?? constants_2.JITO_TIP_SOL_DEFAULT;
51
+ this.log = (0, logger_1.createLogger)(config?.logger);
52
+ }
53
+ /**
54
+ * Send a bundle via Jito Block Engine HTTP API.
55
+ * @param signedTransactions - Up to 5 signed VersionedTransactions (serialized to base58).
56
+ * @param tipPayer - Optional keypair to pay Jito tip (adds tip tx to bundle).
57
+ * @param options - commitment, simulate, uuid, confirmationCommitment.
58
+ * @returns { bundleId, lastTx } or null on failure.
59
+ */
60
+ async sendBundle(signedTransactions, tipPayer, options) {
61
+ const opts = resolveBundleOptions(options);
62
+ if (signedTransactions.length === 0 || signedTransactions.length > 5) {
63
+ this.log.logError("Jito: bundle must contain 1–5 transactions.");
64
+ return null;
65
+ }
66
+ let transactionsToSend = signedTransactions;
67
+ let lastTx = signedTransactions[signedTransactions.length - 1];
68
+ if (tipPayer) {
69
+ const tipTx = await (0, jito_tip_tx_1.createTipTransaction)(this.connection, tipPayer, this.tipSol, opts.commitment);
70
+ tipTx.sign([tipPayer]);
71
+ transactionsToSend = [...signedTransactions, tipTx];
72
+ lastTx = tipTx;
73
+ if (transactionsToSend.length > 5) {
74
+ this.log.logError("Jito: bundle + tip would exceed 5 transactions.");
75
+ return null;
76
+ }
77
+ }
78
+ if (opts.simulate) {
79
+ for (let i = 0; i < transactionsToSend.length; i++) {
80
+ const sim = await this.connection.simulateTransaction(transactionsToSend[i], {
81
+ replaceRecentBlockhash: true,
82
+ sigVerify: false,
83
+ });
84
+ if (sim.value.err) {
85
+ this.log.logError(`Jito: simulation failed for tx ${i + 1}/${transactionsToSend.length}: ${JSON.stringify(sim.value.err)}`);
86
+ if (sim.value.logs && sim.value.logs.length > 0) {
87
+ this.log.logError("Simulation logs:\n" + sim.value.logs.slice(-20).join("\n"));
88
+ }
89
+ return null;
90
+ }
91
+ }
92
+ }
93
+ const serialized = transactionsToSend.map((tx) => bs58_1.default.encode(tx.serialize()));
94
+ const body = { jsonrpc: "2.0", id: 1, method: "sendBundle", params: [serialized] };
95
+ const hosts = [...constants_1.JITO_BLOCK_ENGINE_HOSTS].sort(() => Math.random() - 0.5);
96
+ let lastErr = null;
97
+ for (let attempt = 0; attempt < JITO_429_MAX_RETRIES; attempt++) {
98
+ const host = hosts[attempt % hosts.length];
99
+ const targetUrl = `https://${host}/api/v1/bundles${opts.uuid ? `?uuid=${opts.uuid}` : ""}`;
100
+ try {
101
+ const { data } = await axios_1.default.post(targetUrl, body, {
102
+ headers: { "Content-Type": "application/json" },
103
+ timeout: 15000,
104
+ });
105
+ if (data.error) {
106
+ lastErr = data.error;
107
+ const waitMs = Number(data.error.data?.["x-wait-to-retry-ms"]) || JITO_429_RETRY_MS;
108
+ if (data.error.code === 429 || (data.error.message && String(data.error.message).includes("429"))) {
109
+ if (attempt < JITO_429_MAX_RETRIES - 1) {
110
+ this.log.logWarning(`Jito rate limited (429). Retrying in ${Math.round(waitMs / 1000)}s...`);
111
+ await new Promise((r) => setTimeout(r, waitMs));
112
+ continue;
113
+ }
114
+ this.log.logError(`Jito sendBundle: rate limited (code 429). Wait ${Math.round(waitMs / 1000)}s and try again.`);
115
+ return null;
116
+ }
117
+ this.log.logError("Jito sendBundle: code " + (data.error.code ?? "(no code)") + " – " + (data.error.message ?? shortMessage(data.error)));
118
+ return null;
119
+ }
120
+ const bundleId = data.result;
121
+ if (!bundleId) {
122
+ this.log.logError("Jito sendBundle: no bundle ID in response.");
123
+ return null;
124
+ }
125
+ return { bundleId, lastTx };
126
+ }
127
+ catch (err) {
128
+ lastErr = err;
129
+ if (axios_1.default.isAxiosError(err) && err.response?.status === 429) {
130
+ const h = err.response?.headers;
131
+ const waitMs = Number(h?.["x-wait-to-retry-ms"] ?? h?.["X-Wait-To-Retry-Ms"]) || JITO_429_RETRY_MS;
132
+ if (attempt < JITO_429_MAX_RETRIES - 1) {
133
+ this.log.logWarning(`Jito rate limited (429). Retrying in ${Math.round(waitMs / 1000)}s...`);
134
+ await new Promise((r) => setTimeout(r, waitMs));
135
+ continue;
136
+ }
137
+ this.log.logError(`Jito sendBundle: HTTP 429. Wait ${Math.round(waitMs / 1000)}s and try again.`);
138
+ return null;
139
+ }
140
+ this.log.logError("Jito sendBundle failed: " + shortMessage(err));
141
+ return null;
142
+ }
143
+ }
144
+ if (lastErr) {
145
+ this.log.logError("Jito sendBundle failed after retries: " + shortMessage(lastErr));
146
+ }
147
+ return null;
148
+ }
149
+ /**
150
+ * Wait for the last transaction in a bundle to reach the given commitment on-chain.
151
+ */
152
+ async waitForBundleConfirmation(lastSignedTx, commitment = "finalized") {
153
+ const signature = bs58_1.default.encode(lastSignedTx.signatures[0]);
154
+ const deadline = Date.now() + BUNDLE_FINALIZE_TIMEOUT_MS;
155
+ while (Date.now() < deadline) {
156
+ try {
157
+ const result = await this.connection.getSignatureStatus(signature, {
158
+ searchTransactionHistory: true,
159
+ });
160
+ const status = result?.value?.confirmationStatus;
161
+ if (status === "finalized")
162
+ return true;
163
+ if (commitment === "confirmed" && status === "confirmed")
164
+ return true;
165
+ }
166
+ catch {
167
+ // ignore
168
+ }
169
+ await new Promise((r) => setTimeout(r, BUNDLE_POLL_INTERVAL_MS));
170
+ }
171
+ return false;
172
+ }
173
+ /**
174
+ * Send a bundle and wait for the last tx to reach the requested commitment.
175
+ * @returns true if bundle was sent and the last tx reached confirmationCommitment on-chain.
176
+ */
177
+ async sendBundleAndConfirm(signedTransactions, tipPayer, options) {
178
+ const opts = resolveBundleOptions(options);
179
+ const result = await this.sendBundle(signedTransactions, tipPayer, options);
180
+ if (!result)
181
+ return false;
182
+ this.log.logInfo(" Jito bundle ID: " + result.bundleId);
183
+ const finalized = await this.waitForBundleConfirmation(result.lastTx, opts.confirmationCommitment);
184
+ if (!finalized) {
185
+ this.log.logError("Jito: bundle sent but not finalized within timeout.");
186
+ }
187
+ return finalized;
188
+ }
189
+ }
190
+ exports.JitoClient = JitoClient;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Jito Block Engine and tip defaults.
3
+ */
4
+ /** Jito block engine hostnames (mainnet). */
5
+ export declare const JITO_BLOCK_ENGINE_HOSTS: readonly ["amsterdam.mainnet.block-engine.jito.wtf", "frankfurt.mainnet.block-engine.jito.wtf", "ny.mainnet.block-engine.jito.wtf", "tokyo.mainnet.block-engine.jito.wtf"];
6
+ /** Default Jito tip account (one of the official mainnet tip accounts). */
7
+ export declare const JITO_TIP_ACCOUNT_DEFAULT = "96gYZGLnJYVFmbjzopPSU6QiEV5fGqZNyN9nmNhvrZU5";
8
+ /** Default tip amount in SOL. */
9
+ export declare const JITO_TIP_SOL_DEFAULT = 0.00001;
10
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,6CAA6C;AAC7C,eAAO,MAAM,uBAAuB,4KAK1B,CAAC;AAEX,2EAA2E;AAC3E,eAAO,MAAM,wBAAwB,iDAAiD,CAAC;AAEvF,iCAAiC;AACjC,eAAO,MAAM,oBAAoB,UAAU,CAAC"}
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ /**
3
+ * Jito Block Engine and tip defaults.
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.JITO_TIP_SOL_DEFAULT = exports.JITO_TIP_ACCOUNT_DEFAULT = exports.JITO_BLOCK_ENGINE_HOSTS = void 0;
7
+ /** Jito block engine hostnames (mainnet). */
8
+ exports.JITO_BLOCK_ENGINE_HOSTS = [
9
+ "amsterdam.mainnet.block-engine.jito.wtf",
10
+ "frankfurt.mainnet.block-engine.jito.wtf",
11
+ "ny.mainnet.block-engine.jito.wtf",
12
+ "tokyo.mainnet.block-engine.jito.wtf",
13
+ ];
14
+ /** Default Jito tip account (one of the official mainnet tip accounts). */
15
+ exports.JITO_TIP_ACCOUNT_DEFAULT = "96gYZGLnJYVFmbjzopPSU6QiEV5fGqZNyN9nmNhvrZU5";
16
+ /** Default tip amount in SOL. */
17
+ exports.JITO_TIP_SOL_DEFAULT = 0.00001;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * jito-client: Jito Block Engine client for Solana bundles.
3
+ *
4
+ * Usage:
5
+ * import { Connection } from "@solana/web3.js";
6
+ * import { JitoClient } from "jito-client";
7
+ *
8
+ * const connection = new Connection("https://api.mainnet-beta.solana.com");
9
+ * const client = new JitoClient(connection);
10
+ * const ok = await client.sendBundleAndConfirm([tx], tipPayer, { simulate: true });
11
+ */
12
+ export { JitoClient } from "./JitoClient";
13
+ export { JITO_BLOCK_ENGINE_HOSTS, JITO_TIP_ACCOUNT_DEFAULT, JITO_TIP_SOL_DEFAULT, } from "./constants";
14
+ export type { BundleOptions, JitoClientConfig, JitoClientLogger, OnTipSent, ResolvedBundleOptions, SendBundleResult, } from "./types";
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EACL,uBAAuB,EACvB,wBAAwB,EACxB,oBAAoB,GACrB,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,aAAa,EACb,gBAAgB,EAChB,gBAAgB,EAChB,SAAS,EACT,qBAAqB,EACrB,gBAAgB,GACjB,MAAM,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ /**
3
+ * jito-client: Jito Block Engine client for Solana bundles.
4
+ *
5
+ * Usage:
6
+ * import { Connection } from "@solana/web3.js";
7
+ * import { JitoClient } from "jito-client";
8
+ *
9
+ * const connection = new Connection("https://api.mainnet-beta.solana.com");
10
+ * const client = new JitoClient(connection);
11
+ * const ok = await client.sendBundleAndConfirm([tx], tipPayer, { simulate: true });
12
+ */
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.JITO_TIP_SOL_DEFAULT = exports.JITO_TIP_ACCOUNT_DEFAULT = exports.JITO_BLOCK_ENGINE_HOSTS = exports.JitoClient = void 0;
15
+ var JitoClient_1 = require("./JitoClient");
16
+ Object.defineProperty(exports, "JitoClient", { enumerable: true, get: function () { return JitoClient_1.JitoClient; } });
17
+ var constants_1 = require("./constants");
18
+ Object.defineProperty(exports, "JITO_BLOCK_ENGINE_HOSTS", { enumerable: true, get: function () { return constants_1.JITO_BLOCK_ENGINE_HOSTS; } });
19
+ Object.defineProperty(exports, "JITO_TIP_ACCOUNT_DEFAULT", { enumerable: true, get: function () { return constants_1.JITO_TIP_ACCOUNT_DEFAULT; } });
20
+ Object.defineProperty(exports, "JITO_TIP_SOL_DEFAULT", { enumerable: true, get: function () { return constants_1.JITO_TIP_SOL_DEFAULT; } });
@@ -0,0 +1,7 @@
1
+ import type { JitoClientLogger } from "./types";
2
+ export declare function createLogger(custom?: JitoClientLogger): {
3
+ logError: (m: string) => void;
4
+ logWarning: (m: string) => void;
5
+ logInfo: (m: string) => void;
6
+ };
7
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AA8BhD,wBAAgB,YAAY,CAAC,MAAM,CAAC,EAAE,gBAAgB,GAAG;IAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAAC,UAAU,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAAC,OAAO,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,CAMxJ"}
package/dist/logger.js ADDED
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createLogger = createLogger;
4
+ const RED = "\x1b[31m";
5
+ const YELLOW = "\x1b[33m";
6
+ const RESET = "\x1b[0m";
7
+ function isTty() {
8
+ return typeof process !== "undefined" && process.stderr?.isTTY === true;
9
+ }
10
+ function defaultLogError(message) {
11
+ if (isTty()) {
12
+ process.stderr.write(`${RED}${message}${RESET}\n`);
13
+ }
14
+ else {
15
+ process.stderr.write(`${message}\n`);
16
+ }
17
+ }
18
+ function defaultLogWarning(message) {
19
+ if (isTty()) {
20
+ process.stderr.write(`${YELLOW}${message}${RESET}\n`);
21
+ }
22
+ else {
23
+ process.stderr.write(`${message}\n`);
24
+ }
25
+ }
26
+ function defaultLogInfo(message) {
27
+ process.stderr.write(`${message}\n`);
28
+ }
29
+ function createLogger(custom) {
30
+ return {
31
+ logError: custom?.logError ?? defaultLogError,
32
+ logWarning: custom?.logWarning ?? defaultLogWarning,
33
+ logInfo: custom?.logInfo ?? console.log
34
+ };
35
+ }
@@ -0,0 +1,39 @@
1
+ import type { VersionedTransaction } from "@solana/web3.js";
2
+ /** Result of sendBundle: bundle id and the last tx (e.g. tip tx) for confirmation. */
3
+ export type SendBundleResult = {
4
+ bundleId: string;
5
+ lastTx: VersionedTransaction;
6
+ } | null;
7
+ /** Options for sendBundle and sendBundleAndConfirm. */
8
+ export interface BundleOptions {
9
+ /** Commitment for getLatestBlockhash when building tip tx. Default "finalized". */
10
+ commitment?: "finalized" | "confirmed" | "processed";
11
+ /** Simulate each tx before sending; if any fails, do not send. Default true. */
12
+ simulate?: boolean;
13
+ /** Optional Jito API uuid query param (e.g. for authenticated endpoints). */
14
+ uuid?: string | null;
15
+ /** Consider bundle landed when last tx reaches this status. Default "finalized". */
16
+ confirmationCommitment?: "finalized" | "confirmed";
17
+ }
18
+ /** Resolved options (all optional fields filled). */
19
+ export type ResolvedBundleOptions = Required<Omit<BundleOptions, "uuid">> & {
20
+ uuid?: string | null;
21
+ };
22
+ /** Optional logger; defaults to stderr for errors/warnings. */
23
+ export interface JitoClientLogger {
24
+ logError?(message: string): void;
25
+ logWarning?(message: string): void;
26
+ logInfo?(message: string): void;
27
+ }
28
+ /** Called when a bundle that includes a tip is sent successfully. Use to report lamports tipped to your API. */
29
+ export type OnTipSent = (lamports: number) => void | Promise<void>;
30
+ /** Config passed to JitoClient constructor. */
31
+ export interface JitoClientConfig {
32
+ /** Tip account address when adding tip tx. Default JITO_TIP_ACCOUNT_DEFAULT. */
33
+ tipAccount?: string;
34
+ /** Tip amount in SOL when adding tip tx. Default JITO_TIP_SOL_DEFAULT. */
35
+ tipSol?: number;
36
+ /** Custom logger (errors/warnings). */
37
+ logger?: JitoClientLogger;
38
+ }
39
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAE5D,sFAAsF;AACtF,MAAM,MAAM,gBAAgB,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,oBAAoB,CAAA;CAAE,GAAG,IAAI,CAAC;AAEzF,uDAAuD;AACvD,MAAM,WAAW,aAAa;IAC5B,mFAAmF;IACnF,UAAU,CAAC,EAAE,WAAW,GAAG,WAAW,GAAG,WAAW,CAAC;IACrD,gFAAgF;IAChF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,6EAA6E;IAC7E,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,oFAAoF;IACpF,sBAAsB,CAAC,EAAE,WAAW,GAAG,WAAW,CAAC;CACpD;AAED,qDAAqD;AACrD,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAAC,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AAErG,+DAA+D;AAC/D,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,UAAU,CAAC,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAED,gHAAgH;AAChH,MAAM,MAAM,SAAS,GAAG,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnE,+CAA+C;AAC/C,MAAM,WAAW,gBAAgB;IAC/B,gFAAgF;IAChF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0EAA0E;IAC1E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,uCAAuC;IACvC,MAAM,CAAC,EAAE,gBAAgB,CAAC;CAC3B"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "@solana-mev-sdk/jito-client",
3
+ "version": "0.2.8",
4
+ "description": "Jito Block Engine client — send bundles, tip tx, wait for confirmation",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "files": [
8
+ "dist"
9
+ ],
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "prepublishOnly": "npm run build"
13
+ },
14
+ "keywords": [
15
+ "jito",
16
+ "solana",
17
+ "bundle",
18
+ "mev",
19
+ "block-engine"
20
+ ],
21
+ "author": "",
22
+ "license": "MIT",
23
+ "peerDependencies": {
24
+ "@solana/web3.js": "^1.80.0"
25
+ },
26
+ "dependencies": {
27
+ "axios": "^1.11.0",
28
+ "bs58": "^6.0.0",
29
+ "@solana-mev-sdk/jito-tip-tx": "^0.3.2"
30
+ },
31
+ "devDependencies": {
32
+ "@solana/web3.js": "^1.98.4",
33
+ "@types/node": "^20.0.0",
34
+ "typescript": "^5.9.2"
35
+ },
36
+ "engines": {
37
+ "node": ">=18"
38
+ },
39
+ "repository": {
40
+ "type": "git",
41
+ "url": "git+https://github.com/solana-mev-sdk/jito-client.git"
42
+ },
43
+ "bugs": {
44
+ "url": "https://github.com/solana-mev-sdk/jito-client/issues"
45
+ },
46
+ "homepage": "https://github.com/solana-mev-sdk/jito-client#readme"
47
+ }