sol-trade-sdk 0.1.0

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.
Files changed (87) hide show
  1. package/README.md +390 -0
  2. package/dist/chunk-MMQAMIKR.mjs +3735 -0
  3. package/dist/chunk-NEZDFAYA.mjs +7744 -0
  4. package/dist/clients-VITWK7B6.mjs +1370 -0
  5. package/dist/index-1BK_FXsW.d.mts +2327 -0
  6. package/dist/index-1BK_FXsW.d.ts +2327 -0
  7. package/dist/index.d.mts +2659 -0
  8. package/dist/index.d.ts +2659 -0
  9. package/dist/index.js +13265 -0
  10. package/dist/index.mjs +562 -0
  11. package/dist/perf/index.d.mts +2 -0
  12. package/dist/perf/index.d.ts +2 -0
  13. package/dist/perf/index.js +3742 -0
  14. package/dist/perf/index.mjs +214 -0
  15. package/package.json +101 -0
  16. package/src/__tests__/complete_sdk.test.ts +354 -0
  17. package/src/__tests__/hotpath.test.ts +486 -0
  18. package/src/__tests__/nonce.test.ts +45 -0
  19. package/src/__tests__/sdk.test.ts +425 -0
  20. package/src/address-lookup/index.ts +197 -0
  21. package/src/cache/cache.ts +308 -0
  22. package/src/calc/index.ts +1058 -0
  23. package/src/calc/pumpfun.ts +124 -0
  24. package/src/common/bonding_curve.ts +272 -0
  25. package/src/common/compute-budget.ts +148 -0
  26. package/src/common/confirm-any-signature.ts +184 -0
  27. package/src/common/fast-timing.ts +481 -0
  28. package/src/common/fast_fn.ts +150 -0
  29. package/src/common/gas-fee-strategy.ts +253 -0
  30. package/src/common/map-pool.ts +23 -0
  31. package/src/common/nonce.ts +40 -0
  32. package/src/common/sdk-log.ts +460 -0
  33. package/src/common/seed.ts +381 -0
  34. package/src/common/spl-token.ts +578 -0
  35. package/src/common/subscription-handle.ts +644 -0
  36. package/src/common/trading-utils.ts +239 -0
  37. package/src/common/wsol-manager.ts +325 -0
  38. package/src/compute/compute_budget_manager.ts +187 -0
  39. package/src/compute/index.ts +21 -0
  40. package/src/constants/index.ts +96 -0
  41. package/src/execution/execution.ts +532 -0
  42. package/src/execution/index.ts +42 -0
  43. package/src/hotpath/executor.ts +464 -0
  44. package/src/hotpath/index.ts +64 -0
  45. package/src/hotpath/state.ts +435 -0
  46. package/src/index.ts +2117 -0
  47. package/src/instruction/bonk_builder.ts +730 -0
  48. package/src/instruction/index.ts +24 -0
  49. package/src/instruction/meteora_damm_v2_builder.ts +509 -0
  50. package/src/instruction/pumpfun_builder.ts +1183 -0
  51. package/src/instruction/pumpswap.ts +1123 -0
  52. package/src/instruction/raydium_amm_v4_builder.ts +692 -0
  53. package/src/instruction/raydium_cpmm_builder.ts +795 -0
  54. package/src/middleware/traits.ts +407 -0
  55. package/src/params/index.ts +483 -0
  56. package/src/perf/compiler-optimization.ts +529 -0
  57. package/src/perf/hardware.ts +631 -0
  58. package/src/perf/index.ts +9 -0
  59. package/src/perf/kernel-bypass.ts +656 -0
  60. package/src/perf/protocol.ts +682 -0
  61. package/src/perf/realtime.ts +592 -0
  62. package/src/perf/simd.ts +668 -0
  63. package/src/perf/syscall-bypass.ts +331 -0
  64. package/src/perf/ultra-low-latency.ts +505 -0
  65. package/src/perf/zero-copy.ts +589 -0
  66. package/src/pool/pool.ts +294 -0
  67. package/src/rpc/client.ts +345 -0
  68. package/src/sdk-errors.ts +13 -0
  69. package/src/security/index.ts +26 -0
  70. package/src/security/secure-key.ts +303 -0
  71. package/src/security/validators.ts +281 -0
  72. package/src/seed/pda.ts +262 -0
  73. package/src/serialization/index.ts +28 -0
  74. package/src/serialization/serialization.ts +288 -0
  75. package/src/swqos/clients.ts +1754 -0
  76. package/src/swqos/index.ts +50 -0
  77. package/src/swqos/providers.ts +1707 -0
  78. package/src/trading/core/async-executor.ts +702 -0
  79. package/src/trading/core/confirmation-monitor.ts +711 -0
  80. package/src/trading/core/index.ts +82 -0
  81. package/src/trading/core/retry-handler.ts +683 -0
  82. package/src/trading/core/transaction-pool.ts +780 -0
  83. package/src/trading/executor.ts +385 -0
  84. package/src/trading/factory.ts +282 -0
  85. package/src/trading/index.ts +30 -0
  86. package/src/types.ts +8 -0
  87. package/src/utils/index.ts +155 -0
