@wallfree-dev/solana 0.13.43-beta.11 → 0.13.43-beta.12

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.
@@ -99,7 +99,100 @@ exports.SOLANA_UNITS_METADATA = {
99
99
  var SolanaProtocol = /** @class */ (function () {
100
100
  function SolanaProtocol(options) {
101
101
  this.options = options;
102
+ // Caches
103
+ this.priorityFeeCache = { data: null, timestamp: 0 };
104
+ this.rentExemptionCache = new Map();
102
105
  }
106
+ // Get minimum balance for rent exemption dynamically
107
+ // dataSize: size of account data in bytes
108
+ SolanaProtocol.prototype.getMinimumBalanceForRentExemption = function (dataSize) {
109
+ return __awaiter(this, void 0, void 0, function () {
110
+ var cached, now, rentExemption, e_1;
111
+ var _this = this;
112
+ return __generator(this, function (_a) {
113
+ switch (_a.label) {
114
+ case 0:
115
+ cached = this.rentExemptionCache.get(dataSize);
116
+ now = Date.now();
117
+ if (cached && (now - cached.timestamp) < SolanaProtocol.RENT_EXEMPTION_CACHE_TTL) {
118
+ return [2 /*return*/, cached.value];
119
+ }
120
+ _a.label = 1;
121
+ case 1:
122
+ _a.trys.push([1, 3, , 4]);
123
+ return [4 /*yield*/, this.withFallback(function (connection) { return __awaiter(_this, void 0, void 0, function () {
124
+ return __generator(this, function (_a) {
125
+ return [2 /*return*/, connection.getMinimumBalanceForRentExemption(dataSize)];
126
+ });
127
+ }); })];
128
+ case 2:
129
+ rentExemption = _a.sent();
130
+ this.rentExemptionCache.set(dataSize, { value: rentExemption, timestamp: now });
131
+ return [2 /*return*/, rentExemption];
132
+ case 3:
133
+ e_1 = _a.sent();
134
+ console.warn('[solana][getMinimumBalanceForRentExemption] Failed, using estimate:', e_1);
135
+ // Fallback calculation: ~6.96 lamports per byte + base overhead
136
+ // This is approximate and may not be accurate
137
+ return [2 /*return*/, Math.ceil(dataSize * 6.96 + 128 * 6.96)];
138
+ case 4: return [2 /*return*/];
139
+ }
140
+ });
141
+ });
142
+ };
143
+ // Simulate a transaction to get actual compute units consumed
144
+ SolanaProtocol.prototype.simulateTransaction = function (transaction) {
145
+ return __awaiter(this, void 0, void 0, function () {
146
+ var result, e_2;
147
+ var _this = this;
148
+ return __generator(this, function (_a) {
149
+ switch (_a.label) {
150
+ case 0:
151
+ _a.trys.push([0, 2, , 3]);
152
+ return [4 /*yield*/, this.withFallback(function (connection) { return __awaiter(_this, void 0, void 0, function () {
153
+ var blockhash;
154
+ return __generator(this, function (_a) {
155
+ switch (_a.label) {
156
+ case 0:
157
+ if (!!transaction.recentBlockhash) return [3 /*break*/, 2];
158
+ return [4 /*yield*/, connection.getLatestBlockhash()];
159
+ case 1:
160
+ blockhash = (_a.sent()).blockhash;
161
+ transaction.recentBlockhash = blockhash;
162
+ _a.label = 2;
163
+ case 2:
164
+ // For legacy Transaction, use the simple overload without config
165
+ // Pass undefined for signers to skip signature verification
166
+ return [2 /*return*/, connection.simulateTransaction(transaction)];
167
+ }
168
+ });
169
+ }); })];
170
+ case 1:
171
+ result = _a.sent();
172
+ if (result.value.err) {
173
+ return [2 /*return*/, {
174
+ success: false,
175
+ unitsConsumed: 0,
176
+ error: JSON.stringify(result.value.err)
177
+ }];
178
+ }
179
+ return [2 /*return*/, {
180
+ success: true,
181
+ unitsConsumed: result.value.unitsConsumed || 0
182
+ }];
183
+ case 2:
184
+ e_2 = _a.sent();
185
+ console.warn('[solana][simulateTransaction] Simulation failed:', e_2);
186
+ return [2 /*return*/, {
187
+ success: false,
188
+ unitsConsumed: 0,
189
+ error: String(e_2)
190
+ }];
191
+ case 3: return [2 /*return*/];
192
+ }
193
+ });
194
+ });
195
+ };
103
196
  // Helper for RPC calls with fallback to backup endpoints
104
197
  SolanaProtocol.prototype.withFallback = function (fn, maxRetries) {
105
198
  var _a, _b, _c, _d, _e;
@@ -116,7 +209,7 @@ var SolanaProtocol = /** @class */ (function () {
116
209
  if (!(_i < allUrls_1.length)) return [3 /*break*/, 6];
117
210
  rpcUrl = allUrls_1[_i];
118
211
  _loop_1 = function (retry) {
119
- var connection, _g, e_1, isTemporaryError;
212
+ var connection, _g, e_3, isTemporaryError;
120
213
  return __generator(this, function (_h) {
121
214
  switch (_h.label) {
122
215
  case 0:
@@ -126,13 +219,13 @@ var SolanaProtocol = /** @class */ (function () {
126
219
  return [4 /*yield*/, fn(connection)];
127
220
  case 1: return [2 /*return*/, (_g.value = _h.sent(), _g)];
128
221
  case 2:
129
- e_1 = _h.sent();
130
- lastError = e_1;
131
- isTemporaryError = ((_a = e_1 === null || e_1 === void 0 ? void 0 : e_1.message) === null || _a === void 0 ? void 0 : _a.includes('500')) ||
132
- ((_b = e_1 === null || e_1 === void 0 ? void 0 : e_1.message) === null || _b === void 0 ? void 0 : _b.includes('502')) ||
133
- ((_c = e_1 === null || e_1 === void 0 ? void 0 : e_1.message) === null || _c === void 0 ? void 0 : _c.includes('503')) ||
134
- ((_d = e_1 === null || e_1 === void 0 ? void 0 : e_1.message) === null || _d === void 0 ? void 0 : _d.includes('code":19')) ||
135
- ((_e = e_1 === null || e_1 === void 0 ? void 0 : e_1.message) === null || _e === void 0 ? void 0 : _e.includes('Temporary'));
222
+ e_3 = _h.sent();
223
+ lastError = e_3;
224
+ isTemporaryError = ((_a = e_3 === null || e_3 === void 0 ? void 0 : e_3.message) === null || _a === void 0 ? void 0 : _a.includes('500')) ||
225
+ ((_b = e_3 === null || e_3 === void 0 ? void 0 : e_3.message) === null || _b === void 0 ? void 0 : _b.includes('502')) ||
226
+ ((_c = e_3 === null || e_3 === void 0 ? void 0 : e_3.message) === null || _c === void 0 ? void 0 : _c.includes('503')) ||
227
+ ((_d = e_3 === null || e_3 === void 0 ? void 0 : e_3.message) === null || _d === void 0 ? void 0 : _d.includes('code":19')) ||
228
+ ((_e = e_3 === null || e_3 === void 0 ? void 0 : e_3.message) === null || _e === void 0 ? void 0 : _e.includes('Temporary'));
136
229
  if (!isTemporaryError) {
137
230
  return [2 /*return*/, "break"];
138
231
  }
@@ -169,6 +262,95 @@ var SolanaProtocol = /** @class */ (function () {
169
262
  });
170
263
  });
171
264
  };
265
+ // Get recent priority fees from the network
266
+ // Returns percentile-based estimates for different priority levels
267
+ SolanaProtocol.prototype.getRecentPriorityFees = function () {
268
+ return __awaiter(this, void 0, void 0, function () {
269
+ var now, recentFees, allFeeValues, hasNonZeroFees, feeValues, getPercentile, estimate, e_4;
270
+ var _this = this;
271
+ return __generator(this, function (_a) {
272
+ switch (_a.label) {
273
+ case 0:
274
+ now = Date.now();
275
+ // Use cached value if available
276
+ if (this.priorityFeeCache.data && (now - this.priorityFeeCache.timestamp) < SolanaProtocol.PRIORITY_FEE_CACHE_TTL) {
277
+ return [2 /*return*/, this.priorityFeeCache.data];
278
+ }
279
+ _a.label = 1;
280
+ case 1:
281
+ _a.trys.push([1, 3, , 4]);
282
+ return [4 /*yield*/, this.withFallback(function (connection) { return __awaiter(_this, void 0, void 0, function () {
283
+ return __generator(this, function (_a) {
284
+ // Get recent prioritization fees
285
+ // This returns fees from recent slots (typically last 150 slots)
286
+ return [2 /*return*/, connection.getRecentPrioritizationFees()];
287
+ });
288
+ }); })];
289
+ case 2:
290
+ recentFees = _a.sent();
291
+ if (!recentFees || recentFees.length === 0) {
292
+ // No recent fees data, return defaults
293
+ return [2 /*return*/, this.getDefaultPriorityFees()];
294
+ }
295
+ allFeeValues = recentFees.map(function (f) { return f.prioritizationFee; });
296
+ hasNonZeroFees = allFeeValues.some(function (f) { return f > 0; });
297
+ if (!hasNonZeroFees) {
298
+ // Network is idle, return zeros (no priority fee needed for fast confirmation)
299
+ return [2 /*return*/, {
300
+ none: 0,
301
+ low: 0,
302
+ medium: 0,
303
+ high: 0,
304
+ veryHigh: 0
305
+ }];
306
+ }
307
+ feeValues = allFeeValues
308
+ .filter(function (f) { return f > 0; })
309
+ .sort(function (a, b) { return a - b; });
310
+ if (feeValues.length === 0) {
311
+ // Shouldn't reach here due to hasNonZeroFees check, but just in case
312
+ return [2 /*return*/, this.getDefaultPriorityFees()];
313
+ }
314
+ getPercentile = function (arr, p) {
315
+ var index = Math.ceil((p / 100) * arr.length) - 1;
316
+ return arr[Math.max(0, Math.min(index, arr.length - 1))];
317
+ };
318
+ estimate = {
319
+ none: 0,
320
+ low: getPercentile(feeValues, 25),
321
+ medium: getPercentile(feeValues, 50),
322
+ high: getPercentile(feeValues, 75),
323
+ veryHigh: getPercentile(feeValues, 90)
324
+ };
325
+ // Cache the result
326
+ this.priorityFeeCache = { data: estimate, timestamp: now };
327
+ return [2 /*return*/, estimate];
328
+ case 3:
329
+ e_4 = _a.sent();
330
+ console.warn('[solana][getRecentPriorityFees] Failed to get priority fees:', e_4);
331
+ return [2 /*return*/, this.getDefaultPriorityFees()];
332
+ case 4: return [2 /*return*/];
333
+ }
334
+ });
335
+ });
336
+ };
337
+ // Default priority fees when network data is unavailable
338
+ SolanaProtocol.prototype.getDefaultPriorityFees = function () {
339
+ return {
340
+ none: 0,
341
+ low: 1000,
342
+ medium: 10000,
343
+ high: 100000,
344
+ veryHigh: 1000000 // 1000000 micro-lamports per CU
345
+ };
346
+ };
347
+ // Calculate total fee including priority fee
348
+ // priorityFeePerCU is in micro-lamports (1 lamport = 1,000,000 micro-lamports)
349
+ SolanaProtocol.prototype.calculateTotalFee = function (baseFee, priorityFeePerCU, computeUnits) {
350
+ // Priority fee = (computeUnits * priorityFeePerCU) / 1,000,000
351
+ var priorityFeeLamports = Math.ceil((computeUnits * priorityFeePerCU) / 1000000);
352
+ return baseFee + priorityFeeLamports;
353
+ };
172
354
  SolanaProtocol.prototype.getMetadata = function () {
173
355
  return __awaiter(this, void 0, void 0, function () {
174
356
  return __generator(this, function (_a) {
@@ -258,7 +440,7 @@ var SolanaProtocol = /** @class */ (function () {
258
440
  };
259
441
  SolanaProtocol.prototype.getBalanceOfAddress = function (address) {
260
442
  return __awaiter(this, void 0, void 0, function () {
261
- var pubKey, balance, e_2;
443
+ var pubKey, balance, e_5;
262
444
  var _this = this;
263
445
  return __generator(this, function (_a) {
264
446
  switch (_a.label) {
@@ -278,8 +460,8 @@ var SolanaProtocol = /** @class */ (function () {
278
460
  total: (0, module_kit_1.newAmount)(balance, 'Lamports')
279
461
  }];
280
462
  case 3:
281
- e_2 = _a.sent();
282
- console.error('[solana][balance][error]', e_2);
463
+ e_5 = _a.sent();
464
+ console.error('[solana][balance][error]', e_5);
283
465
  return [2 /*return*/, { total: (0, module_kit_1.newAmount)(0, 'Lamports') }];
284
466
  case 4: return [2 /*return*/];
285
467
  }
@@ -302,7 +484,7 @@ var SolanaProtocol = /** @class */ (function () {
302
484
  SolanaProtocol.prototype.getDetailsFromTransaction = function (transaction, publicKey) {
303
485
  var _a;
304
486
  return __awaiter(this, void 0, void 0, function () {
305
- var tx, fallbackFeePayer, _b, _c, _d, feePayer, firstIx, decoded, amountLamports, fromAddress, toAddress, fee, connection, feeInfo, e_3, e_4, fallbackTx;
487
+ var tx, fallbackFeePayer, _b, _c, _d, feePayer, firstIx, decoded, amountLamports, fromAddress, toAddress, fee, connection, feeInfo, e_6, e_7, fallbackTx;
306
488
  return __generator(this, function (_e) {
307
489
  switch (_e.label) {
308
490
  case 0:
@@ -342,7 +524,7 @@ var SolanaProtocol = /** @class */ (function () {
342
524
  fee = (0, module_kit_1.newAmount)((_a = feeInfo === null || feeInfo === void 0 ? void 0 : feeInfo.value) !== null && _a !== void 0 ? _a : 5000, 'Lamports');
343
525
  return [3 /*break*/, 7];
344
526
  case 6:
345
- e_3 = _e.sent();
527
+ e_6 = _e.sent();
346
528
  // Network unavailable (e.g., offline vault), use default fee
347
529
  console.warn('[solana][getDetailsFromTransaction] Network unavailable, using default fee');
348
530
  return [3 /*break*/, 7];
@@ -357,8 +539,8 @@ var SolanaProtocol = /** @class */ (function () {
357
539
  }
358
540
  ]];
359
541
  case 8:
360
- e_4 = _e.sent();
361
- console.error('[solana][getDetailsFromTransaction] Failed to parse transaction:', e_4);
542
+ e_7 = _e.sent();
543
+ console.error('[solana][getDetailsFromTransaction] Failed to parse transaction:', e_7);
362
544
  fallbackTx = {
363
545
  from: [],
364
546
  to: [],
@@ -512,14 +694,14 @@ var SolanaProtocol = /** @class */ (function () {
512
694
  });
513
695
  };
514
696
  SolanaProtocol.prototype.getTransactionsForAddress = function (address, limit, cursor) {
515
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
697
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0;
516
698
  return __awaiter(this, void 0, void 0, function () {
517
- var effectiveLimit, queryOptions_1, signatures, txs, _loop_2, this_1, _i, signatures_1, sigInfo, hasNext, lastSignature, newCursor, e_5;
699
+ var effectiveLimit, queryOptions_1, signatures, txs, _loop_2, this_1, _i, signatures_1, sigInfo, hasNext, lastSignature, newCursor, e_8;
518
700
  var _this = this;
519
- return __generator(this, function (_m) {
520
- switch (_m.label) {
701
+ return __generator(this, function (_1) {
702
+ switch (_1.label) {
521
703
  case 0:
522
- _m.trys.push([0, 6, , 7]);
704
+ _1.trys.push([0, 6, , 7]);
523
705
  effectiveLimit = limit || SolanaProtocol.DEFAULT_TX_LIMIT;
524
706
  queryOptions_1 = {
525
707
  limit: effectiveLimit
@@ -534,19 +716,19 @@ var SolanaProtocol = /** @class */ (function () {
534
716
  });
535
717
  }); })];
536
718
  case 1:
537
- signatures = _m.sent();
719
+ signatures = _1.sent();
538
720
  txs = [];
539
721
  _loop_2 = function (sigInfo) {
540
- var parsed, amount, fee, from, to, instructions, _o, instructions_1, ix, parsedIx, info, accountKeys, preBalances, postBalances, i, pubkeyStr, diff, sentAmount, blockTime, timestamp, e_6;
541
- return __generator(this, function (_p) {
542
- switch (_p.label) {
722
+ var parsed, amount, fee, from, to, foundRelevantTransfer, instructions, _2, instructions_1, ix, parsedIx, info, source, destination, accountKeys, preBalances, postBalances, ourBalanceChange, ourAddressIndex, i, pubkeyStr, totalSpent, txFee, sentAmount, i, diff, pubkeyStr, i, diff, pubkeyStr, isInbound, isOutbound, feePayerKey, feePayerStr, blockTime, timestamp, e_9;
723
+ return __generator(this, function (_3) {
724
+ switch (_3.label) {
543
725
  case 0:
544
726
  if (!sigInfo.signature) {
545
727
  return [2 /*return*/, "continue"];
546
728
  }
547
- _p.label = 1;
729
+ _3.label = 1;
548
730
  case 1:
549
- _p.trys.push([1, 3, , 4]);
731
+ _3.trys.push([1, 3, , 4]);
550
732
  return [4 /*yield*/, this_1.withFallback(function (connection) { return __awaiter(_this, void 0, void 0, function () {
551
733
  return __generator(this, function (_a) {
552
734
  return [2 /*return*/, connection.getParsedTransaction(sigInfo.signature, {
@@ -556,7 +738,7 @@ var SolanaProtocol = /** @class */ (function () {
556
738
  });
557
739
  }); })];
558
740
  case 2:
559
- parsed = _p.sent();
741
+ parsed = _3.sent();
560
742
  if (!parsed) {
561
743
  return [2 /*return*/, "continue"];
562
744
  }
@@ -564,50 +746,125 @@ var SolanaProtocol = /** @class */ (function () {
564
746
  fee = (0, module_kit_1.newAmount)((_b = (_a = parsed.meta) === null || _a === void 0 ? void 0 : _a.fee) !== null && _b !== void 0 ? _b : 0, 'Lamports');
565
747
  from = [];
566
748
  to = [];
749
+ foundRelevantTransfer = false;
567
750
  instructions = ((_d = (_c = parsed.transaction) === null || _c === void 0 ? void 0 : _c.message) === null || _d === void 0 ? void 0 : _d.instructions) || [];
568
- for (_o = 0, instructions_1 = instructions; _o < instructions_1.length; _o++) {
569
- ix = instructions_1[_o];
751
+ for (_2 = 0, instructions_1 = instructions; _2 < instructions_1.length; _2++) {
752
+ ix = instructions_1[_2];
570
753
  // Check if it's a parsed instruction (has 'parsed' property)
571
754
  if ('parsed' in ix && ix.parsed) {
572
755
  parsedIx = ix;
573
756
  if (parsedIx.program === 'system' && ((_e = parsedIx.parsed) === null || _e === void 0 ? void 0 : _e.type) === 'transfer') {
574
757
  info = parsedIx.parsed.info;
575
758
  if (info) {
576
- amount = (0, module_kit_1.newAmount)(((_f = info.lamports) === null || _f === void 0 ? void 0 : _f.toString()) || '0', 'Lamports');
577
- from = info.source ? [info.source] : [];
578
- to = info.destination ? [info.destination] : [];
579
- break;
759
+ source = info.source || '';
760
+ destination = info.destination || '';
761
+ // Only include transfers that involve our address
762
+ if (source === address || destination === address) {
763
+ foundRelevantTransfer = true;
764
+ amount = (0, module_kit_1.newAmount)(((_f = info.lamports) === null || _f === void 0 ? void 0 : _f.toString()) || '0', 'Lamports');
765
+ from = source ? [source] : [];
766
+ to = destination ? [destination] : [];
767
+ break;
768
+ }
580
769
  }
581
770
  }
582
771
  }
583
772
  }
584
773
  // Fallback: try to extract from preBalances/postBalances if transfer info not found
585
- if (from.length === 0 && to.length === 0 && parsed.meta) {
774
+ if (!foundRelevantTransfer && parsed.meta) {
586
775
  accountKeys = ((_h = (_g = parsed.transaction) === null || _g === void 0 ? void 0 : _g.message) === null || _h === void 0 ? void 0 : _h.accountKeys) || [];
587
776
  preBalances = parsed.meta.preBalances || [];
588
777
  postBalances = parsed.meta.postBalances || [];
778
+ ourBalanceChange = 0;
779
+ ourAddressIndex = -1;
589
780
  for (i = 0; i < accountKeys.length; i++) {
590
781
  pubkeyStr = typeof accountKeys[i] === 'string'
591
782
  ? accountKeys[i]
592
- : ((_j = accountKeys[i].pubkey) === null || _j === void 0 ? void 0 : _j.toString()) || accountKeys[i].toString();
593
- diff = (postBalances[i] || 0) - (preBalances[i] || 0);
594
- if (diff < 0) {
595
- // This account sent SOL (balance decreased)
596
- from.push(pubkeyStr);
597
- if (amount.value === '0') {
598
- sentAmount = Math.abs(diff) - (((_k = parsed.meta) === null || _k === void 0 ? void 0 : _k.fee) || 0);
599
- if (sentAmount > 0) {
600
- amount = (0, module_kit_1.newAmount)(sentAmount.toString(), 'Lamports');
783
+ : ((_k = (_j = accountKeys[i].pubkey) === null || _j === void 0 ? void 0 : _j.toBase58) === null || _k === void 0 ? void 0 : _k.call(_j)) || ((_l = accountKeys[i].pubkey) === null || _l === void 0 ? void 0 : _l.toString()) || accountKeys[i].toString();
784
+ if (pubkeyStr === address) {
785
+ ourAddressIndex = i;
786
+ ourBalanceChange = (postBalances[i] || 0) - (preBalances[i] || 0);
787
+ }
788
+ }
789
+ // If our SOL balance didn't change, this transaction is not relevant for SOL history
790
+ // (e.g., we're just an ATA owner in someone else's token transfer)
791
+ if (ourAddressIndex >= 0 && ourBalanceChange === 0) {
792
+ return [2 /*return*/, "continue"];
793
+ }
794
+ // Only consider this transaction relevant if our balance actually changed
795
+ if (ourAddressIndex >= 0 && ourBalanceChange !== 0) {
796
+ foundRelevantTransfer = true;
797
+ if (ourBalanceChange < 0) {
798
+ totalSpent = Math.abs(ourBalanceChange);
799
+ txFee = ((_m = parsed.meta) === null || _m === void 0 ? void 0 : _m.fee) || 0;
800
+ sentAmount = totalSpent - txFee;
801
+ // We are the sender
802
+ from = [address];
803
+ if (sentAmount > 0) {
804
+ // There was an actual SOL transfer beyond the fee
805
+ amount = (0, module_kit_1.newAmount)(sentAmount.toString(), 'Lamports');
806
+ // Find who received the SOL
807
+ for (i = 0; i < accountKeys.length; i++) {
808
+ if (i === ourAddressIndex)
809
+ continue;
810
+ diff = (postBalances[i] || 0) - (preBalances[i] || 0);
811
+ if (diff > 0) {
812
+ pubkeyStr = typeof accountKeys[i] === 'string'
813
+ ? accountKeys[i]
814
+ : ((_p = (_o = accountKeys[i].pubkey) === null || _o === void 0 ? void 0 : _o.toBase58) === null || _p === void 0 ? void 0 : _p.call(_o)) || ((_q = accountKeys[i].pubkey) === null || _q === void 0 ? void 0 : _q.toString()) || accountKeys[i].toString();
815
+ to.push(pubkeyStr);
816
+ }
601
817
  }
602
818
  }
819
+ else {
820
+ // Only fee was spent (e.g., token transfer, ATA creation)
821
+ // Show the transaction with amount = total spent (including fee)
822
+ amount = (0, module_kit_1.newAmount)(totalSpent.toString(), 'Lamports');
823
+ // No specific recipient for fee-only transactions
824
+ }
603
825
  }
604
- else if (diff > 0) {
605
- // This account received SOL (balance increased)
606
- to.push(pubkeyStr);
826
+ else {
827
+ // We received SOL (ourBalanceChange > 0)
828
+ amount = (0, module_kit_1.newAmount)(ourBalanceChange.toString(), 'Lamports');
829
+ to = [address];
830
+ // Find who sent us the SOL
831
+ for (i = 0; i < accountKeys.length; i++) {
832
+ if (i === ourAddressIndex)
833
+ continue;
834
+ diff = (postBalances[i] || 0) - (preBalances[i] || 0);
835
+ if (diff < 0) {
836
+ pubkeyStr = typeof accountKeys[i] === 'string'
837
+ ? accountKeys[i]
838
+ : ((_s = (_r = accountKeys[i].pubkey) === null || _r === void 0 ? void 0 : _r.toBase58) === null || _s === void 0 ? void 0 : _s.call(_r)) || ((_t = accountKeys[i].pubkey) === null || _t === void 0 ? void 0 : _t.toString()) || accountKeys[i].toString();
839
+ from.push(pubkeyStr);
840
+ }
841
+ }
607
842
  }
608
843
  }
609
844
  }
610
- blockTime = (_l = sigInfo.blockTime) !== null && _l !== void 0 ? _l : parsed.blockTime;
845
+ // Skip transactions that don't involve our address in a meaningful way
846
+ if (!foundRelevantTransfer) {
847
+ return [2 /*return*/, "continue"];
848
+ }
849
+ isInbound = to.includes(address);
850
+ isOutbound = from.includes(address);
851
+ // If neither contains our address, add it based on fee payment
852
+ // (fee payer is always in the transaction, so this ensures visibility)
853
+ if (!isInbound && !isOutbound) {
854
+ feePayerKey = (_w = (_v = (_u = parsed.transaction) === null || _u === void 0 ? void 0 : _u.message) === null || _v === void 0 ? void 0 : _v.accountKeys) === null || _w === void 0 ? void 0 : _w[0];
855
+ feePayerStr = typeof feePayerKey === 'string'
856
+ ? feePayerKey
857
+ : ((_y = (_x = feePayerKey === null || feePayerKey === void 0 ? void 0 : feePayerKey.pubkey) === null || _x === void 0 ? void 0 : _x.toBase58) === null || _y === void 0 ? void 0 : _y.call(_x)) || ((_z = feePayerKey === null || feePayerKey === void 0 ? void 0 : feePayerKey.pubkey) === null || _z === void 0 ? void 0 : _z.toString()) || (feePayerKey === null || feePayerKey === void 0 ? void 0 : feePayerKey.toString());
858
+ if (feePayerStr === address) {
859
+ from.push(address);
860
+ }
861
+ else {
862
+ // Transaction involves our address somehow, keep it visible
863
+ // This handles edge cases where address format doesn't match
864
+ from.push(address);
865
+ }
866
+ }
867
+ blockTime = (_0 = sigInfo.blockTime) !== null && _0 !== void 0 ? _0 : parsed.blockTime;
611
868
  timestamp = blockTime ? blockTime : Math.floor(Date.now() / 1000);
612
869
  txs.push({
613
870
  hash: sigInfo.signature,
@@ -617,12 +874,12 @@ var SolanaProtocol = /** @class */ (function () {
617
874
  fee: fee,
618
875
  from: from,
619
876
  to: to,
620
- isInbound: to.includes(address),
877
+ isInbound: isInbound,
621
878
  network: this_1.options.network
622
879
  });
623
880
  return [3 /*break*/, 4];
624
881
  case 3:
625
- e_6 = _p.sent();
882
+ e_9 = _3.sent();
626
883
  console.warn('[solana][getTransactionsForAddress] Failed to parse transaction:', sigInfo.signature);
627
884
  return [3 /*break*/, 4];
628
885
  case 4: return [2 /*return*/];
@@ -631,19 +888,19 @@ var SolanaProtocol = /** @class */ (function () {
631
888
  };
632
889
  this_1 = this;
633
890
  _i = 0, signatures_1 = signatures;
634
- _m.label = 2;
891
+ _1.label = 2;
635
892
  case 2:
636
893
  if (!(_i < signatures_1.length)) return [3 /*break*/, 5];
637
894
  sigInfo = signatures_1[_i];
638
895
  return [5 /*yield**/, _loop_2(sigInfo)];
639
896
  case 3:
640
- _m.sent();
641
- _m.label = 4;
897
+ _1.sent();
898
+ _1.label = 4;
642
899
  case 4:
643
900
  _i++;
644
901
  return [3 /*break*/, 2];
645
902
  case 5:
646
- hasNext = signatures.length === effectiveLimit;
903
+ hasNext = signatures.length > 0;
647
904
  lastSignature = signatures.length > 0 ? signatures[signatures.length - 1].signature : undefined;
648
905
  newCursor = {
649
906
  hasNext: hasNext,
@@ -654,8 +911,8 @@ var SolanaProtocol = /** @class */ (function () {
654
911
  cursor: newCursor
655
912
  }];
656
913
  case 6:
657
- e_5 = _m.sent();
658
- console.error('[solana][getTransactionsForAddress] Failed:', e_5);
914
+ e_8 = _1.sent();
915
+ console.error('[solana][getTransactionsForAddress] Failed:', e_8);
659
916
  return [2 /*return*/, {
660
917
  transactions: [],
661
918
  cursor: { hasNext: false }
@@ -728,7 +985,7 @@ var SolanaProtocol = /** @class */ (function () {
728
985
  };
729
986
  SolanaProtocol.prototype.getTransactionFeeWithPublicKey = function (publicKey, details, configuration) {
730
987
  return __awaiter(this, void 0, void 0, function () {
731
- var fromAddress, fromPubkey, transaction, _i, details_1, detail, lamportsFee;
988
+ var fromAddress, fromPubkey, transaction, _i, details_1, detail, baseFee, feeResult, e_10, computeUnits, simulation, e_11, priorityFees, lowFee, mediumFee, highFee;
732
989
  var _this = this;
733
990
  return __generator(this, function (_a) {
734
991
  switch (_a.label) {
@@ -746,28 +1003,67 @@ var SolanaProtocol = /** @class */ (function () {
746
1003
  }));
747
1004
  }
748
1005
  transaction.feePayer = fromPubkey;
1006
+ baseFee = SolanaProtocol.DEFAULT_BASE_FEE_LAMPORTS;
1007
+ _a.label = 2;
1008
+ case 2:
1009
+ _a.trys.push([2, 4, , 5]);
749
1010
  return [4 /*yield*/, this.withFallback(function (connection) { return __awaiter(_this, void 0, void 0, function () {
750
- var latestBlockhash, feeForMessage;
751
- var _a;
752
- return __generator(this, function (_b) {
753
- switch (_b.label) {
1011
+ var blockhash, feeForMessage;
1012
+ return __generator(this, function (_a) {
1013
+ switch (_a.label) {
754
1014
  case 0: return [4 /*yield*/, connection.getLatestBlockhash()];
755
1015
  case 1:
756
- latestBlockhash = _b.sent();
757
- transaction.recentBlockhash = latestBlockhash.blockhash;
1016
+ blockhash = (_a.sent()).blockhash;
1017
+ transaction.recentBlockhash = blockhash;
758
1018
  return [4 /*yield*/, connection.getFeeForMessage(transaction.compileMessage())];
759
1019
  case 2:
760
- feeForMessage = _b.sent();
761
- return [2 /*return*/, (_a = feeForMessage === null || feeForMessage === void 0 ? void 0 : feeForMessage.value) !== null && _a !== void 0 ? _a : 5000];
1020
+ feeForMessage = _a.sent();
1021
+ return [2 /*return*/, feeForMessage === null || feeForMessage === void 0 ? void 0 : feeForMessage.value];
762
1022
  }
763
1023
  });
764
- }); }).catch(function () { return 5000; })];
765
- case 2:
766
- lamportsFee = _a.sent();
1024
+ }); })];
1025
+ case 3:
1026
+ feeResult = _a.sent();
1027
+ if (feeResult && feeResult > 0) {
1028
+ baseFee = feeResult;
1029
+ }
1030
+ return [3 /*break*/, 5];
1031
+ case 4:
1032
+ e_10 = _a.sent();
1033
+ console.warn('[solana][getTransactionFeeWithPublicKey] Failed to get base fee from network:', e_10);
1034
+ return [3 /*break*/, 5];
1035
+ case 5:
1036
+ computeUnits = details.length * SolanaProtocol.DEFAULT_SOL_TRANSFER_CU // Fallback
1037
+ ;
1038
+ _a.label = 6;
1039
+ case 6:
1040
+ _a.trys.push([6, 8, , 9]);
1041
+ return [4 /*yield*/, this.simulateTransaction(transaction)];
1042
+ case 7:
1043
+ simulation = _a.sent();
1044
+ if (simulation.success && simulation.unitsConsumed > 0) {
1045
+ computeUnits = simulation.unitsConsumed;
1046
+ }
1047
+ return [3 /*break*/, 9];
1048
+ case 8:
1049
+ e_11 = _a.sent();
1050
+ console.warn('[solana][getTransactionFeeWithPublicKey] Simulation failed, using default CU:', e_11);
1051
+ return [3 /*break*/, 9];
1052
+ case 9: return [4 /*yield*/, this.getRecentPriorityFees()
1053
+ // Calculate total fees for each tier
1054
+ // low: base fee only (no priority fee) - may be slow during congestion
1055
+ // medium: base fee + median priority fee - reasonable confirmation time
1056
+ // high: base fee + 75th percentile priority fee - fast confirmation
1057
+ ];
1058
+ case 10:
1059
+ priorityFees = _a.sent();
1060
+ lowFee = baseFee;
1061
+ mediumFee = this.calculateTotalFee(baseFee, priorityFees.medium, computeUnits);
1062
+ highFee = this.calculateTotalFee(baseFee, priorityFees.high, computeUnits);
767
1063
  return [2 /*return*/, {
768
- low: (0, module_kit_1.newAmount)(lamportsFee, 'Lamports'),
769
- medium: (0, module_kit_1.newAmount)(lamportsFee, 'Lamports'),
770
- high: (0, module_kit_1.newAmount)(lamportsFee, 'Lamports')
1064
+ low: (0, module_kit_1.newAmount)(lowFee, 'Lamports'),
1065
+ medium: (0, module_kit_1.newAmount)(mediumFee, 'Lamports'),
1066
+ high: (0, module_kit_1.newAmount)(highFee, 'Lamports')
771
1067
  }];
772
1068
  }
773
1069
  });
@@ -847,6 +1143,13 @@ var SolanaProtocol = /** @class */ (function () {
847
1143
  SolanaProtocol.FALLBACK_RPC_URLS = [
848
1144
  'https://solana.drpc.org'
849
1145
  ];
1146
+ // Default fee constants (fallback when network queries fail)
1147
+ // These are only used as fallbacks - actual values are fetched from network
1148
+ SolanaProtocol.DEFAULT_BASE_FEE_LAMPORTS = 5000;
1149
+ SolanaProtocol.DEFAULT_SOL_TRANSFER_CU = 450; // Fallback CU for SOL transfer
1150
+ // Cache configuration
1151
+ SolanaProtocol.PRIORITY_FEE_CACHE_TTL = 30000; // 30 seconds
1152
+ SolanaProtocol.RENT_EXEMPTION_CACHE_TTL = 300000; // 5 minutes (rarely changes)
850
1153
  // Default number of transactions to fetch per page
851
1154
  SolanaProtocol.DEFAULT_TX_LIMIT = 10;
852
1155
  return SolanaProtocol;