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

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,32 @@ 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 = Math.min(
28
+ 14e5,
29
+ Math.ceil(computeUnits * (computeUnitMarginMultiplier ?? DEFAULT_COMPUTE_UNIT_MARGIN_MULTIPLIER))
30
+ );
31
+ const priorityFee = config.priorityFee;
32
+ if (priorityFee) {
33
+ if (priorityFee.type === "exact") {
34
+ priorityFeeMicroLamports = priorityFee.amountLamports * 1000000n / BigInt(units);
35
+ } else if (priorityFee.type === "dynamic") {
36
+ const estimatedPriorityFee = await calculateDynamicPriorityFees(
37
+ rpc,
38
+ message.instructions,
39
+ priorityFee.priorityFeePercentile ?? "50"
40
+ );
41
+ if (!priorityFee.maxCapLamports) {
42
+ priorityFeeMicroLamports = estimatedPriorityFee;
43
+ } else {
44
+ const maxCapMicroLamports = priorityFee.maxCapLamports * 1000000n / BigInt(units);
45
+ priorityFeeMicroLamports = maxCapMicroLamports > estimatedPriorityFee ? estimatedPriorityFee : maxCapMicroLamports;
46
+ }
53
47
  }
54
48
  }
55
49
  if (priorityFeeMicroLamports > 0) {
@@ -62,7 +56,7 @@ async function processComputeBudgetForTxMessage(rpc, message, computeUnits, conf
62
56
  }
63
57
  message = prependTransactionMessageInstruction(
64
58
  getSetComputeUnitLimitInstruction({
65
- units: Math.ceil(computeUnits * (computeUnitMarginMultiplier ?? DEFAULT_COMPUTE_UNIT_MARGIN_MULTIPLIER))
59
+ units
66
60
  }),
67
61
  message
68
62
  );
@@ -88,18 +82,38 @@ async function calculateDynamicPriorityFees(rpc, instructions, percentile) {
88
82
  }
89
83
 
90
84
  // src/jito.ts
91
- import { address, lamports, prependTransactionMessageInstruction as prependTransactionMessageInstruction2 } from "@solana/kit";
85
+ import {
86
+ appendTransactionMessageInstruction,
87
+ getBase64EncodedWireTransaction
88
+ } from "@solana/kit";
89
+ import { address, lamports } from "@solana/kit";
92
90
  import { getTransferSolInstruction } from "@solana-program/system";
91
+ var JITO_BUNDLE_EXPIRY_TIME = 3e4;
92
+ var JitoApiUrl = /* @__PURE__ */ ((JitoApiUrl2) => {
93
+ JitoApiUrl2["Amsterdam"] = "https://amsterdam.mainnet.block-engine.jito.wtf";
94
+ JitoApiUrl2["Frankfurt"] = "https://frankfurt.mainnet.block-engine.jito.wtf";
95
+ JitoApiUrl2["London"] = "https://london.mainnet.block-engine.jito.wtf";
96
+ JitoApiUrl2["NY"] = "https://ny.mainnet.block-engine.jito.wtf";
97
+ JitoApiUrl2["Singapore"] = "https://singapore.mainnet.block-engine.jito.wtf";
98
+ JitoApiUrl2["SLC"] = "https://slc.mainnet.block-engine.jito.wtf";
99
+ JitoApiUrl2["Tokyo"] = "https://tokyo.mainnet.block-engine.jito.wtf";
100
+ JitoApiUrl2["Default"] = "https://mainnet.block-engine.jito.wtf";
101
+ return JitoApiUrl2;
102
+ })(JitoApiUrl || {});
93
103
  async function processJitoTipForTxMessage(message, signer, config) {
94
- let jitoTipLamports = BigInt(0);
95
104
  const jito = config.jito;
105
+ if (!jito) throw new Error("jito config is undefined");
106
+ let jitoTipLamports = BigInt(0);
96
107
  if (jito.type === "exact") {
97
108
  jitoTipLamports = jito.amountLamports;
98
109
  } else if (jito.type === "dynamic") {
99
110
  jitoTipLamports = await recentJitoTip(config);
111
+ if (jito.maxCapLamports && jitoTipLamports > jito.maxCapLamports) {
112
+ jitoTipLamports = jito.maxCapLamports;
113
+ }
100
114
  }
101
115
  if (jitoTipLamports > 0) {
102
- return prependTransactionMessageInstruction2(
116
+ return appendTransactionMessageInstruction(
103
117
  getTransferSolInstruction({
104
118
  source: signer,
105
119
  destination: getJitoTipAddress(),
@@ -112,7 +126,8 @@ async function processJitoTipForTxMessage(message, signer, config) {
112
126
  }
113
127
  }
114
128
  async function recentJitoTip(config) {
115
- const response = await fetch(`${config.jitoBlockEngineUrl}/api/v1/bundles/tip_floor`);
129
+ const baseUrl = config.jitoBlockEngineUrl ?? DEFAULT_JITO_BLOCK_ENGINE_URL;
130
+ const response = await fetch(`${baseUrl}/api/v1/bundles/tip_floor`);
116
131
  if (!response.ok) {
117
132
  return BigInt(0);
118
133
  }
@@ -125,7 +140,7 @@ async function recentJitoTip(config) {
125
140
  "99": "landed_tips_99th_percentile",
126
141
  "50ema": "ema_landed_tips_50th_percentile"
127
142
  };
128
- const key = percentileToKey[config.priorityFee.priorityFeePercentile ?? "50"];
143
+ const key = percentileToKey[config.jito?.priorityFeePercentile ?? "50"];
129
144
  if (!key || !data[key]) {
130
145
  return BigInt(0);
131
146
  }
@@ -144,19 +159,127 @@ var jitoTipAddresses = [
144
159
  function getJitoTipAddress() {
145
160
  return address(jitoTipAddresses[Math.floor(Math.random() * jitoTipAddresses.length)]);
146
161
  }
162
+ async function sendJitoBundle(jitoApiUrl, transactions, jitoUUID) {
163
+ const encodedTransactions = transactions.map((tx) => getBase64EncodedWireTransaction(tx));
164
+ const url = new URL("/api/v1/bundles", jitoApiUrl);
165
+ if (jitoUUID && jitoUUID.length > 0) {
166
+ url.searchParams.set("uuid", jitoUUID);
167
+ }
168
+ const request = {
169
+ id: 1,
170
+ jsonrpc: "2.0",
171
+ method: "sendBundle",
172
+ params: [
173
+ encodedTransactions,
174
+ {
175
+ encoding: "base64"
176
+ }
177
+ ]
178
+ };
179
+ const response = await fetch(url, {
180
+ method: "POST",
181
+ headers: {
182
+ "Content-Type": "application/json"
183
+ },
184
+ body: JSON.stringify(request)
185
+ });
186
+ if (!response.ok) {
187
+ throw new Error(`Jito HTTP error: ${response.status}`);
188
+ }
189
+ const data = await response.json();
190
+ if (data.error) {
191
+ throw new Error(`Jito bundle failed: ${data.error.code} ${data.error.message}`);
192
+ }
193
+ if (!data.result) {
194
+ throw new Error("sendBundle did not return a bundle id");
195
+ }
196
+ const bundleId = data.result;
197
+ const expiryTime = Date.now() + JITO_BUNDLE_EXPIRY_TIME;
198
+ while (Date.now() < expiryTime) {
199
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
200
+ const request2 = {
201
+ jsonrpc: "2.0",
202
+ id: 1,
203
+ method: "getInflightBundleStatuses",
204
+ params: [[bundleId]]
205
+ };
206
+ const response2 = await fetch(url, {
207
+ method: "POST",
208
+ headers: {
209
+ "Content-Type": "application/json"
210
+ },
211
+ body: JSON.stringify(request2)
212
+ });
213
+ if (!response2.ok) {
214
+ throw new Error(`Jito HTTP error: ${response2.status}`);
215
+ }
216
+ const data2 = await response2.json();
217
+ const result = data2.result?.value?.[0];
218
+ if (!result) {
219
+ throw new Error(`getInflightBundleStatuses method returned undefined result`, { cause: { bundleId } });
220
+ }
221
+ switch (result.status) {
222
+ case "Landed":
223
+ return bundleId;
224
+ case "Pending":
225
+ case "Invalid":
226
+ continue;
227
+ case "Failed":
228
+ throw new Error(`Bundle failed`, { cause: { bundleId } });
229
+ default:
230
+ throw new Error(`Bundle status is unknown`, { cause: { bundleId } });
231
+ }
232
+ }
233
+ throw new Error(`Bundle expired`, { cause: { bundleId } });
234
+ }
235
+ async function simulateBundle(rpc, transactions) {
236
+ const encodedTransactions = transactions.map((tx) => getBase64EncodedWireTransaction(tx));
237
+ return rpc.simulateBundle({
238
+ encodedTransactions
239
+ }).send();
240
+ }
241
+ async function sendBundle(rpc, transactions) {
242
+ const encodedTransactions = transactions.map((tx) => getBase64EncodedWireTransaction(tx));
243
+ const bundleId = await rpc.sendBundle(encodedTransactions, {
244
+ encoding: "base64"
245
+ }).send();
246
+ if (!bundleId) throw new Error(`sendBundle method failed`);
247
+ const expiryTime = Date.now() + JITO_BUNDLE_EXPIRY_TIME;
248
+ while (Date.now() < expiryTime) {
249
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
250
+ const statuses = await rpc.getBundleStatuses([bundleId]).send();
251
+ const bundleStatus = statuses?.value?.[0];
252
+ if (!bundleStatus) continue;
253
+ if (bundleStatus.err && "Err" in bundleStatus.err) {
254
+ throw new Error(`Bundle failed`, { cause: { bundleId, error: bundleStatus.err.Err } });
255
+ } else {
256
+ const confirmation_status = bundleStatus.confirmation_status;
257
+ if (confirmation_status == "confirmed") {
258
+ return bundleId;
259
+ }
260
+ }
261
+ }
262
+ throw new Error(`Bundle expired`, { cause: { bundleId } });
263
+ }
147
264
 
148
265
  // src/buildTransaction.ts
149
- async function buildTransaction(rpc, config, instructions, feePayer, lookupTableAccounts) {
266
+ async function buildTransaction(rpc, instructions, feePayer, config, lookupTableAccounts) {
150
267
  return buildTransactionMessage(
151
268
  rpc,
152
- config,
153
269
  instructions,
154
270
  !("address" in feePayer) ? createNoopSigner(feePayer) : feePayer,
271
+ config,
155
272
  lookupTableAccounts
156
273
  );
157
274
  }
158
- async function buildTransactionMessage(rpc, config, instructions, signer, lookupTableAccounts) {
159
- let message = await prepareTransactionMessage(instructions, rpc, signer);
275
+ async function buildTransactionMessage(rpc, instructions, signer, config, lookupTableAccounts) {
276
+ let blockhash = config.blockhash;
277
+ if (!blockhash) {
278
+ blockhash = (await rpc.getLatestBlockhash({
279
+ commitment: "confirmed"
280
+ }).send()).value;
281
+ }
282
+ let message = await prepareTransactionMessage(instructions, signer, blockhash);
160
283
  if (lookupTableAccounts?.length) {
161
284
  const tables = lookupTableAccounts.reduce(
162
285
  (prev, account) => {
@@ -173,10 +296,7 @@ async function buildTransactionMessage(rpc, config, instructions, signer, lookup
173
296
  const messageWithExtraInstructions = await addPriorityInstructions(rpc, message, signer, config);
174
297
  return signTransactionMessageWithSigners(messageWithExtraInstructions);
175
298
  }
176
- async function prepareTransactionMessage(instructions, rpc, signer) {
177
- const { value: blockhash } = await rpc.getLatestBlockhash({
178
- commitment: "confirmed"
179
- }).send();
299
+ async function prepareTransactionMessage(instructions, signer, blockhash) {
180
300
  return pipe(
181
301
  createTransactionMessage({ version: 0 }),
182
302
  (tx) => setTransactionMessageLifetimeUsingBlockhash(blockhash, tx),
@@ -185,7 +305,7 @@ async function prepareTransactionMessage(instructions, rpc, signer) {
185
305
  );
186
306
  }
187
307
  async function addPriorityInstructions(rpc, message, signer, config) {
188
- if (config.jito.type !== "none") {
308
+ if (config.jito && config.jito.type !== "none") {
189
309
  message = await processJitoTipForTxMessage(message, signer, config);
190
310
  }
191
311
  let computeUnits = 14e5;
@@ -205,22 +325,16 @@ async function getComputeUnitsForTxMessage(rpc, txMessage) {
205
325
  // src/sendTransaction.ts
206
326
  import {
207
327
  getBase58Decoder,
208
- getBase64EncodedWireTransaction
328
+ getBase64EncodedWireTransaction as getBase64EncodedWireTransaction2
209
329
  } from "@solana/kit";
210
330
  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);
331
+ const tx = await buildTransaction(rpc, instructions, payer, config ?? {}, lookupTableAccounts);
332
+ return sendSignedTransaction(rpc, tx, config?.skipSimulation ?? false, commitment);
219
333
  }
220
- async function sendSignedTransaction(rpc, transaction, config, commitment = "confirmed") {
334
+ async function sendSignedTransaction(rpc, transaction, skipSimulation = false, commitment = "confirmed") {
221
335
  const txSignature = getTxSignature(transaction);
222
- const encodedTransaction = getBase64EncodedWireTransaction(transaction);
223
- if (!config.skipSimulation) {
336
+ const encodedTransaction = getBase64EncodedWireTransaction2(transaction);
337
+ if (!skipSimulation) {
224
338
  const simResult = await rpc.simulateTransaction(encodedTransaction, {
225
339
  encoding: "base64"
226
340
  }).send();
@@ -252,9 +366,16 @@ function getTxSignature(transaction) {
252
366
  }
253
367
  export {
254
368
  DEFAULT_COMPUTE_UNIT_MARGIN_MULTIPLIER,
255
- DEFAULT_TRANSACTION_CONFIG,
369
+ DEFAULT_JITO_BLOCK_ENGINE_URL,
370
+ JitoApiUrl,
256
371
  buildTransaction,
372
+ getTxSignature,
373
+ processJitoTipForTxMessage,
374
+ recentJitoTip,
375
+ sendBundle,
376
+ sendJitoBundle,
257
377
  sendSignedTransaction,
258
- sendTransaction
378
+ sendTransaction,
379
+ simulateBundle
259
380
  };
260
381
  //# sourceMappingURL=index.js.map