@@ -0,0 +1,124 @@
1
+ /**
2
+ * PumpFun bonding curve calculations.
3
+ * Based on sol-trade-sdk Rust implementation.
4
+ */
5
+
6
+ // Constants from Rust
7
+ export const FEE_BASIS_POINTS = 100; // 1%
8
+ export const CREATOR_FEE = 50; // 0.5%
9
+ export const INITIAL_VIRTUAL_TOKEN_RESERVES = 1_073_000_000_000_000;
10
+ export const INITIAL_VIRTUAL_SOL_RESERVES = 30_000_000_000; // 30 SOL
11
+ export const INITIAL_REAL_TOKEN_RESERVES = 793_100_000_000_000;
12
+ export const TOKEN_TOTAL_SUPPLY = 1_000_000_000_000_000;
13
+ export const LAMPORTS_PER_SOL = 1_000_000_000;
14
+
15
+ /**
16
+ * Compute fee for a given amount
17
+ */
18
+ export function computeFee(amount: number, feeBasisPoints: number): number {
19
+ return Math.floor((amount * feeBasisPoints) / 10_000);
20
+ }
21
+
22
+ /**
23
+ * Calculate token amount received for given SOL amount using bonding curve formula
24
+ */
25
+ export function getBuyTokenAmountFromSolAmount(
26
+ virtualTokenReserves: number,
27
+ virtualSolReserves: number,
28
+ realTokenReserves: number,
29
+ creator: Uint8Array,
30
+ amount: number,
31
+ ): number {
32
+ if (amount === 0) {
33
+ return 0;
34
+ }
35
+
36
+ if (virtualTokenReserves === 0) {
37
+ return 0;
38
+ }
39
+
40
+ // Calculate total fee
41
+ const hasCreator = creator.some(b => b !== 0);
42
+ const totalFeeBasisPoints = FEE_BASIS_POINTS + (hasCreator ? CREATOR_FEE : 0);
43
+
44
+ // Calculate input amount after fees
45
+ const inputAmount = Math.floor((amount * 10_000) / (totalFeeBasisPoints + 10_000));
46
+
47
+ const denominator = virtualSolReserves + inputAmount;
48
+
49
+ let tokensReceived = Math.floor((inputAmount * virtualTokenReserves) / denominator);
50
+
51
+ // Cap at real reserves
52
+ tokensReceived = Math.min(tokensReceived, realTokenReserves);
53
+
54
+ // Special handling for small amounts
55
+ if (tokensReceived <= 100 * 1_000_000) {
56
+ if (amount > 0.01 * LAMPORTS_PER_SOL) {
57
+ tokensReceived = 25547619 * 1_000_000;
58
+ } else {
59
+ tokensReceived = 255476 * 1_000_000;
60
+ }
61
+ }
62
+
63
+ return tokensReceived;
64
+ }
65
+
66
+ /**
67
+ * Calculate SOL amount received for given token amount
68
+ */
69
+ export function getSellSolAmountFromTokenAmount(
70
+ virtualTokenReserves: number,
71
+ virtualSolReserves: number,
72
+ creator: Uint8Array,
73
+ amount: number,
74
+ ): number {
75
+ if (amount === 0) {
76
+ return 0;
77
+ }
78
+
79
+ if (virtualTokenReserves === 0) {
80
+ return 0;
81
+ }
82
+
83
+ // Calculate SOL received
84
+ const numerator = amount * virtualSolReserves;
85
+ const denominator = virtualTokenReserves + amount;
86
+
87
+ const solCost = Math.floor(numerator / denominator);
88
+
89
+ // Calculate fee
90
+ const hasCreator = creator.some(b => b !== 0);
91
+ const totalFeeBasisPoints = FEE_BASIS_POINTS + (hasCreator ? CREATOR_FEE : 0);
92
+
93
+ const fee = computeFee(solCost, totalFeeBasisPoints);
94
+
95
+ return Math.max(0, solCost - fee);
96
+ }
97
+
98
+ /**
99
+ * Calculate max SOL cost with slippage for buy
100
+ */
101
+ export function calculateWithSlippageBuy(amount: number, slippageBasisPoints: number): number {
102
+ return amount + Math.floor((amount * slippageBasisPoints) / 10_000);
103
+ }
104
+
105
+ /**
106
+ * Calculate min tokens out with slippage for sell
107
+ */
108
+ export function calculateWithSlippageSell(amount: number, slippageBasisPoints: number): number {
109
+ return amount - Math.floor((amount * slippageBasisPoints) / 10_000);
110
+ }
111
+
112
+ /**
113
+ * Convert lamports to SOL
114
+ */
115
+ export function lamportsToSol(lamports: number): number {
116
+ return lamports / LAMPORTS_PER_SOL;
117
+ }
118
+
119
+ /**
120
+ * Convert SOL to lamports
121
+ */
122
+ export function solToLamports(sol: number): number {
123
+ return Math.floor(sol * LAMPORTS_PER_SOL);
124
+ }
@@ -0,0 +1,272 @@
1
+ /**
2
+ * Bonding curve account for Pump.fun.
3
+ * Based on sol-trade-sdk Rust implementation.
4
+ */
5
+
6
+ import { PublicKey } from '@solana/web3.js';
7
+ import {
8
+ getBuyTokenAmountFromSolAmount,
9
+ getSellSolAmountFromTokenAmount,
10
+ INITIAL_VIRTUAL_TOKEN_RESERVES,
11
+ INITIAL_VIRTUAL_SOL_RESERVES,
12
+ INITIAL_REAL_TOKEN_RESERVES,
13
+ TOKEN_TOTAL_SUPPLY,
14
+ } from '../calc/pumpfun';
15
+
16
+ /**
17
+ * Represents the bonding curve account for token pricing
18
+ */
19
+ export class BondingCurveAccount {
20
+ discriminator: number = 0;
21
+ account: PublicKey = PublicKey.default;
22
+ virtualTokenReserves: number = 0;
23
+ virtualSolReserves: number = 0;
24
+ realTokenReserves: number = 0;
25
+ realSolReserves: number = 0;
26
+ tokenTotalSupply: number = TOKEN_TOTAL_SUPPLY;
27
+ complete: boolean = false;
28
+ creator: PublicKey = PublicKey.default;
29
+ isMayhemMode: boolean = false;
30
+ isCashbackCoin: boolean = false;
31
+
32
+ constructor(fields?: Partial<BondingCurveAccount>) {
33
+ if (fields) {
34
+ Object.assign(this, fields);
35
+ }
36
+ }
37
+
38
+ /**
39
+ * Create from dev trade data
40
+ */
41
+ static fromDevTrade(
42
+ bondingCurve: PublicKey,
43
+ mint: PublicKey,
44
+ devTokenAmount: number,
45
+ devSolAmount: number,
46
+ creator: PublicKey,
47
+ isMayhemMode: boolean = false,
48
+ isCashbackCoin: boolean = false,
49
+ ): BondingCurveAccount {
50
+ return new BondingCurveAccount({
51
+ discriminator: 0,
52
+ account: bondingCurve,
53
+ virtualTokenReserves: INITIAL_VIRTUAL_TOKEN_RESERVES - devTokenAmount,
54
+ virtualSolReserves: INITIAL_VIRTUAL_SOL_RESERVES + devSolAmount,
55
+ realTokenReserves: INITIAL_REAL_TOKEN_RESERVES - devTokenAmount,
56
+ realSolReserves: devSolAmount,
57
+ tokenTotalSupply: TOKEN_TOTAL_SUPPLY,
58
+ complete: false,
59
+ creator,
60
+ isMayhemMode,
61
+ isCashbackCoin,
62
+ });
63
+ }
64
+
65
+ /**
66
+ * Create from trade data
67
+ */
68
+ static fromTrade(
69
+ bondingCurve: PublicKey,
70
+ mint: PublicKey,
71
+ creator: PublicKey,
72
+ virtualTokenReserves: number,
73
+ virtualSolReserves: number,
74
+ realTokenReserves: number,
75
+ realSolReserves: number,
76
+ isMayhemMode: boolean = false,
77
+ isCashbackCoin: boolean = false,
78
+ ): BondingCurveAccount {
79
+ return new BondingCurveAccount({
80
+ discriminator: 0,
81
+ account: bondingCurve,
82
+ virtualTokenReserves,
83
+ virtualSolReserves,
84
+ realTokenReserves,
85
+ realSolReserves,
86
+ tokenTotalSupply: TOKEN_TOTAL_SUPPLY,
87
+ complete: false,
88
+ creator,
89
+ isMayhemMode,
90
+ isCashbackCoin,
91
+ });
92
+ }
93
+
94
+ /**
95
+ * Calculate tokens received for given SOL amount
96
+ */
97
+ getBuyPrice(amount: number): number {
98
+ if (this.complete) {
99
+ throw new Error('Curve is complete');
100
+ }
101
+
102
+ return getBuyTokenAmountFromSolAmount(
103
+ this.virtualTokenReserves,
104
+ this.virtualSolReserves,
105
+ this.realTokenReserves,
106
+ this.creator.toBytes(),
107
+ amount,
108
+ );
109
+ }
110
+
111
+ /**
112
+ * Calculate SOL received for given token amount
113
+ */
114
+ getSellPrice(amount: number): number {
115
+ if (this.complete) {
116
+ throw new Error('Curve is complete');
117
+ }
118
+
119
+ return getSellSolAmountFromTokenAmount(
120
+ this.virtualTokenReserves,
121
+ this.virtualSolReserves,
122
+ this.creator.toBytes(),
123
+ amount,
124
+ );
125
+ }
126
+
127
+ /**
128
+ * Calculate current market cap in SOL
129
+ */
130
+ getMarketCapSol(): number {
131
+ if (this.virtualTokenReserves === 0) {
132
+ return 0;
133
+ }
134
+
135
+ const pricePerToken = this.virtualSolReserves / this.virtualTokenReserves;
136
+ return (pricePerToken * this.tokenTotalSupply) / 1e9;
137
+ }
138
+
139
+ /**
140
+ * Calculate price to buy out all remaining tokens
141
+ */
142
+ getBuyOutPrice(amount: number): number {
143
+ if (this.complete) {
144
+ throw new Error('Curve is complete');
145
+ }
146
+
147
+ // Rough estimate: current price * amount
148
+ if (this.virtualTokenReserves === 0) {
149
+ return 0;
150
+ }
151
+
152
+ const priceRatio = this.virtualSolReserves / this.virtualTokenReserves;
153
+ return Math.floor(priceRatio * amount);
154
+ }
155
+
156
+ /**
157
+ * Calculate the current token price in SOL.
158
+ * 100% from Rust: src/common/bonding_curve.rs get_token_price
159
+ */
160
+ getTokenPrice(): number {
161
+ const vSol = this.virtualSolReserves / 100_000_000.0;
162
+ const vTokens = this.virtualTokenReserves / 100_000.0;
163
+ if (vTokens === 0) {
164
+ return 0.0;
165
+ }
166
+ return vSol / vTokens;
167
+ }
168
+
169
+ /**
170
+ * Calculate the final market cap in SOL after all tokens are sold.
171
+ * 100% from Rust: src/common/bonding_curve.rs get_final_market_cap_sol
172
+ */
173
+ getFinalMarketCapSol(feeBasisPoints: number = 95): bigint {
174
+ const totalSellValue = this.getBuyOutPriceInternal(this.realTokenReserves, feeBasisPoints);
175
+ const totalVirtualValue = BigInt(this.virtualSolReserves) + BigInt(totalSellValue);
176
+ const totalVirtualTokens = BigInt(this.virtualTokenReserves) - BigInt(this.realTokenReserves);
177
+
178
+ if (totalVirtualTokens === 0n) {
179
+ return 0n;
180
+ }
181
+
182
+ return (BigInt(this.tokenTotalSupply) * totalVirtualValue) / totalVirtualTokens;
183
+ }
184
+
185
+ private getBuyOutPriceInternal(amount: number, feeBasisPoints: number): number {
186
+ const solTokens = Math.max(amount, this.realSolReserves);
187
+
188
+ if (this.virtualTokenReserves <= solTokens) {
189
+ return 0;
190
+ }
191
+
192
+ const totalSellValue = Number((BigInt(solTokens) * BigInt(this.virtualSolReserves)) / (BigInt(this.virtualTokenReserves) - BigInt(solTokens))) + 1;
193
+ const fee = Math.floor((totalSellValue * feeBasisPoints) / 10000);
194
+
195
+ return totalSellValue + fee;
196
+ }
197
+ }
198
+
199
+ // ===== Decoding Functions - from Rust: src/instruction/utils/pumpfun.rs =====
200
+
201
+ export const BONDING_CURVE_ACCOUNT_SIZE = 8 + 8 + 8 + 8 + 8 + 8 + 1 + 32 + 1 + 1; // 77 bytes after discriminator
202
+
203
+ /**
204
+ * Decode a BondingCurveAccount from on-chain account data.
205
+ * 100% from Rust: src/common/bonding_curve.rs
206
+ */
207
+ export function decodeBondingCurveAccount(data: Buffer, account?: PublicKey): BondingCurveAccount | null {
208
+ if (data.length < BONDING_CURVE_ACCOUNT_SIZE) {
209
+ return null;
210
+ }
211
+
212
+ try {
213
+ let offset = 0;
214
+
215
+ // Check if data starts with discriminator (8 bytes)
216
+ if (data.length >= 8 + BONDING_CURVE_ACCOUNT_SIZE) {
217
+ // Skip discriminator
218
+ offset = 8;
219
+ }
220
+
221
+ // virtual_token_reserves: u64
222
+ const virtualTokenReserves = Number(data.readBigUInt64LE(offset));
223
+ offset += 8;
224
+
225
+ // virtual_sol_reserves: u64
226
+ const virtualSolReserves = Number(data.readBigUInt64LE(offset));
227
+ offset += 8;
228
+
229
+ // real_token_reserves: u64
230
+ const realTokenReserves = Number(data.readBigUInt64LE(offset));
231
+ offset += 8;
232
+
233
+ // real_sol_reserves: u64
234
+ const realSolReserves = Number(data.readBigUInt64LE(offset));
235
+ offset += 8;
236
+
237
+ // token_total_supply: u64
238
+ const tokenTotalSupply = Number(data.readBigUInt64LE(offset));
239
+ offset += 8;
240
+
241
+ // complete: bool
242
+ const complete = data.readUInt8(offset) === 1;
243
+ offset += 1;
244
+
245
+ // creator: Pubkey (32 bytes)
246
+ const creator = new PublicKey(data.subarray(offset, offset + 32));
247
+ offset += 32;
248
+
249
+ // is_mayhem_mode: bool
250
+ const isMayhemMode = data.readUInt8(offset) === 1;
251
+ offset += 1;
252
+
253
+ // is_cashback_coin: bool
254
+ const isCashbackCoin = data.readUInt8(offset) === 1;
255
+
256
+ return new BondingCurveAccount({
257
+ discriminator: 0,
258
+ account: account ?? PublicKey.default,
259
+ virtualTokenReserves,
260
+ virtualSolReserves,
261
+ realTokenReserves,
262
+ realSolReserves,
263
+ tokenTotalSupply,
264
+ complete,
265
+ creator,
266
+ isMayhemMode,
267
+ isCashbackCoin,
268
+ });
269
+ } catch {
270
+ return null;
271
+ }
272
+ }
@@ -0,0 +1,148 @@
1
+ /**
2
+ * Compute Budget Manager - 100% port from Rust: src/trading/common/compute_budget_manager.rs
3
+ *
4
+ * Provides utilities for managing compute budget instructions:
5
+ * - Setting compute unit price
6
+ * - Setting compute unit limit
7
+ * - Caching for performance
8
+ */
9
+
10
+ import { TransactionInstruction, PublicKey } from '@solana/web3.js';
11
+
12
+ // ===== Constants =====
13
+
14
+ const COMPUTE_BUDGET_PROGRAM_ID = new PublicKey('ComputeBudget111111111111111111111111111111');
15
+
16
+ // Instruction types for Compute Budget program
17
+ const COMPUTE_BUDGET_INSTRUCTIONS = {
18
+ REQUEST_UNITS: 0,
19
+ REQUEST_HEAP_FRAME: 1,
20
+ SET_COMPUTE_UNIT_LIMIT: 2,
21
+ SET_COMPUTE_UNIT_PRICE: 3,
22
+ } as const;
23
+
24
+ // ===== Cache =====
25
+
26
+ interface ComputeBudgetCacheKey {
27
+ unitPrice: bigint;
28
+ unitLimit: number;
29
+ }
30
+
31
+ const computeBudgetCache = new Map<string, TransactionInstruction[]>();
32
+
33
+ function getCacheKey(key: ComputeBudgetCacheKey): string {
34
+ return `${key.unitPrice}:${key.unitLimit}`;
35
+ }
36
+
37
+ // ===== Instruction Builders =====
38
+
39
+ /**
40
+ * Create Set Compute Unit Price instruction
41
+ */
42
+ function setComputeUnitPrice(price: bigint): TransactionInstruction {
43
+ const data = Buffer.alloc(9);
44
+ data.writeUInt8(COMPUTE_BUDGET_INSTRUCTIONS.SET_COMPUTE_UNIT_PRICE, 0);
45
+ data.writeBigUInt64LE(price, 1);
46
+
47
+ return new TransactionInstruction({
48
+ keys: [],
49
+ programId: COMPUTE_BUDGET_PROGRAM_ID,
50
+ data,
51
+ });
52
+ }
53
+
54
+ /**
55
+ * Create Set Compute Unit Limit instruction
56
+ */
57
+ function setComputeUnitLimit(limit: number): TransactionInstruction {
58
+ const data = Buffer.alloc(5);
59
+ data.writeUInt8(COMPUTE_BUDGET_INSTRUCTIONS.SET_COMPUTE_UNIT_LIMIT, 0);
60
+ data.writeUInt32LE(limit, 1);
61
+
62
+ return new TransactionInstruction({
63
+ keys: [],
64
+ programId: COMPUTE_BUDGET_PROGRAM_ID,
65
+ data,
66
+ });
67
+ }
68
+
69
+ // ===== Public Functions =====
70
+
71
+ /**
72
+ * Extend instructions array with compute budget instructions
73
+ * Uses caching for performance
74
+ * 100% from Rust: src/trading/common/compute_budget_manager.rs extend_compute_budget_instructions
75
+ */
76
+ export function extendComputeBudgetInstructions(
77
+ instructions: TransactionInstruction[],
78
+ unitPrice: bigint,
79
+ unitLimit: number
80
+ ): void {
81
+ const cacheKey: ComputeBudgetCacheKey = { unitPrice, unitLimit };
82
+ const key = getCacheKey(cacheKey);
83
+
84
+ let cachedInstructions = computeBudgetCache.get(key);
85
+
86
+ if (!cachedInstructions) {
87
+ cachedInstructions = [];
88
+
89
+ if (unitPrice > BigInt(0)) {
90
+ cachedInstructions.push(setComputeUnitPrice(unitPrice));
91
+ }
92
+
93
+ if (unitLimit > 0) {
94
+ cachedInstructions.push(setComputeUnitLimit(unitLimit));
95
+ }
96
+
97
+ computeBudgetCache.set(key, cachedInstructions);
98
+ }
99
+
100
+ instructions.push(...cachedInstructions);
101
+ }
102
+
103
+ /**
104
+ * Get compute budget instructions as array
105
+ * 100% from Rust: src/trading/common/compute_budget_manager.rs compute_budget_instructions
106
+ */
107
+ export function computeBudgetInstructions(
108
+ unitPrice: bigint,
109
+ unitLimit: number
110
+ ): TransactionInstruction[] {
111
+ const cacheKey: ComputeBudgetCacheKey = { unitPrice, unitLimit };
112
+ const key = getCacheKey(cacheKey);
113
+
114
+ let cachedInstructions = computeBudgetCache.get(key);
115
+
116
+ if (!cachedInstructions) {
117
+ cachedInstructions = [];
118
+
119
+ if (unitPrice > BigInt(0)) {
120
+ cachedInstructions.push(setComputeUnitPrice(unitPrice));
121
+ }
122
+
123
+ if (unitLimit > 0) {
124
+ cachedInstructions.push(setComputeUnitLimit(unitLimit));
125
+ }
126
+
127
+ computeBudgetCache.set(key, cachedInstructions);
128
+ }
129
+
130
+ return [...cachedInstructions]; // Return copy
131
+ }
132
+
133
+ /**
134
+ * Clear the compute budget cache
135
+ */
136
+ export function clearComputeBudgetCache(): void {
137
+ computeBudgetCache.clear();
138
+ }
139
+
140
+ // ===== Predefined Compute Budgets =====
141
+
142
+ export const COMPUTE_BUDGET_PRESETS = {
143
+ LOW: { unitLimit: 100_000, unitPrice: BigInt(1_000) },
144
+ MEDIUM: { unitLimit: 200_000, unitPrice: BigInt(10_000) },
145
+ HIGH: { unitLimit: 400_000, unitPrice: BigInt(50_000) },
146
+ VERY_HIGH: { unitLimit: 800_000, unitPrice: BigInt(100_000) },
147
+ MAX: { unitLimit: 1_400_000, unitPrice: BigInt(200_000) },
148
+ } as const;