@unio-aggregator/unio-tx-sender 1.0.1 → 1.0.2

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/dist/index.d.cts CHANGED
@@ -1,14 +1,11 @@
1
- import { Rpc, SolanaRpcApi, Instruction, TransactionSigner, Address, MaybeAccount, SendableTransaction, Transaction, TransactionWithLifetime, Commitment, Signature, KeyPairSigner } from '@solana/kit';
1
+ import { BlockhashLifetimeConstraint, Rpc, SolanaRpcApi, Instruction, TransactionSigner, Address, MaybeAccount, SendableTransaction, Transaction, TransactionWithLifetime, TransactionMessage, TransactionMessageWithFeePayer, Signature, Commitment, KeyPairSigner } from '@solana/kit';
2
2
  import { AddressLookupTable } from '@solana-program/address-lookup-table';
3
3
 
4
4
  /**
5
5
  * Default compute unit margin multiplier used to ensure sufficient compute budget.
6
6
  */
7
7
  declare const DEFAULT_COMPUTE_UNIT_MARGIN_MULTIPLIER = 1.15;
8
- /**
9
- * Default prioritization settings, including priority fees and Jito tips.
10
- */
11
- declare const DEFAULT_TRANSACTION_CONFIG: TransactionConfig;
8
+ declare const DEFAULT_JITO_BLOCK_ENGINE_URL = "https://bundles.jito.wtf";
12
9
  type FeeSetting = {
13
10
  type: "dynamic";
14
11
  maxCapLamports?: bigint;
@@ -27,21 +24,18 @@ type JitoFeeSetting = FeeSetting & {
27
24
  type PriorityFeeSetting = FeeSetting & {
28
25
  priorityFeePercentile?: Percentile;
29
26
  };
30
- type TransactionConfig = {
31
- jito: JitoFeeSetting;
32
- priorityFee: PriorityFeeSetting;
33
- computeUnitMarginMultiplier: number;
34
- jitoBlockEngineUrl: string;
35
- skipSimulation: boolean;
36
- };
37
27
  /**
38
28
  * Defines a percentile value for priority fee selection.
39
29
  */
40
30
  type Percentile = "25" | "50" | "75" | "95" | "99";
41
- /**
42
- * Represents a supported blockchain network chain ID.
43
- */
44
- type ChainId = "solana" | "eclipse" | "solana-devnet" | "eclipse-testnet" | "unknown";
31
+ type TransactionConfig = {
32
+ jito?: JitoFeeSetting;
33
+ priorityFee?: PriorityFeeSetting;
34
+ computeUnitMarginMultiplier?: number;
35
+ jitoBlockEngineUrl?: string;
36
+ skipSimulation?: boolean;
37
+ blockhash?: BlockhashLifetimeConstraint;
38
+ };
45
39
 
46
40
  /**
47
41
  * Builds and signs a transaction from the given instructions and configuration.
@@ -63,7 +57,95 @@ type ChainId = "solana" | "eclipse" | "solana-devnet" | "eclipse-testnet" | "unk
63
57
  * feePayer,
64
58
  * );
65
59
  */
66
- declare function buildTransaction(rpc: Rpc<SolanaRpcApi>, config: TransactionConfig, instructions: Instruction[], feePayer: TransactionSigner | Address, lookupTableAccounts?: MaybeAccount<AddressLookupTable>[]): Promise<Readonly<SendableTransaction & Transaction & TransactionWithLifetime>>;
60
+ declare function buildTransaction(rpc: Rpc<SolanaRpcApi>, instructions: Instruction[], feePayer: TransactionSigner | Address, config: TransactionConfig, lookupTableAccounts?: MaybeAccount<AddressLookupTable>[]): Promise<Readonly<SendableTransaction & Transaction & TransactionWithLifetime>>;
61
+
62
+ type AccountConfig = {
63
+ accountIndex: number;
64
+ addresses: string[];
65
+ };
66
+ type JitoAccountInfo = {
67
+ executable: boolean;
68
+ owner: string;
69
+ lamports: number;
70
+ data: string;
71
+ rentEpoch: number;
72
+ };
73
+ type JitoRpcApi = SolanaRpcApi & {
74
+ simulateBundle: (params: {
75
+ encodedTransactions: string[];
76
+ }, config?: {
77
+ preExecutionAccountsConfigs?: AccountConfig;
78
+ postExecutionAccountsConfigs?: AccountConfig;
79
+ skipSigVerify?: boolean;
80
+ simulationBank?: {
81
+ commitment?: {
82
+ commitment: "processed" | "confirmed" | "finalized";
83
+ };
84
+ };
85
+ transactionEncoding?: "base64";
86
+ replaceRecentBlockhash?: boolean;
87
+ }) => SimulateBundleResponse;
88
+ sendBundle: (params: string[], config?: {
89
+ encoding?: "base64";
90
+ }) => string;
91
+ getBundleStatuses: (params: string[]) => GetBundleStatusesResponse;
92
+ };
93
+ type SimulateBundleResponse = {
94
+ context: {
95
+ slot: number;
96
+ apiVersion?: string;
97
+ };
98
+ value: {
99
+ summary: "succeeded" | {
100
+ failed: {
101
+ error: unknown;
102
+ tx_signature: string;
103
+ };
104
+ };
105
+ transactionResults: Array<{
106
+ err: unknown;
107
+ logs: string[] | null;
108
+ unitsConsumed?: number;
109
+ returnData: {
110
+ programId: string;
111
+ data: string;
112
+ } | null;
113
+ preExecutionAccounts: JitoAccountInfo[] | null;
114
+ postExecutionAccounts: JitoAccountInfo[] | null;
115
+ }>;
116
+ };
117
+ };
118
+ type GetBundleStatusesResponse = {
119
+ context: {
120
+ slot: number;
121
+ };
122
+ value: Array<{
123
+ bundleId: string;
124
+ transactions: string[];
125
+ slot: number;
126
+ confirmation_status: "processed" | "confirmed" | "finalized";
127
+ err: {
128
+ Ok: null;
129
+ } | {
130
+ Err: object;
131
+ };
132
+ }>;
133
+ };
134
+ declare enum JitoApiUrl {
135
+ Amsterdam = "https://amsterdam.mainnet.block-engine.jito.wtf",
136
+ Frankfurt = "https://frankfurt.mainnet.block-engine.jito.wtf",
137
+ London = "https://london.mainnet.block-engine.jito.wtf",
138
+ NY = "https://ny.mainnet.block-engine.jito.wtf",
139
+ Singapore = "https://singapore.mainnet.block-engine.jito.wtf",
140
+ SLC = "https://slc.mainnet.block-engine.jito.wtf",
141
+ Tokyo = "https://tokyo.mainnet.block-engine.jito.wtf",
142
+ Default = "https://mainnet.block-engine.jito.wtf"
143
+ }
144
+ declare function processJitoTipForTxMessage(message: TransactionMessage & TransactionMessageWithFeePayer, signer: TransactionSigner, config: TransactionConfig): Promise<TransactionMessage & TransactionMessageWithFeePayer<string>>;
145
+ declare function recentJitoTip(config: TransactionConfig): Promise<bigint>;
146
+ declare function sendJitoBundle(jitoApiUrl: JitoApiUrl, transactions: (SendableTransaction & Transaction & TransactionWithLifetime)[], jitoUUID?: string): Promise<string>;
147
+ declare function simulateBundle(rpc: Rpc<JitoRpcApi>, transactions: (SendableTransaction & Transaction & TransactionWithLifetime)[]): Promise<SimulateBundleResponse>;
148
+ declare function sendBundle(rpc: Rpc<JitoRpcApi>, transactions: (SendableTransaction & Transaction & TransactionWithLifetime)[]): Promise<string>;
67
149
 
68
150
  /**
69
151
  * Builds and sends a transaction with the given instructions, signers, and commitment level.
@@ -96,7 +178,7 @@ declare function sendTransaction(rpc: Rpc<SolanaRpcApi>, instructions: Instructi
96
178
  *
97
179
  * @param {Rpc<SolanaRpcApi>} rpc - Rpc client.
98
180
  * @param {SendableTransaction & Transaction & TransactionWithLifetime} transaction - The fully signed transaction to send.
99
- * @param {TransactionConfig} config - The transaction config.
181
+ * @param {boolean} skipSimulation - True if skip simulation
100
182
  * @param {Commitment} [commitment="confirmed"] - The commitment level for transaction confirmation.
101
183
  *
102
184
  * @returns {Promise<Signature>} A promise that resolves to the transaction signature.
@@ -112,6 +194,7 @@ declare function sendTransaction(rpc: Rpc<SolanaRpcApi>, instructions: Instructi
112
194
  * );
113
195
  * ```
114
196
  */
115
- declare function sendSignedTransaction(rpc: Rpc<SolanaRpcApi>, transaction: SendableTransaction & Transaction & TransactionWithLifetime, config: TransactionConfig, commitment?: Commitment): Promise<Signature>;
197
+ declare function sendSignedTransaction(rpc: Rpc<SolanaRpcApi>, transaction: SendableTransaction & Transaction & TransactionWithLifetime, skipSimulation?: boolean, commitment?: Commitment): Promise<Signature>;
198
+ declare function getTxSignature(transaction: Transaction): Signature;
116
199
 
117
- export { type ChainId, DEFAULT_COMPUTE_UNIT_MARGIN_MULTIPLIER, DEFAULT_TRANSACTION_CONFIG, type JitoFeeSetting, type Percentile, type PriorityFeeSetting, type TransactionConfig, buildTransaction, sendSignedTransaction, sendTransaction };
200
+ export { type AccountConfig, DEFAULT_COMPUTE_UNIT_MARGIN_MULTIPLIER, DEFAULT_JITO_BLOCK_ENGINE_URL, type GetBundleStatusesResponse, type JitoAccountInfo, JitoApiUrl, type JitoFeeSetting, type JitoRpcApi, type Percentile, type PriorityFeeSetting, type SimulateBundleResponse, type TransactionConfig, buildTransaction, getTxSignature, processJitoTipForTxMessage, recentJitoTip, sendBundle, sendJitoBundle, sendSignedTransaction, sendTransaction, simulateBundle };
package/dist/index.d.ts CHANGED
@@ -1,14 +1,11 @@
1
- import { Rpc, SolanaRpcApi, Instruction, TransactionSigner, Address, MaybeAccount, SendableTransaction, Transaction, TransactionWithLifetime, Commitment, Signature, KeyPairSigner } from '@solana/kit';
1
+ import { BlockhashLifetimeConstraint, Rpc, SolanaRpcApi, Instruction, TransactionSigner, Address, MaybeAccount, SendableTransaction, Transaction, TransactionWithLifetime, TransactionMessage, TransactionMessageWithFeePayer, Signature, Commitment, KeyPairSigner } from '@solana/kit';
2
2
  import { AddressLookupTable } from '@solana-program/address-lookup-table';
3
3
 
4
4
  /**
5
5
  * Default compute unit margin multiplier used to ensure sufficient compute budget.
6
6
  */
7
7
  declare const DEFAULT_COMPUTE_UNIT_MARGIN_MULTIPLIER = 1.15;
8
- /**
9
- * Default prioritization settings, including priority fees and Jito tips.
10
- */
11
- declare const DEFAULT_TRANSACTION_CONFIG: TransactionConfig;
8
+ declare const DEFAULT_JITO_BLOCK_ENGINE_URL = "https://bundles.jito.wtf";
12
9
  type FeeSetting = {
13
10
  type: "dynamic";
14
11
  maxCapLamports?: bigint;
@@ -27,21 +24,18 @@ type JitoFeeSetting = FeeSetting & {
27
24
  type PriorityFeeSetting = FeeSetting & {
28
25
  priorityFeePercentile?: Percentile;
29
26
  };
30
- type TransactionConfig = {
31
- jito: JitoFeeSetting;
32
- priorityFee: PriorityFeeSetting;
33
- computeUnitMarginMultiplier: number;
34
- jitoBlockEngineUrl: string;
35
- skipSimulation: boolean;
36
- };
37
27
  /**
38
28
  * Defines a percentile value for priority fee selection.
39
29
  */
40
30
  type Percentile = "25" | "50" | "75" | "95" | "99";
41
- /**
42
- * Represents a supported blockchain network chain ID.
43
- */
44
- type ChainId = "solana" | "eclipse" | "solana-devnet" | "eclipse-testnet" | "unknown";
31
+ type TransactionConfig = {
32
+ jito?: JitoFeeSetting;
33
+ priorityFee?: PriorityFeeSetting;
34
+ computeUnitMarginMultiplier?: number;
35
+ jitoBlockEngineUrl?: string;
36
+ skipSimulation?: boolean;
37
+ blockhash?: BlockhashLifetimeConstraint;
38
+ };
45
39
 
46
40
  /**
47
41
  * Builds and signs a transaction from the given instructions and configuration.
@@ -63,7 +57,95 @@ type ChainId = "solana" | "eclipse" | "solana-devnet" | "eclipse-testnet" | "unk
63
57
  * feePayer,
64
58
  * );
65
59
  */
66
- declare function buildTransaction(rpc: Rpc<SolanaRpcApi>, config: TransactionConfig, instructions: Instruction[], feePayer: TransactionSigner | Address, lookupTableAccounts?: MaybeAccount<AddressLookupTable>[]): Promise<Readonly<SendableTransaction & Transaction & TransactionWithLifetime>>;
60
+ declare function buildTransaction(rpc: Rpc<SolanaRpcApi>, instructions: Instruction[], feePayer: TransactionSigner | Address, config: TransactionConfig, lookupTableAccounts?: MaybeAccount<AddressLookupTable>[]): Promise<Readonly<SendableTransaction & Transaction & TransactionWithLifetime>>;
61
+
62
+ type AccountConfig = {
63
+ accountIndex: number;
64
+ addresses: string[];
65
+ };
66
+ type JitoAccountInfo = {
67
+ executable: boolean;
68
+ owner: string;
69
+ lamports: number;
70
+ data: string;
71
+ rentEpoch: number;
72
+ };
73
+ type JitoRpcApi = SolanaRpcApi & {
74
+ simulateBundle: (params: {
75
+ encodedTransactions: string[];
76
+ }, config?: {
77
+ preExecutionAccountsConfigs?: AccountConfig;
78
+ postExecutionAccountsConfigs?: AccountConfig;
79
+ skipSigVerify?: boolean;
80
+ simulationBank?: {
81
+ commitment?: {
82
+ commitment: "processed" | "confirmed" | "finalized";
83
+ };
84
+ };
85
+ transactionEncoding?: "base64";
86
+ replaceRecentBlockhash?: boolean;
87
+ }) => SimulateBundleResponse;
88
+ sendBundle: (params: string[], config?: {
89
+ encoding?: "base64";
90
+ }) => string;
91
+ getBundleStatuses: (params: string[]) => GetBundleStatusesResponse;
92
+ };
93
+ type SimulateBundleResponse = {
94
+ context: {
95
+ slot: number;
96
+ apiVersion?: string;
97
+ };
98
+ value: {
99
+ summary: "succeeded" | {
100
+ failed: {
101
+ error: unknown;
102
+ tx_signature: string;
103
+ };
104
+ };
105
+ transactionResults: Array<{
106
+ err: unknown;
107
+ logs: string[] | null;
108
+ unitsConsumed?: number;
109
+ returnData: {
110
+ programId: string;
111
+ data: string;
112
+ } | null;
113
+ preExecutionAccounts: JitoAccountInfo[] | null;
114
+ postExecutionAccounts: JitoAccountInfo[] | null;
115
+ }>;
116
+ };
117
+ };
118
+ type GetBundleStatusesResponse = {
119
+ context: {
120
+ slot: number;
121
+ };
122
+ value: Array<{
123
+ bundleId: string;
124
+ transactions: string[];
125
+ slot: number;
126
+ confirmation_status: "processed" | "confirmed" | "finalized";
127
+ err: {
128
+ Ok: null;
129
+ } | {
130
+ Err: object;
131
+ };
132
+ }>;
133
+ };
134
+ declare enum JitoApiUrl {
135
+ Amsterdam = "https://amsterdam.mainnet.block-engine.jito.wtf",
136
+ Frankfurt = "https://frankfurt.mainnet.block-engine.jito.wtf",
137
+ London = "https://london.mainnet.block-engine.jito.wtf",
138
+ NY = "https://ny.mainnet.block-engine.jito.wtf",
139
+ Singapore = "https://singapore.mainnet.block-engine.jito.wtf",
140
+ SLC = "https://slc.mainnet.block-engine.jito.wtf",
141
+ Tokyo = "https://tokyo.mainnet.block-engine.jito.wtf",
142
+ Default = "https://mainnet.block-engine.jito.wtf"
143
+ }
144
+ declare function processJitoTipForTxMessage(message: TransactionMessage & TransactionMessageWithFeePayer, signer: TransactionSigner, config: TransactionConfig): Promise<TransactionMessage & TransactionMessageWithFeePayer<string>>;
145
+ declare function recentJitoTip(config: TransactionConfig): Promise<bigint>;
146
+ declare function sendJitoBundle(jitoApiUrl: JitoApiUrl, transactions: (SendableTransaction & Transaction & TransactionWithLifetime)[], jitoUUID?: string): Promise<string>;
147
+ declare function simulateBundle(rpc: Rpc<JitoRpcApi>, transactions: (SendableTransaction & Transaction & TransactionWithLifetime)[]): Promise<SimulateBundleResponse>;
148
+ declare function sendBundle(rpc: Rpc<JitoRpcApi>, transactions: (SendableTransaction & Transaction & TransactionWithLifetime)[]): Promise<string>;
67
149
 
68
150
  /**
69
151
  * Builds and sends a transaction with the given instructions, signers, and commitment level.
@@ -96,7 +178,7 @@ declare function sendTransaction(rpc: Rpc<SolanaRpcApi>, instructions: Instructi
96
178
  *
97
179
  * @param {Rpc<SolanaRpcApi>} rpc - Rpc client.
98
180
  * @param {SendableTransaction & Transaction & TransactionWithLifetime} transaction - The fully signed transaction to send.
99
- * @param {TransactionConfig} config - The transaction config.
181
+ * @param {boolean} skipSimulation - True if skip simulation
100
182
  * @param {Commitment} [commitment="confirmed"] - The commitment level for transaction confirmation.
101
183
  *
102
184
  * @returns {Promise<Signature>} A promise that resolves to the transaction signature.
@@ -112,6 +194,7 @@ declare function sendTransaction(rpc: Rpc<SolanaRpcApi>, instructions: Instructi
112
194
  * );
113
195
  * ```
114
196
  */
115
- declare function sendSignedTransaction(rpc: Rpc<SolanaRpcApi>, transaction: SendableTransaction & Transaction & TransactionWithLifetime, config: TransactionConfig, commitment?: Commitment): Promise<Signature>;
197
+ declare function sendSignedTransaction(rpc: Rpc<SolanaRpcApi>, transaction: SendableTransaction & Transaction & TransactionWithLifetime, skipSimulation?: boolean, commitment?: Commitment): Promise<Signature>;
198
+ declare function getTxSignature(transaction: Transaction): Signature;
116
199
 
117
- export { type ChainId, DEFAULT_COMPUTE_UNIT_MARGIN_MULTIPLIER, DEFAULT_TRANSACTION_CONFIG, type JitoFeeSetting, type Percentile, type PriorityFeeSetting, type TransactionConfig, buildTransaction, sendSignedTransaction, sendTransaction };
200
+ export { type AccountConfig, DEFAULT_COMPUTE_UNIT_MARGIN_MULTIPLIER, DEFAULT_JITO_BLOCK_ENGINE_URL, type GetBundleStatusesResponse, type JitoAccountInfo, JitoApiUrl, type JitoFeeSetting, type JitoRpcApi, type Percentile, type PriorityFeeSetting, type SimulateBundleResponse, type TransactionConfig, buildTransaction, getTxSignature, processJitoTipForTxMessage, recentJitoTip, sendBundle, sendJitoBundle, sendSignedTransaction, sendTransaction, simulateBundle };
package/dist/index.js CHANGED
@@ -18,38 +18,34 @@ import { getSetComputeUnitLimitInstruction, getSetComputeUnitPriceInstruction }
18
18
 
19
19
  // src/config.ts
20
20
  var DEFAULT_COMPUTE_UNIT_MARGIN_MULTIPLIER = 1.15;
21
- var DEFAULT_TRANSACTION_CONFIG = {
22
- priorityFee: {
23
- type: "none",
24
- priorityFeePercentile: "50"
25
- },
26
- jito: {
27
- type: "none",
28
- priorityFeePercentile: "50"
29
- },
30
- computeUnitMarginMultiplier: DEFAULT_COMPUTE_UNIT_MARGIN_MULTIPLIER,
31
- jitoBlockEngineUrl: "https://bundles.jito.wtf",
32
- skipSimulation: false
33
- };
21
+ var DEFAULT_JITO_BLOCK_ENGINE_URL = "https://bundles.jito.wtf";
34
22
 
35
23
  // src/computeBudget.ts
36
24
  async function processComputeBudgetForTxMessage(rpc, message, computeUnits, config) {
37
- const priorityFee = config.priorityFee;
38
25
  const computeUnitMarginMultiplier = config.computeUnitMarginMultiplier;
39
26
  let priorityFeeMicroLamports = 0n;
40
- if (priorityFee.type === "exact") {
41
- priorityFeeMicroLamports = priorityFee.amountLamports * 1000000n / BigInt(computeUnits);
42
- } else if (priorityFee.type === "dynamic") {
43
- const estimatedPriorityFee = await calculateDynamicPriorityFees(
44
- rpc,
45
- message.instructions,
46
- priorityFee.priorityFeePercentile ?? "50"
47
- );
48
- if (!priorityFee.maxCapLamports) {
49
- priorityFeeMicroLamports = estimatedPriorityFee;
50
- } else {
51
- const maxCapMicroLamports = priorityFee.maxCapLamports * 1000000n / BigInt(computeUnits);
52
- priorityFeeMicroLamports = maxCapMicroLamports > estimatedPriorityFee ? estimatedPriorityFee : maxCapMicroLamports;
27
+ const units = BigInt(
28
+ Math.min(
29
+ 14e5,
30
+ Math.ceil(computeUnits * (computeUnitMarginMultiplier ?? DEFAULT_COMPUTE_UNIT_MARGIN_MULTIPLIER))
31
+ )
32
+ );
33
+ const priorityFee = config.priorityFee;
34
+ if (priorityFee) {
35
+ if (priorityFee.type === "exact") {
36
+ priorityFeeMicroLamports = priorityFee.amountLamports * 1000000n / units;
37
+ } else if (priorityFee.type === "dynamic") {
38
+ const estimatedPriorityFee = await calculateDynamicPriorityFees(
39
+ rpc,
40
+ message.instructions,
41
+ priorityFee.priorityFeePercentile ?? "50"
42
+ );
43
+ if (!priorityFee.maxCapLamports) {
44
+ priorityFeeMicroLamports = estimatedPriorityFee;
45
+ } else {
46
+ const maxCapMicroLamports = priorityFee.maxCapLamports * 1000000n / units;
47
+ priorityFeeMicroLamports = maxCapMicroLamports > estimatedPriorityFee ? estimatedPriorityFee : maxCapMicroLamports;
48
+ }
53
49
  }
54
50
  }
55
51
  if (priorityFeeMicroLamports > 0) {
@@ -62,7 +58,7 @@ async function processComputeBudgetForTxMessage(rpc, message, computeUnits, conf
62
58
  }
63
59
  message = prependTransactionMessageInstruction(
64
60
  getSetComputeUnitLimitInstruction({
65
- units: Math.ceil(computeUnits * (computeUnitMarginMultiplier ?? DEFAULT_COMPUTE_UNIT_MARGIN_MULTIPLIER))
61
+ units: computeUnits
66
62
  }),
67
63
  message
68
64
  );
@@ -88,18 +84,38 @@ async function calculateDynamicPriorityFees(rpc, instructions, percentile) {
88
84
  }
89
85
 
90
86
  // src/jito.ts
91
- import { address, lamports, prependTransactionMessageInstruction as prependTransactionMessageInstruction2 } from "@solana/kit";
87
+ import {
88
+ appendTransactionMessageInstruction,
89
+ getBase64EncodedWireTransaction
90
+ } from "@solana/kit";
91
+ import { address, lamports } from "@solana/kit";
92
92
  import { getTransferSolInstruction } from "@solana-program/system";
93
+ var JITO_BUNDLE_EXPIRY_TIME = 3e4;
94
+ var JitoApiUrl = /* @__PURE__ */ ((JitoApiUrl2) => {
95
+ JitoApiUrl2["Amsterdam"] = "https://amsterdam.mainnet.block-engine.jito.wtf";
96
+ JitoApiUrl2["Frankfurt"] = "https://frankfurt.mainnet.block-engine.jito.wtf";
97
+ JitoApiUrl2["London"] = "https://london.mainnet.block-engine.jito.wtf";
98
+ JitoApiUrl2["NY"] = "https://ny.mainnet.block-engine.jito.wtf";
99
+ JitoApiUrl2["Singapore"] = "https://singapore.mainnet.block-engine.jito.wtf";
100
+ JitoApiUrl2["SLC"] = "https://slc.mainnet.block-engine.jito.wtf";
101
+ JitoApiUrl2["Tokyo"] = "https://tokyo.mainnet.block-engine.jito.wtf";
102
+ JitoApiUrl2["Default"] = "https://mainnet.block-engine.jito.wtf";
103
+ return JitoApiUrl2;
104
+ })(JitoApiUrl || {});
93
105
  async function processJitoTipForTxMessage(message, signer, config) {
94
- let jitoTipLamports = BigInt(0);
95
106
  const jito = config.jito;
107
+ if (!jito) throw new Error("jito config is undefined");
108
+ let jitoTipLamports = BigInt(0);
96
109
  if (jito.type === "exact") {
97
110
  jitoTipLamports = jito.amountLamports;
98
111
  } else if (jito.type === "dynamic") {
99
112
  jitoTipLamports = await recentJitoTip(config);
113
+ if (jito.maxCapLamports && jitoTipLamports > jito.maxCapLamports) {
114
+ jitoTipLamports = jito.maxCapLamports;
115
+ }
100
116
  }
101
117
  if (jitoTipLamports > 0) {
102
- return prependTransactionMessageInstruction2(
118
+ return appendTransactionMessageInstruction(
103
119
  getTransferSolInstruction({
104
120
  source: signer,
105
121
  destination: getJitoTipAddress(),
@@ -112,7 +128,8 @@ async function processJitoTipForTxMessage(message, signer, config) {
112
128
  }
113
129
  }
114
130
  async function recentJitoTip(config) {
115
- const response = await fetch(`${config.jitoBlockEngineUrl}/api/v1/bundles/tip_floor`);
131
+ const baseUrl = config.jitoBlockEngineUrl ?? DEFAULT_JITO_BLOCK_ENGINE_URL;
132
+ const response = await fetch(`${baseUrl}/api/v1/bundles/tip_floor`);
116
133
  if (!response.ok) {
117
134
  return BigInt(0);
118
135
  }
@@ -125,7 +142,7 @@ async function recentJitoTip(config) {
125
142
  "99": "landed_tips_99th_percentile",
126
143
  "50ema": "ema_landed_tips_50th_percentile"
127
144
  };
128
- const key = percentileToKey[config.priorityFee.priorityFeePercentile ?? "50"];
145
+ const key = percentileToKey[config.jito?.priorityFeePercentile ?? "50"];
129
146
  if (!key || !data[key]) {
130
147
  return BigInt(0);
131
148
  }
@@ -144,19 +161,127 @@ var jitoTipAddresses = [
144
161
  function getJitoTipAddress() {
145
162
  return address(jitoTipAddresses[Math.floor(Math.random() * jitoTipAddresses.length)]);
146
163
  }
164
+ async function sendJitoBundle(jitoApiUrl, transactions, jitoUUID) {
165
+ const encodedTransactions = transactions.map((tx) => getBase64EncodedWireTransaction(tx));
166
+ const url = new URL("/api/v1/bundles", jitoApiUrl);
167
+ if (jitoUUID && jitoUUID.length > 0) {
168
+ url.searchParams.set("uuid", jitoUUID);
169
+ }
170
+ const request = {
171
+ id: 1,
172
+ jsonrpc: "2.0",
173
+ method: "sendBundle",
174
+ params: [
175
+ encodedTransactions,
176
+ {
177
+ encoding: "base64"
178
+ }
179
+ ]
180
+ };
181
+ const response = await fetch(url, {
182
+ method: "POST",
183
+ headers: {
184
+ "Content-Type": "application/json"
185
+ },
186
+ body: JSON.stringify(request)
187
+ });
188
+ if (!response.ok) {
189
+ throw new Error(`Jito HTTP error: ${response.status}`);
190
+ }
191
+ const data = await response.json();
192
+ if (data.error) {
193
+ throw new Error(`Jito bundle failed: ${data.error.code} ${data.error.message}`);
194
+ }
195
+ if (!data.result) {
196
+ throw new Error("sendBundle did not return a bundle id");
197
+ }
198
+ const bundleId = data.result;
199
+ const expiryTime = Date.now() + JITO_BUNDLE_EXPIRY_TIME;
200
+ while (Date.now() < expiryTime) {
201
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
202
+ const request2 = {
203
+ jsonrpc: "2.0",
204
+ id: 1,
205
+ method: "getInflightBundleStatuses",
206
+ params: [[bundleId]]
207
+ };
208
+ const response2 = await fetch(url, {
209
+ method: "POST",
210
+ headers: {
211
+ "Content-Type": "application/json"
212
+ },
213
+ body: JSON.stringify(request2)
214
+ });
215
+ if (!response2.ok) {
216
+ throw new Error(`Jito HTTP error: ${response2.status}`);
217
+ }
218
+ const data2 = await response2.json();
219
+ const result = data2.result?.value?.[0];
220
+ if (!result) {
221
+ throw new Error(`getInflightBundleStatuses method returned undefined result`, { cause: { bundleId } });
222
+ }
223
+ switch (result.status) {
224
+ case "Landed":
225
+ return bundleId;
226
+ case "Pending":
227
+ case "Invalid":
228
+ continue;
229
+ case "Failed":
230
+ throw new Error(`Bundle failed`, { cause: { bundleId } });
231
+ default:
232
+ throw new Error(`Bundle status is unknown`, { cause: { bundleId } });
233
+ }
234
+ }
235
+ throw new Error(`Bundle expired`, { cause: { bundleId } });
236
+ }
237
+ async function simulateBundle(rpc, transactions) {
238
+ const encodedTransactions = transactions.map((tx) => getBase64EncodedWireTransaction(tx));
239
+ return rpc.simulateBundle({
240
+ encodedTransactions
241
+ }).send();
242
+ }
243
+ async function sendBundle(rpc, transactions) {
244
+ const encodedTransactions = transactions.map((tx) => getBase64EncodedWireTransaction(tx));
245
+ const bundleId = await rpc.sendBundle(encodedTransactions, {
246
+ encoding: "base64"
247
+ }).send();
248
+ if (!bundleId) throw new Error(`sendBundle method failed`);
249
+ const expiryTime = Date.now() + JITO_BUNDLE_EXPIRY_TIME;
250
+ while (Date.now() < expiryTime) {
251
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
252
+ const statuses = await rpc.getBundleStatuses([bundleId]).send();
253
+ const bundleStatus = statuses?.value?.[0];
254
+ if (!bundleStatus) continue;
255
+ if (bundleStatus.err && "Err" in bundleStatus.err) {
256
+ throw new Error(`Bundle failed`, { cause: { bundleId, error: bundleStatus.err.Err } });
257
+ } else {
258
+ const confirmation_status = bundleStatus.confirmation_status;
259
+ if (confirmation_status == "confirmed") {
260
+ return bundleId;
261
+ }
262
+ }
263
+ }
264
+ throw new Error(`Bundle expired`, { cause: { bundleId } });
265
+ }
147
266
 
148
267
  // src/buildTransaction.ts
149
- async function buildTransaction(rpc, config, instructions, feePayer, lookupTableAccounts) {
268
+ async function buildTransaction(rpc, instructions, feePayer, config, lookupTableAccounts) {
150
269
  return buildTransactionMessage(
151
270
  rpc,
152
- config,
153
271
  instructions,
154
272
  !("address" in feePayer) ? createNoopSigner(feePayer) : feePayer,
273
+ config,
155
274
  lookupTableAccounts
156
275
  );
157
276
  }
158
- async function buildTransactionMessage(rpc, config, instructions, signer, lookupTableAccounts) {
159
- let message = await prepareTransactionMessage(instructions, rpc, signer);
277
+ async function buildTransactionMessage(rpc, instructions, signer, config, lookupTableAccounts) {
278
+ let blockhash = config.blockhash;
279
+ if (!blockhash) {
280
+ blockhash = (await rpc.getLatestBlockhash({
281
+ commitment: "confirmed"
282
+ }).send()).value;
283
+ }
284
+ let message = await prepareTransactionMessage(instructions, signer, blockhash);
160
285
  if (lookupTableAccounts?.length) {
161
286
  const tables = lookupTableAccounts.reduce(
162
287
  (prev, account) => {
@@ -173,10 +298,7 @@ async function buildTransactionMessage(rpc, config, instructions, signer, lookup
173
298
  const messageWithExtraInstructions = await addPriorityInstructions(rpc, message, signer, config);
174
299
  return signTransactionMessageWithSigners(messageWithExtraInstructions);
175
300
  }
176
- async function prepareTransactionMessage(instructions, rpc, signer) {
177
- const { value: blockhash } = await rpc.getLatestBlockhash({
178
- commitment: "confirmed"
179
- }).send();
301
+ async function prepareTransactionMessage(instructions, signer, blockhash) {
180
302
  return pipe(
181
303
  createTransactionMessage({ version: 0 }),
182
304
  (tx) => setTransactionMessageLifetimeUsingBlockhash(blockhash, tx),
@@ -185,7 +307,7 @@ async function prepareTransactionMessage(instructions, rpc, signer) {
185
307
  );
186
308
  }
187
309
  async function addPriorityInstructions(rpc, message, signer, config) {
188
- if (config.jito.type !== "none") {
310
+ if (config.jito && config.jito.type !== "none") {
189
311
  message = await processJitoTipForTxMessage(message, signer, config);
190
312
  }
191
313
  let computeUnits = 14e5;
@@ -205,22 +327,16 @@ async function getComputeUnitsForTxMessage(rpc, txMessage) {
205
327
  // src/sendTransaction.ts
206
328
  import {
207
329
  getBase58Decoder,
208
- getBase64EncodedWireTransaction
330
+ getBase64EncodedWireTransaction as getBase64EncodedWireTransaction2
209
331
  } from "@solana/kit";
210
332
  async function sendTransaction(rpc, instructions, payer, config, lookupTableAccounts, commitment = "confirmed") {
211
- const tx = await buildTransaction(
212
- rpc,
213
- config ?? DEFAULT_TRANSACTION_CONFIG,
214
- instructions,
215
- payer,
216
- lookupTableAccounts
217
- );
218
- return sendSignedTransaction(rpc, tx, config ?? DEFAULT_TRANSACTION_CONFIG, commitment);
333
+ const tx = await buildTransaction(rpc, instructions, payer, config ?? {}, lookupTableAccounts);
334
+ return sendSignedTransaction(rpc, tx, config?.skipSimulation ?? false, commitment);
219
335
  }
220
- async function sendSignedTransaction(rpc, transaction, config, commitment = "confirmed") {
336
+ async function sendSignedTransaction(rpc, transaction, skipSimulation = false, commitment = "confirmed") {
221
337
  const txSignature = getTxSignature(transaction);
222
- const encodedTransaction = getBase64EncodedWireTransaction(transaction);
223
- if (!config.skipSimulation) {
338
+ const encodedTransaction = getBase64EncodedWireTransaction2(transaction);
339
+ if (!skipSimulation) {
224
340
  const simResult = await rpc.simulateTransaction(encodedTransaction, {
225
341
  encoding: "base64"
226
342
  }).send();
@@ -252,9 +368,16 @@ function getTxSignature(transaction) {
252
368
  }
253
369
  export {
254
370
  DEFAULT_COMPUTE_UNIT_MARGIN_MULTIPLIER,
255
- DEFAULT_TRANSACTION_CONFIG,
371
+ DEFAULT_JITO_BLOCK_ENGINE_URL,
372
+ JitoApiUrl,
256
373
  buildTransaction,
374
+ getTxSignature,
375
+ processJitoTipForTxMessage,
376
+ recentJitoTip,
377
+ sendBundle,
378
+ sendJitoBundle,
257
379
  sendSignedTransaction,
258
- sendTransaction
380
+ sendTransaction,
381
+ simulateBundle
259
382
  };
260
383
  //# sourceMappingURL=index.js.map